Terraform 변수, 依存성, 조건 사용법에서 유연성 改善하기

개 introductions

Hashicorp Configuration Language (HCL), Terraform이 사용하는 것과 같은 다른 프로그래밍 언어에도 존재하는 많은 유용한 구조와 기능을 제공합니다. 인frastructure code에서 루프를 사용하면 코드 副本화를 大幅하게 줄일 수 있으며 읽기 쉬운 것으로 앞으로 refactoring하는 것을 더 легче하고 더 많은 유연성을 얻을 수 있습니다. HCL는 또한 一些 常见的 데이터 구조, 如下所示 list와 map(다른 언어에서 array와 dictionary라고 불립니다), 以及 실행 경로 분기를 위한 conditionals를 제공합니다.

Terraform 独有的时候, 자신이 의존하는 자원을 수동으로 지정할 수 있습니다. 당신의 code를 실행하면 이미 감지된 링크(대부분의 경우에는 correct하게 감지되었습니다)를 포함하는 실행 그래프를 생성합니다. 그러나 Terraform가 감지하지 못하는 의존성 관계를 강제하는 것이 필요할 수 있습니다.

이 articl에서는 HCL이 제공하는 데이터 구조, 자원에 대한 루핑 기능(count 키, for_each, for), 알려진 값과 未知 값을 处理하는 conditionals, 자원 사이의 의존성 관계를 다룰 것입니다.

사전 요구 사항

  • 디지털 오cean의 개인 액세스 토큰을 생성하는 것을 배울 수 있는 DigitalOcean 제어 パネル을 통해 생성할 수 있습니다. DigitalOcean 제품 문서에서 지침을 찾으실 수 있으며, How to Create a Personal Access Token를 통해 지침을 확인할 수 있습니다.
  • 로컬 컴퓨터에 Terraform을 설치하고 DigitalOcean 제공자를 사용하는 프로젝트를 세팅합니다. Step 1Step 2How To Use Terraform with DigitalOcean 튜orial에서 완료하시고, 프로젝트 폴더를 terraform-flexibility로 지정하시오. 대신 loadbalance로 지정하지 마십시오. Step 2 단계에서는 제공자 구성 때에 pvt_key 변수와 SSH キー 자원을 포함する 必要가 없습니다.

Note: 이 튜orial은 Terraform 1.0.2와 함께 specifically 시험되었습니다.

HCL의 데이터 유형

HCL의 循环节과 다양한 기능을 배울 수 있을 때 까지 이전에 사용 가능한 데이터 유형과 그들의 용도를 알아봅시다.

Hashicorp Configuration Language (HCL)는 기본복잡 자료 유형을 지원합니다. 기본 자료 유형은 문자열, 숫자, 및 불리언 값입니다. 이러한 기본 유형은 다른 유형에서 派生할 수 없는 자료 유형입니다. 대신 복잡한 유형은 여러 값을 하나로 그룹按照国家합니다. 이 두 유형의 복합 값은 구조 유형과 컬렉션 유형입니다.

구조 유형은 다양한 유형의 값을 하나로 그룹按照国家합니다. 주요 예제는 자원 정의입니다. 이는 인프RASTRUCTURE가 어떻게 보이게 될 것인지 지정하는 것입니다. 구조 유형과 比较하여 컬렉션 유형도 값을 그룹按照国家하지만, 유형이 같은 것만 그룹按照国家합니다. HCL에서 관심을 가지는 세 가지 컬렉션 유형은 리스트, 맵, 세트입니다.

리스트

리스트는 다른 프로그래밍 언어의 배열과 유사합니다. 이들은 같은 유형의 여러 요소를 포함하고 있으며, 0부터 시작하는 정수 인덱스를 사용하여 배열 표기法([])를 통해 액세스할 수 있습니다. 다음은 다음 단계에서 배포하게 될 드롭렛의 이름을 보관하는 리스트 변수 선언의 예입니다.

variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third"]
}

type로는 문자열 유형의 리스트가 되고 default 값을 제공합니다. HCL에서는 괄호에 枚举되는 값은 리스트를 나타냅니다.

지도는 键-值 쌍의 コレク션이며, 각 값은 그 键(key)의 형態로 string를 사용하여 액세스되ます. かくして 중괄호 안에 지도를 SPECIFY 하는 두 가지 방법이 있습니다: 冒号(:) 또는 等号(=)를 사용하여 값을 지정하는 것입니다. どちら의 경우も, 값은 引用符로 감싸야 합니다. 冒号을 사용할 때, 键도 감싸야 합니다.

