본문 바로가기
Terraform/Terraform 101 Study

1주차 2편 테라폼 기초 - 기본 사용 1/3

by 개발자 영만 2024. 6. 16.

3.3 테라폼 블록

테라폼 블록

테라폼 블록은 테라폼 구성을 명시하는 데 사용됩니다. 주요 요소는 다음과 같습니다.

  • 테라폼 버전과 프로바이더 버전을 명시적으로 선언하여 실행 오류를 최소화합니다. 이는 오늘 실행하던, 3년 후에 실행하던 동일한 결과를 얻기 위함입니다.
terraform {
  required_version = "~> 1.3.0" # 테라폼 버전

  required_providers { # 프로바이더 버전
    random = {
      version = ">= 3.0.0, < 3.1.0"
    }
    aws = {
      version = "4.2.0"
    }
  }

  cloud { # Cloud/Enterprise 같은 원격 실행을 위한 정보
    organization = "<MY_ORG_NAME>"
    workspaces {
      name = "my-first-workspace"
    }
  }

  backend "local" { # state를 보관하는 위치
    path = "relative/path/to/terraform.tfstate"
  }
}
  • 테라폼 블록과 모듈에서 버전을 명시하여 테라폼, 프로바이더, 모듈이 항상 의도한 대로 실행되도록 합니다.
  • 버전 체계는 시맨틱 버전 관리 Semantic Versioning 방식을 따릅니다.
# version = Major.Minor.Patch
version = 1.3.4
  • 시맨틱 버전 관리(Semantic Versioning):
    • Major 버전 : 하위 호환이 되지 않는 변경사항 (API 변경/삭제).
    • Minor 버전 : 새로운 기능 추가, 하위 호환 가능.
    • Patch 버전 : 버그 수정, 하위 호환 가능.
  • 버전 제약 구문:
    • = 또는 연산자 없음 : 지정된 버전만 허용.
    • != : 지정된 버전 제외.
    • >, >=, <, <= : 지정된 버전과 비교해 조건에 맞는 경우 허용.
    • ~> : 가장 낮은 자리수의 버전만 증가 허용.
      • ~> x.y 는 y 버전, ~> x.y.z 는 z 버전의 상위 버전 허용.
  • 테라폼 버전 관리의 선언 방식 의미
선언된 버전 의미 고려 사항
1.0.0 테라폼 v1.0.0만을 허용 테라폼을 업그레이드하려면 선언된 버전을 변경해야 함
>= 1.0.0 테라폼 v1.0.0 이상의 모든 버전을 허용 v1.0.0 버전을 포함한 그 이상의 모든 버전을 허용해 실행
~> 1.0.0 테라폼 v1.0.0을 포함한 v1.0.x 버전만 허용하고 v1.x는 허용하지 않음 부버전에 대한 업데이트는 무중단으로 이루어짐
>= 1.0, < 2.0.0 테라폼 v1.0.0 이상 v2.0.0 미만인 버전을 허용 주버전에 대한 업데이트를 방지

 

테라폼 버전 required_version

테라폼 버전 관리는 코드의 안정성과 일관성을 유지하는 데 중요한 역할을 합니다. 테라폼에서는 required_version 설정을 통해 어떤 버전의 테라폼이 필요한지 명시할 수 있습니다. 이 설정은 main.tf 파일의 맨 위에 terraform 블록 내에서 선언됩니다.

  • 디렉터리 이동
cd 03.start
  • 현재 테라폼 버전 확인
    현재 설치된 테라폼의 버전을 확인합니다. v1.X.Y는 현재 사용 중인 테라폼의 메이저 버전, 마이너 버전, 패치 버전을 나타냅니다.
terraform version
Terraform v1.X.Y

  • required_version 설정
    main.tf 파일에서 terraform 블록을 추가하고 required_version을 < 1.0.0으로 설정합니다. 이 설정은 테라폼이 실행되기 위해 필요한 최소 버전을 나타냅니다.
terraform {
  required_version = "< 1.0.0"
}

