1주차 - Terraform 기본 사용법 (3/3)

728x90

Terraform 주요 구성요소 / 리소스 블록

 

  • 리소스: 선언된 항목을 생성하는 동작 수행
  • 리소스 선언 : 리소스 유형(프로바이더이름_제공리소스유형), 동일한 유형에 대한 식별자 역할로 고유한 이름, 구성 인수들이 이름 뒤에 중괄호 내에 선언됨
resource "<리소스 유형>" "<이름>" {
  <인수> = <값>
}

resource "local_file" "abc" {
  content  = "123"
  filename = "${path.module}/abc.txt"
}
  • 리소스에서 사용되는 유형들은 프로바이더에 종속성을 갖기 때문에 별도로 프로바이더 블록을 지정하지 않아도 init 수행 시 해당 프로바이더(최신버전)를 설치
    • 현재 작업 디렉토리 내 .terrform 디렉토리에 프로바이더 설치
# 프로바이더 블록을 지정하지 않아도 리소스 블록에 프로바이더를 명시해야 하기 때문에 init 실행 시
# 지정된 프로바이더를 자동 설치

# main.tf

resource "local_file" "abc" {
  content  = "123"
  filename = "${path.module}/abc.txt"
}

resource "aws_instance" "web" {
  ami = "ami-a1b2c3d4"
  instance_type = "t2.micro"  
}

# init 진행 시 자동으로 local 프로바이더와 aws 프로바이더 설치 진행
root@Burst:/home/yjsong/t101/04# tree .terraform
.terraform
└── providers
    └── registry.terraform.io
        └── hashicorp
            ├── aws
            │   └── 5.54.1
            │       └── linux_amd64
            │           ├── LICENSE.txt
            │           └── terraform-provider-aws_v5.54.1_x5
            └── local
                └── 2.5.1
                    └── linux_amd64
                        └── terraform-provider-local_v2.5.1_x5

9 directories, 3 files

etc-image-0etc-image-1

 

종속성

  • 테라폼 종속성은 resource, module 선언으로 프로비저닝되는 각 요소의 생성 순서를 구분
  • 기본적으로 다른 리소스에서 값을 참조해 불러올 경우 생성 선후 관계에 따라 작업자가 의도하지는 않았지만 자동으로 연관 관계가 정의되는 암시적 종속성을 갖음
    • 강제로 리소스 간 명시적 종속성을 부여할 경우에는 메타인수인 depends_on을 활용
  • 종속성 확인은 vscode graphviz 플러그인을 통해 확인

 

1. 두 개 local_file 리소스 간 종속성이 없는 경우

resource "local_file" "abc" {
  content  = "123!"
  filename = "${path.module}/abc.txt"
}

resource "local_file" "def" {
  content  = "456!"
  filename = "${path.module}/def.txt"
}

 

etc-image-2

2. 두 개 local_file 리소스 간 종속성이 있는 경우(암묵적)

resource "local_file" "abc" {
  content  = "123!"
  filename = "${path.module}/abc.txt"
}

# local_file.def에서 content내용을 local_file.abc의 content 내용 참조
resource "local_file" "def" {
  content  = local_file.abc.content   # 123!
  filename = "${path.module}/def.txt"
}

etc-image-3

3. 두 개 local_file 리소스 간 종속성이 있는 경우(명시적)

resource "local_file" "abc" {
  content  = "123!"
  filename = "${path.module}/abc.txt"
}

#local_file.def에서 명시적으로 local_file.abc에 대하여 종속성 선언
resource "local_file" "def" {
  depends_on = [
    local_file.abc
  ]

  content  = "456!"
  filename = "${path.module}/def.txt"
}

etc-image-4

리소스 속성 참조

  • 리소스 구성에서 참조 가능한 값은 인수속성이다
    • 인수 : 리소스 생성 시 사용자가 선언하는 값
    • 속성 : 사용자가 설정하는 것은 불가능하지만 리소스 생성 이후 획득 가능한 리소스 고유 값
  • 리소스 인수의 선언과 참조 가능한 인수 및 속성 패턴
# Terraform Code
resource "<리소스 유형>" "<이름>" {
  <인수> = <값>
}

# 리소스 참조
<리소스 유형>.<이름>.<인수>
<리소스 유형>.<이름>.<속성>
  • 리소스가 생성될 때, 사용자가 입력한 ‘인수’를 받아 실제 리소스가 생성되면 일부 리소스는 자동으로 기본값이나 추가되는 ‘속성’이 부여
  • 각 리소스마다 문서를 확인해보면 인수는 Arguments로 표현되어 있으며, 리소스 생성 후 추가되는 속성 값으로 Attributes에 안내되어 있음
  • 리소스 속성을 참조하는 다른 리소스 또는 구성요소에서는 생성 후의 속성 값들도 인수로 가져올 수 있음