다음 지도 정의는 다양한 환경에서 降水(Droplet) 이름을 포함하고 있으며, 等号을 사용하여 쓰여 있습니다:

variable "droplet_env_names" {
  type = map(string)

  default = {
    development = "dev-droplet"
    staging = "staging-droplet"
    production = "prod-droplet"
  }
}

键이 숫자로 시작하면, 冒号 Syntax를 사용해야 합니다:

variable "droplet_env_names" {
  type = map(string)

  default = {
    "1-development": "dev-droplet"
    "2-staging": "staging-droplet"
    "3-production": "prod-droplet"
  }
}

Sets

Set은 요소 정렬을 지원하지 않는다는 의미로, 지도를 순회하는 것은 每次 같은 順序을 보장하지 않으며, 그들의 요소를 지정적으로 액세스하는 것도 할 수 없습니다. 그들은 完全히 일정한 요소를 繰resents하며, 같은 요소를 다시 지정하는 것은 그들을 결합하고 있는 것처럼 보입니다. 한 인스턴스만 지도에 존재합니다.

Set을 선언하는 것은 List를 선언하는 것과 유사하나, 변수의 형태가 다릅니다:

variable "droplet_names" {
  type    = set(string)
  default = ["first", "second", "third", "fourth"]
}

이제 HCL가 제공하는 데이터 구조 유형을 배웠고, 이 튜토리얼에서 사용할 것입니다 List, Maps, Sets의 문법을 살펴봅니다. 마지막으로 Terraform에서 같은 자원의 여러 인스턴스를 배치하는 靈活한 방법을 시도하는 것입니다.

`count` 키를 사용하여 자원 수 설정하기

이 섹션에서는 `count` 키를 사용하여 같은 자원의 여러 인스턴스를 생성할 것입니다. `count` 키는 모든 자원에 사용할 수 있는 매개변수로 어떻게 인스턴스를 생성할지 지정합니다.

이를 구현하는 것을 보여주는 Droplet 자원을 書い고, 사전 요구 사항에 따라 생성한 프로젝트 디렉터리에 `droplets.tf` 이라는 파일에 저장하고 편집할 것입니다. 다음과 같이 실행하여 생성하고 edit를 실행합니다:

  1. nano droplets.tf

다음 各行을 추가합니다:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = 3
  image  = "ubuntu-20-04-x64"
  name   = "web"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

이 코드는 이름이 `test_droplet`인 Droplet 자원을 정의하고 있으며, 이를 Ubuntu 20.04로 실행하며 1GB 램과 CPU 核를 갖추고 있습니다.

`count`의 값이 `3`로 설정되어 있음을 알 수 있습니다. 이는 Terraform이 같은 자원의 세 인스턴스를 생성하려고 하는 것을 의미합니다. 다음으로 파일을 저장하고 닫을 것입니다.

프로젝트를 계획하여 Terraform이 어떤 행동을 취할지 보기 위해서는 다음과 같이 실행합니다:

  1. terraform plan -var "do_token=${DO_PAT}"

이 출력은 다음과 유사하게 보입니다:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.test_droplet[0] will be created + resource "digitalocean_droplet" "test_droplet" { ... name = "web" ... } # digitalocean_droplet.test_droplet[1] will be created + resource "digitalocean_droplet" "test_droplet" { ... name = "web" ... } # digitalocean_droplet.test_droplet[2] will be created + resource "digitalocean_droplet" "test_droplet" { ... name = "web" ... } Plan: 3 to add, 0 to change, 0 to destroy. ...

test_droplet 인스턴스의 세 개의 인스턴스가 모두 同じ web 이름을 갖게 될 것이라고 지시되어 있음. 이는 가능하지만 좋지 않으므로 각 인스턴스의 이름을 유니크하게 만들기 위한 드롭LET 정의를 수정합시다. droplets.tf 를 편집하기 전에 하나의 세팅을 띄어보겠습니다.

  1. nano droplets.tf

표시된 줄을 수정합니다.

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = 3
  image  = "ubuntu-20-04-x64"
  name   = "web.${count.index}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

변경사항을 저장하고 파일을 닫습니다.

count 객체는 index 매개변수를 제공합니다. 이는 현재 반복 인덱스를 0부터 시작하여 가지고 있습니다. 현재 인덱스는 string interpolation을 사용하여 드롭LET의 이름에 대입되어 동적으로 문자열을 생성할 수 있습니다. 변수를 대입하여 동적으로 문자열을 만들 수 있습니다. 项目을 다시 계획하여 변경사항을 보기 위해서는 다음과 같습니다:

  1. terraform plan -var "do_token=${DO_PAT}"