resource "local_file" "abc" {
  content  = "abc!"
  filename = "${path.module}/abc.txt"
}
  • terraform init 실행
    terraform init 명령을 실행하여 초기화를 진행합니다. 이 과정에서 테라폼은 지정된 required_version과 맞는 플러그인을 설치하고 초기 설정을 완료합니다.
terraform init

  • required_version 변경
    main.tf 파일에서 required_version을 >= 1.0.0으로 변경하여 테라폼이 1.0.0 버전 이상이 필요하다는 것을 명시합니다.
terraform {
  required_version = ">= 1.0.0"
}

resource "local_file" "abc" {
  content  = "abc!"
  filename = "${path.module}/abc.txt"
}
  • terraform init 실행
    변경된 required_version에 맞게 다시 terraform init을 실행합니다. 테라폼은 이제 1.0.0 버전 이상의 플러그인과 호환되는 설정을 초기화합니다.
terraform init

 

프로바이더 버전

프로바이더 버전 관리는 테라폼 코드의 안정성과 호환성을 유지하는 데 중요합니다. 테라폼 0.13 버전 이후부터는 required_providers 블록을 사용하여 각 프로바이더의 소스 경로와 버전을 명시합니다. 이를 통해 특정 버전 이상의 프로바이더를 사용하도록 지정하거나, 최신 버전을 자동으로 업데이트할 수 있습니다.

v0.13 이전 v0.13 부터 적용
provider "aws" {
  version = "~> 4.2.0"
  region = "ap-northeast-2"
}

provider "azurerm" {
  version = ">= 2.99.0"
  features {}
}
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "~> 4.2.0"
    }
    azurerm = {
      source = "hashicorp/azurerm"
      version = ">= 2.99.0"
    }
  }
}
  • 각 프로바이더의 이름에 소스 경로와 버전을 명시하며, 테라폼 레지스트리 공식 페이지에서 원하는 프로바이더를 선택한 다음 화면에서 우측 상단의 [USE PROVIDER]를 클릭하면 테라폼 코드에 해당 버전을 사용하는 샘플 코드가 표기됩니다.
  • 코드 파일 수정 - 프로바이더 버전 과하게 높게 설정
terraform {
  required_version = ">= 1.0.0"
  required_providers {
    local = {
      source  = "hashicorp/local"
      version = ">= 10000.0.0"
    }
  }
}

resource "local_file" "abc" {
  content  = "123!"
  filename = "${path.module}/abc.txt"
}
  • init 실행 - upgrade 옵션 사용
    terraform init -upgrade 명령을 실행하여 초기화합니다. -upgrade 옵션은 초기화 과정에서 필요한 프로바이더 버전을 업그레이드합니다.
terraform init -upgrade

  • 코드 파일 수정 - local 프로바이더 버전 수정
    프로바이더 버전을 >= 2.0.0으로 수정하여 실제 존재하는 최소 버전으로 설정합니다.
terraform {
  required_version = ">= 1.0.0"
  required_providers {
    local = {
      source  = "hashicorp/local"
      version = ">= 2.0.0"
    }
  }
}

resource "local_file" "abc" {
  content  = "123!"
  filename = "${path.module}/abc.txt"
}
  • init 실행
terraform init -upgrade

 

cloud 블록

cloud 블록은 Terraform 1.1 버전에서 추가된 설정으로, Terraform Cloud 및 Terraform Enterprise와 같은 호스팅 서비스를 사용할 때 필요한 설정을 포함합니다. 이 설정은 CLI, VCS, API를 통한 실행 방식을 정의하며, 특정 환경에 대한 구성을 제어합니다.

v1.1 이전 v1.1 이후
terraform {
  backend "remote" {
    hostname = "app.terraform.io"
    organization = "my-org"
    workspades = {
      name = "my-app-prod"
    }
  }
}
terraform {
  cloud {
    hostname = "app.terraform.io"
    organization = "my-org"
    workspaces {
      name = "my-workspace"
    }
  }
}

 

백엔드 블록: State

