[IaC]Terraform의 tfstate파일에 관하여
Terraform은 어떻게 인프라를 코드로 관리할 수 있는 것일까? 항상 클라우드 상에 있는 리소스를 최신상태로 유지하고 변동사항을 추적하는 모습을 보이는데, 그것이 가능한 이유가 궁금했다. 그 이유는 tfstate파일의 존재 때문이었다. tfstate파일이 무엇인지 알아보고 작동원리를 알아볼 수 있는 간단한 실습을 해볼 것이다.
tfstate 상태파일
- 최신 테라폼 상태 정보를 담고 있는 파일
- 현재 시점에서 존재하는 인프라 상태를 보장 x
- 인프라의 실제 상태와 비교할 대상으로 사용됨
이것이 상태 파일의 정의와 특징인데 잘 와닿지 않는다. 이를 잘 이해하기 위해서는 3가지 관점에서 바라보아야 한다.
Code, State, Infra. 위 세 가지가 일치하도록 유지하는 것이 테라폼 운영의 목적이다. 즉 정상적으로 작동하는 상태라는 것이다. AWS s3를 간단하게 구현하는 테라폼 코드에서 각 부분에 해당하는 것들을 지우면 어떤 일이 벌어질지 살펴보고, 각 부분의 역할을 느껴보자.
S3 인프라를 구축하는 간단한 terraform
//파일명 provider.tf
provider "aws" {
region = "ap-northeast-2"
}
//파일명 s3.tf
resource "aws_s3_bucket" "bucket" {
bucket = "s3-terraform-mason"
tags = {
"Name" = "s3-terraform-mason"
}
}
정말 간단하게 위와 같이 코드를 짜고 명령어만 치면 리소스가 aws상에서 구축된다.
$ terraform init //초기화
$ terraform plan //apply전 확인
$ terraform apply //리소스 생성
그런데 .tfstate라는 파일이 생겼다? 확인해보자.
{
"version": 4,
"terraform_version": "1.1.8",
"serial": 1,
"lineage": "2e46735b-d2be-76ce-606a-beaf1a2aef70",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "aws_s3_bucket",
"name": "bucket",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 0,
"attributes": {
"acceleration_status": "",
"acl": null,
"arn": "arn:aws:s3:::s3-terraform-mason",
"bucket": "s3-terraform-mason",
"bucket_domain_name": "s3-terraform-mason.s3.amazonaws.com",
"bucket_prefix": null,
"bucket_regional_domain_name": "s3-terraform-mason.s3.ap-northeast-2.amazonaws.com",
"cors_rule": [],
"force_destroy": false,
"grant": [
{
"id": "7c2788f832e345874e517851f5648bba2b0e6ceaa603a99ed036f844b430ccd5",
"permissions": [
"FULL_CONTROL"
],
"type": "CanonicalUser",
"uri": ""
}
],
"hosted_zone_id": "Z3W03O7B5YMIYP",
"id": "s3-terraform-mason",
"lifecycle_rule": [],
"logging": [],
"object_lock_configuration": [],
"object_lock_enabled": false,
"policy": "",
"region": "ap-northeast-2",
"replication_configuration": [],
"request_payer": "BucketOwner",
"server_side_encryption_configuration": [],
"tags": {
"Name": "s3-terraform-mason"
},
"tags_all": {
"Name": "s3-terraform-mason"
},
"versioning": [
{
"enabled": false,
"mfa_delete": false
}
],
"website": [],
"website_domain": null,
"website_endpoint": null
},
"sensitive_attributes": [],
"private": "bnVsbA=="
}
]
}
]
}
너무 어려워서 잘 모르겠지만 내가 코드로 만든 리소스가 잘 생성되었다는 파일인 것 같다! 실제로 AWS에서 s3가 잘 생성되었다. 이것이 테라폼이 원하는 이상적인 상태이다. 내가 짠 코드와 상태 파일과 리소스가 모두 일치하는 상태이다. 만약 상태파일을 지운다면?
상태파일 지우기
위와 같은 에러가 발생하였다. 읽어보니 내 요청에 따라 새 버킷을 생성하려 했으나 이미 리소스에 존재한다는 것이다! 이 말은 테라폼은 이미 리소스가 AWS에 있다는 사실을 모른다는 것이다. 그래서 한번 더 만들려고 시도를 한 것이고 버킷의 이름은 중복될 수 없으니 실패한 것이다.
이 상태 파일은 apply 할 때 생성되었는데, 그때 리소스의 상태를 기록해 놓는다고 생각하면 된다. 테라폼은 상태 파일을 바탕으로 리소스의 상태를 판단한다고 할 수 있다.
코드 지우기
그렇다면 코드를 지우면 어떻게 될까?
리소스가 destroy 된다고 경고한다. 코드는 내가 원하는 리소스의 상태인데 코드를 지웠으니 원하는 리소스의 상태가 "없음"이 된다. 그러나 상태 파일은 존재하므로 테라폼은 리소스가 존재한다고 판단한다. 따라서 apply를 통해 적용하면 원하는 "없음"의 상태로 맞춰주고자 리소스를 지우는 것이다.
리소스를 직접 변경하기
그렇다면 콘솔을 이용하여 리소스를 직접 변경하면 어떻게 될까? 키를 하나 추가해보았다.
테라폼은 리소스의 상태를 확인하고 다름을 작성된 상태 파일과 다름을 인지한다. 그리고 상태 파일에 맞게 리소스를 수정할지 말지 물어본다.
테라폼은 code, state, infra 세 가지 요소를 이용하여 리소스와 직접 소통하며 최신의 상태를 유지할 수 있다. 참 효율적이고 강력한 방법인 것 같다.