표시는 이렇게 보입니다:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.test_droplet[0] will be created + resource "digitalocean_droplet" "test_droplet" { ... name = "web.0" ... } # digitalocean_droplet.test_droplet[1] will be created + resource "digitalocean_droplet" "test_droplet" { ... name = "web.1" ... } # digitalocean_droplet.test_droplet[2] will be created + resource "digitalocean_droplet" "test_droplet" { ... name = "web.2" ... } Plan: 3 to add, 0 to change, 0 to destroy. ...

이번에 test_droplet 인스턴스의 세 개의 인스턴스는 인스턴스의 인덱스를 이름에 대입하여 추적하기 더 容易하게 만들어집니다.

이제 count 키를 사용하여 자원의 여러 인스턴스를 생성하는 방법을 알고 있고 프로비저닝 도중 인스턴스의 인덱스를 가져와 사용할 수 있습니다. 다음으로 드롭LET의 이름을 목록에서 가져오는 방법을 배울 것입니다.

리스트에서 드랍럭 이름 가져오기

동일한 자원의 여러 인스턴스가 custome 이름을 가져야 하는 경우, 정의하신 list 변수에서 동적으로 가져 올 수 있습니다. 이를 통해 드랍럭 배포를 여러 이름의 리스트로 자동화하는 다양한 방법을 배울 수 있습니다.

まず, Droplet 이름을 담기 위한 list를 정의해야 합니다. variables.tf 이라는 이름의 파일을 만들고 편집해 보세요:

  1. nano variables.tf

다음과 같은 行을 추가하세요:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third", "fourth"]
}

파일을 저장하고 닫으세요. 이 코드는 droplet_names라는 list를 정의하고, 문자열 first, second, third, fourth를 포함합니다.

droplets.tf 파일을 편집해 보세요:

  1. nano droplets.tf

하이라이트 된 行을 수정하세요:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = length(var.droplet_names)
  image  = "ubuntu-20-04-x64"
  name   =  var.droplet_names[count.index]
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

constant number of elements를 수동으로 지정하는 대신에, droplet_names list의 길이를 count parameter로 전달하여, 항상 list의 요소 수를 반환합니다. 이름은 count.index 위치에 있는 list의 요소를 가져와, 배열 괄호 문법을 사용합니다. 수정이 끝나면 파일을 저장하고 닫으세요.

项目을 다시 計画하십시오. 이러한 출력이 나올 것입니다:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.test_droplet[0]가 생성되며 + resource "digitalocean_droplet" "test_droplet" { ... + name = "first" ... } # digitalocean_droplet.test_droplet[1]가 생성되며 + resource "digitalocean_droplet" "test_droplet" { ... + name = "second" ... } # digitalocean_droplet.test_droplet[2]가 생성되며 + resource "digitalocean_droplet" "test_droplet" { ... + name = "third" ... } # digitalocean_droplet.test_droplet[3]가 생성되며 + resource "digitalocean_droplet" "test_droplet" { ... + name = "fourth" ... Plan: 4 to add, 0 to change, 0 to destroy. ...

이러한 수정 사항 묵시에, 네 개의 Droplet이 차례대로 droplet_names 리스트의 요소의 이름을 따서 배포되게 됩니다.

이제 count를 배웠으며, 그 특징과 구문을 이해하고 리소스 인스턴스를 modify하는 것을 함께 사용했습니다. 이제 그 단점을 알아보고, 어떻게 그 문제를 극복할 수 있는지 배워봅시다.

count의 단점을 이해하기

이제 count가 어떻게 사용되는지 알고 있으므로, 그 리스트에 대해 어떻게 수정되는지 examinieren합니다.

Droplet을 クラウド로 배포하도록 해봅시다:

  1. terraform apply -var "do_token=${DO_PAT}"

questioned할 때 yes를 입력하십시오. 결과물의 끝은 다음과 유사하게 보입니다:

Output
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

이제 droplet_names 리스트를 확장하여 한 개 더의 Droplet 인스턴스를 생성합시다. variables.tf을 편집하기 위해 오픈하십시오:

  1. nano variables.tf

리스트의 시작에 새로운 요소를 추가하십시오:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["zero", "first", "second", "third", "fourth"]
}

작업을 끝내고 파일을 닫으십시오.

프로젝트 計画하기:

  1. terraform plan -var "do_token=${DO_PAT}"