백엔드 블록은 테라폼에서 State(상태 파일)의 저장 위치를 설정하는 데 사용됩니다. 이 설정은 테라폼이 생성하는 인프라 리소스의 현재 상태를 기록하고, 코드로 관리된 리소스의 변경 사항을 추적하는 데 필요합니다. 다음은 백엔드 블록에 대한 주요 사항들입니다.

  • State(상태 파일) 저장 위치 선언: 백엔드 블록은 State 파일이 저장될 위치를 명시합니다. 이는 로컬 파일 시스템이나 클라우드 서비스 등 다양한 백엔드를 설정할 수 있습니다.
  • 단일 백엔드 사용: 테라폼은 한 번에 하나의 백엔드 설정만 허용합니다. 여러 작업자가 동일한 백엔드를 공유하여 상태를 안전하게 관리할 수 있습니다.
  • State 데이터 활용: State 파일에는 현재 인프라 리소스의 상태 정보가 포함되어 있어, 테라폼은 이를 사용해 코드로 관리된 리소스를 식별하고 변경 사항을 추적합니다.
  • 협업을 위한 외부 백엔드 저장소: 여러 작업자가 협업할 경우, 백엔드 저장소가 필요합니다. AWS S3, Azure Blob Storage와 같은 클라우드 저장소를 백엔드로 설정하여 State 파일을 공유하고 관리할 수 있습니다.
  • 민감한 데이터 보호: State 파일에는 패스워드, 인증서와 같은 민감한 정보가 포함될 수 있으므로, 이러한 데이터가 외부로 노출되지 않도록 적절한 접근 제어와 보안 설정이 필요합니다.

State 잠금은 테라폼에서 여러 작업자가 동시에 같은 State 파일을 수정하지 못하도록 하는 메커니즘입니다. State 잠금은 백엔드에서 관리되며, 다음과 같은 중요한 점들이 있습니다

  • 기본 백엔드(local): 기본적으로 테라폼은 로컬 백엔드를 사용하여 State 파일을 작업자의 로컬 환경에 저장하고 관리합니다.
  • 공유 백엔드: 상업적 환경이나 팀 단위 작업에서는 State 파일을 공유 백엔드(예: AWS S3, Azure Blob Storage 등)에 저장하여 여러 작업자가 접근하고 동시에 사용할 수 있도록 합니다. 이 경우 State 잠금이 중요한 역할을 합니다.
  • State 잠금 파일(.terraform.tfstate.lock.info): 공유 백엔드를 사용할 때, 테라폼은 State를 변경하는 동안 .terraform.tfstate.lock.info 파일을 생성하여 State를 잠금 처리합니다. 이 파일은 동시에 여러 사용자가 동일한 State를 변경하지 못하도록 합니다.
  • State 잠금 파일을 확인하려면 terraform apply를 실행하고, 생성된 .terraform.tfstate.lock.info 파일을 확인합니다. 이를 통해 동시 작업자가 State를 변경하는 동안 충돌이 발생하지 않도록 합니다.
ID:        30773305-a78d-49f1-8f3f-5604d742b66f    # State 잠금의 고유 식별자
Operation: OperationTypeApply                      # State 잠금이 생성된 동작 유형 (예: apply, plan)
Info:
Who:       gasida@seojonghoui-MacBookPro.local     # State를 변경한 작업자의 정보
Version:   1.5.1                                   # 테라폼 버전
Created:   2023-06-28 12:23:59.113608 +0000 UTC    # 잠금 파일 생성 시간
Path:      state/terraform.tfstate                 # 잠긴 State 파일의 경로

 

테라폼의 State 잠금 파일이 실행에 미치는 영향을 살펴보겠습니다.

  • 코드 파일 수정 - content 내용을 수정
resource "local_file" "abc" {
  content  = "123456!"
  filename = "${path.module}/abc.txt"
}
  • 두 개의 터미널 창을 열어 terraform apply를 실행
    하나의 터미널에서는 사용자 입력을 대기하고 있으며, 다른 터미널에서는 파일 목록을 확인합니다. State 잠금 파일은 이러한 동시 실행을 제어하고, 동시에 State를 변경하지 못하게 합니다.
# 터미널1
terraform apply
...
Enter a value: 대기

# 터미널2
terraform apply
...
ls -a

  • terraform apply 적용
