Terraform 사용시 모범 사례 [닫힘]


111

인프라를 테라 폼으로 교체하는 중입니다. 실제로 테라 폼 파일과 상태를 관리하는 가장 좋은 방법은 무엇입니까? 코드로서의 인프라라는 것을 알고 있으며 .tf 파일을 git로 커밋하지만 tfstate도 커밋합니까? S3 같은 곳에 있어야합니까? 결국 CI가이 모든 것을 관리하기를 원하지만, 그 정도가 너무 길어서 파일의 움직이는 부분을 파악해야합니다.

저는 실제로 사람들이 실제로 이런 유형의 물건을 프로덕션에 활용하는 방법을 찾고 있습니다.

답변:


85

또한 기존 AWS 인프라를 Terraform으로 마이그레이션하는 중이므로 개발할 때 답변을 업데이트하는 것을 목표로합니다.

나는 내가 불확실한 영역을 구체화하기 위해 공식 Terraform 예제 와 여러 번의 시행 착오 에 크게 의존해 왔습니다.

.tfstate 파일

Terraform 구성을 사용하여 각기 다른 상태를 가질 수있는 서로 다른 인프라에 많은 상자를 프로비저닝 할 수 있습니다. 여러 사람이 실행할 수도 있으므로이 상태는 중앙 위치 (예 : S3)에 있어야하지만 git이 아니 어야합니다 .

이것은 Terraform을 보면 확인할 수 있습니다 .gitignore.

개발자 제어

우리의 목표는 전체 감사 (git 로그) 및 온 전성 검사 변경 (pull 요청) 기능을 유지하면서 개발자에게 인프라에 대한 더 많은 제어를 제공하는 것입니다. 이를 염두에두고 내가 목표로하는 새로운 인프라 워크 플로는 다음과 같습니다.

  1. 퍼펫과 같은 재사용 가능한 모듈을 포함하는 공통 AMI의 기본 기반.
  2. Terraform을 사용하여 DevOps에서 프로비저닝 한 핵심 인프라.
  3. 개발자는 필요에 따라 Git에서 Terraform 구성을 변경합니다 (인스턴스 수, 새 VPC, 지역 / 가용성 영역 추가 등).
  4. Git 구성이 푸시되고 풀 요청이 제출되어 DevOps 스쿼드의 구성원이 온 전성을 확인했습니다.
  5. 승인 된 경우 웹훅을 CI에 호출하여 빌드 및 배포 (현재 여러 환경을 분할하는 방법을 알 수 없음)

편집 1-현재 상태 업데이트

이 답변을 시작한 이후로 많은 TF 코드를 작성했으며 우리의 상황이 더 편안해졌습니다. 우리는 그 과정에서 버그와 제한에 부딪 혔지만 이것이 새롭고 빠르게 변화하는 소프트웨어를 사용하는 특징이라는 점을 인정합니다.

나열한 것

각각 여러 서브넷이있는 여러 VPC가있는 복잡한 AWS 인프라가 있습니다. 이를 쉽게 관리하기위한 핵심은 인프라 코드 (테라 폼 및 퍼펫 모두)를 구성하는 데 사용할 수있는 지역, 환경, 서비스 및 소유자를 포함하는 유연한 분류를 정의하는 것이 었습니다.

모듈

다음 단계는 terraform 모듈을 저장할 단일 git 저장소를 만드는 것이 었습니다. 모듈의 최상위 디렉토리 구조는 다음과 같습니다.

tree -L 1 .

결과:

├── README.md
├── aws-asg
├── aws-ec2
├── aws-elb
├── aws-rds
├── aws-sg
├── aws-vpc
└── templates

각각은 정상적인 기본값을 설정하지만 "glue"로 덮어 쓸 수있는 변수로 노출합니다.

접착제

glue위에서 언급 한 모듈을 사용 하는 두 번째 저장소 가 있습니다. 분류 문서에 따라 배치됩니다.

.
├── README.md
├── clientA
   ├── eu-west-1
      └── dev
   └── us-east-1
       └── dev
├── clientB
   ├── eu-west-1
      ├── dev
      ├── ec2-keys.tf
      ├── prod
      └── terraform.tfstate
   ├── iam.tf
   ├── terraform.tfstate
   └── terraform.tfstate.backup