이렇게의 产出이 들어온다:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create ~ update in-place Terraform will perform the following actions: # digitalocean_droplet.test_droplet[0] 는 場所에서 갱신될 것입니다. ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "first" -> "zero" ... } # digitalocean_droplet.test_droplet[1] 는 場所에서 갱신될 것입니다. ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "second" -> "first" ... } # digitalocean_droplet.test_droplet[2] 는 場所에서 갱신될 것입니다. ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "third" -> "second" ... } # digitalocean_droplet.test_droplet[3] 는 場所에서 갱신될 것입니다. ~ resource "digitalocean_droplet" "test_droplet" { ... ~ name = "fourth" -> "third" ... } # digitalocean_droplet.test_droplet[4] 는 생성될 것입니다. + resource "digitalocean_droplet" "test_droplet" { ... + name = "fourth" ... } Plan: 1 to add, 4 to change, 0 to destroy. ...

생产出은 Terraform이 첫 네 개의 돔let을 이름을 바꿀 것이며 fourth라는 第五의 돔let을 생성할 것입니다. 이는 인스턴스를 sequenced list로 고려하고 요소들(돔let)을 목록에서 그 인덱스 숫자로 구분하는 것을 인지합니다. Terraform은 네 개의 돔let을 이렇게 초기에 고려합니다:

Index Number 0 1 2 3
Droplet Name first second third fourth

새로운 돔let zero가 시작에 추가되면, 其的内部 리스트 표현은 이렇게 보입니다:

Index Number 0 1 2 3 4
Droplet Name zero first second third fourth

네 개의 초기 돔let은 현재 위치에서 한 위치 왼쪽으로 옮겨 있습니다. Terraform은 表에 represented된 two states를 比较하는 것입니다: 위치 0에서, 돔let이 first라고 불립니다. 그리고 第二届 table와 다르게 느껴지는 이유로, 갱신 행동을 계획합니다. 이를 계속하다가 4에서 위치하며, 首届 table에서 비교 가능한 요소가 없으며, 대신 돔let 제공 행동을 계획합니다.

이는 리스트에 새로운 요소를 추가하는 것이 마지막에 있어야만 하는 것과 다르면 리소스를 수정하는 것이 필요하지 않은 경우에도 리소스를 수정하게 되는 것을 의미한다. droplet_names 리스트의 요소가 제거되었을 때도 유사한 업데이트 행동을 계획하게 되ます.

리소스 추적이 incomplete(incomplete resource tracking)하다는 것은 count을 사용하여 동적으로 다양한 인스턴스의 même(same) 리소스를 배포하는 것에 대해서는 마주 큰 하 Kumar(downfall)이다. 지정적인 수의 지정적인 인스턴스를 위한 경우 count은 간단한 솔루션이며 잘 동작합니다. 그러나 이러한 상황에서, 일부 속성이 변수를 통해 가져와지는 경우가 있으며, 이 튜토리얼의 나중에 배울 것이다 for_each 루프는 훨씬 좋은 선택이다고 합니다.

현재 리소스를 참조하는 것 (self)

count의 또 다른 downside( downside)이는 리소스의 임의의 인스턴스를 인덱스를 통해 참조하는 것이 某些情况下(某些 cases)에는 불가능하다는 것입니다.

주로 destroy-time provisioners가 그렇습니다. 이 것은 리소스가 销毁(destroy)되고자 하는 시점에 실행되는 것입니다. 이유는 요청한 인스턴스가 존재하지 않을 수 있는(이미 销毁되었습니다)거나 返信 依存 사이클을 생성할 것입니다. 이러한 상황에서는 리스트의 인스턴스로 객체를 참조하는 것이 아닌 현재 리소스를 self 키워드를 통해 独占적으로 참조할 수 있습니다.

test_droplet 정의에 파괴 시간 Locally-executed provisor를 추가하여 실행 시 메시지를 보여줍니다. droplets.tf 파일을 편집하기 위해 열어 주세요:

  1. nano droplets.tf
terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = length(var.droplet_names)
  image  = "ubuntu-20-04-x64"
  name   =  var.droplet_names[count.index]
  region = "fra1"
  size   = "s-1vcpu-1gb"

  provisioner "local-exec" {
    when    = destroy
    command = "echo 'Droplet ${self.name} is being destroyed!'"
  }
}

이 行을 추가하십시오.

로컬 실행(local-exec) provisor는 Terraform이 실행되고 있는 로컬 머신上调用 명령어를 실행합니다. 因為 when 매개 변수가 destroy로 설정되어 있기 때문에, 자원이 파괴되기 직전에만 실행되며, 이 명령어가 실행되면 stdout에 문자열을 삽입하여 현재 자원의 이름을 대체합니다.

