본문 바로가기
DevOps

[T1014-실습] Terraform Backend: AWS S3 + DynamoDB

by 서어켜엉 2024. 7. 7.
해당 내용은 cloudNet@ 팀의 가시다 님이 진행하는 테라폼 스터디 T101 4기에서 다룬 내용으로 악분님이 제공해준 실습 예제를 정리한 것입니다.

 

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 = "smlim-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=smlim-hello-tf101-remote-backend
aws s3 ls s3://$MYBUCKET --recursive --human-readable --summarize

백엔드로 지정한 S3 버킷에 tfstate 파일이 있는 것을 확인

 

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         = "smlim-hello-tf101-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 확인

# 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 없음 확인

apply 하는 도중에 DynamoDB 테이블에서 정보 확인 가능.

 

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",

 

한 파일에 여러 버전이 생성된 것을 확인.

 

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

s3에 객체가 남아있을 경우 에러 발생. 따라서 객체 삭제 및 삭제마커 삭제이후 버킷 삭제를 시도해야 함.

 

테라폼 백엔드 단점

  • 테라폼의 backend 블록에는 변수나 참조를 사용할 수 없음. -> 아래 코드 사용 불가능
terraform {
  backend "s3" {
    bucket = var.bucket
    region = var.region
    dynamodb_table = var.dynamodb_table
    key = "example/terraform.tfstate"
    encrypt = true
  }
}
  • 그 결과 s3 버킷 이름, 리전, DynamoDB 테이블 이름을 모두 테라폼 모듈에 수동으로 넣어야 한다. 심지어 key 값은 중복되면 안되며 고유하게 넣어야함
  • partial configuration 을 통해 일부 매개 변수를 전달해서 사용할 수 있음
bucket = terraform-test
region = "ap-northeast-2"
dynamodb_table = "terraform-test-locks"
encrypt = true
  • 부분적으로 구성한 것들을 모두 결합하려면 -backend-config 인수와 함께 terraform init 명령을 실행
terraform init -backend-config=backend.hcl

'DevOps' 카테고리의 다른 글

[T1014-실습] Terraform Runner  (1) 2024.07.14
[T1014-이론] 6장 Module  (0) 2024.07.10
[T1014-이론] 5장 State  (0) 2024.07.07
[T1014-이론] 4장 프로바이더  (0) 2024.07.07
[T1014-이론] 3장 기본 사용법 (6)  (0) 2024.06.30