# 터미널1 취소 후 apply
terraform apply -auto-approve

 

백엔드 설정 변경

  • 현재 State 파일 정보 확인
ls terraform.tfstate*
terraform.tfstate        terraform.tfstate.backup

# 리소스 확인
terraform state list

# State 파일 정보 확인
cat terraform.tfstate

  • 백엔드가 설정되면 다시 init 명령을 수행해 State의 위치를 재설정해야 합니다.
  • 백엔드 블록에 local을 정의합니다.
terraform {
  backend "local" {
    path = "state/terraform.tfstate"
  }
}

resource "local_file" "abc" {
  content  = "123456!"
  filename = "${path.module}/abc.txt"
}
  • terraform init을 실행합니다.
# init 시 백엔드 변경에 따른 마이그레이션 안내
terraform init
...
Enter a value: yes
...

#
ls terraform.tfstate*
tree state
cat state/terraform.tfstate | jq
cat state/terraform.tfstate | jq -r .serial

# 
terraform apply -auto-approve

  • 코드 파일 수정 - content 내용을 수정
terraform {
  backend "local" {
    path = "state/terraform.tfstate"
  }
}

resource "local_file" "abc" {
  content  = "123456789!"
  filename = "${path.module}/abc.txt"
}
  • terraform apply를 통해 변경 사항을 적용합니다.
#
terraform plan
terraform apply -auto-approve

#
cat abc.txt
ls terraform.tfstate*
tree state
cat state/terraform.tfstate | jq
cat state/terraform.tfstate | jq -r .serial          # 예시)현재: 10
cat state/terraform.tfstate.backup | jq -r .serial   # 예시)백업: 7

# 이전 사용한던 현재 디렉터리에 state 파일 삭제 후 확인
rm -rf terraform.tfstate*
ls -al

# 
terraform plan
terraform apply -auto-approve
cat abc.txt

  • 추가 옵션
    • 이전 구성 유지 : -migrate-state는 terraform.tfstate의 이전 구성에서 최신의 state 스냅샷을 읽고 기록된 정보를 새 구성으로 전환합니다.
    • 새로 초기화 : -reconfigure는 init을 실행하기 전에 terraform.tfstate 파일을 삭제해 테라폼을 처음 사용할 때처럼 이 작업 공간(디렉터리)을 초기화 하는 동작입니다.

 

3.4 리소스

리소스 블록은 선언된 항목생성하는 동작을 수행한다.

 

리소스 구성

  • 리소스 블록 생성
    Terraform에서 리소스 블록은 resource 키워드로 시작하며, 특정 리소스 유형을 정의합니다.
resource "<리소스 유형>" "<이름>" {
  <인수> = <값>
}

resource "local_file" "abc" {
  content  = "123"
  filename = "${path.module}/abc.txt"
}
  • 프로바이더 종속성
    리소스 유형은 특정 프로바이더에 종속됩니다. 이를 명시하면 terraform init 명령어 실행 시 해당 프로바이더가 설치됩니다.
resource "local_file" "abc" {
  content  = "123"
  filename = "${path.module}/abc.txt"
}

resource "aws_instance" "web" {
  ami           = "ami-a1b2c3d4"
  instance_type = "t2.micro"
}
  • init 명령어 실행
# init 시 프로바이더 선언 없이도 리소스 추가로 자동 인식된 프로바이더 요구사항과 초기화
terraform init
tree .terraform
  • 추가적인 리소스 설정 옵션
    리소스 블록에서는 다양한 메타 인수를 설정할 수 있습니다.
    • depends_on: 종속성을 선언하여 리소스 생성 순서를 정의합니다.
    • count: 여러 개의 리소스를 한 번에 생성할 수 있습니다.
    • for_each: Map 또는 Set 타입의 데이터를 기반으로 여러 리소스를 생성합니다.
    • provider: 여러 프로바이더 중 하나를 명시적으로 선택합니다.
    • lifecycle: 리소스의 생명 주기를 관리합니다.
    • provisioner: 리소스 생성 후 추가 작업을 정의합니다.
    • timeouts: 리소스 생성, 업데이트, 삭제에 대한 타임아웃을 설정합니다.

 