다음 섹션에서는 Droplet을 다른 방법으로 생성하기 때문에, 현재 배치된 것을 파괴하기 위해 다음 명령을 실행하십시오:

  1. terraform destroy -var "do_token=${DO_PAT}"

When prompted, enter yes. You will see the local-exec provisioner run four times:

Output
... digitalocean_droplet.test_droplet[0] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet first is being destroyed!'"] digitalocean_droplet.test_droplet[1] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet second is being destroyed!'"] digitalocean_droplet.test_droplet[1] (local-exec): Droplet second is being destroyed! digitalocean_droplet.test_droplet[2] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet third is being destroyed!'"] digitalocean_droplet.test_droplet[2] (local-exec): Droplet third is being destroyed! digitalocean_droplet.test_droplet[3] (local-exec): Executing: ["/bin/sh" "-c" "echo 'Droplet fourth is being destroyed!'"] digitalocean_droplet.test_droplet[3] (local-exec): Droplet fourth is being destroyed! digitalocean_droplet.test_droplet[0] (local-exec): Droplet first is being destroyed! ...

이 단계에서 count의 flaw을 배웠습니다. 이제 for_each loop construct를 배울 것입니다. 이는 그것을 극복하고 다양한 변수 유형에 대해 작동하는 것입니다.

for_each 를 사용한 루프

이 섹션에서 for_each loop, 그 구문을 고려하고 자원을 여러 인스턴스로 정의할 때 유용하게 도울 수 있는 것을 배울 것입니다.

for_each는 각 자원에 있는 매개변수로, count과 달리 인스턴스를 생성하기 위해 인스턴스 수를 필요로하는 것이 아닌, 맵 또는 집합을 받는 특성을 가지고 있습니다. 제공된 모음의 각 요소가 한번에 遍历되고, 그 요소에 대응하는 인스턴스가 생성됩니다. for_eacheach 키워드 아래에 键과 值를 인스턴스의 속성으로 제공합니다. (键과 值가 each.keyeach.value로 각각 제공됩니다.) 집합을 제공하면 键과 值는 같습니다.

因为它在each 객체에 현재 요소를 제공하므로, 리스트처럼 원하는 요소를 수동으로 접근할 필요가 없습니다. 집합의 경우는 실제로 그 내부에서 관찰 가능한 顺序이 없기 때문에 불가능합니다. 리스트도 제공할 수 있지만, toset 함수를 사용하여 셋로 변환해야 합니다.

for_each의 주요 장점은 세 가지 모음 데이터 유형을 모두 枚举할 수 있음 뿐만 아니라, 변경, 생성, 또는 삭제가 필요한 요소에 대해만 대응하는 요소들이 변경되는 것입니다. 입력 요소의 顺序을 변경하더라도 어떠한 행동도 계획되지 않고, 입력에서 추가, 제거, 또는 수정하더라도 그 요소에 대해 적절한 행동이 льколько 계획되는 것입니다.

이제 countfor_each로 변경하여 실제로 어떻게 작동하는지 보실 수 있습니다. droplets.tf 파일을 편집하기 위해 실행하는 것을

  1. nano droplets.tf

하고, 채薇 Fermentable 자원을 이용하세요. 발lighted 行을 수정하십시오:

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  for_each = toset(var.droplet_names)
  image    = "ubuntu-20-04-x64"
  name     = each.value
  region   = "fra1"
  size     = "s-1vcpu-1gb"
}

local-exec 프로비저ancer를 제거할 수 있습니다. 완료하면 파일을 저장하고 닫으십시오.

첫 줄은 `count`을 대체하고 `for_each`를 호출하고 있으며, `droplet_names` 리스트를 `toset` 함수를 사용하여 셋 형태로 변환하며 전달하고 있습니다. 드랍벳 이름에 대해서는 `each.value`을 사용하여 현재 요소의 값을 가지고 있는 것입니다.

프로젝트를 계획하기 위해서는 다음과 같이 실행합니다:

  1. terraform plan -var "do_token=${DO_PAT}"

출력은 Terraform이 실행할 단계를 자세하게 보여줍니다:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: # digitalocean_droplet.test_droplet["first"] will be created + resource "digitalocean_droplet" "test_droplet" { ... + name = "first" ... } # digitalocean_droplet.test_droplet["fourth"] will be created + resource "digitalocean_droplet" "test_droplet" { ... + name = "fourth" ... } # digitalocean_droplet.test_droplet["second"] will be created + resource "digitalocean_droplet" "test_droplet" { ... + name = "second" ... } # digitalocean_droplet.test_droplet["third"] will be created + resource "digitalocean_droplet" "test_droplet" { ... + name = "third" ... } # digitalocean_droplet.test_droplet["zero"] will be created + resource "digitalocean_droplet" "test_droplet" { ... + name = "zero" ... } Plan: 5 to add, 0 to change, 0 to destroy. ...