└── clientC
    ├── eu-west-1
       ├── aws.tf
       ├── dev
       ├── iam-roles.tf
       ├── ec2-keys.tf
       ├── prod
       ├── stg
       └── terraform.tfstate
    └── iam.tf

클라이언트 수준에는 .tf글로벌 리소스 (예 : IAM 역할)를 프로비저닝하는 AWS 계정 별 파일이 있습니다. 다음은 EC2 SSH 퍼블릭 키가있는 지역 수준입니다. 마지막 환경 (년 dev, stg, prod등) 우리 VPC 셋업, 인스턴스의 생성 등에 연결 저장된 피어링된다.

참고 사항 : 보시다시피 나는 terraform.tfstategit에 보관하는 것보다 위의 내 조언 에 어긋납니다. 이것은 내가 S3로 이동할 때까지 일시적인 조치이지만 현재 유일한 개발자이므로 나에게 적합합니다.

다음 단계

이것은 여전히 ​​수동 프로세스이며 Jenkins에는 없지만 우리는 다소 크고 복잡한 인프라를 포팅하고 있습니다. 내가 말했듯이 버그는 거의 없지만 잘되고 있습니다!

편집 2-변경

이 초기 답변을 작성한 지 거의 1 년이 지났고 Terraform과 저의 상태가 크게 변경되었습니다. 저는 이제 Terraform을 사용하여 Azure 클러스터를 관리하는 새로운 위치에 있으며 Terraform은 이제 v0.10.7.

상태

사람들은 계속 저 상태가되어야 말한 하지 힘내 갈 - 그리고 그들은 정확합니다. 우리는 이것을 개발자 커뮤니케이션과 규율에 의존하는 2 인 팀의 임시 조치로 사용했습니다. 더 큰 규모의 분산 된 팀과 함께 이제 DynamoDB에서 제공하는 잠금 을 통해 S3의 원격 상태를 완전히 활용 하고 있습니다. 이상적으로 이것은 consul로 마이그레이션 될 것입니다. 이제는 크로스 클라우드 공급자를 잘라 내기위한 v1.0입니다.

모듈

이전에는 내부 모듈을 만들고 사용했습니다. 이것은 여전히 ​​사례이지만 Terraform 레지스트리 의 출현과 성장으로 우리는 이것을 적어도 기반으로 사용하려고합니다.

파일 구조

새로운 위치는 infx 환경 devprod. 각각은 자신의 변수와 출력을 가지고 있으며 위에서 만든 모듈을 재사용합니다. remote_state제공자는 또한 환경 사이에 작성된 자원의 출력을 공유하는 데 도움이됩니다. 시나리오는 전역 적으로 관리되는 TLD에 대한 서로 다른 Azure 리소스 그룹의 하위 도메인입니다.

├── main.tf
├── dev
   ├── main.tf
   ├── output.tf
   └── variables.tf
└── prod
    ├── main.tf
    ├── output.tf
    └── variables.tf

계획

다시 분산 된 팀의 추가 과제로 인해 이제 우리는 항상 terraform plan명령 출력을 저장합니다 . 우리는 검사와 사이에 변화의 위험없이 실행됩니다 알 수 planapply(잠금이 함께 할 수 있지만) 단계. 이 계획 파일은 잠재적으로 일반 텍스트 "비밀"변수를 포함 할 수 있으므로 삭제해야합니다.

전반적으로 우리는 Terraform에 매우 만족하며 추가 된 새로운 기능으로 계속 배우고 개선합니다.


이 답변 이후 운 / 문제가 있었습니까? 당신은 내가하려는 것과 매우 비슷해 보이지만 당신은 나보다 더 멀리있을 수 있습니다.
Marc Young

3
tfstate 파일이 git에 저장되어서는 안된다고 생각하는 이유가 궁금합니다. 단순히 구 상태가 저축 할 가치가 없기 때문입니까, 아니면 다른 문제가 있습니까?
agbodike

3
@agbodike-단일 개발자 또는 소규모 팀의 일부로 작업 할 때 충돌을 피하기 위해 정기적으로 커밋되고 푸시되는 한 tfstate를 git에 보관할 수 있습니다. 다음 단계는 S3 의 원격 상태 문서에 따라이를 설정하는 것입니다 ( "병합 충돌이 자주 발생하기 때문에 팀에서 Terraform 작업을 복잡하게 만듭니다. 원격 상태는 이러한 문제를 완화하는 데 도움이됩니다."). . 대부분의 경우와 마찬가지로 좋은 팀 의사 소통은 상태 유지 전략에 관계없이 대부분 / 모든 문제를 완화하는 데 도움이 될 수 있습니다 :-)
Ewan

