Terraform

[ Terraform101 Study - 4w ] State - 실습

su''@ 2024. 7. 7. 02:10

[악분님] 실습 따라하기 - Blog

  1. [사전 준비 1] 리모트 공용 저장소 AWS S3 생성
    #
    git clone https://github.com/sungwook-practice/t101-study.git example
    cd example/state/step3_remote_backend/s3_backend
    tree
    
    # VSCODE에서 코드 파일들 확인 : main.tf, variables.tf , terraform.tfvars
    ## S3 버킷에 버저닝 활성화 <- 권장 옵션 설정
    
    # terraform.tfvars 파일 내용 수정 : 각자 자신의 '닉네임' 추가하여 S3 버킷 이름 작성
    bucket_name = "<닉네임>-hello-t1014-remote-backend"
    bucket_name = "gasida-hello-t1014-remote-backend"
    
    # 생성
    terraform init && terraform apply -auto-approve
    
    # 확인
    terraform state list
    aws s3 ls
  2. 테라폼 자원 배포 시 ‘리모트 백엔드 저장소’ 설정 사용
    # VSCODE에서 provider.tf 코드 확인
    cd ../vpc
    ls
    cat provider.tf
    
    # VSCODE에서 provider.tf 수정
    ...
      backend "s3" {
        #bucket         = "<닉네임>-hello-t1014-remote-backend"
        bucket         = "gasida-hello-t1014-remote-backend"
        key            = "terraform/state-test/terraform.tfstate"
        region         = "ap-northeast-2"
        #dynamodb_table = "terraform-lock" 주석처리
      }
    ...
    
    # 테라폼 초기화
    terraform init
    Initializing the backend...
    
    Successfully configured the backend "s3"! Terraform will automatically
    use this backend unless the backend configuration changes.
    ...
    
    # tfstate 파일 로컬 확인
    terraform apply -auto-approve
    terraform state list
    ls 
    
    # AWS S3 버킷 내에 tfstate 파일 확인
    MYBUCKET=gasida-hello-t1014-remote-backend
    aws s3 ls s3://$MYBUCKET --recursive --human-readable --summarize
  3. [사전 준비 2] Locking 을 위한 DynamoDB 활용을 위해 DynamoDB 생성
    • 테라폼에서 DynamoDB 잠금을 사용하기 위해서는 LockID 라는 기본 키가 있는 테이블을 생성해야됨
      # VSCODE에서 provider.tf 코드 확인
      cd ../dynamodb
      ls
      cat main.tf
      
      # 생성
      terraform init && terraform apply -auto-approve
      
      # 확인
      terraform state list
      terraform state show aws_dynamodb_table.terraform_state_lock
      
      # DynamoDB 테이블 생성 확인
      aws dynamodb list-tables --output text
      TABLENAMES	terraform-lock
      
      aws dynamodb describe-table --table-name terraform-lock | jq
      aws dynamodb describe-table --table-name terraform-lock --output table
  4. 2번 테라폼 자원 배포에 백엔드 설정 수정 및 적용
    # VSCODE에서 provider.tf 코드 확인
    cd ../vpc
    cat provider.tf
    
    # VSCODE에서 provider.tf 수정 : dynamodb_table = "terraform-lock" 주석 제거
    ...
      backend "s3" {
        bucket         = "gasida-hello-t1014-remote-backend"
        key            = "terraform/state-test/terraform.tfstate"
        region         = "ap-northeast-2"
        dynamodb_table = "terraform-lock"
      }
    ...
    
    # backend설정이 달라졌으므로 terraform init 으로 적용
    # Reconfigure a backend, and attempt to migrate any existing state.
    terraform init -migrate-state
  5. VPC tag 수정 후 apply 와서 Locking 확인 : 예전과 다르게 md5 Item은 생성되지 않는듯..
    # main.tf 수정 : '2' 추가
    resource "aws_vpc" "main" {
      cidr_block = var.vpc_cidr
    
      tags = {
        Name = "terraform VPC 2"
      }
    }
    
    # apply 후 DynamoDB 테이블 확인
    terraform apply
    ...
     Enter a value: <입력하지 않고 대기>
    
    # 아래 LockID 정보 확인 후 apply
    # apply 완료 후 다시 DynamoDB 테이블 확인 : item 없음 확인

     
    1. LockID 상태 확인 : 테라폼을 통해 apply 하는 도중에 아래 정보 확인 가능
    2. LockID : gasida-t101study-tfstate/stg/terraform.tfstate
    3. Info
      {"ID":"354ed19e-0446-d8c7-269a-3139fbdac463","Operation":"OperationTypeApply","Info":"","Who":"gasida@JongHoui-MacBookPro.local","Version":"1.3.3","Created":"2022-10-23T06:20:42.753567Z","Path":"gasida-t101study-tfstate/stg/terraform.tfstate"}
       
  6. S3 버저닝 정보 확인
    # main.tf 수정 : '3' 추가
    resource "aws_vpc" "main" {
      cidr_block = var.vpc_cidr
    
      tags = {
        Name = "terraform VPC 3"
      }
    }
    
    # apply 
    terraform apply -auto-approve
    
    # S3 버킷에 파일 확인 
    aws s3 ls s3://$MYBUCKET --recursive --human-readable --summarize
    
    # 버저닝된 파일 확인
    aws s3api list-object-versions --bucket $MYBUCKET | egrep "Key|VersionId|LastModified"
                "Key": "dev/terraform.tfstate",
                "VersionId": "oyo59fIIQ239_tVTY88upFoVgnp630BC",
                "LastModified": "2022-10-23T08:54:04+00:00",
                "Key": "dev/terraform.tfstate",
                "VersionId": "vlOO1wCPEy3mzAOB7W76171u_i3WSG8r",
                "LastModified": "2022-10-23T08:53:04+00:00",
                "Key": "dev/terraform.tfstate",
                "VersionId": "ukF5F_CMKQhoF_jDGftbsMO0eNIGLmDV",
                "LastModified": "2022-10-23T08:51:55+00:00",
    - S3 버킷에 버전 표시 확인
  7. 실습 리소스 삭제
    # 테라폼 배포 리소스 삭제 : 현재 vpc 디렉터리
    terraform destroy -auto-approve
    
    # DynamoDB 삭제
    cd ../dynamodb
    terraform destroy -auto-approve
    
    # S3 삭제
    cd ../s3_backend
    terraform destroy -auto-approve
    
    # S3 버킷에 객체 삭제
    aws s3 rm s3://$MYBUCKET --recursive
    
    # S3 버킷에 버저닝 객체 삭제 
    aws s3api delete-objects \
        --bucket $MYBUCKET \
        --delete "$(aws s3api list-object-versions \
        --bucket "$MYBUCKET" \
        --output=json \
        --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"
    
    # S3 버킷에 삭제마커 삭제
    aws s3api delete-objects --bucket $MYBUCKET \
        --delete "$(aws s3api list-object-versions --bucket "$MYBUCKET" \
        --query='{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}}')"
    
    # S3 삭제
    terraform destroy -auto-approve

 테라폼 백엔드 단점 - 링크

  • 테라폼의 backend 블록에는 변수나 참조를 사용 할 수 없음 → 아래 코드 사용할 수 없음
  • 그 결과 S3 버킷 이름, 리전, DynamoDB 테이블 이름을 모두 테라폼 모듈에 수동으로 복사붙여녛어야 함, 심지어 key 값은 중복되면 안되며 고유하게 넣어야함
  • partial configuration 을 통해 일부 매개 변수를 전달해서 사용 할 수 있음 - 링크
  • 다만, 이 경우에도 모듈마다 서로 다른 key 값을 설정해야 하기 때문에 key 매개 변수는 테라폼 코드에 있어야함
  • 부분적으로 구성한 것들을 모두 결합하려면 -backend-config 인수와 함께 terraform init 명령을 실행
    terraform init -backend-config=backend.hcl
    ⇒ 위 단점을 보완해주는 오픈 소스 테라그런트(Terragrunt)가 있음 - 링크
 

Terragrunt | Terraform wrapper

Terragrunt is a thin wrapper for Terraform that provides extra tools for keeping your Terraform configurations DRY, working with multiple Terraform modules, and managing remote state.

terragrunt.gruntwork.io