`count`을 사용하는 대신, Terraform은 이제 각 인스턴스를 개별적으로 고려하고 순서가 있는 목록의 요소가 아닙니다. 각 인스턴스는 주어진 셋에 대응하는 요소와 연결되며, 생성될 리소스의 콤마 다음에 표시되는 문자 요소가 그 것을 나타냅니다.

클라우드에 적용하기 위해서는 다음과 같이 실행합니다:

  1. terraform apply -var "do_token=${DO_PAT}"

征兆이 나면 `yes`를 입력하십시오. 완료되면, `droplet_names` 목록에서 하나의 요소를 제거하여 다른 인스턴스가 영향받지 않는지 보여주기 위함입니다. `variables.tf`를 편집하십시오.

  1. nano variables.tf

리스트를 다음과 같이 수정하세요:

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third", "fourth"]
}

지정한 文件을 저장하고 닫으세요.

项目을 다시 计画하고, 다음과 같은 产出을 收할 것입니다:

Output
... Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: - destroy Terraform will perform the following actions: # digitalocean_droplet.test_droplet["zero"] will be destroyed - resource "digitalocean_droplet" "test_droplet" { ... - name = "zero" -> null ... } Plan: 0 to add, 0 to change, 1 to destroy. ...

이번에, Terraform는 제거 된 인스턴스(zero)만 摧毁하고, 다른 인스턴스들에 대해 任何事情都不 하는 것이 正确的 행동입니다.

이 단계에서, 您이제 for_each에 대해 学習하고, 어떻게 사용하는지 以及 其의 장점과 count과의 차이를 배웠습니다. 次に, 您이 for 루프에 대해 배울 것입니다. 그 문법과 使用方法에 대해, 어떻게 특정 任务을 자동화 할 수 있는지 배울 것입니다.

for 루프를 사용하여 循apping

for 루프는 コレク션을 기반으로 동작하며, 입력의 각 요소에 적용된 변형을 통해 새로운 コレク션을 생성합니다. 루프가 方括号([]) 또는 的花括号({})로 감싸져 있는지에 따라 정확한 产出의 형태는 리스트나 맵이 될 것입니다. 따라서, 리су스ources를 조회하고 나중에 처리할 것인 구조화된 产出을 형성하는 일에 적절합니다.

for 루프의 일반적인 문법은 다음과 같습니다:

for element in collection:
transform(element)
if condition

다른 프로그램 언어와 마찬가지로, 첫 번째 것은 이동 変数(element)를 이름 지정하고, 목록을 枚举하는 collection을 지정합니다. 루프의 obyektiva는 변형 단계이며, 선택적인 if CLAUSE는 입력 목록을 필터링하기 위해 사용할 수 있습니다.

이제, 출력을 사용하여 몇 가지 예제를 작업할 것입니다. 그것들을 outputs.tf라는 파일에 보관합니다. 다음 명령을 실행하여 편집하기 위해 그 파일을 생성합니다.:

  1. nano outputs.tf

다음 行을 추가하여 배포된 Droplet 이름 쌍과 그들의 IP 주소를 출력합니다:

terraform-flexibility/outputs.tf
output "ip_addresses" {
  value = {
    for instance in digitalocean_droplet.test_droplet:
    instance.name => instance.ipv4_address
  }
}

이 코드는 ip_addresses라는 출력을 지정하고, 이전 단계에서 사용자 정의 하는 test_droplet 자원의 인스턴스를 반복하는 for 루프를 지정합니다. loop가 괄호 안에 감싸져 있으므로 그 출력은 맵이 될 것입니다. 맵의 변형 단계는 다른 프로그램 언어의 람다 함수와 유사하며, 여기에서는 인스턴스 이름을 клю지로 하고 그 privater IP를 값으로 합성하여 键值 쌍을 생성합니다.

파일을 저장하고 닫고, 그 后来에 Terraform 상태를 새로 고침하여 새 출력을 처리하기 위해 다음 명령을 실행합니다.:

  1. terraform refresh -var "do_token=${DO_PAT}"

Terraform refresh 명령은 로컬 상태에 실제 云 인프rastructure 상태를 갱신합니다.

그 后来, 출력 내용을 核验하십시오:

Output
ip_addresses
= { "first" = "ip_address" "fourth" = "ip_address" "second" = "ip_address" "third" = "ip_address" }