1
@ the0ther-내 주 저장소가 독점적이지만 현재는 개인 저장소에서 작업 중이며 가까운 시일 내에 공개적으로 사용할 수 있습니다.
이완

2
Git repo @Ewan에 행운이 있습니까? 당신이 뭘하는지보고 싶어요.
David

85

Terraform을 많이 사용하며 권장 설정은 다음과 같습니다.

파일 레이아웃

각 환경 (예 : stage, prod, qa)에 대한 Terraform 코드를 별도의 템플릿 집합 (따라서 별도의 .tfstate파일)에 저장하는 것이 좋습니다 . 변경하는 동안 별도의 환경이 실제로 서로 격리되도록하는 것이 중요합니다. 그렇지 않으면 스테이징에서 일부 코드를 엉망으로 만드는 동안 prod에서도 무언가를 날려 버리는 것이 너무 쉽습니다. 이유 에 대한 다채로운 토론은 Terraform, VPC 및 env 당 tfstate 파일이 필요한 이유를 참조하십시오 .

따라서 일반적인 파일 레이아웃은 다음과 같습니다.

stage
   main.tf
   vars.tf
   outputs.tf
prod
   main.tf
   vars.tf
   outputs.tf
global
   main.tf
   vars.tf
   outputs.tf

단계 VPC의 모든 Terraform 코드는 stage폴더 로 이동하고, prod VPC의 모든 코드는 prod폴더 로 이동하고, VPC 외부에있는 모든 코드 (예 : IAM 사용자, SNS 주제, S3 버킷)는 global폴더 로 이동 합니다. .

규칙에 따라 일반적으로 Terraform 코드를 3 개의 파일로 나눕니다.

  • vars.tf: 입력 변수.
  • outputs.tf: 출력 변수.
  • main.tf: 실제 자원.

모듈

일반적으로 인프라를 두 개의 폴더에 정의합니다.

  1. infrastructure-modules:이 폴더에는 재사용 가능한 작은 버전의 모듈이 포함되어 있습니다. 각 모듈을 VPC 또는 데이터베이스와 같은 단일 인프라를 생성하는 방법에 대한 청사진으로 생각하십시오.
  2. infrastructure-live:이 폴더에는 .NET의 모듈을 결합하여 생성하는 실제 라이브 실행 인프라가 포함되어 있습니다 infrastructure-modules. 이 폴더의 코드를 청사진에서 지은 실제 주택이라고 생각하십시오.

Terraform 모듈은 폴더에 Terraform 템플릿 다만 어떤 집합입니다. 예를 들어 단일 VPC에 대한 모든 라우팅 테이블, 서브넷, 게이트웨이, ACL 등을 정의하는 vpcin 이라는 폴더가있을 수 있습니다 infrastructure-modules.

infrastructure-modules
   vpc
     main.tf
     vars.tf
     outputs.tf

우리는 다음에 해당 모듈을 사용할 수 있습니다 infrastructure-live/stageinfrastructure-live/prod무대와 자극 VPC의를 만들 수 있습니다. 예를 들어 다음은 infrastructure-live/stage/main.tf다음과 같습니다.

module "stage_vpc" {
  source = "git::git@github.com:gruntwork-io/module-vpc.git//modules/vpc-app?ref=v0.0.4"

  vpc_name         = "stage"
  aws_region       = "us-east-1"
  num_nat_gateways = 3
  cidr_block       = "10.2.0.0/18"
}

모듈을 사용하려면 module리소스 를 사용하고 해당 source필드를 하드 드라이브의 로컬 경로 (예 :) source = "../infrastructure-modules/vpc"또는 위의 예에서와 같이 Git URL ( 모듈 소스 참조) 을 가리 킵니다 . Git URL의 장점은 특정 git sha1 또는 태그 ( ref=v0.0.4)를 지정할 수 있다는 것 입니다. 이제 인프라를 작은 모듈 묶음으로 정의 할뿐만 아니라 해당 모듈의 버전을 지정하고 필요에 따라 신중하게 업데이트하거나 롤백 할 수 있습니다.