수명주기(**)

  • lifecycle은 리소스의 기본 수명주기를 작업자가 의도적으로 변경하는 메타인수
    • create_before_destroy (bool): 리소스 수정 시 신규 리소스를 우선 생성하고 기존 리소스를 삭제
    • prevent_destroy (bool): 해당 리소스를 삭제 Destroy 하려 할 때 명시적으로 거부
    • ignore_changes (list): 리소스 요소에 선언된 인수의 변경 사항을 테라폼 실행 시 무시
    • precondition: 리소스 요소에 선언해 인수의 조건을 검증
    • postcondition: Plan과 Apply 이후의 결과를 속성 값으로 검증

 

1. create_before_destroy

  • 테라폼의 기본 수명주기는 삭제 후 생성이기 때문에 작업자가 의도적으로 수정된 리소스를 먼저 생성하는 경우 사용
  • create_before_destroytrue로 선언되면 의도한 생성을 실행한 후 삭제로 동작
create_before_destroy가 false인 경우 리소스 내용 변경 시 기존 파일 삭제 후 변경된 리소스 생성(Destroy and Then Create Replacement)
resource "local_file" "abc" {
  content  = "lifecycle - step 1"
  filename = "${path.module}/abc.txt"

  lifecycle {
    create_before_destroy = false
  }
}

terraform init && terraform plan && terraform apply -auto-approve

resource "local_file" "abc" {
  content  = "lifecycle - step 1111111111111111"
  filename = "${path.module}/abc.txt"

  lifecycle {
    create_before_destroy = false
  }
}

etc-image-5

create_before_destroy가 true인 경우 리소스 내용 변경 시 리소스 변경 후 삭제(Create Replacement and ThenDestroy)
resource "local_file" "abc" {
  content  = "lifecycle - step 2"
  filename = "${path.module}/abc.txt"

  lifecycle {
    create_before_destroy = true
  }
}

terraform plan && terraform apply -auto-approve

# 확인1
# .txt파일이 존재하지 않음. / local_file.abc 리소스는 존재
terraform state list
local_file.abc
cat abc.txt

# 확인2
# 재 apply진행하면, abc.txt파일 생성

terraform plan && terraform apply -auto-approve
terraform state list
local_file.abc
cat abc.txt
lifecycle - step 2

etc-image-6

  • abc.txt파일이 없기 때문에 Create가 동작

etc-image-7

  • AWS ASG의 경우 기존 웹 서버를 유지하여 서비스를 하고, 새로운 웹서버를 생성 후 기존 웹서버를 삭제하는 경우 사용
    • 사용하는 상황과 결과를 잘 파악하고 설정해야 함

2. prevent_destory

  • 해당 리소스를 삭제 Destroy 하려 할 때 명시적으로 거부
prevent_destory = true를 지정하는 경우, 기존 내용을 삭제하지 못하기 때문에 plan실행 시 error 발생
resource "local_file" "abc" {
  content  = "lifecycle - step 3"
  filename = "${path.module}/abc.txt"

  lifecycle {
    prevent_destroy = true
  }
}

etc-image-8

 

3. ignore_changes

  • ignore_changes 리소스 요소의 인수를 지정해 수정 계획에 변경 사항이 반영되지 않도록 하는 것
resource "local_file" "abc" {
  content  = "lifecycle - step 4"
  filename = "${path.module}/abc.txt"

  lifecycle {
    ignore_changes = []
  }
}

terraform apply -auto-approve
cat abc.txt

etc-image-9

resource "local_file" "abc" {
  content  = "lifecycle - step 5"
  filename = "${path.module}/abc.txt"

  lifecycle {
    ignore_changes = [
      content
    ]
  }
}

terraform apply -auto-approve
cat abc.txt
ignore_chages의 값을 content로 지정하여 content 내용이 변경되어도 반영되지 않게 지정

etc-image-10

 

4. precondition / postcondition

 

  • precondition: 리소스 생성 이전에 입력된 인수 값을 검증하는 데 사용해 프로비저닝 이전에 미리 약속된 값 이외의 값 또는 필수로 명시해야 하는 인수 값을 검증
    • postcondition: 프로비저닝해야 하는 클라우드 인프라의 VM을 생성할 때 내부적으로 검증된 이미지 아이디를 사용하는지 등과 같은 구성을 미리 확인하고 사전에 잘못된 프로비저닝을 실행할 수 없도록 구성
variable 블록으로 지정한 file_name과 precondition으로 지정한 file_name이 일치하는지 검증 ( precondition 수행)
해당 실습은 일치하지 않기 때문에 Error 발생
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\""
    }
  }
}

etc-image-11

  • postcondition: Plan과 Apply 이후의 결과를 속성 값으로 검증
    • 프로비저닝 변경 이후 결과를 검증함과 동시에 의존성을 갖는 다른 구성의 변경을 맞는 효과
postcondition 검증으로 인하여 local_file_abc 리소스 내 content 내용이 없어 Error 발생
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
}

etc-image-12

postcondition 검증으로 인하여 local_file_abc 리소스 내 content 내용을 추가하여 정상적으로 apply 적용
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
}

etc-image-13

 

728x90

'T101' 카테고리의 다른 글

1주차 - Terraform 기본 사용법 (2/3)  (0) 2024.06.16
1주차 - Terraform 기본 사용법 (1/3)  (0) 2024.06.16