테라포ム은 ip_addresses 출력의 내용을 보여줍니다. 이는 for 루프로 구성된 맵입니다. (당신에게는 다른 순서가 있을 수도 있습니다.) loop는 매 번 Number of entries 만큼 동작합니다. 즉, 새로운 요소를 droplet_names 리스트에 추가하고 나면, 다음으로 생성되는 새로운 Droplet는 아무 manuel 입력 없이 自動적으로 이 출력에 나타나게 됩니다.

Square brackets can be used to output a list. For example, you might want to output only the Droplet IP addresses, which is useful for external software that may be parsing the data. The code would look like this:

terraform-flexibility/outputs.tf
output "ip_addresses" {
  value = [
    for instance in digitalocean_droplet.test_droplet:
    instance.ipv4_address
  ]
}

Here, the transformational step selects the IP address attribute. It would give the following output:

Output
ip_addresses
= [ "ip_address", "ip_address", "ip_address", "ip_address", ]

As was mentioned before, you can also filter the input collection using the if clause. Here is how you would write the loop to filter by the fra1 region:

terraform-flexibility/outputs.tf
output "ip_addresses" {
  value = [
    for instance in digitalocean_droplet.test_droplet:
    instance.ipv4_address
    if instance.region == "fra1"
  ]
}

In HCL, the == operator checks the equality of the values of the two sides—here it checks if instance.region is equal to fra1. If it is, the check passes and the instance is transformed and added to the output, otherwise it is skipped. The output of this code would be the same as the prior example, because all Droplet instances are in the fra1 region, according to the test_droplet resource definition. The if conditional is also useful when you want to filter the input collection for other values in your project, like the Droplet size or distribution.

次の섹션에서 리소스를 다르게 생성할 때, 현재 배포된 리소스를 소멸하기 위해 다음 명령을 실행하십시오.

  1. terraform destroy -var "do_token=${DO_PAT}"

추促され면 yes 를 입력하여 프로세스를 완료하십시오.

지난 섹션에서 for 루프, 그 문법以及 출력에서 사용하는 예제에 대해 배웠습니다. 이제 조건문과 그들이 count와 함께 사용되는 방법에 대해 배울 것입니다.

지시어 및 조건문

지난 섹션 중 하나에서 count ключ과 그 작동方式을 보았습니다. 이제 三元 조건 연산자에 대해 배울 것입니다. 이들은 Terraform 코드 내에서 다른 곳에 사용할 수 있으며 count와 어떻게 사용할 수 있는지 배울 것입니다.

三元 연산자의 문법은 다음과 같습니다:

condition ? value_if_true : value_if_false

condition는 참 또는 거짓의 boolean 값을 리턴하는 표현式입니다. 조건이 참이면 value_if_true를 리턴하고, 조건이 거짓이면 value_if_false를 리턴합니다.

三元 연산자의 주요 用途는 변수의 내용에 따라 단일 리소스 생성을 사용하거나 사용하지 않는다. 이를 실현하는 方法은 比较 결과(1 또는 0)를 원하는 리소스의 count 키에 전달하는 것입니다.

ternary 연산자를 사용하여 리스트 또는 집합から 單独의 요소를 가져와야 할 때, one 함수를 사용할 수 있습니다. given collection이 비어 있다면 null을 반환합니다. 그렇지 않으면, コレク션에 단 하나의 요소를 반환합니다. 여러 개의 요소가 있으면 에러를 던집니다.

変数 create_droplet를 추가하는 것이 좋습니다. 이 변수는 Droplet이 생성되는지 여부를 제어합니다. まず variables.tf 을 편집하기 위해 열어봅니다.

  1. nano variables.tf

強調された 行을 추가하십시오.

terraform-flexibility/variables.tf
variable "droplet_names" {
  type    = list(string)
  default = ["first", "second", "third", "fourth"]
}

variable "create_droplet" {
  type = bool
  default = true
}

이 코드는 create_droplet 変数을 bool 형식으로 정의합니다. ファイルを保存하고 닫으십시오.

次に, Droplet 宣言を変更하기 위해 droplets.tf 을 편집하는 것을 실행하십시오.

  1. nano droplets.tf

다음과 같이 あなた의 ファイル을 수정하십시오.