우리는 VPC, Docker 클러스터, 데이터베이스 등을 만들기 위해 재사용 가능하고 테스트되고 문서화 된 여러 인프라 패키지 를 만들었으며 내부적으로는 대부분 버전이 지정된 Terraform 모듈입니다.

상태

Terraform을 사용하여 리소스 (예 : EC2 인스턴스, 데이터베이스, VPC)를 생성하면 생성 된 내용에 대한 정보가 .tfstate파일 에 기록 됩니다. 이러한 리소스를 변경하려면 팀의 모든 구성원이 동일한 .tfstate파일에 액세스 해야하지만 Git에 체크인해서는 안됩니다 ( 이유에 대한 설명여기 참조 ).

대신 Terraform 을 실행할 때마다 최신 파일을 자동으로 푸시 / 풀하는 Terraform Remote State.tfstate 를 활성화하여 S3에 파일을 저장하는 것이 좋습니다 . 최신 버전이 손상 될 경우 이전 파일로 롤백 할 수 있도록 S3 버킷에서 버전 관리활성화 해야합니다 . 그러나 중요한 참고 사항 : Terraform은 잠금을 제공하지 않습니다 . 따라서 두 팀 구성원 이 같은 파일 에서 동시에 실행되면 서로의 변경 사항을 덮어 쓸 수 있습니다..tfstateterraform apply.tfstate

이 문제를 해결하기 위해 Amazon DynamoDB를 사용하여 잠금을 제공하는 Terraform 용 씬 래퍼 인 Terragrunt 라는 오픈 소스 도구를 만들었습니다 (대부분의 팀에서 완전히 무료 여야 함). 자세한 내용 은 Terragrunt 를 사용 하여 Terraform에 자동 원격 상태 잠금 및 구성 추가를 확인하십시오 .

추가 읽기

우리는 현실 세계에서 Terraform을 사용하기 위해 배운 모든 모범 사례를 자세히 설명 하는 A Comprehensive Guide to Terraform 이라는 일련의 블로그 게시물을 막 시작했습니다 .

업데이트 : Terraform 블로그 게시물 시리즈에 대한 포괄적 인 가이드가 인기를 얻어 Terraform : Up & Running 이라는 책으로 확장했습니다 !


나는 이것이 정답이라고 생각합니다. 모듈을 사용하고 버전을 지정하고 환경을 별도로 유지하십시오.
wrangler

terragrunt 또는 다른 래퍼를 사용하지 않는 경우 다른 terraform 구성 요소 / 환경 / 모듈에서 작업 할 때마다 원격 구성 단계를 다시 실행해야합니까?
jmreicha

@jmreicha : remote configTerraform 구성을 방금 확인했거나 이전 원격 구성을 변경하려는 경우 실행해야 합니다. Terraform 0.9는 개념을 도입하여 backends많은 것을 단순화합니다. 자세한 내용은 이 PR 을 참조하십시오.
Yevgeniy Brikman

내가 이해할 수 있도록-나는 환경 '단계'에서 작업하고 있지만 '프로드'작업을 시작합니다. remote configprod 상태를 가리 키 도록 명령 을 다시 실행 해야합니다 . 환경마다 다른 상태를 가정합니다. 맞습니까? v0.9가 기대됩니다.
jmreicha

.tf두 개의 서로 다른 환경에 정확히 동일한 파일 세트를 배포 remote config하려면 전환 할 때마다 실행해야합니다 . 이것은 분명히 오류가 발생하기 쉬우므로 실제로이 기술을 사용하지 않는 것이 좋습니다. 대신 이 블로그 게시물 에서 Terraform 모듈을 사용하는 방법함께이 블로그 게시물에서 권장되는 Terraform 파일 레이아웃을 확인하십시오 .
Yevgeniy Brikman

9

이전에는이를 remote config허용했지만 지금은 " 백엔드 " 로 대체 되었으므로 terraform 원격은 더 이상 사용할 수 없습니다.

terraform remote config -backend-config="bucket=<s3_bucket_to_store_tfstate>" -backend-config="key=terraform.tfstate" -backend=s3
terraform remote pull
terraform apply
terraform remote push

자세한 내용은 문서 를 참조하십시오.


다른 테라 폼 구성 요소 / 환경 / 모듈 / 무엇이든 작업 할 때마다 원격 소스를 다시 구성해야합니까?
jmreicha

6