종속성

  • 테라폼에서의 종속성은 여러 리소스나 모듈 간의 생성 순서와 관계를 정의하는 중요한 개념입니다.
  • 코드 파일 수정
resource "local_file" "abc" {
  content  = "123!"
  filename = "${path.module}/abc.txt"
}

resource "local_file" "def" {
  content  = "456!"
  filename = "${path.module}/def.txt"
}
  • apply 실행 및 확인 - 선후 관계가 없는 동일한 수준으로 병렬(동시) 실행
terraform apply -auto-approve
...
Plan: 2 to add, 0 to change, 0 to destroy.
local_file.def: Creating...
local_file.abc: Creating...
local_file.abc: Creation complete after 0s [id=5f30576af23a25b7f44fa7f5fdf70325ee389155]
local_file.def: Creation complete after 0s [id=b9fbde4d33ab9c450a7ce303fb4788c9d2db9aed]

# graph 확인 > graph-1.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph-1.dot

  • 암시적 종속성 부여
    두 번째 리소스(local_file.def)에서 첫 번째 리소스(local_file.abc)의 값을 참조하여 종속성을 부여합니다.
resource "local_file" "abc" {
  content  = "123!"
  filename = "${path.module}/abc.txt"
}

resource "local_file" "def" {
  content  = local_file.abc.content  # local_file.abc의 content 속성을 참조하여 사용
  filename = "${path.module}/def.txt"
}
  • apply 실행 및 확인
#terraform apply -auto-approve
...
Plan: 2 to add, 0 to change, 0 to destroy.
local_file.abc: Creating... <- local_file.abc가 먼저 생성된 후
local_file.abc: Creation complete after 0s [id=5f30576af23a25b7f44fa7f5fdf70325ee389155]
local_file.def: Creating... <- local_file.def를 생성
local_file.def: Creation complete after 0s [id=5f30576af23a25b7f44fa7f5fdf70325ee389155]

# graph 확인 > graph-2.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph-2.dot

  • 명시적 종속성 부여
    강제로 리소스 간 종속성을 설정하려면 depends_on 메타 인수를 사용합니다.
resource "local_file" "abc" {
  content  = "123!"
  filename = "${path.module}/abc.txt"
}

resource "local_file" "def" {
  depends_on = [
    local_file.abc
  ]

  content  = "456!"
  filename = "${path.module}/def.txt"
}
  • apply 실행 및 확인
terraform apply -auto-approve
...

# graph 확인 > graph-3.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph-3.dot

 

리소스 속성

Terraform에서는 리소스의 속성(attributes)과 인수(arguments)를 통해 리소스를 정의하고 관리합니다.

resource "<리소스 유형>" "<이름>" {
  <인수> = <값>
}

# 리소스 참조
<리소스 유형>.<이름>.<인수>
<리소스 유형>.<이름>.<속성>
  • 인수 (Arguments):
    • 인수는 Terraform 코드에서 사용자가 리소스를 생성할 때 지정하는 값입니다.
    • Kubernetes 네임스페이스를 생성할 때는 네임스페이스의 이름을 인수로 지정할 수 있습니다.
resource "kubernetes_namespace" "example" {
  metadata {
    name = "terraform-example-namespace"  # 인수로 사용자가 지정한 값
  }
}
  • 속성 (Attributes):
    • 속성은 리소스가 실제로 생성된 후에 Terraform이 자동으로 관리하는 값입니다.
    • 리소스의 속성은 사용자가 직접 설정할 수 없고, 리소스가 생성된 후에 리소스의 상태에 따라 자동으로 설정됩니다.
    • 네임스페이스 리소스가 생성된 후에는 해당 리소스의 ID나 기타 정보가 속성으로 반환될 수 있습니다.
