본문 바로가기
IaC/Terraform

[Terraform] 4-1. AWS S3와 DynamoDB를 활용하여 백엔드 구성하기

by okms1017 2024. 7. 7.
728x90

✍ Posted by Immersive Builder  Seong

 

 

1. 실습 소개

이번 실습은 AWS S3DynamoDB를 활용하여 State 백엔드를 구성합니다. 

백엔드 구성 시 S3는 원격 공유 저장소의 역할을 하며 DynamoDB는 State Locking 기능을 제공합니다. 

 

즉, 팀 구성원들이 동일한 State를 사용하고 동시 작업으로 인한 충돌을 방지하기 위한 구성입니다. 

 

실습은 하기와 같은 순서로 진행할 예정입니다. 

 

  • Step1. AWS S3 생성하기 
  • Step2. AWS S3 백엔드 설정하기 
  • Step3. DynamoDB 생성하기 
  • Step4. State Locking 설정하기 
  • Step5. AWS S3 버저닝하기 
  • Step6. 실습 리소스 삭제하기 

 


2. AWS S3와 DynamoDB를 활용하여 백엔드 구성하기 

Step1. AWS S3 생성하기 

State를 공유할 원격 저장소 S3 버킷을 생성합니다. 

 

S3 Bucket (seong-remote-backend)

 

Step2. AWS S3 백엔드 설정하기 

생성한 S3 버킷에 State를 업로드하기 위해 백엔드를 설정합니다. 

그리고 간단하게 테스트용 VPC를 하나 배포하여 State의 저장 위치를 확인할 예정입니다. 

 

./vpc
├── main.tf
├── provider.tf
├── terraform.tfvars
└── variables.tf

provider.tf

테라폼 블록 안에 백엔드 블록을 추가하여 저장소 관련 설정을 진행합니다. 

 


        terraform {
          required_providers {
            aws = {
              source  = "hashicorp/aws"
              version = "5.4.0"
            }
          }

          backend "s3" {
            bucket         = "seong-remote-backend"
            key            = "terraform/state/terraform.tfstate"
            region         = "ap-northeast-2"
          }

          required_version = ">= 1.4"
        }
 

 

  • backend "s3" :  백엔드 저장소 유형으로 S3를 지정함  ex) s3, consul, gcs etc..
  • bucket : State를 저장할 S3 버킷명. 모든 리전에서 고유해야함.
  • key : State를 저장하는 S3 버킷 하위 경로 
  • region : S3 버킷을 생성할 리전을 지정함 

main.tf


        resource "aws_vpc" "main" {
          cidr_block = var.vpc_cidr

          tags = {
            Name = "seong-vpc"
          }
        }
 

variables.tf


        variable "vpc_cidr" {
          type = string
        }
 

terraform.tfvars


        vpc_cidr = "192.168.0.0/16"
 

 

VPC를 배포하고 State의 저장 위치를 확인합니다. 

로컬 저장소가 아니라 지정한 S3 버킷의 하위 경로(terraform/state/terraform.tfstate)에 State가 저장됨을 확인할 수 있습니다. 

 

VPC (seong-vpc)
s3://seong-remote-backend/terraform/state/terraform.tfstate

 

Step3. DynamoDB 생성하기

./dynamodb/
├── main.tf
└── provider.tf

provider.tf

테라폼 버전과 프로바이더 소스 및 버전 외에 별다른 설정은 없습니다. 

 


        terraform {
          required_providers {
            aws = {
              source  = "hashicorp/aws"
              version = "5.4.0"
            }
          }

          required_version = ">= 1.4"
        }
 

main.tf

DynamoDB의 Locking 기능을 사용하기 위해서는 'LockID' 라는 기본키가 있는 테이블을 생성해야 합니다. 

 


        resource "aws_dynamodb_table" "terraform_state_lock" {
          name         = "terraform-lock" 
          hash_key     = "LockID"         
          billing_mode = "PAY_PER_REQUEST"

          attribute {
            name = "LockID"
            type = "S" 
          }
        }
 

 

  • aws_dynamodb_table.terraform_state_lock : DynamoDB 리소스 선언 
  • aws_dynamodb_table.terraform_state_lock.name : DynamoDB 테이블명 
  • aws_dynamodb_table.terraform_state_lock.hash_key : hash_key 타입 지정  ex) LockID => 잠금 기능 제공
  • aws_dynamodb_table.terraform_state_lock.billing_mode : Read/Write 처리량에 대한 요금 청구 및 용량 관리 방법  ex) PROVISIONED | PAY_PER_REQUEST
  • aws_dynamodb_table.terraform_state_lock.attribute : hash_key/range_key에 대한 속성 리스트 정의
    - name/type 2가지 속성 정의 (type: S=>String, N=>Number, B=>Binary data)

 