terraform-flexibility/droplets.tf
resource "digitalocean_droplet" "test_droplet" {
  count  = var.create_droplet ? 1 : 0
  image  = "ubuntu-20-04-x64"
  name   =  "test_droplet"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

count 는 ternary 연산자를 사용하여 create_droplet 変数가 true일 때 1, false일 때 0 을 반환하는 것이 좋습니다. 이렇게 하면 Droplet이 제공되지 않습니다. 다 结束后에 count 에 대한 것을 저장하고 닫으십시오.

변수가 false로 설정되어 있으면 프로젝트 실행 계획을 계획하십시오.

  1. terraform plan -var "do_token=${DO_PAT}" -var "create_droplet=false"

다음과 같은 출력을 받을 것입니다.

Output
Changes to Outputs: + ip_addresses = {} You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.

create_dropletfalse의 값을 전달했기 때문에, count 인스턴스는 0이고, Droplet이 생성되지 않으므로 IP 주소를 표시할 것이 없습니다.

Tigerflex 변경사항에 대해서는 자세히 이해하고 있으며, 변경사항이 적용되었는지 확인하기 위해서는 어떻게 proceed하는지 指导 받았습니다. 또한, 변경사항이 적용되었는지 확인하기 위해서는 어떤 과정을 거쳐야 하는지에 대해서도 指导 받았습니다. 따라서, 변경사항을 적용하고자 하는 과정에 대해서는 자신이 이해하고 있으며, 어떻게 proceed하는지에 대해서도 자신이 指导 받았다고 생각합니다.

명시적 자원 依存 관계 설정

프로젝트의 실행 플랜을 생성하는 과정에서, Terraform이 자원 사이의 依存 관계 체이닝을 감지하여 자동으로 그들을 적절한 順序로 생성시키는 것을 배웠습니다. 대부분의 경우, 모든 표현을 조사하고 그래프를 만들어 관계를 감지하는 것입니다.

그러나, 하나의 자원이 제공되기 위해서는 이미 云 제공자에서 접근 제어 설정이 배포되어 있어야 하는 경우, Terraform에게는 그들이 관계가 있는 것을 자동으로 감지하는 것이 없습니다. 따라서, Terraform은 그들이 서로를 行为적으로 依存하는 것을 알 수 없습니다. 이러한 경우, depends_on 인자를 사용하여 手動으로 依存 관계를 지정해야 합니다.

depends_on 키는 각 자원에 대해 사용되어 특정 자원 사이의 은하 invisible dependency links를 지정합니다. invisible dependency relationships은 자원이 다른 자원의 behavior에 依存하는 경우에 형성되며, 자원의 data를 사용하지 않고 자신의 선언을 통해 Terraform이 그들을 하나로 연결하는 것을 의미합니다.

다음은 depends_on 를 코드에서 지정하는 예시입니다.

resource "digitalocean_droplet" "droplet" {
  image  = "ubuntu-20-04-x64"
  name   = "web"
  region = "fra1"
  size   = "s-1vcpu-1gb"

  depends_on = [
    # 리소스...
  ]
}

다른 리소스에 대한 참조 목록을 接受하며, 任意の 표현을 接受하지 않습니다.

depends_on는 sparse하게 사용해야 하며, 모든 다른 옵션을 모두 소비한 다음에만 사용해야 합니다. 이것의 사용은 Terraform의 자동 依存성 감지 시스템의 경계를 벗어나는 것을 의미합니다; 리소스가 명확하게 过多하게 다른 리소스에 의존하는 것을 의미할 수 있습니다.

이제 depends_on 키를 사용하여 리소스의 추가 依存성을 명시적으로 설정하는 것을 배웠고, 언제 사용해야 하는지 배웠습니다.

결론

이 記事에서는, HCL로 코드의 靈活性和 스케일ability를 改善하는 기능들을 인지할 수 있습니다. 예를 들어 count를 사용하여 배포할 리소스 인스턴스 수를 지정하고, for_each를 사용하여 コレク션 자료 유형을 반복하고 인스턴스를 カスタマ이징할 수 있습니다. correct하게 사용하면, 코드 복사하는 것과 배포한 인프라STRUCTURE를 관리하는 operaional overhead를 大幅に 줄일 수 있습니다.

또한 조건문과 三元运算자에 대해 배웠고, 리소스가 배포될지 여부를 결정하는 것을 배웠습니다. Terraform의 자동 依存성 분석 시스템은 매우 능력 있지만, 某些情况下 리소스 依存성을 depends_on 키를 사용하여 수동으로 지정해야 하는 것이 있을 수 있습니다.

이 튜토리얼은 Terraform로 인frastructure 관리하기 시리즈의 일부입니다. 이 시리즈는 Terraform에 대한 다양한 주제를 涵蓋하며, Terraform을 처음 설치하는 것부터 複雑한 프로젝트를 관리하는 것까지의 주제를 涵蓋합니다.

Source:
https://www.digitalocean.com/community/tutorials/how-to-improve-flexibility-using-terraform-variables-dependencies-and-conditionals