resource "kubernetes_secret" "example" {
  metadata {
    namespace = kubernetes_namespace.example.metadata.0.name  # 다른 리소스의 속성 참조
    name      = "terraform-example"
  }
  data = {
    password = "P4ssw0rd"
  }
}
  • Terraform에서는 각 공급자(provider)가 제공하는 리소스의 세부 정보와 사용 방법을 문서화하여 사용자에게 제공합니다.
  • 이 문서는 Terraform 공식 웹사이트나 각 공급자의 문서 사이트에서 확인할 수 있습니다. 일반적으로 인수(Arguments)와 속성(Attributes)에 대한 구분이 명확하게 설명되어 있습니다.

 

수명주기

lifecycle은 Terraform에서 리소스의 기본 수명주기를 변경할 수 있는 메타인수로, 특정 상황에서 리소스의 생성, 수정, 삭제 등의 행위를 조정하는 데 사용됩니다.

  • create_before_destroy (bool) : 리소스를 변경할 때 기존 리소스를 먼저 삭제한 후 새로운 리소스를 생성합니다. 이 옵션을 사용하면 변경 작업 시 새로운 리소스를 먼저 생성하고, 생성이 완료된 후 기존 리소스를 삭제합니다.
  • prevent_destroy (bool) : 리소스를 삭제하지 않도록 합니다. 주로 중요한 데이터를 포함한 리소스나 실수로 삭제를 방지해야 할 경우에 사용됩니다.
  • ignore_changes (list) : 특정 리소스의 속성이 변경될 때 Terraform이 이를 무시하도록 설정합니다.
  • precondition : 리소스를 생성하거나 업데이트하기 전에 조건을 검증하는 옵션입니다.
  • postcondition : Plan과 Apply 이후의 결과를 속성 값으로 검증하여, 리소스의 설정이나 상태가 예상대로 설정되었는지를 확인할 수 있습니다.

create_before_destroy (bool)

  • 테라폼의 기본 수명주기삭제 후 생성이기 때문에 작업자가 수정된 리소스를 먼저 생성하기를 원한다면 lifecycle 변경이 필요합니다.
  • 이 경우 create_before_destroy 를 true로 선언하면 생성 후 삭제가 이뤄집니다.
  • 하지만 생성되는 리소스가 기존 리소스로 인해 생성이 실패되거나 삭제 시 함께 삭제될 수 있으니 주의해야 합다.
    • 잘못된 사례 1 : 리소스의 명시적 구분이 사용자가 지정한 특정 이름이나 ID인 경우 기존 리소스에 할당되어 있기 때문에 생성 실패
    • 잘못된 사례 2 : 생성 후 삭제 시 동일한 리소스에 대한 삭제 명령이 수행되어 리소스가 모두 삭제
  • 코드 파일 내용 수정
resource "local_file" "abc" {
  content  = "lifecycle - step 1"
  filename = "${path.module}/abc.txt"

  lifecycle {
    create_before_destroy = false
  }
}
  • apply 실행
# apply 
terraform init && terraform plan && terraform apply -auto-approve
terraform state list

# 파일 내용 확인
cat abc.txt
  • content 내용 수정
resource "local_file" "abc" {
  content  = "lifecycle - step 1111111111111111"
  filename = "${path.module}/abc.txt"

  lifecycle {
    create_before_destroy = false
  }
}
  • create_before_destroy = false 동작 확인
