ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [IaC] Terraform 모범 사례 & 컨벤션 💫
    DevOps/Terraform 2021. 6. 11. 22:14

    📌 테라폼 문서


    ✨ 문서화 모범 사례

    테라폼 코드는 그 자체로 문서의 한 형태입니다. 간단한 언어로 배포한 인프라와 인프라 구성 방법을 정확하게 설명하고 있으나 자체 문서화 코드는 없습니다.

    잘 쓰인 코드는 어떤 기능을 하는지 잘 알려주지만, 왜 그렇게 하는지 설명하지 않습니다. 그렇기 때문에 IaC를 포함한 모든 소프트웨어가 코드 자체를 넘어서는 문서가 필요합니다.

    🚀 정의된 문서

    github VPC Module 저장소의 README.md 문서를 참고하세요. 😉

    🧩 정의된 문서(README)를 사용해야 하는 이유

    🌈 테라폼 모듈에는 용도, 사용 이유, 사용 및 수정 방법을 설명하는 Readme가 있어야 합니다.

    🌈 테라폼 코드 작성보다 먼저 Readme를 작성하는 것이 좋습니다.

    • RDD (Readme Driven Development)
    • 코드 작성을 고려하기 전에 무엇을 빌드할지 이유를 고려해야 합니다.
    • 작성하는 데 약간에 시간이 걸리더라도 나중에 코드 작성 시간을 줄이고 오류를 최소하고 코드 작성 시간을 절약할 수 있다.

    🌈 Readme 의 기본 정보 외에도 튜토리얼, API 문서, 위키 페이지 및 코드가 어떻게 동작하는지, 왜 이렇게 작성되었는지에 대한 설명하는 디자인 문서가 필요합니다.

     

    🚀 코드화된 문서

    github VPC Module 저장소의 main.tf 파일을 참고하세요 😉
    github VPC Module 저장소의 variables.tf 파일을 참고하세요 😁

    🧩 코드화된 문서를 사용하자

    ######
    # VPC
    ######
    resource "aws_vpc" "this" {
      count = var.create_vpc ? 1 : 0
    ...
    }
    ###################
    # DHCP Options Set
    ###################
    resource "aws_vpc_dhcp_options" "this" {
      count = var.create_vpc && var.enable_dhcp_options ? 1 : 0
    ...
    }

    🌈 코드 자체 내에서 주석을 문서 형식으로 사용합니다.

    🌈 테라폼은 해시(#)로 시작하는 모든 텍스트를 주석 처리 합니다.

    🌈 코드의 사용 방법이나 코드가 특정 디자인 선택을 사용하는 이유와 같이 코드에서 표현할 수 없는 정보를 제공하는 주석만 포함 합니다.

    코드가 하는 일을 설명하기 위해 주석(#)을 사용하면 안됩니다.

    🌈 테라폼을 사용하면 모든 입력 변수(Input variable) 설명 매개변수를 선언할 수 있으며, 설명 매개변수는 변수의 사용 방법을 설명합니다.

    variable "create_vpc" {
      description = "Controls if VPC should be created (it affects almost all resources)"
      type = bool
      default = true
    }

    🌈 테라폼 언어는 주석에 대해 세 가지 다른 구문을 지원합니다.

    • # 한 줄 주석을 시작하고 줄 끝에서 끝납니다.
    • // 또한 한 줄 주석을 시작합니다.
    • /* 시작하고 */ 끝으로 여러 줄 이상에 걸쳐 수 있는 코멘트에 대한 최종 구분 기호입니다.

    #한 줄 주석 스타일은 기본 주석 스타일이며 대부분의 경우에 사용한다. 자동 구성 서식 도구는 이중 슬래시 스타일이 관용적이지 않기 때문에 //주석을 #주석 으로 자동 변환 할 수 있습니다 .

     

    🚀 예제 코드

    github VPC Module 저장소의 example 디렉토리를 참고하세요.😘
    github My Module 저장소의 exmaple 디렉토리를 참고하세요. 😛

    🧩 예제 코드 사용

    🌈 테라폼 모듈을 개발할 때 해당 모듈의 사용 방법을 보여주는 예제 코드를 만들 수 있습니다.

    🌈 올바른 사용법 패턴을 강조하는 훌륭한 방법이자 사용자가 코드를 작성하지 않고도 모듈을 사용하는 방법입니다.

    🌈 예제 코드를 통해 자동화된 테스트를 추가하기에도 좋습니다.

     

    📌 테라폼 스타일


    ✨ Terraform 스타일 규칙

    Terraform 파서는 구성 파일에 요소를 배치하는 방법에 약간의 유연성을 허용하지만 Terraform 언어에는 사용자가 서로 다른 팀에서 작성한 파일과 모듈 간의 일관성을 위해 항상 따르도록 권장하는 관용적 스타일 규칙도 있습니다. 자동 소스 코드 서식 도구는 이러한 규칙을 자동으로 적용 할 수 있습니다.

    • 각 중첩 수준에 대해 두 개의 공백을 들여 씁니다.
    • 한 줄 값이 있는 여러 인수가 동일한 중첩 수준에서 연속 줄에 나타날 경우 등호(=)를 정렬합니다.
    ami = "abc123"
    instance_type = "t2.micro"
    • 인수와 블록이 모두 블록 본문 안에 함께 나타나면 모든 인수를 맨 위에 함께 배치 한 다음 그 아래에 중첩 된 블록을 배치합니다. 하나의 빈 행을 사용하여 블록에서 인수를 분리하십시오.
    • 블록 내에서 인수의 논리 그룹을 구분하려면 빈 줄을 사용하십시오.
    • 인수와 “meta-arguments”를 모두 포함하는 블록의 경우 먼저 메타 인수를 나열하고 하나의 빈 줄로 다른 인수와 구분합니다.
    • 메타 인수 블록을 마지막에 놓고 하나의 빈 줄로 다른 블록과 분리합니다.
    resource "aws_instance" "example" {
      count = 2 # meta-argument first  
      ami           = "abc123"   
      instance_type = "t2.micro"    
      network_interface {
        # ...   
      }
      lifecycle { # meta-argument block last
        create_before_destroy = true
      }
    }
    • 최상위 블록은 항상 하나의 빈 줄로 서로 분리되어야 합니다.
      중첩 된 블록은 동일한 유형의 관련 블록을 함께 그룹화하는 경우를 제외하고는 빈 줄로도 구분되어야 합니다 (예 provisioner: 리소스의 여러 블록).
    • 블록 유형이 의미론으로 정의되어 패밀리를 형성하지 않는 한, 동일한 유형의 여러 블록을 다른 유형의 다른 블록과 분리하지 않아야 합니다. (예 : root_block_device, ebs_block_device및 ephemeral_block_deviceon aws_instance은 AWS 블록 디바이스를 설명하는 블록 유형 패밀리를 형성하므로 함께 그룹화하고 혼합 할 수 있습니다.)

     

    📌 테라폼 모듈


    ✨ 모듈 모범 사례

    Terraform 모듈은 대부분의 프로그래밍 언어에서 볼 수 있는 라이브러리, 패키지 또는 모듈의 개념과 유사하며 동일한 이점 제공합니다.

    🚀 테라폼 모범 사례

    🧩 Terraform 실무자는 다음 모범 사례에 따라 모듈을 사용

    🌈 모듈을 염두하고 HCL을 작성

    • 한 사람이 관리하는 적당히 복잡한 Terraform 구성의 경우에도 모듈을 올바르게 사용하는 데 걸리는 시간보다 모듈 사용의 이점이 더 큽니다.

    🌈 로컬 모듈을 사용하여 코드를 구성하고 캡슐화

    • 원격 모듈을 사용하거나 게시하지 않더라도 처음부터 모듈 측면에서 HCL을 구성하면 인프라가 복잡해짐에 따라 구성을 유지 관리하고 업데이트하는 부담이 크게 줄어 듭니다.

    🌈 공용 Terraform 레지스트리를 사용하여 유용한 모듈을 검색

    • 이렇게 하면 다른 사람의 작업에 의존하여 공통 인프라 시나리오를 구현함으로써 보다 빠르고 확실하게 구성을 구현할 수 있습니다.

    🌈 모듈을 게시하고 공유

    • 대부분의 인프라는 팀원에 의해 관리되며 모듈은 팀이 인프라를 만들고 유지 관리하기 위해 협력 할 수 있는 중요한 방법입니다. 앞서 언급했듯이 모듈을 공개 또는 비공개로 게시 할 수 있습니다.

     

    ✨ 모듈 개발 (권장 패턴)

    사전 구축 된 HCL을 사용하는 테라폼 사용자의 도입 속도를 높이고 진입 장벽을 낮춥니다.

    가능한 명확한 구성 및 DRY ( “Don’t Repeat Yourself”) 원칙과 같은 코딩 모범 사례를 사용합니다.

     

    🚀 모듈 생성 워크 플로우

    새 모듈을 만드는 첫 단계는 얼리 어답터(early adopter)팀👨🏻‍🤝‍👨🏻 을 찾고 요구 사항을 수집하는 일입니다. 😉

    🧩 얼리 어답터(early adopter)팀👨🏻‍🤝‍👨🏻과 협력하면 좋은점

    🌈 충분히 유연하게 모듈 기능을 연마할 수 있습니다.

    🌈 최소한의 코드 변경으로 유사한 요구 사항 신속 처리합니다.

    🌈 코드 중복이 제거되고 출시 시간을 단축 시킵니다.

     

    🚀 요구 사항을 적절한 모듈로 범위 지정

    모듈은 한 가지를 잘 수행하도록 독립적으로 설계하고, 처음에 모듈의 범위를 지정할 때 작고 간단한 시작을 목표로 합시다. 😁

    🧩 모듈을 만들 때 고려 할 사항

    🌈 캡슐화 : 항상 함께 배포되는 그룹 인프라

    • 모듈에 더 많은 인프라을 포함시키면 사용자가 좀 더 쉽게 배포 할 수 있지만 모듈의 목적과 요구 사항을 이해하기가 어려워집니다.

    🌈 권한 : 모듈을 권한 경계로 제한

    • 모듈의 인프라가 둘 이상의 그룹의 책임인 경우 해당 모듈을 사용하면 실수로 업무 분리를 위반할 수 있습니다. 권한 경계 내의 리소스만 그룹화하여 인프라 분리해서 인프라를 보호 해야 합니다.

    🌈 변동성 : 수명이 긴 인프라와 수명이 짧은 인프라 분리

    • 예를 들어, DB 인프라는 비교적 정적이지만 APP서버는 하루에도 여러 번 배포할 수가 있습니다. APP서버와 동일한 모듈에서 DB 인프라를 관리하면 불필요한 변동과 위험에 노출됩니다.

     

    🚀 모듈 MVP 만들기

    모든 코드와 마찬가지로 모듈은 완전하지 않고, 항상 새로운 모듈 요구 사항과 변경 사항이 있습니다. 이를 수용하고 최소 실행 가능한 제품 (MVP) 표준을 충족하는 처음 몇 가지 모듈 버전을 목표로 합니다. 😀

    🧩 모듈을 만들 때 고려 할 사항

    🌈 항상 사용 사례의 80% 이상에서 작동하는 모듈을 제공하는 것을 목표로 합니다.

    🌈 모듈은 가장 일반적으로 수정되는 인수만 변수로 노출하고, 처음에 모듈은 가장 필요할 가능성이 높은 변수만 사용합니다.

    🌈 현재 사용하고 있지 않더라도 모듈 MVP에서 가능한 한 많은 정보를 출력합니다.

    • 모듈의 출력을 다음 모듈의 입력으로 사용하여 여러 모듈을 자주 사용하는 최종 사용자에게 모듈이 더 유용합니다.

     

    🚀 MVP 범위 지정 살펴보기 (예제)

    팀은 Terraform을 사용하여 인프라, 웹 계층 애플리케이션 및 앱 계층 애플리케이션을 프로비저닝하려고합니다. 이를 수용하고 최소 실행 가능한 제품 (MVP) 표준을 충족하는 처음 몇 가지 모듈 버전을 목표로 합니다. 😀

    🧩 네트워크 모듈

    네트워크 모듈은 인프라의 네트워킹을 담당합니다. 여기에는 VPC, Subnet, Routing Table, NAT G/W를 포함하는데, 필요한 경우 NACL 및 Peering 등을 포함할 수 있습니다.

    🌈 네트워크 모듈에는 높은 권한  낮은 변동성이 있기 때문에 이러한 리소스가 포함됩니다.

    • 네트워크 리소스를 만들거나 수정할 권한이 있는 구성원만이 모듈을 사용할 수 있어야 합니다.
    • 이 모듈의 리소스는 자주 변경되지 않기 때문에 자체 모듈로 그룹화하면 불필요한 위험으로부터 보호됩니다.

    🧩 웹 애플리케이션 모듈

    웹 모듈은 웹 애플리케이션을 실행하는 데 필요한 인프라를 생성하고 관리합니다. 여기에는 로드 밸런서 및 오토스켈링 그룹이 포함됩니다. 또한 EC2 인스턴스, 애플리케이션 내부 보안 그룹 및 로깅이 포함될 수 있습니다

    🌈 웹 모듈에는 캡슐화 되고 변동성 이 높기 때문에 이러한 리소스가 포함됩니다.

    • 이 모듈의 리소스는 범위가 엄격하고 특히 웹 애플리케이션과 연결되어 있습니다. 웹 애플리케이션 구성원이 쉽게 배포 할 수 있도록 단일 모듈로 그룹화 합니다.
    • 모듈의 리소스는 코드 릴리스마다 자주 변경 됩니다. 자체 모듈로 분리하면 불필요한 변동과 다른 모듈에 대한 위험을 줄일 수 있습니다.

    🧩 데이터베이스 모듈

    데이터베이스 모듈은 데이터베이스를 실행하는 데 필요한 인프라를 생성하고 관리합니다. 여기에는 애플리케이션에서 참조하는 RDS 인스턴스가 포함됩니다. 또한 모든 관련 스토리지, 모든 백업 데이터 및 로깅을 포함 할 수 있습니다.

    🌈 데이터베이스 모듈에는 리소스가 높은 권한 을 갖고 변동성 이 낮기 때문에 이러한 리소스가 포함됩니다.

    • 데이터베이스 리소스를 만들거나 수정할 권한이 있는 구성원만이 모듈을 사용할 수 있어야 합니다.
    • 팀은 이 모듈의 리소스를 자주 변경하지 않을 것이므로 별도의 모듈로 만들면 불필요한 이탈과 위험이 줄어 듭니다.

     

    🚀 일관된 모듈 구조 정의 및 사용

    모듈 구조는 취향의 문제이지만 모듈 구조를 문서화하고 모든 모듈의 일관성을 유지해야 합니다. 😀

    🧩 모듈 구조를 일관되게 유지하려면

    🌈 모듈에 있어야 하는 .tf 파일 목록과 포함 해야 하는 내용을 정의 합니다.

    🌈 모듈에 대해 .gitignore 정의 합니다.

    # Local .terraform directories
    **/.terraform/*
    # .tfstate files
    *.tfstate
    *.tfstate.*

    🌈 변수의 예를 제공하는 표준 방법을 만듭니다. (예 : terraform.tfvars.example)

    🌈 비어있는 경우에도 정의 된 디렉토리 세트와 함께 일관된 디렉토리 구조를 사용합니다.

    🌈 모든 모듈 디렉토리에는 그 README안에 있는 파일의 용도와 사용에 대한 세부 정보를 작성합니다.

     

    🚀 소스 제어를 사용하여 모듈 추적

    Terraform 모듈은 모든 좋은 코드 사례를 준수해야 합니다. 😀

    🧩 Terraform 모듈은 모든 좋은 코드 사례를 준수

    🌈 소스 제어에 모듈을 배치하여 릴리스 버전, 협업 및 변경 추적 감사를 관리합니다.

    🌈 마스터에 모든 릴리스에 태그 및 문서화 (CHANGELOG, README 사용)

    🌈 마스터에 대한 모든 변경 사항을 코드 검토합니다.

    🌈 모듈 사용자가 태그로 참조하도록 권장합니다.

    # ref인수의 값은 git checkout분기 및 태그 이름을 포함 하여 명령에서 허용되는 모든 참조
    module "vpc" {
      source = "git::<https://example.com/vpc.git?ref=v1.2.0>"
    }

    🌈 각 모듈에 소유자를 지정합니다.

    🌈 저장소 당 하나의 모듈만 사용합니다.

    • 모듈이 멱등성을 유지하고 라이브러리로 작동하는데 중요합니다.
    • 태그가 지정된 릴리스는 비공개 모듈 레지스트리에 대한 요구 사항

     

    📌 코드로서의 협업 인프라


    🚀 collaborative infrastructure as code

    • 조직 내의 사용자들이 Terraform으로 인프라스트럭처를 안전하게 프로비저닝 할 수 있고 이때 충돌이 발생하지 않으며 접근 권한을 명확하게 이해할 수 있습니다.
    • 조직 내의 전문가가 표준화된 인프라스트럭처 템플릿을 만들 수 있고 초심자는 조직의 인프라스트럭처 권장 사용사례를 따르기 위해 이 템플릿을 사용할 수 있습니다.
    • 워크스페이스의 접근제어로 워크스페이스의 커미터와 승인자가 프로덕션 환경을 보호할 수 있다.
    • Terraform을 직접 작성하지 않는 기능 그룹은 인프라스트럭처의 상태를 볼 수 있고 Terraform Enterprise의 UI로 변경할 수 있다.

     

    🚀 Terraform Cloud & Enterprise 워크플로우

    모듈을 생성하여 조직이 바라는 검증되고 안전하고 표준화된 인프라를 효율적으로 프로비저닝 합니다. 😀

    🌈 코드로 재사용 가능한 템플릿 인프라

    🌈 필요에 따라 가변적 값 정의

    🌈 Producer 👨🏻‍💻는 워크스페이스를 기반으로 모듈을 생성

    🌈 모듈의 레지스트리에 등록하여 탐색 가능하도록 작업

    🌈 Cunsumer👨🏻‍🚀는 레지스트리를 활용하여 애플리케이션에 필요한 인프라 생성

    'DevOps > Terraform' 카테고리의 다른 글

    Terraform 작동 방식 ✨  (0) 2021.07.16

    댓글

작은거인's Blog / Designed by TISTORY