이 내용은 CloudNet@ 에서 진행하는 테라폼 기초 입문 스터디에 대한 연재글입니다.
스터디에서 사용하는 교재는 Terraform Up & Running 2nd Edition 입니다.
이번 장은, 1장부터 6장까지의 내용을 리와인드하는 장으로 하기로 하였습니다. 중간 스터디를 하면서도 복습했지만 스터디 모임이 한 주 쉬어가며 문서화를 하여 개념을 스스로 정리해야겠다 싶었습니다.
tfenv
를 통한 테라폼 버전관리를 수행해봅시다. 저는 리눅스 환경에서 실습을 진행하므로, 공식 repository에 작성된 Manual 설치대로 진행하겠습니다.# ${HOME}/.tfenv에 관련 내용 설치
git clone --depth=1 https://github.com/tfutils/tfenv.git ~/.tfenv
# 사용하고있는 쉘에 따라 ${PATH} 추가.
# 저는 zsh을 사용하고 있습니다.
# 해당명령 수행 후 쉘을 종료하고 다시 켜주세요.
echo 'export PATH=$PATH:$HOME/.tfenv/bin' >> ~/.zshrc
# 설치 가능 버전 확인
tfenv list-remote | head
1.4.0-alpha20221109
1.3.6
...
# 현재 설치된 버전 확인
tfenv list
No versions available. Please install one with: tfenv install
# 특정 버전 설치
#(옵션) export TFENV_ARCH=arm64 # mac Apple silicon M1/M2
tfenv install 1.2.3
tfenv list
# 특정 버전 사용
tfenv use 1.2.3
Switching default version to v1.2.3
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.2.3
# 테라폼 버전 확인
terraform version
on linux_amd64
오하이오 리전(us-east-2
)으로 변경합시다.
저는 direnv를 사용하고 있으므로, 작업이 필요한 하부 워킹디렉토리에 .envrc
파일을 생성 후 AWS_DEFAULT_REGION
을 오하이오 리전으로 변경하여 사용하였습니다. 아래 커맨드로 바꾸고, 확인해봅시다.
# AWS_DEFAULT_REGION 수정
vi .envrc
# direnv 내의 추가/수정된 .envrc 파일을 사용합시다.
direnv allow
# 반영여부 확인
aws configure list
Name Value Type Location
---- ----- ---- --------
profile <not set> None None
access_key ************REDACTED env
secret_key ************REDACTED env
region us-east-2 env ['AWS_REGION', 'AWS_DEFAULT_REGION']
먼저, 영문 개정 3판의 코드를 클론합시다.
git clone https://github.com/brikis98/terraform-up-and-running-code.git
cd terraform-up-and-running/code/terraform
테라폼 교재 예시의 가장 기본입니다. 위에서 설명드린 아키텍처에 작성된 내용을 코드로 배포하는 것이 주요 내용인지라, 해당 내용을 이해하고 넘어가야 다음 진도를 이해하며 넘어가실 수 있습니다!
아래 명령으로 구동을 진행할 수 있습니다.
# [터미널2]
cd 02-intro-to-terraform-syntax/webserver-cluster
cat main.tf variables.tf
# 배포
terraform init
terraform plan
terraform apply -auto-approve
# 배포 완료 후 ALB 접속 확인
ALBDNS=$(terraform output -raw alb_dns_name)
while true; do curl --connect-timeout 1 http://$ALBDNS/ ; echo; echo "------------------------------"; date; sleep 1; done
# 삭제
terraform destroy -auto-approve
cd ~/terraform-up-and-running-code/code/terraform
이 장에서는, .tfstate
파일이나 폴더구조 관리에 대해 배웠습니다. 관리를 제대로 하지 않았을 때의 리스크는 이 링크를 다시 봅시다…
.tfstate
파일에 대한 관리를 진행합니다.
아래 명령으로 구동을 진행할 수 있습니다.
# 환경변수에 지정
export TF_VAR_bucket_name=ex07-tfstate
export TF_VAR_table_name=ex07-t101-locks
export TF_VAR_bucket_name=ex07-t101-tfstate
export TF_VAR_table_name=ex07-t101-locks
# 환경변수 확인
export | grep TF_VAR_
# (옵션) 환경변수 지정 삭제
unset TF_VAR_bucket_name
unset TF_VAR_table_name
#
cd 03-terraform-state/file-layout-example/global/s3
cat main.tf variables.tf
# 초기화 및 검증 : 환경변수 적용 확인
terraform init && terraform plan
# 배포
terraform apply -auto-approve
# 확인
aws s3 ls
aws dynamodb list-tables --output text
# 이동
cd ../..
# [터미널1] RDS 생성 모니터링
while true; do aws rds describe-db-instances --query "*[].[Endpoint.Address,Endpoint.Port,MasterUsername]" --output text ; echo "------------------------------" ; sleep 1; done
# [터미널2]
cd stage/data-stores/mysql
cat main.tf variables.tf
# 환경변수에 지정
export TF_VAR_db_username='cloudneta'
export TF_VAR_db_password='cloudnetaQ!'
# 환경변수 확인
export | grep TF_VAR_
# main.tf 에 백엔드 부분 수정
vi main.tf
backend "s3" {
# This backend configuration is filled in automatically at test time by Terratest. If you wish to run this example
# manually, uncomment and fill in the config below.
bucket = "ex07-tfstate"
key = "stage/data-stores/mysql/terraform.tfstate"
region = "us-east-2"
dynamodb_table = "ex07-t101-locks"
# encrypt = true
}
# 초기화 및 검증 : 환경변수 적용 확인
terraform init && terraform plan
# 배포 : RDS는 생성 시 6분 정도 시간 소요
terraform apply -auto-approve
terraform output
aws s3 ls s3://$TF_VAR_bucket_name --recursive --human-readable --summarize
# 이동
cd ../..
#
cd services/webserver-cluster
cat main.tf variables.tf
# 환경변수에 지정
export TF_VAR_db_remote_state_bucket=$TF_VAR_bucket_name # description = "The name of the S3 bucket used for the database's remote state storage"
export TF_VAR_db_remote_state_key='stage/data-stores/mysql/terraform.tfstate' # description = "The name of the key in the S3 bucket used for the database's remote state storage"
# 환경변수 확인
export | grep TF_VAR_
# 초기화 및 검증 : 환경변수 적용 확인
terraform init && terraform plan
# 배포
terraform apply -auto-approve
# ALB DNS주소로 curl 접속 확인
ALBDNS=$(terraform output -raw alb_dns_name)
while true; do curl --connect-timeout 1 http://$ALBDNS ; echo; echo "------------------------------"; date; sleep 1; done
curl -s http://$ALBDNS
# 삭제
# 각 폴더에서 리소스 삭제
stage/services/webserver-cluster$ terraform destroy -auto-approve
stage/data-stores/mysql$ terraform destroy -auto-approve
global/s3$ terraform destroy -auto-approve
# 이동
cd ~/terraform-up-and-running-code/code/terraform
테라폼 state 파트에서 작성해본 내용들을 모듈화하여, 보다 효율적인 테라폼 코드를 작성해봅시다. 코드 재사용, 여러 테라폼 리소스를 논리적 그룹으로 묶을 수 있습니다. 논리적으로 구상할 수 있다는 것은 우리의 사고대로 코드들을 재배합할 수 있다는 이야기지요.
여기서는 웹서버 내용에 대해서만 아직 모듈로 묶어두었고, 8장에서 ALB, ASG, EC2가 묶여있는 부분을 해제해봅시다.
상기 내용과 동일합니다!
Staging RDS 배포하기
# [터미널1] RDS 생성 모니터링
while true; do aws rds describe-db-instances --query "*[].[Endpoint.Address,Endpoint.Port,MasterUsername]" --output text ; echo "------------------------------" ; sleep 1; done
# [터미널2]
cd 04-terraform-module/module-example/stage/data-stores/mysql
cat main.tf variables.tf
# 환경변수에 지정
export TF_VAR_db_username='cloudneta'
export TF_VAR_db_password='cloudnetaQ!'
# 환경변수 확인
export | grep TF_VAR_
# main.tf 에 백엔드 부분 수정
vi main.tf
backend "s3" {
# This backend configuration is filled in automatically at test time by Terratest. If you wish to run this example
# manually, uncomment and fill in the config below.
bucket = "ex07-tfstate"
key = "stage/data-stores/mysql/terraform.tfstate"
region = "us-east-2"
dynamodb_table = "ex07-t101-locks"
# encrypt = true
}
# 초기화 및 검증 : 환경변수 적용 확인
terraform init && terraform plan
# 배포 : RDS는 생성 시 6분 정도 시간 소요
terraform apply -auto-approve
terraform output
aws s3 ls s3://$TF_VAR_bucket_name --recursive --human-readable --summarize
# 이동
cd ../../
#
cd services/webserver-cluster
cat main.tf variables.tf
# 환경변수에 지정
export TF_VAR_db_remote_state_bucket=$TF_VAR_bucket_name # description = "The name of the S3 bucket used for the database's remote state storage"
export TF_VAR_db_remote_state_key='stage/data-stores/mysql/terraform.tfstate' # description = "The name of the key in the S3 bucket used for the database's remote state storage"
# 환경변수 확인
export | grep TF_VAR_
# 초기화 및 검증 : 환경변수 적용 확인
terraform init && terraform plan
# 배포
terraform apply -auto-approve
# ALB DNS주소로 curl 접속 확인
ALBDNS=$(terraform output -raw alb_dns_name)
while true; do curl --connect-timeout 1 http://$ALBDNS ; echo; echo "------------------------------"; date; sleep 1; done
curl -s http://$ALBDNS
# 삭제
# 각 폴더에서 리소스 삭제
stage/services/webserver-cluster$ terraform destroy -auto-approve
stage/data-stores/mysql$ terraform destroy -auto-approve
03-terraform-state/file-layout-example/global/s3$ terraform destroy -auto-approve # 아래 Production 실습을 이어서 할 경우에는 실습 완료 후 삭제 할 것
# 이동
cd ~/terraform-up-and-running-code/code/terraform
cf. Production 배포는 04-terraform-module/module-example
의 prod 디렉토리의 RDS와 웹서버 클러스터를 배포하면 됩니다.
무중단 배포(zero-downtime deployment)의 경우, 수정된 테라폼 코드나 환경변수를 사용하여 terraform apply
를 하면 끝입니다. 배포과정은 상기 내용과 동일하지만, 모듈을 활용하여 배포하는 단계가 다릅니다. 여기서는 배포가 “어떻게” 되는지를 살펴보겠습니다.
# [터미널1] RDS 생성 모니터링
while true; do aws rds describe-db-instances --query "*[].[Endpoint.Address,Endpoint.Port,MasterUsername]" --output text ; echo "------------------------------" ; sleep 1; done
# [터미널2]
cd 05-tips-and-tricks/module-example/stage/data-stores/mysql
cat main.tf variables.tf
# 환경변수에 지정
export TF_VAR_db_username='cloudneta'
export TF_VAR_db_password='cloudnetaQ!'
# 환경변수 확인
export | grep TF_VAR_
# main.tf 에 백엔드 부분 수정
vi main.tf
backend "s3" {
# This backend configuration is filled in automatically at test time by Terratest. If you wish to run this example
# manually, uncomment and fill in the config below.
bucket = "ex07-tfstate"
key = "stage/data-stores/mysql/terraform.tfstate"
region = "us-east-2"
dynamodb_table = "ex07-t101-locks"
# encrypt = true
}
# 초기화 및 검증 : 환경변수 적용 확인
terraform init && terraform plan
# 배포 : RDS는 생성 시 6분 정도 시간 소요
terraform apply -auto-approve
terraform output
aws s3 ls s3://$TF_VAR_bucket_name --recursive --human-readable --summarize
# 이동
cd ../../
#
cd services/webserver-cluster
cat main.tf variables.tf
# 환경변수에 지정
export TF_VAR_db_remote_state_bucket=$TF_VAR_bucket_name # description = "The name of the S3 bucket used for the database's remote state storage"
export TF_VAR_db_remote_state_key='stage/data-stores/mysql/terraform.tfstate' # description = "The name of the key in the S3 bucket used for the database's remote state storage"
# 환경변수 확인
export | grep TF_VAR_
# 초기화 및 검증 : 환경변수 적용 확인
terraform init && terraform plan -var server_text='Old server text'
# 배포
terraform apply -auto-approve -var server_text='Old server text'
# ALB DNS주소로 curl 접속 확인
ALBDNS=$(terraform output -raw alb_dns_name)
while true; do curl --connect-timeout 1 http://$ALBDNS ; echo; echo "------------------------------"; date; sleep 1; done
curl -s http://$ALBDNS
# [터미널1]
ALBDNS=<직접입력>
while true; do curl --connect-timeout 1 http://$ALBDNS ; echo; echo "------------------------------"; date; sleep 1; done
# [터미널2]
while true; do aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output text ; echo "------------------------------" ; sleep 1; done
# 무중단 업그레이드 배포 : 환경변수 수정 적용 >> 오토스케일링그룹 2개중 기존 그룹은 5분 정도 후에 EC2가 삭제됨(오래 걸리니 맘 편히 기다리자)
terraform plan -var server_text='NEW server text'
terraform apply -auto-approve -var server_text='NEW server text'
# 삭제
# 각 폴더에서 리소스 삭제
stage/services/webserver-cluster$ terraform destroy -auto-approve
stage/data-stores/mysql$ terraform destroy -auto-approve
03-terraform-state/file-layout-example/global/s3$ terraform destroy -auto-approve
# 이동
cd ~/terraform-up-and-running-code/code/terraform
제 7장에서는 아래의 내용을 반드시 기억하셨으면 좋겠습니다.
이것으로 제 7장을 마칩니다. 긴 글 읽어주셔서 감사합니다.