#
terraform plan && terraform apply -auto-approve
...
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # local_file.abc must be replaced
-/+ resource "local_file" "abc" {
      ~ content              = "lifecycle - step 1" -> "lifecycle - step 1111111111111111" # forces replacement
...

# 파일 내용 확인
cat abc.txt
  • content 내용 수정
resource "local_file" "abc" {
  content  = "lifecycle - step 2"
  filename = "${path.module}/abc.txt"

  lifecycle {
    create_before_destroy = true
  }
}
  • create_before_destroy = true 동작 확인
#terraform plan && terraform apply -auto-approve
...
+/- create replacement and then destroy

Terraform will perform the following actions:

  # local_file.abc must be replaced
+/- resource "local_file" "abc" {
      ~ content              = "lifecycle - step 11" -> "lifecycle - step 2" # forces replacement
...

# 파일 내용 확인 >> 어떻게 되나요?
terraform state list
cat abc.txt

# 파일 내용 확인 >> 어떻게 되나요?
terraform plan && terraform apply -auto-approve
terraform state list
cat abc.txt

 

prevent_destroy (bool)

  • 코드 파일 내용 수정
resource "local_file" "abc" {
  content  = "lifecycle - step 3"
  filename = "${path.module}/abc.txt"

  lifecycle {
    prevent_destroy = true
  }
}
  • apply 실행
terraform plan
terraform apply -auto-approve
...
│ Error: Instance cannot be destroyed
│ 
│   on main.tf line 1:
│    1: resource "local_file" "abc" {
...

  • 코드 파일 내용 수정
resource "local_file" "abc" {
  content  = "lifecycle - step 3"
  filename = "${path.module}/abc.txt"
}
  • apply 실행
terraform apply -auto-approve
cat abc.txt

 

ignore_changes (list)

  • 코드 파일 내용 수정
resource "local_file" "abc" {
  content  = "lifecycle - step 4"
  filename = "${path.module}/abc.txt"

  lifecycle {
    ignore_changes = []
  }
}
  • apply 실행
terraform apply -auto-approve
cat abc.txt

  • 코드 파일 내용 수정
resource "local_file" "abc" {
  content  = "lifecycle - step 5"
  filename = "${path.module}/abc.txt"

  lifecycle {
    ignore_changes = [
      content
    ]
  }
}
  • apply 실행
terraform apply -auto-approve
cat abc.txt

  • 리소스 속성에 변경이 있었지만 ignore_changes의 대상이므로 해당 속성에 대한 변경을 감지하지 않고, 적용 계획에도 변경 사항이 반영되지 않습니다.
  • 만약 모든 속성의 변경을 무시하고 싶다면, ignore_changes 값을 all로 설정하면 됩니다.

 

precondition

  • 코드 파일 내용 수정
variable "file_name" {
  default = "step0.txt"
}

resource "local_file" "abc" {
  content  = "lifecycle - step 6"
  filename = "${path.module}/${var.file_name}"

  lifecycle {
    precondition {
      condition     = var.file_name == "step6.txt"
      error_message = "file name is not \"step6.txt\""
    }
  }
}
  • apply 실행
terraform plan

  • precondition은 Terraform의 메타인수 중 하나로, 리소스를 생성 또는 업데이트하기 전에 사전 조건을 검증할 수 있도록 도와줍니다. 이를 통해 잘못된 프로비저닝을 사전에 방지하고, 예기치 않은 문제를 줄일 수 있습니다.
  • 일반적으로 precondition은 클라우드 인프라에서 특정 리소스를 생성하거나 업데이트하기 전에 필요한 조건을 정의하는 데 사용됩니다. 예를 들어, 가상 머신(VM)을 생성할 때 사용할 이미지 ID가 특정 값과 일치해야 한다는 것을 검증하는 경우가 있습니다.

 

postcondition

  • 코드 파일 내용 수정
resource "local_file" "abc" {
  content  = ""
  filename = "${path.module}/step7.txt"

  lifecycle {
    postcondition {
      condition     = self.content != ""
      error_message = "content cannot empty"
    }
  }
}

output "step7_content" {
  value = local_file.abc.id
}
  • apply 실행
terraform apply -auto-approve
terraform state list
cat step7.txt

  • 코드 파일 내용 수정
resource "local_file" "abc" {
  content  = "**step7 file ok**"
  filename = "${path.module}/step7.txt"

  lifecycle {
    postcondition {
      condition     = self.content != ""
      error_message = "content cannot empty"
    }
  }
}

output "step7_content" {
  value = local_file.abc.id
}
  • apply 실행
terraform apply -auto-approve
terraform state list
cat step7.txt

  • 종속성을 갖는 여러 리소스를 구성하는 경우, 리소스의 데이터가 다른 리소스 생성 시 활용될 때 원하는 속성이 정의되어야 하는 경우 확인할 수 있습니다.
  • 특히, 프로비저닝 이후에 생성되는 속성 값이 있으므로 영향을 받는 다른 리소스가 생성되기 전에 예상되지 않은 프로비저닝 작업을 방지할 수 있습니다.