DynamoDB를 배포하여 지정한 'LockID' 기본키를 가지는 테이블(terraform-lock)이 생성되었음을 확인합니다. 

DynamoDB (terraform-lock)

 

Step4. State Locking 설정하기

S3에서 해당 DynamoDB 테이블의 Locking 기능을 사용할 수 있도록 백엔드 설정을 수정합니다. 

VPC 구성 파일 중 provider.tf 파일의 백엔드 블록에 'dynamodb_table' 값을 아래와 같이 추가합니다. 

 


          backend "s3" {
            bucket         = "seong-remote-backend"
            key            = "terraform/state/terraform.tfstate"
            region         = "ap-northeast-2"
            dynamodb_table = "terraform-lock"
          }
 

 

수정된 백엔드 설정을 적용하려면 'terraform init' 명령어를 '-migrate-state' 옵션과 함께 실행하면 됩니다. 

 

$ terraform apply -auto-approve

Error: Backend initialization required: please run "terraform init"
│ Reason: Backend configuration block has changed

 

$ terraform init -migrate-state

Initializing the backend...
Backend configuration changed!

 

VPC 태그를 수정하고 Apply 작업을 수행하는 과정에서 State Locking 기능이 정상 동작하는지 확인합니다. 

이미 Apply 작업이 수행중인 상태에서는 다른 작업 요청을 허용하지 않기 때문에 'state lock' 에러를 출력하게 됩니다. 

 

State Locking 테스트

 

그리고 콘솔에서 DynamoDB 테이블의 항목을 탐색하면 반환된 항목이 생성되었음을 확인할 수 있습니다. 

출력 에러와 콘솔 항목의 정보를 비교해보면 동일한 LockID와 Info 값을 가지고 있습니다. 

 

DynamoDB > 항목 탐색 > terraform-lock
LockID & Info

'yes'를 입력하여 변경내역을 반영합니다. 

Apply 작업이 완료되면 반환된 목록에서 Locking 항목이 사라지고 md5 항목이 남게 됩니다. 

 

Apply 이후 md5 항목

 

Step5. AWS S3 버저닝하기 

이전 상태로 롤백하거나 장애가 발생하여 복구할 필요가 있을 경우를 대비하여 State를 항시 백업해야 합니다. 

S3 버저닝(S3 Versioning) 기능을 활성화하여 State 백업본을 버전별로 관리할 수 있습니다. 

 

S3 Bucket 버전 관리 활성화
S3 Versioning

 

Step6. 실습 리소스 삭제하기 

각 디렉토리로 이동하여 생성한 리소스를 삭제합니다. 

다만 S3의 경우, 버킷에 담긴 객체와 삭제마커를 비워주어야 삭제할 수 있습니다. 

 

 

하기 내용을 참고하여 리소스를 깨끗이 삭제합니다. 

 

# VPC 삭제 
$ cd ./vpc
$ terraform destroy -auto-approve

# DynamoDB 삭제
$ cd ../dynamodb
$ terraform destroy -auto-approve

# S3 삭제
cd ../s3
MYBUCKET=seong-remote-backend
aws s3 rm s3://$MYBUCKET --recursive # 객체 삭제 

aws s3api delete-objects \
    --bucket $MYBUCKET \
    --delete "$(aws s3api list-object-versions \
    --bucket "$MYBUCKET" \
    --output=json \
    --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')" # 버저닝 객체 삭제 

aws s3api delete-objects --bucket $MYBUCKET \
    --delete "$(aws s3api list-object-versions --bucket "$MYBUCKET" \
    --query='{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}}')" # 삭제마커 삭제 
terraform destroy -auto-approve

 

 


[출처]

1) CloudNet@, T1014 실습 스터디

2) https://developer.hashicorp.com/terraform/language/settings/backends/s3

 

Backend Type: s3 | Terraform | HashiCorp Developer

Terraform can store state remotely in S3 and lock that state with DynamoDB.

developer.hashicorp.com

3) https://github.com/binbashar/terraform-aws-tfstate-backend

 

GitHub - binbashar/terraform-aws-tfstate-backend

Contribute to binbashar/terraform-aws-tfstate-backend development by creating an account on GitHub.

github.com

728x90