프로바이더(Provider)
Terraform 프로바이더는 다양한 클라우드 서비스 및 인프라 플랫폼과 상호작용할 수 있게 해주는 플러그인입니다. 프로바이더는 Terraform이 관리할 수 있는 리소스 유형과 API를 정의하며, Terraform 구성 파일에서 해당 리소스를 선언하고 관리할 수 있도록 합니다.
프로바이더 구성
테라폼 레지스트리를 통해 수 많은 벤더사의 프로바이더를 제공합니다. 프로바이더 목록에는 유지 보수 및 게시에 권한에 따라 티어가 존재한다고 합니다.
provider 키워드를 통해 선언하고 terraform init 명령어 시, 프로바이더 파일을 다운로드합니다.
# main.tf
provider "aws" {
region = "us-west-2"
access_key = "your-access-key"
secret_key = "your-secret-key"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
}
상태(State)
Terraform state(상태)는 Terraform이 인프라 리소스를 추적하고 관리하는 데 사용되는 중요한 구성 요소입니다. 상태 파일은 리소스의 현재 상태를 저장하고, Terraform이 인프라의 변경 사항을 계획하고 적용할 수 있도록 합니다. 테라폼의 변경관리라고도 할 수 있습니다.
State 기본 실습
terraform init과 plan이 아닌 apply 명령어 시, terraform.tfstate라는 상태파일이 생성됩니다.
# 실습 폴더 생성
mkdir 5.0 && cd 5.0
# vpc.tf - 리소스 파일 작성
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_vpc" "myvpc" {
cidr_block = "10.10.0.0/16"
tags = {
Name = "tf-state"
}
}
# 파일확인 -> tfstate파일:X
ls
vpc.tf
# 실행
terraform init && terraform plan && terraform apply -auto-approve
# 파일확인 -> tfstate파일:O
ls
terraform.tfstate vpc.tf
terraform.tfstate 파일의 정보를 통해 state 명령어가 동작합니다.
# tfstate 파일이 존재할 경우
ls
terraform.tfstate vpc.tf
terraform state list
aws_vpc.myvpc
# tfstate 파일이 존재하지 않을 경우
rm terraform.tfstate # 삭제
ls
vpc.tf
terraform state list
No state file was found!
State management commands require a state file. Run this command
in a directory where Terraform has been run or use the -state flag
to point the command to a specific state location.
리소스의 상태가 2번이상 변경될 경우, 상태파일의 백업을 위해서 terraform.tfstate.backup 파일이 생성됩니다.
이전에 변경된 리소스의 상태파일의 내용을 확인할 수 있습니다.
# vpc.tf 파일 수정 -> 리소스 변경
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_vpc" "myvpc" {
cidr_block = "10.10.0.0/16"
tags = {
Name = "tf-state ADD"
}
}
# 파일내용 비교
diff terraform.tfstate terraform.tfstate.backup
4c4
< "serial": 3,
---
> "serial": 1,
39c39
< "Name": "tf-state ADD"
---
> "Name": "tf-state"
42c42
< "Name": "tf-state ADD"
---
> "Name": "tf-state"
로컬에서 tfstate 파일을 관리하면 협업의 어려움, 백업 및 복구 문제, 보안 위험 등의 문제가 발생할 수 있습니다. 따라서 원격 저장소(예: S3, Terraform Cloud 등)를 사용하여 상태 파일을 관리하는 것이 권장됩니다. 이렇게 하면 여러 사용자가 안전하게 협업하고, 자동으로 백업 및 복구할 수 있으며, 보안과 접근 제어를 보다 쉽게 관리할 수 있습니다.
다음 실습을 통해 백엔드(원격저장소)를 통해 State를 관리해보고, 이후에 발생하는 문제를 해결해봅니다.
실습 : Terraform Backend : AWS S3 + DynamoDB
- AWS S3 오브젝트 스토리지로 테라폼 백엔드를 구성하여 State 파일을 관리합니다.
- 협업에서 발생하는 동시성 문제 해결을 위해, AWS DynamoDB의 Locking 기능을 활용합니다.
- 악분님께서 잘 만들어주신 예제 코드를 활용하여 실습합니다.(감사합니다)
1. 리모트 공용 저장소(AWS S3) 생성
먼저, 악분님의 실습 레포지토리를 Clone 받아 s3_backend 디렉토리로 이동합니다.
git clone https://github.com/sungwook-practice/t101-study.git example
cd example/state/step3_remote_backend/s3_backend
tree
.
├── Readme.md
├── main.tf
├── provider.tf
├── terraform.tfvars
└── variables.tf
0 directories, 5 files
생성할 S3버킷 이름으로 terraform.tfvars 파일을 수정하고 테라폼 코드를 배포합니다.
aws cli를 통해 s3가 잘 생성됨을 확인할 수 있습니다.
# terraform.tfvars
bucket_name = "hackjap-hello-tf102-remote-backend"
# main.tf
resource "aws_s3_bucket" "main" {
bucket = var.bucket_name
tags = {
Name = "terraform test"
}
}
resource "aws_s3_bucket_versioning" "main" {
bucket = aws_s3_bucket.main.id
versioning_configuration {
status = "Enabled"
}
}
# 생성 및 확인
terraform init && terraform apply -auto-approve
terraform state list
aws s3 ls
2024-07-06 17:29:43 hackjap-hello-tf102-remote-backend
2. 리모트 벡엔드 저장소를 사용하여 VPC 배포
테라폼 백엔드를 사용하면 원격 저장소에 상태 파일을(tfstate) 저장할 수 있습니다. 백엔드 설정을 위해 provider.tf 파일을 먼저 수정합니다.
provider.tf 수정
- 위에서 생성한 S3 버킷이름을 작성합니다.
- dynamodb_table 속성은 주석처리 합니다(dynamodb 생성 후 주석 해제 예정)
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.4.0"
}
}
backend "s3" {
bucket = "hackjap-hello-tf102-remote-backend"
key = "terraform/state-test/terraform.tfstate"
region = "ap-northeast-2"
dynamodb_table = "terraform-lock"
}
required_version = ">= 1.4"
}
provider "aws" {}
테라폼을 초기화와 배포가 정상적으로 동작하고, 로컬이 아닌 S3 버킷 내에 tfstate 파일이 존재하는 것을 확인 할 수 있습니다.
terraform init
Initializing the backend...
Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
...
# tfstate 파일 로컬 확인 -> X
terraform apply -auto-approve
terraform state list
ls
main.tf provider.tf terraform.tfvars variables.tf
# AWS S3 버킷 내에 tfstate 파일 확인 -> O
MYBUCKET=gasida-hello-t1014-remote-backend
aws s3 ls s3://$MYBUCKET --recursive --human-readable --summarize
2024-07-06 17:44:13 1.7 KiB terraform/state-test/terraform.tfstate
Total Objects: 1
Total Size: 1.7 KiB
3. Locking을 위한 DynamoDB 생성
테라폼 원격 백엔드를 통해 테라폼의 단점인 협업을 보완할 수는 있지만, 동시에 state파일이 수정할 경우 race condition 과 같은 동시성 문제를 야기합니다. 따라서, AWS DynamoDB의 Locking 기능을 활용해서 동시성 문제를 해결해봅니다.
먼저, DynamoDB를 생성합니다. 테라폼에서 DynamoDB Lockiing 기능을 사용하기 위해서는 LockID라는 기본키가 있는 테이블을 생성해야합니다.
cd ../dynamodb
tree
|── Readme.md
├── main.tf
└── provider.tf
# main.tf
resource "aws_dynamodb_table" "terraform_state_lock" {
name = "terraform-lock" # table이름
hash_key = "LockID" # key 이름
billing_mode = "PAY_PER_REQUEST"
attribute {
name = "LockID"
type = "S" # key 타입
}
}
# provider.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.4.0"
}
}
required_version = ">= 1.4"
}
provider "aws" {}
# 생성
terraform init && terraform apply -auto-approve
DynamoDB 생성 및 테이블을 확인합니다.
# 확인
terraform state list
aws_dynamodb_table.terraform_state_lock
# 테이블 확인
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번 VPC 배포에 백엔드 설정 수정 및 적용
이전에 배포 하였던 VPC 백엔드 설정에서 주석처리 하였던 dynamodb_table 속성의 주석을 해제합니다.
cd ../vpc
# provider.tf 수정 -> dynamodb_table = "terraform-lock" 주석 제거
...
backend "s3" {
bucket = "hackjap-hello-tf102-remote-backend"
key = "terraform/state-test/terraform.tfstate"
region = "ap-northeast-2"
dynamodb_table = "terraform-lock"
}
...
백엔드 설정이 달라졌으므로 terraform init 명령어로 재적용이 필요합니다. 추가적으로 백엔드의 state파일이 달라지기 때문에 -migrate-state 옵션이 필요합니다,
terraform init -migrate-state
5. VPC tag 수정후 Locking 동작 확인
main.tf 파일에서 vpc의 태그를 수정합니다.
# main.tf -> 3추가
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
tags = {
Name = "terraform VPC 3"
}
}
terraform apply 명렁어를 실행하고 승인 여부에 입력 전 후의 Lock 테이블의 변화를 확인해보면, 실행하기 전 Lock ID와 같은 Locking 과 관련된 정보를 보여줍니다. 실행 후에는 Lock info 값이 사라짐을 확인할 수 있습니다.
6. 실습 리소스 삭제
실습에서 사용된 테라폼 배포 리소스를 삭제합니다. S3의 버킷의 경우, 하위 오브젝트들이 존재하면 삭제가 되지 않기 때문에, 추가적인 명령어로 삭제 한 후에 테라폼 배포 리소스를 삭제 하도록합니다.
# 테라폼 배포 리소스 삭제 : 현재 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
Terraform 백엔드는 상태 파일 관리를 개선하지만, 초기 설정의 복잡성, 운영 비용 증가, 잠금 기능 문제, 네트워크 의존성, 보안 문제, 백업 및 복구 관리의 어려움 등의 단점이 있습니다. 위 단점을 보완해주는 오픈소스도 테라그런트 존재합니다.
워크스페이스(Workspace)
Terraform 워크스페이스는 동일한 Terraform 구성 파일을 사용하여 여러 환경(예: 개발, 스테이징, 프로덕션)을 관리할 수 있게 해주는 기능입니다. 각 워크스페이스는 고유한 상태 파일을 유지하므로, 한 환경의 변경 사항이 다른 환경에 영향을 미치지 않습니다.
주요 기능 및 장점은 다음과 같습니다.
- 환경 분리: 워크스페이스를 사용하여 개발, 스테이징, 프로덕션 등 여러 환경을 분리하여 관리할 수 있습니다. 각 워크스페이스는 별도의 상태 파일을 가지므로, 한 환경의 변경 사항이 다른 환경에 영향을 미치지 않습니다.
- 동일한 코드 사용: 동일한 Terraform 코드 베이스를 사용하여 여러 환경을 관리할 수 있어 코드 중복을 줄일 수 있습니다.
- 편리한 전환: 명령어를 통해 쉽게 워크스페이스를 전환할 수 있어 환경 간 전환이 용이합니다.
1. 작업 공간을 통한 격리
terraform workspace 기능을 통해 작업환경을 격리하는 방식으로 동일한 구성에서 빠르고 격리된 테스트 환경에 유용합니다.
tfstate.d/워크스페이스명 형태로 폴더가 생성되며 tfstate파일을 격리해서 저장한다. 또한 워크스페이스 변수명을 활용하여 환경별로 다양한 로직을 구현할 수 있습니다.
terraform workspace new mywork
Created and switched to workspace "mywork"!
terraform workspace select default
terraform workspace select mywork
terraform workspace list
default
* mywork
tree
.
├── main.tf
├── provider.tf
├── terraform.tfstate
├── terraform.tfstate.d
│ └── mywork
│ └── terraform.tfstate
├── terraform.tfvars
└── variables.tf
# main.tf - workspace 변수 활용
provider "aws" {
region = "us-west-2"
}
resource "aws_s3_bucket" "example" {
bucket = "hackjap-bucket-${terraform.workspace}"
acl = "private"
}
2. 파일 레이아웃을 이용한 격리
파일 레이아웃을 이용한 격리는 명확한 파일 구조와 완전한 환경 격리의 장점이 있어, 강력하게 분리해야 하는 운영 환경에 적합합니다.
하지만, 코드 중복과 초기 설정의 복잡성이 단점이 존재합니다.
환경별 디렉터리 구조
- 각 환경(예: 개발, 스테이징, 프로덕션)에 대해 별도의 디렉터리를 생성합니다.
- 기능(예: 네트워크, 데이터베이스, 컴퓨팅 자원)에 따라 코드를 모듈화하고, 이를 디렉터리로 분리합니다.
'Automation > Terraform' 카테고리의 다른 글
테라폼으로 AWS EKS 배포 - T101 7주차 (0) | 2024.07.27 |
---|---|
Terraform Module & Runner - T101 5주차 (2) | 2024.07.14 |
Terraform 기본사용 3 - T101 3주차 (0) | 2024.06.29 |
Terraform 기본사용 2 - T101 2주차 (0) | 2024.06.23 |
Terraform 기본사용 1 - T101 1주차 (0) | 2024.06.16 |