@Yevgeny Brikman이 더 자세히 다루었지만 특히 OP의 질문에 대답합니다.

실제로 테라 폼 파일과 상태를 관리하는 가장 좋은 방법은 무엇입니까?

TF 파일에는 git을 사용하십시오. 그러나 상태 파일 (예 : tfstate)을 확인하지 마십시오. 대신 TerragruntS3에 대한 상태 파일 동기화 / 잠금에 사용 합니다.

하지만 tfstate도 커밋합니까?

아니.

S3 같은 곳에 있어야합니까?


2

여기에 많은 답변이 있다는 것을 알고 있지만 제 접근 방식은 상당히 다릅니다.

   Modules
   Environment management 
   Separation of duties

모듈

  1. 리소스의 논리적 컬렉션을위한 모듈을 만듭니다. 예 : 목표가 DB, HA VM, 자동 확장, DNS, PubSub 및 객체 저장소가 필요한 API를 배포하는 것이라면 이러한 모든 리소스를 단일 모듈에 템플릿으로 작성해야합니다.
  2. 단일 리소스를 사용하는 모듈을 만들지 마십시오. 이것은 할 수 있고 이루어졌고 레지스트리의 많은 모듈이이 작업을 수행하지만 인프라 오케스트레이션보다는 리소스 접근성에 도움이되는 관행입니다. 예 : AWS EC2 용 모듈은 복잡한 구성을보다 간단하게 호출하여 사용자가 EC2에 액세스하는 데 도움이되지만 1의 예와 같은 모듈은 애플리케이션, 구성 요소 또는 서비스 기반 인프라를 오케스트레이션 할 때 사용자를 지원합니다.
    1. 작업 공간에서 리소스 선언을 피하십시오. 이것은 코드를 깔끔하고 체계적으로 유지하는 것에 관한 것입니다. 모듈의 버전이 쉽게 지정되므로 릴리스를 더 많이 제어 할 수 있습니다.

환경 관리

IaC는 인프라 관리와 관련된 SDLC 프로세스를 만들었으며 개발 인프라 및 개발 애플리케이션 환경을 기대하는 것은 정상이 아닙니다.

  1. 폴더를 사용하여 IaC 환경을 관리하지 마십시오. 인프라에 대한 공통 템플릿이 없기 때문에 드리프트가 발생합니다.
  2. 단일 작업 공간과 변수를 사용하여 환경 사양을 제어하십시오. 예 : 환경 변수 (var.stage가 널리 사용됨)를 변경할 때 계획이 요구 사항에 맞게 변경되도록 모듈을 작성하십시오. 일반적으로 환경은 수량, 노출 및 용량이 일반적으로 가변 구성이므로 가능한 한 적게 변해야합니다. Dev는 프라이빗 토폴로지에 1 코어 및 1GB RAM이있는 VM 1 개를 배포 할 수 있지만 프로덕션은 추가 공용 토폴로지가있는 2 코어 및 4GB RAM이있는 3 개의 VM 일 수 있습니다. 물론 더 많은 변형이있을 수 있습니다. 개발자는 비용을 절약하기 위해 애플리케이션과 동일한 서버에서 데이터베이스 프로세스를 실행할 수 있지만 프로덕션에는 전용 DB 인스턴스가있을 수 있습니다. 이 모든 것은 단일 변수, 삼 항문 및 보간을 변경하여 관리 할 수 ​​있습니다.

업무 분리

소규모 조직에 있거나 개인 인프라를 운영하는 경우 이는 실제로 적용되지는 않지만 운영 관리에 도움이됩니다.

  1. 업무, 책임 또는 팀별로 인프라를 분류하십시오. 예 : 중앙 IT는 기본 공유 서비스 (가상 네트워크, 서브넷, 공용 IP 주소, 로그 그룹, 거버넌스 리소스, 멀티 테넌트 DB, 공유 키 등)를 제어하는 ​​반면 API 팀은 서비스에 필요한 리소스 (VM, LB) 만 제어합니다. , PubSub 등) 데이터 소스 및 원격 상태 조회를 통해 중앙 IT 서비스를 사용합니다.
    1. 팀 액세스를 관리합니다. 예 : 중앙 IT는 관리자 권한을 가질 수 있지만 API 팀은 제한된 공용 클라우드 API 세트에만 액세스 할 수 있습니다.

