해당 내용은 cloudNet@ 팀의 가시다 님이 진행하는 테라폼 스터디 T101 4기에서 다룬 내용과 "테라폼으로 시작하는 IaC" (한빛미디어) 저서 내용을 정리한 것입니다.
1. State의 목적과 의미
- terraform apply 명령을 실행하면 이전에 생성된 리소스와 비교해 생성, 수정, 삭제 동작이 수행된다.
- 이 때 테라폼은 State를 사용해 대상 환경에서 어떤 리소스가 테라폼으로 관리되는 리소스인지 판별하고 결과를 기록한다.
- State의 역할
- State에는 테라폼 구성과 실제를 동기화하고 각 리소스에 고유한 아이디(리소스 주소)를 매핑
- 리소스 종속성과 같은 메타데이터를 저장하고 추적
- 테라폼 구성으로 프로비저닝된 결과를 캐싱하는 역할을 수행
- 예제 코드
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_vpc" "myvpc" {
cidr_block = "10.10.0.0/16"
tags = {
Name = "t101-study"
}
}
terraform init && terraform plan && terraform apply -auto-approve
cat terraform.tfstate | jq | grep "serial"
- tag 수정 후 다시 아래 명령어 실행하면 serial 번호가 바뀐 것을 확인할 수 있다.
cat terraform.tfstate | jq | grep "serial"
이론 내용
- 상태 파일은 배포할 때마다 변경되는 Private API로, 오직 테라폼 내부에서 사용하기 위한 것.
- 테라폼 상태 파일을 직접 편집하거나 직접 읽는 코드로 작성해서는 안된다.
팀 단위에서 테라폼 운영 시 문제점
- 상태 파일을 저장하는 공유 스토리지
- 각 팀원이 동일한 테라폼 상태 파일 사용을 위해서 공유 위치에 저장이 필요
- 상태 잠금 파일
- 잠금 기능 없이 두 팀원이 동시에 테라폼 실행 시 여러 테라폼 프로세스가 상태 파일을 동시에 업데이트하여 충돌 가능 ( 경쟁 상태 race condition )
- 상태 파일 격리
- 예를 들면 테스트 dev 와 검증 stage 와 상용 production 각 환경에 대한 격리가 필요
상태 파일 공유로 버전 관리 시스템 비추천
- 수동 오류
- 테라폼을 실행하기 전에 최신 변경 사항을 가져오거나 실행하고 나서 push 하는 것을 잊기 쉽습니다(?).
- 팀의 누군가가 이전 버전의 상태 파일로 테라폼을 실행하고, 그 결과 실수로 이전 버전으로 롤백하거나 이전에 배포된 인프라를 복제하는 문제가 발생 할 수 있음.
- 잠금
- 대부분의 버전 관리 시스템은 여러 명의 팀 구성원이 동시에 하나의 상태 파일에 terraform apply 명령을 실행하지 못하게 하는 잠금 기능이 제공되지 않음.
- 시크릿 (보안)
- 테라폼 상태 파일의 모든 데이터는 평문으로 저장됨. 민감 정보가 노출될 위험.
지원되는 원격 백엔드
AWS S3, Azure Blob Storage, Google Cloud Storage, Consul, Postgres database, k8s secret 등
- 수동 오류 해결
- plan/apply 실행 시 마다 해당 백엔드에서 파일을 자동을 로드, apply 후 상태 파일을 백엔드에 자동 저장
- 잠금
- apply 실행 시 테라폼은 자동으로 잠금을 활성화, -lock-timout=<TIME> 로 대기 시간 설정 지정 가능
- 시크릿
- 대부분 원격 백엔드는 기본적으로 데이터를 보내거나 상태 파일을 저장할 때 암호화하는 기능을 지원
2. State 동기화
테라폼 구성파일은 기존 State와 구성을 비교해 실행 계획에서 생성, 수정, 삭제 여부를 결정한다.
- 유형별 실습 + 문제상황 -> 복구 import *
유형 | 구성 리소스 정의 | State 구성 데이터 | 실제 리소스 | 기본 예상 동작 |
1 | 있음 | 리소스 생성 | ||
2 | 있음 | 있음 | 리소스 생성 | |
3 | 있음 | 있음 | 있음 | 리소스 생성 |
4 | 있음 | 있음 | 리소스 삭제 | |
5 | 있음 | 동작 없음 |
유형1 : 신규 리소스 정의 -> Apply -> 리소스 생성
locals {
name = "t1014-smlim"
}
resource "aws_iam_user" "myiamuser1" {
name = "${local.name}1"
}
resource "aws_iam_user" "myiamuser2" {
name = "${local.name}2"
}
terraform init && terraform apply -auto-approve
aws iam list-users | jq
유형 2 : 실제 리소스 수정 제거 -> Apply -> 리소스 생성
aws iam delete-user --user-name t1014-smlim1
aws iam delete-user --user-name t1014-smlim2
aws iam list-users | jq
terraform state list
terraform plan
terraform plan -refresh=false
cat terraform.tfstate | jq .serial
cat terraform.tfstate | jq .serial
# apply
terraform apply -auto-approve
terraform state list
# apply 전후 serial 비교
cat terraform.tfstate | jq .serial
# iam 사용자 리스트 확인
aws iam list-users | jq
유형 3 : Apply -> apply <- 코드, State, 형상 모두 일치한 경우
#
terraform apply -auto-approve
cat terraform.tfstate | jq .serial
terraform apply -auto-approve
cat terraform.tfstate | jq .serial
terraform apply -auto-approve
cat terraform.tfstate | jq .serial
유형 4 : 코드에서 일부러 리소스 삭제 -> Apply
locals {
name = "t1014-smlim"
}
resource "aws_iam_user" "myiamuser1" {
name = "${local.name}1"
}
aws iam list-users | jq
유형 5 : 실수로 tfstate 파일 삭제 -> plan / apply
유형 5 의 경우 해결 방법
# iam 사용자 리스트 확인
aws iam list-users | jq
# import 도움말 : 빨간색 설명 출력...
terraform import
# ADDR은 리소스주소 , ID는
# terraform [global options] import [options] ADDR ID
terraform import aws_iam_user.myiamuser1 t1014-smlim1
aws_iam_user.myiamuser1: Importing from ID "t1014-smlim1"...
aws_iam_user.myiamuser1: Import prepared!
Prepared aws_iam_user for import
aws_iam_user.myiamuser1: Refreshing state... [id=t1014-smlim1]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.
#
terraform state list
cat terraform.tfstate | jq
terraform apply -auto-approve
3. 워크스페이스
State를 관리하는 논리적인 가상 공간을 워크스페이스라고 한다. 테라폼 구성파일은 동일하지만 작업자는 서로 다른 State를 갖는 실제 대상을 프로비저닝할 수 있다. 워크스페이스는 기본 default로 정의된다.
- 예제 코드
resource "aws_instance" "mysrv1" {
ami = "ami-0ea4d4b8dc1e46212"
instance_type = "t2.micro"
tags = {
Name = "t1014-study"
}
}
terraform workspace list
terraform init && terraform plan && terraform apply -auto-approve
terraform state list
terraform workspace new smlim1
terraform workspace show
terraform plan
terraform workspace select default
terraform destroy -auto-approve
workspace 를 "default"로 선택하고 destroy 명령을 실행하면 기존에 생성했던 aws_instance 리소스를 삭제한다.
terraform workspace delete [워크스페이스 이름]
사용하지 않는 workspace 를 위 명령어로 삭제한다.
다수의 워크스페이스를 사용할 때의 장점
- 하나의 루트 모듈에서 다른 환경을 위한 리소스를 동일한 테라폼 구성으로 프로비저닝하고 관리
- 기존 프로비저닝된 환경에 영향을 주지 않고 변경 사항 실험 가능
- 깃의 브랜치 전략처럼 동일한 구성에서 서로 다른 리소스 결과 관리
단점
- State 가 동일한 저장소에 저장되어 State 접근 권한 관리가 불가능
- 모든 환경이 동일한 리소스를 요구하지 않을 수 있으므로 테라폼 구성에 분기 처리가 다수 발생 가능
- 프로비저닝 대상에 대한 인증 요소를 완벽히 분리하기 어려움
'DevOps' 카테고리의 다른 글
[T1014-이론] 6장 Module (0) | 2024.07.10 |
---|---|
[T1014-실습] Terraform Backend: AWS S3 + DynamoDB (0) | 2024.07.07 |
[T1014-이론] 4장 프로바이더 (0) | 2024.07.07 |
[T1014-이론] 3장 기본 사용법 (6) (0) | 2024.06.30 |
[T1014-이론] 3장 기본 사용법 (5) (0) | 2024.06.30 |