"테라폼으로 시작하는 IaC"책을 기준으로 4주차 정리 내용입니다.
프로비저닝 결과에 따른 State를 저장하고 모든 내용을 저장된 상태로 추적한다. State에는 작업자가 정의한 코드와 실제 반영된 프로비저닝 결과를 저장하고, 이 정보를 토대로 이후의 리소스 생성, 수정, 삭제에 대한 동작 판단 작업을 수행한다.
State로 대상 환경에 어떤 리소스가 테라폼으로 관리되는 리소스인지 판별하고 결과를 기록한다.
- State에는 테라폼 구성과 실제를 동기화하고 각 리소스에 고유한 아이디(리소스 주소)로 맴핑
- 리소스 종속성과 같은 메타데이터를 저장하고 추적
- 테라폼 구성으로 프로비저닝된 결과를 캐싱하는 역할을 수행
resource "random_password" "mypass" {
length = 16
special = true
override_special = "!#$%"
}
{
"version": 4,
"terraform_version": "1.5.2",
"serial": 1,
"lineage": "447822de-cfd3-2d4d-32d4-21ee99a1b2d9",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "random_password",
"name": "mypw",
"provider": "provider[\"registry.terraform.io/hashicorp/random\"]",
"instances": [
{
"schema_version": 3,
"attributes": {
"bcrypt_hash": "$2a$10$84ketJYqHYqzGOKJN/709OzIrYzuHY8CawDxHq.EFMlh7p/yujifC",
"id": "none",
"keepers": null,
"length": 16,
"lower": true,
"min_lower": 0,
"min_numeric": 0,
"min_special": 0,
"min_upper": 0,
"number": true,
"numeric": true,
"override_special": "!#$%",
"result": "3wG9oUMHdeDAZDPS",
"special": true,
"upper": true
},
"sensitive_attributes": []
}
]
}
],
"check_results": null
}
JSON 형태로 작성된 State를 통해 속성과 인수를 확인할 수 있다.
!!!password도 console로 볼 수 있을까?
다행히 sensitive value로 보이지 않는다.
테라폼 구성 파일은 기존 State와 구성을 비교해 실행 계획에서 생성, 수정, 삭제 여부를 결정한다.

https://kschoi728.tistory.com/135 출처
| 기호 | 의미 |
|---|---|
| + | Create |
| - | Destroy |
| -/+ | Replace |
| ~ | Updated in-place |
| 유형 | 구성 리소스 정의 | State 구성 데이터 | 실제 리소스 | 기본 예상 동작 |
|---|---|---|---|---|
| 1 | 있음 | 리소스 생성 | ||
| 2 | 있음 | 있음 | 리소스 생성 | |
| 3 | 있음 | 있음 | 있음 | 동작 없음 |
| 4 | 있음 | 있음 | 리소스 삭제 | |
| 5 | 있음 | 동작 없음 |
신규 리소스 정의로 Apply로 리소스 생성
locals {
name = "mytest"
}
resource "aws_iam_user" "myiamuser1" {
name = "${local.name}1"
}
resource "aws_iam_user" "myiamuser2" {
name = "${local.name}2"
}

mytest1, mytest2 ID가 추가된 것을 확인할 수 있다.
실제 리소스를 수동으로 제거하고 Apply를 진행하여 리소스 생성
# 실제 리소스 수동 제거
aws iam delete-user --user-name mytest1
aws iam delete-user --user-name mytest2
aws iam list-users | jq
수동으로 삭제!!
# 아래 명령어 실행 결과 차이는?
terraform plan
terraform plan -refresh=false


plan은 Real을 참조하여 생성하는 계획이 있지만, refresh=false는 실재하는 리소스를 확인하지 않고 State만 확인하기에 변화가 없다.
Apply를 두 번을 진행, 코드/State/형상이 모두 일치한 경우
terraform apply -auto-approve
cat terraform.tfstate | jq .serial
terraform apply -auto-approve
cat terraform.tfstate | jq .serial

두 번째는 No changes로 출력된다.
코드에서 일부 리소스 삭제 후 Apply
# 리소스 하나 삭제
locals {
name = "mytest"
}
resource "aws_iam_user" "myiamuser1" {
name = "${local.name}1"
}


serial은 증가하고, 2개의 instance(EC2 instance 아니고, terraform에서 구별하는 instance)는 한 개로 되었습니다.
이미 만들어진 리소스만 있다면 테라폼의 State에 없는 내용으로 관리되지 않아 아무 작업도 수행할 수 없다.
- 처음부터 테라폼으로 관리되지 않는 리소시인 경우
- 테라폼으로 생성하고 구성과 State가 삭제된 경우
위의 두 가지로 정의할 수 있습니다.
실수로 tfstate 파일을 삭제한 경우에 plan/apply
# 실수로 tfstate 파일 삭제
rm -rf terraform.tfstate*
#
terraform plan
terraform plan -refresh=false
#
terraform apply -auto-approve
terraform state list
cat terraform.tfstate | jq


plan이 참조하는 State 파일이 없으므로 생성하지만, apply에서 실제로 생성하게되면 존재하기에 에러가 발생한다.
복구 방법은 !! Import !!로 해결한다.
!! 상태 파일 격리 소개 State File Isolation
State를 관리하는 논리적인 가상 공간을 워크스페이스라고 한다.

https://kschoi728.tistory.com/136 출처
resource "aws_instance" "mysrv1" {
ami = "ami-0ea4d4b8dc1e46212"
instance_type = "t2.micro"
tags = {
Name = "t101-week4"
}
}
# 새 작업 공간 workspace 생성 : mywork1
terraform workspace new mywork1
terraform workspace show
# 서브 디렉터리 확인
tree terraform.tfstate.d
terraform.tfstate.d
└── mywork1
# plan 시 어떤 결과 내용이 출력되나요?
terraform plan
# apply 해보자!
terraform apply -auto-approve
# 워크스페이스 확인
terraform workspace list
기본 워크스페이스는 default로 지정되어 있지만, 새로운 워크스페이스를 만드면 다른 State 파일을 참조하므로 새로운 Instance가 만들어진다!
좋은 글 감사합니다. 자주 올게요 :)