일부 리소스는 거의 변경되지 않고 다른 리소스는 항상 변경되므로 릴리스 문제에도 도움이됩니다. 분리는 위험과 복잡성을 제거합니다.

이 전략은 AWS의 다중 계정 전략과 유사합니다. 더 많은 정보를 읽으십시오.

CI / CD

이것은 자체 주제이지만 Terraform은 좋은 파이프 라인 내에서 매우 잘 작동합니다. 여기서 가장 일반적인 오류는 CI를 은색 총알로 취급하는 것입니다. 기술적으로 Terraform은 어셈블리 파이프 라인 단계 중에 만 인프라를 프로비저닝해야합니다. 이는 일반적으로 템플릿을 검증하고 테스트하는 CI 단계에서 발생하는 것과는 별개입니다.

NB 모바일로 작성되었으므로 오류가 있으시면 양해 바랍니다.


0

답변이 매우 견고하고 유익하기 전에 여기에 2 센트를 추가하려고합니다.

코드 구조화에 대한 일반적인 권장 사항

  1. 적은 수의 리소스로 작업하는 것이 더 쉽고 빠릅니다.

    • Cmds terraform planterraformapply 둘 다 클라우드 API 호출을 통해 리소스 상태를 확인합니다.
    • 단일 컴포지션에 전체 인프라가있는 경우 (동일한 폴더에 여러 파일이 있더라도) 몇 분이 걸릴 수 있습니다.
  2. 적은 자원으로 폭발 반경이 더 작습니다.

    • 관련없는 리소스를 별도의 컴포지션 (폴더)에 배치하여 서로 격리하면 문제가 발생할 경우 위험을 줄일 수 있습니다.
  3. 원격 상태를 사용하여 프로젝트를 시작합니다.

  4. 일관된 구조와 명명 규칙을 연습하십시오.

    • 절차 적 코드와 마찬가지로 Terraform 코드는 사람들이 먼저 읽을 수 있도록 작성되어야하며, 지금부터 6 개월 후 변경 사항이 발생하면 일관성이 도움이 될 것입니다.
    • Terraform 상태 파일 에서 리소스를 이동할 수 있지만 구조와 이름이 일치하지 않으면 수행하기가 더 어려울 수 있습니다.
  5. 리소스 모듈을 가능한 한 단순하게 유지하십시오.

  6. 변수로 전달되거나 데이터 소스를 사용하여 검색 될 수있는 값을 하드 코딩 하지 마십시오 .

  7. data소스를 사용 하고 terraform_remote_state특히 컴포지션 내에서 인프라 모듈 간의 접착제로 사용 합니다 .

