이 내용은 CloudNet@ 에서 진행하는 테라폼 기초 입문 스터디에 대한 연재글입니다.
스터디에서 사용하는 교재는 Terraform Up & Running 2nd Edition 입니다.
아래에서 3주차 스터디 내용을 공유합니다.
교재의 3장을 다룹니다.
테라폼의 상태 관리에 대해 정리하고자 합니다. 왜 상태관리를 해야하는지, 어떤방안이 있으며 어떤식으로 작성하면 좋은지 작성합니다.
테라폼은 기본적으로 생성한 인프라에 대한 정보를 상태파일에 기록합니다.
terraform.tfstate
파일로 기록됩니다.본격적으로 테라폼을 도입하고, 코드를 작성/배포하다 보면 자연스럽게 여러 사람들이 작업하겠지요. 그렇다면 자연스레 아래와 같은 요구사항이 발생할 수 있습니다.
운영, 프로덕션 레벨에서 팀 단위로 인프라 구성 코드를 공유하는 방법은 여러가지가 있습니다.
terraform apply
에 대한 락을 의미)
이런 문제를 해결하기 위해선, 원격 백엔드를 사용합니다. 1장에서 배운 “backend”의 저장공간을 원격 저장소로 설정하는 것을 의미합니다.
.tfstate
파일을 원격지에 두고 관리할 수 있습니다.
그렇다면, 원격 백엔드를 활용한 상태관리를 살펴봅시다.
제 3장의 예시를 보면 dev, staging 환경을 S3, DynamoDB로 분리하긴 했지만, 상태파일 자체가 단일인 상황은 막을 수 없습니다. 따라서, 책에서는 상태 격리에 대해서는 두가지 접근법을 함께 사용하기를 제안합니다.
테라폼의 Workspace
(이하 워크스페이스) 라는 개념
분리된 파일 레이아웃 지정
function
기능과도 밀접한 영향을 가집니다. 필요한 사항에 대해서는 프로그램을 작성하거나 모듈화를 잘 하여 반복되는 코드를 없애자는 것이 주요 골자죠.그렇다면, 상태관리를 가능하게 하는 방법 중 하나인 Workspace
를 알아봅시다.
테라폼은 기본적으로 default
라는 워크스페이스를 사용합니다. 새 작업공간을 만들기 위해서는 terraform workspace
커맨드를 사용합니다.
그렇다면 워크스페이스를 변경하는 것은 어떤 의미를 가질까요?
상술하였듯, 워크스페이스 지정만으로는 문제를 해결할 수 없습니다. 후술할 파일 레이아웃을 함께 지정하여 작업하는 것이 권장됩니다. 어떤 이유로 인해 워크스페이스 만을 사용할 수 없는지 아래에서 설명하겠습니다:
terraform destroy
명령을 실행 할 수 있습니다… :scream_cat:
상태관리 방법 중 또다른 하나는 파일 레이아웃을 잡는 것입니다. 핵심은 아래와 같습니다.
예시를 위해, 아래와 같은 구조를 가진다고 하죠.
.
├── global
│ └── s3
│ ├── main.tf
│ └── outputs.tf
├── mgmt
│ ├── services
│ └── vpc
├── prod
│ ├── services
│ └── vpc
└── stage
├── data-stores
│ └── mysql
│ ├── main-vpgsg.tf
│ ├── main.tf
│ ├── outputs.tf
│ ├── terraform.tfstate
│ └── variables.tf
└── services
└── webserver-cluster
├── main.tf
└── user-data.sh
최상위 폴더
각 환경별 구성 요소
명명 규칙 naming conventions (예시)
이 문단에서는 ELB, ASG, 그리고 RDS가 구축된 환경을 만들고, 이에 대해 디렉토리 구조를 아래와 같이 작성하여 실습하도록 하겠습니다.
├── global
│ └── s3
│ ├── main.tf
│ └── outputs.tf
└── stage
├── data-stores
│ └── mysql
│ ├── main-vpgsg.tf
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── services
└── webserver-cluster
├── main.tf
└── user-data.sh
코드의 위치는 아래와 같습니다:
export TF_VAR_db_password="(YOUR_DB_PASSWORD)"
direnv
의 .envrc
파일에 상기 명령과 같은 환경변수를 넣어놓고 사용합니다.웹 서버 클러스터를 배포하며 terraform_remote_state
라는 값과, 테라폼의 내장 함수(build-in function)에 대해 살펴봅시다.
terraform_remote_state
데이터 소스에서 읽을 수 있으며, 그 양식은 아래와 같습니다.data.terraform_remote_state.<NAME>.outputs.<ATTRIBUTE>
terraform_remote_state
데이터 소스에서 데이터베이스 주소와 포트 정보를 가져와서 HTTP 응답에 정보를 노출user_data = <<EOF
#!/bin/bash
echo "Hello, World" >> index.html
echo "${data.terraform_remote_state.db.outputs.address}" >> index.html
echo "${data.terraform_remote_state.db.outputs.port}" >> index.html
nohup busybox httpd -f -p ${var.server_port} &
EOF
template_file
라는 데이터 소스를 사용해봅시다.function_name()
format
함수는 아래 처럼 사용합니다. 문자열 FMT의 sprintf
구문에 따라 ARGS
인수를 형식화하는 호출방식입니다.format(<FMT>, <ARGS>, ...)
# 참고: 테라폼 콘솔 사용에 관하여
terraform console
> format("%.3f", 3.14159265359)
"3.142"
templatefile
함수를 살펴봅시다.templatefile
함수는 PATH 에서 파일을 읽고 그 내용을 문자열로 반환합니다.templatefile(<PATH>, <VARS>)
#!/bin/bash
cat > index.html <<EOF
<h1>Hello, World</h1>
<p>DB address: ${db_address}</p>
<p>DB port: ${db_port}</p>
EOF
nohup busybox httpd -f -p ${server_port} &
templatefile
데이터 소스의 vars 맵에 있는 변수만 사용 가능resource "aws_launch_configuration" "example" {
image_id = "ami-0fb653ca2d3203ac1"
instance_type = "t2.micro"
security_groups = [aws_security_group.instance.id]
# Render the User Data script as a template
user_data = templatefile("user-data.sh", {
server_port = var.server_port
db_address = data.terraform_remote_state.db.outputs.address
db_port = data.terraform_remote_state.db.outputs.port
})
# Required when using a launch configuration with an auto scaling group.
lifecycle {
create_before_destroy = true
}
}
제 3장에서는 아래의 내용을 반드시 기억하셨으면 좋겠습니다.
이것으로 제 3장을 마칩니다. 긴 글 읽어주셔서 감사합니다.