해당 파일에는 테라폼을 실행 시 매핑되는 리소스들의 상태값을 가지고 있습니다.
기본적으로 /foo/bar 폴더에서 테라폼을 실행하면 JSON 형태의 /foo/bar/terraform.tfstate 파일을 생성합니다.
ex) terraform.tfstate 예시
{
"version": 4,
"terraform_version": "1.1.9",
"serial": 6,
"lineage": "xxxxxxxxxxxxxxxx",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "google_compute_firewall",
"name": "default",
"provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"allow": [
{
"ports": [
"8080"
],
"protocol": "tcp"
}
],
"creation_timestamp": "2022-04-24T03:21:09.940-07:00",
"deny": [],
"description": "",
"destination_ranges": [],
"direction": "INGRESS",
"disabled": false,
"enable_logging": null,
"id": "xxxxxxxxxxxxxxxx",
"log_config": [],
"name": "webserver-firewall",
"network": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"priority": 1000,
"project": "terraform",
"self_link": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"source_ranges": [],
"source_service_accounts": [],
"source_tags": [
"web"
],
"target_service_accounts": [],
"target_tags": [
"web"
],
"timeouts": null
},
"sensitive_attributes": [],
"private": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
]
}
]
}
즉, plan 명령어의 출력은 코드상의 설계와 실제 인프라의 설계의 차이를 보여준다고 생각하면 됩니다.
상태파일은 프라이빗이며 직접 편집하거나 수정해서는 안됩니다. 파일 상태를 조작해야 하는 경우 terraform import, terraform state 명령을 통해 조작을 해야 합니다.
테라폼을 실제 운영 환경에서 팀 단위로 사용하고자 할 때는 다음과 같은 몇 가지 문제에 직면하게 됩니다.
테라폼의 상태 파일을 깃과 같은 형상관리 시스템에 공유하는 것은 다음과 같은 이유 때문에 부적절합니다.
1. 변경 사항을 실행하고 나서 푸시하는 것을 잊어버리는 경우가 있습니다.
2. 여러 명의 팀 구성원이 동시에 하나의 상태 파일에 apply 명령을 실행하지 못하게 하는 잠금 기능을 제공하지 않습니다.
3. 테라폼의 상태 파일은 모든 데이터를 평문으로 저장하기에 보안적으로 적절하지 않습니다.
이의 문제와 같은 상황을 해결하기 위해서는 테라폼에 내장된 원격 백엔드 기능을 사용하여 클라우드 스토리지에 저장하는 것이 좋습니다.
1. 원격 백엔드 구성 시 테라폼은 plan이나 apply 명령을 실행할 때마다 해당 백엔드에서 상태 파일을 자동으로 로드합니다. apply 명령을 실행한 후에는 상태 파일을 백엔드에 자동 저장합니다.
2. apply 명령을 실행 시 자동으로 잠금을 활성화합니다. -lock-timeout=<TIME>을 사용하면 apply 명령을 실행할 때 잠금이 해제되기까지 테라폼이 얼마 동안 대기하도록 할지 설정합니다.
3. 데이터를 보내거나 상태 파일을 저장할 때 암호화하는 기능을 지원합니다.
ex) GCP 스토리지 생성 리소스
provider "google" {
credentials = file("key2.json")
project = "terraform-348208"
region = "asia-northeast3"
}
resource "random_id" "instance_id" {
byte_length = 8
}
resource "google_storage_bucket" "terraform_state" {
# 버킷 이름
name = "terraform-up-and-running-state-${random_id.instance_id.hex}"
# 버킷을 삭제할 때 해당 버킷에 포함된 모든 객체를 삭제합니다.
force_destroy = true
location = "ASIA"
storage_class = "Standard"
# 실수로 S3 버킷을 삭제하는 것을 방지합니다.(생명주기 설정)
lifecycle {
prevent_destroy = true
}
# 코드 이력을 관리하기 위해 상태 파일의 버전 관리를 활성화합니다.
versioning {
enabled = false
}
// GCP는 스토리지 디폴트가 암호화
}
terraform {
backend "gcs" {
bucket = "terraform-up-and-running-state-0d9027ef04cb8b9b"
credentials = "key2.json"
}
}
테라폼으로 구글 클라우드 스토리지 버킷을 생성하고 백엔드를 구성하는 코드입니다.
먼저 스토리지를 생성 후 backend를 적용해야 합니다.
AWS의 경우 버킷과 다이나모DB를 사용하여 Lock을 걸지만, GCP 경우 스토리지만으로 Lock을 걸 수 있는 듯 합니다.
ex) AWS S3 생성 리소스
provider "aws" {
region = "us-east-2"
}
resource "aws_s3_bucket" "terraform_state" {
bucket = var.bucket_name
// This is only here so we can destroy the bucket as part of automated tests. You should not copy this for production
// usage
force_destroy = true
# 상태 파일의 이력관리를 위해
# 버전관리 기능을 활성화 합니다.
versioning {
enabled = true
}
# Enable server-side encryption by default
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
}
resource "aws_dynamodb_table" "terraform_locks" {
name = var.table_name
billing_mode = "PAY_PER_REQUEST"
hash_key = "LockID"
attribute {
name = "LockID"
type = "S"
}
}
GCP 스토리지 백엔드 참조
https://www.terraform.io/language/settings/backends/gcs
Backend Type: gcs | Terraform by HashiCorp
Terraform can store the state remotely, making it easier to version and work with in a team.
www.terraform.io
AWS S3 백엔드 참조
https://www.terraform.io/language/settings/backends/s3
Backend Type: s3 | Terraform by HashiCorp
Terraform can store state remotely in S3 and lock that state with DynamoDB.
www.terraform.io
테라폼 백엔드에는 몇 가지 단점이 있습니다.
1. 2단계로 백엔드를 구성해야 합니다.
- 백엔드 구성 시
- 백엔드 삭제 시
2. 테라폼의 백엔드 블록에서는 변수나 참조를 사용할 수 없다는 점입니다.
해당 단점의 유일한 해결책은 init 명령어 실행 시 -backend-config 옵션을 통해 변수를 전달하는 것 입니다.(2019년 5월 기준)
# backend.hcl
bucket = "terraform-running-state"
region = "us-east-2"
dynamodb_table = "terraform-running-locks"
encrypt = true
$ terraform init -backend-config=backend.hcl
위와 같은 hcl 코드를 작성한 뒤 terraform init -backend-config=backend.hcl 명령어를 실행할 수 있습니다. 이 외의 방법으로는 단점을 보완해주는 오픈 소스 도구인 테라그런트(Terragrunt)를 사용하는 것입니다.
백엔드 구성 참조
https://www.terraform.io/language/settings/backends/configuration
Backend Configuration - Configuration Language | Terraform by HashiCorp
Terraform is an open-source infrastructure as code software tool that enables you to safely and predictably create, change, and improve infrastructure.
www.terraform.io
※ 테라그런트란?
테라폼에서 필연적으로 발생하는 중복 코드를 줄여주는 툴.
테라그런트의 명령어는 내부적으로 테라폼 명령어로 변환되어 실행되며, 모든 테라폼의 명령어를 사용할 수 있습니다.
참조 : https://book.naver.com/bookdb/book_detail.naver?bid=20489970
테라폼 업앤러닝
이 책은 예제 소개를 뛰어넘어 실제 환경에서 테라폼을 사용하는 방법에 중점을 두고 만들어졌다. 외국어에 능통해지려면 원어민과 대화하고, 외국어 TV 쇼를 보고, 외국 음악을 듣는데 시간을
book.naver.com
[테라폼/Terraform]테라폼 상태 관리/terraform_remote_state 데이터 소스 (0) | 2022.05.31 |
---|---|
[테라폼/Terraform]테라폼 상태 관리하기/상태 파일 격리 (0) | 2022.05.31 |
[테라폼/Terraform]테라폼 변수 (0) | 2022.05.31 |
[테라폼/Terraform]단일 웹 서버 배포 (0) | 2022.05.31 |
[테라폼/Terraform]단일 서버 배포 (0) | 2022.05.31 |
댓글 영역