( 참조 기사 : https://www.terraform-best-practices.com/code-structure )


예:

적은 수의 리소스로 작업하는 것이 더 쉽고 빠르므로 아래에 권장 코드 레이아웃이 나와 있습니다.

참고 : 각 프로젝트에는 고유 한 특성이 있으므로 엄격하게 따르지 않는 참고 자료입니다.

.
├── 1_tf-backend #remote AWS S3 + Dynamo Lock tfstate 
   ├── main.tf
   ├── ...
├── 2_secrets
   ├── main.tf
   ├── ...
├── 3_identities
   ├── account.tf
   ├── roles.tf
   ├── group.tf
   ├── users.tf
   ├── ...
├── 4_security
   ├── awscloudtrail.tf
   ├── awsconfig.tf
   ├── awsinspector.tf
   ├── awsguarduty.tf
   ├── awswaf.tf
   └── ...
├── 5_network
   ├── account.tf
   ├── dns_remote_zone_auth.tf
   ├── dns.tf
   ├── network.tf
   ├── network_vpc_peering_dev.tf
   ├── ...
├── 6_notifications
   ├── ...
├── 7_containers
   ├── account.tf
   ├── container_registry.tf
   ├── ...
├── config
   ├── backend.config
   └── main.config
└── readme.md

0

인프라를 오케스트레이션하기 위해 terraform을 사용하는 동안 따라야 할 모범 사례가 거의 없다고 생각합니다.

  1. 동일한 코드를 다시 작성하지 마십시오 (재사용 성).
  2. 쉽게 유지할 수 있도록 환경 구성을 별도로 유지하십시오.
  3. 원격 백엔드 s3 (암호화) 및 dynamo DB를 사용하여 동시성 잠금 처리
  4. 다른 매개 변수를 전달하여 여러 번 호출 할 수있는 재사용 가능한 함수처럼 모듈을 생성하고 기본 인프라에서 해당 모듈을 여러 번 사용합니다.

여러 환경 처리

대부분의 권장 방법은 terraform '작업 공간'을 사용하여 여러 환경을 처리하는 것이지만 작업 공간의 사용은 조직의 작업 방식에 따라 다를 수 있다고 생각합니다. 다른 하나는 각 환경 (예 : 스테이지, 제품, QA)에 대한 Terraform 코드를 저장하여 환경 상태를 분리하는 것입니다. 그러나이 경우에는 여러 위치에서 동일한 코드를 복사하고 있습니다.

├── main.tf
├── dev
   ├── main.tf
   ├── output.tf
   └── variables.tf
└── prod
├── main.tf
├── output.tf
└── variables.tf

대부분의 경우 모든 환경이 90 % 동일 할 것이라고 믿기 때문에 각 환경 폴더에 보관하여 동일한 테라 폼 코드의 중복을 처리하고 방지하기 위해 몇 가지 다른 접근 방식을 따랐습니다.

├── deployment
 ├── 01-network.tf
 ├── 02-ecs_cluster.tf
 ├── 03-ecs_service.tf
 ├── 04-eks_infra.tf
 ├── 05-db_infra.tf
 ├── 06-codebuild-k8s.tf
 ├── 07-aws-secret.tf
 ├── backend.tf
 ├── provider.tf
 └── variables.tf
├── env
 ├── dev
  ├── dev.backend.tfvar
  └── dev.variables.tfvar
 └── prod
 ├── prod.backend.tfvar
 └── prod.variables.tfvar
├── modules
 └── aws
 ├── compute
  ├── alb_loadbalancer
  ├── alb_target_grp
  ├── ecs_cluster
  ├── ecs_service
  └── launch_configuration
 ├── database
  ├── db_main
  ├── db_option_group
  ├── db_parameter_group
  └── db_subnet_group
 ├── developertools
 ├── network
  ├── internet_gateway
  ├── nat_gateway
  ├── route_table
  ├── security_group
  ├── subnet
  ├── vpc
 └── security
 ├── iam_role
 └── secret-manager
└── templates

환경과 관련된 구성

환경 관련 구성 및 매개 변수를 변수 파일에 별도로 보관하고 해당 값을 전달하여 인프라를 구성하십시오. 예 : 아래와 같이

  • dev.backend.tfvar

      region = "ap-southeast-2"
      bucket = "dev-samplebackendterraform"
      key = "dev/state.tfstate"
      dynamo_db_lock = "dev-terraform-state-lock"
  • dev.variable.tfvar

    environment                     =   "dev"
    vpc_name                        =   "demo"
    vpc_cidr_block                  =   "10.20.0.0/19"
    private_subnet_1a_cidr_block    =   "10.20.0.0/21"
    private_subnet_1b_cidr_block    =   "10.20.8.0/21"
    public_subnet_1a_cidr_block     =   "10.20.16.0/21"
    public_subnet_1b_cidr_block     =   "10.20.24.0/21"

인프라 부분의 조건부 건너 뛰기

환경 특정 변수 파일에 구성을 만들고 해당 변수를 기반으로 해당 부분을 만들거나 건너 뛰기로 결정합니다. 이러한 방식으로 필요에 따라 인프라의 특정 부분을 건너 뛸 수 있습니다.

variable vpc_create {
   default = "true"
}

module "vpc" {
  source = "../modules/aws/network/vpc"
  enable = "${var.vpc_create}"
  vpc_cidr_block = "${var.vpc_cidr_block}"
  name = "${var.vpc_name}"
 }

 resource "aws_vpc" "vpc" {
    count                = "${var.enable == "true" ? 1 : 0}"
    cidr_block           = "${var.vpc_cidr_block}"
    enable_dns_support   = "true"
   enable_dns_hostnames = "true"
}

각 환경에 대한 인프라 변경을 초기화하고 실행하려면 아래 명령이 필요합니다. 필요한 환경 폴더로 cd합니다.

  terraform init -var-file=dev.variables.tfvar -backend-config=dev.backend.tfvar ../../deployment/

  terraform apply -var-file=dev.variables.tfvar ../../deployment

참고 : https://github.com/mattyait/devops_terraform


0

하위 폴더의 아이디어가 마음에 들지 않습니다. 환경마다 소스가 달라지고 표류하는 경향이 있기 때문입니다.

더 나은 접근 방식은 모든 환경 (dev, preprod 및 prod)에 대해 단일 스택을 사용하는 것입니다. 단일 환경에서 작업하려면 terraform workspace.

terraform workspace new dev

그러면 새 작업 공간이 생성됩니다. 여기에는 전용 상태 파일과 terraform.workspace코드에서 사용할 수 있는 변수가 포함 됩니다.

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${terraform.workspace}"
}

이렇게하면 버킷이 호출됩니다.

  • my-tf-test-bucket-dev
  • my-tf-test-bucket-preprod
  • my-tf-test-bucket-prod

위의 작업 공간에 적용한 후 ( terraform workspace select <WORKSPACE>환경 변경에 사용 ). 코드를 다중 지역에서 증명하려면 다음과 같이하십시오.

data "aws_region" "current" {}

resource "aws_s3_bucket" "bucket" {
  bucket = "my-tf-test-bucket-${data.aws_region.current.name}-${terraform.workspace}"
}

얻기 위해 (us-east-1 지역의 경우)

  • my-tf-test-bucket-us-east-1-dev
  • my-tf-test-bucket-us-east-1-preprod
  • my-tf-test-bucket-us-east-1-prod

0

따라야 할 몇 가지 Terraform 모범 사례 :

  1. 하드 코딩 방지 : 때때로 개발자가 직접 리소스를 수동으로 생성했습니다. 이러한 리소스를 표시하고 terraform 가져 오기를 사용하여 코드에 포함해야합니다. 샘플:

    account_number =“123456789012 "account_alias ="mycompany "

  2. Docker 컨테이너에서 Terraform 실행 : Terraform은 실행할 수있는 버전을 쉽게 제어 할 수있는 공식 Docker 컨테이너를 출시합니다.

CI / CD 파이프 라인에서 빌드 작업을 설정할 때 Terraform Docker 컨테이너를 실행하는 것이 좋습니다.

TERRAFORM_IMAGE=hashicorp/terraform:0.11.7
TERRAFORM_CMD="docker run -ti --rm -w /app -v ${HOME}/.aws:/root/.aws -v ${HOME}/.ssh:/root/.ssh -v `pwd`:/app $TERRAFORM_IMAGE"

자세한 내용은 내 블로그를 참조하십시오 : https://medium.com/tech-darwinbox/how-darwinbox-manages-infrastructure-at-scale-with-terraform-371e2c5f04d3


0

이 스레드에 기여하고 싶습니다.

  • Terraform Cloud를 사용하지 않는 한 AWS S3 + DynamoDB 일 가능성이 높습니다.
  • 프로덕션 및 비 프로덕션 백엔드의 별도 인프라 (네트워크 + RBAC).
  • 지정된 네트워크 (예 : 배포 에이전트 풀) 외부에서 상태 파일 (네트워크 액세스 및 RBAC)에 대한 액세스를 비활성화하도록 계획합니다.
  • 런타임 환경에서 Terraform 백엔드 인프라를 유지하지 마십시오. 별도의 계정을 사용하십시오.
  • 변경 사항 및 상태 파일 손실을 방지하고 Terraform 상태 기록을 유지하기 위해 Terraform 백엔드에서 객체 버전 관리를 활성화합니다.

일부 특별한 경우에는 Terraform 상태 파일에 대한 수동 액세스가 필요합니다. 리팩토링, 변경 중단 또는 결함 수정과 같은 작업을 수행하려면 운영 담당자가 Terraform 상태 작업을 실행해야합니다. 이러한 경우 배스 천 호스트, VPN 등을 사용하여 Terraform 상태에 대한 특별 제어 액세스를 계획하십시오.

CI / CD 파이프 라인에 대한 지침을 포함하여 자세한 내용을 다루는 더 긴 모범 사례 블로그 를 확인하십시오 .


-1

여전히 더 나은 솔루션을 찾고 있다면, 다른 환경 폴더 구조를 유지하는 대신 작업 공간 별 변수를 가질 수있는 작업 공간을 살펴보십시오.

예브게니 Brikman가 언급 그것은 모듈 구조를 가지고하는 것이 좋습니다.


-1

위의 조언과 함께 테라 폼 클라우드를 사용하여 상태를 관리하고 저장하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.