Nubes et Stella

Terraform #05 (count/for_each) 본문

DevOps/Terraform

Terraform #05 (count/for_each)

SeongYeong Han 2023. 10. 18. 22:38

01. Terraform count 문

테라폼에는 프로그래밍에서와 비슷하게 반복문을 사용할 수 있다. 예를 들어 불특정 20개의 계정을 생성해야 한다면 resource를 20개 생성해야 하는 불편함이 있다. 이 때 반복문을 쓰게 되면 간단하게 구현할 수 있다.

 

테라폼 문서 : https://developer.hashicorp.com/terraform/language/meta-arguments/count

 

The count Meta-Argument - Configuration Language | Terraform | HashiCorp Developer

Count helps you efficiently manage nearly identical infrastructure resources without writing a separate block for each one.

developer.hashicorp.com


  • 아래의 코드는 반복문 중에 "count"를 사용하여 10개의 계정을 생성하는 코드이다.
  • resource 블록에 count 메타 인자를 추가하고 값(몇 번 반복할 건지)을 추가한다.
  • ${count-index}는 0부터 count-1까지를 숫자들을 표현한다.
provider "aws" {
  region = "ap-northeast-2"
}

/*
 * count
 */

resource "aws_iam_user" "count" {
  count = 10

  name = "count-user-${count.index}"
}

output "count_user_arns" {
  value = aws_iam_user.count.*.arn
  • 위 코드를 terraform apply하게 되면 10개의 계정이 생성되는 것을 볼 수 있다.

** count문을 쓸 때는 한가지 주의해야 할 점이 있다. count로 생성된 객체들 중에서 가운데 하나를 제거한다면, 이후의 값들이 count-1 쉬프트 되면서 삭제된 자리를 채우게 된다.

 

 

02. Terraform for_each 문

count 문은 문법이 간단하여 이해하기 쉽다는 장점이 있지만, 기능적으로 문제가 있다. 그래서 그 대안으로 나온게 for_each 문이다. for_each는 테라폼에서 미리 정의한 메타인자이며, resource를 비롯하여 module등 여러 label 타입에 사용할 수 있다.

 

우선 for_each문을 다루기 위해서는 "set" 과 "map" 형식을 이해할 수 있어야 한다.

 

  • set문 = Unique 한 요소를 가지는 리스트 형식이다. | Ex. ["apple", "banana", "melon"]
  • map = 중괄호로 표현하며 "key=value" 형식이다. 파이썬의 딕셔너리와 유사하다. | Ex. {a = 가, b = 나, c = 다}

 

추가적으로 for_each 문을 map으로 표현할 경우 Key와 Value값을 추가적으로 표현할 수 있다.

  • each.key = map 형식에서 Key값을 리스트로 표현한다.
  • each.value = map 형식에서 Value값을 리스트로 표현한다. (set에서는 each.key와 동일한 값이 된다.)

 

테라폼 문서 : https://developer.hashicorp.com/terraform/language/meta-arguments/for_each

 

The for_each Meta-Argument - Configuration Language | Terraform | HashiCorp Developer

The for_each meta-argument allows you to manage similar infrastructure resources without writing a separate block for each one.

developer.hashicorp.com


아래의 코드는 for_each에서 "set"을 사용하여 계정 3개를 생성한다.

  • line10 : toset(....) 함수를 사용하여 set문으로 변환한다.
  • line16 : each.key는 set의 요소들을 불러온다. (set 문이기 때문에 each.value로 해도 동일하다.)
  1 provider "aws" {
  2   region = "ap-northeast-2"
  3 }
  4
  5 /*
  6  * for_each
  7  */
  8
  9 resource "aws_iam_user" "for_each_set" {
 10   for_each = toset([
 11     "for-each-set-user-1",
 12     "for-each-set-user-2",
 13     "for-each-set-user-3",
 14   ])
 15
 16   name = each.key
 17 }
 18
 19 output "for_each_set_user_arns" {
 20   value = values(aws_iam_user.for_each_set).*.arn
 21 }

 

아래의 코드는 for_each에서 "map"을 사용하여 계정 3개를 생성한다.

  • line 6~19 : map 형식으로 여기서는 "alice"가 Key가 되며, 그 아래 level = low, manager = posquit0가 value가 된다.
  • line 21, 23 : IAM 블록의 name 메타인자로 each.key(alice, bob, john), tags 메타인자로 each.value(level, manager)를 넣는다.
  1 provider "aws" {
  2   region = "ap-northeast-2"
  3 }
  4
  5 resource "aws_iam_user" "for_each_map" {
  6   for_each = {
  7     alice = {
  8       level = "low"
  9       manager = "posquit0"
 10     }
 11     bob = {
 12       level = "mid"
 13       manager = "posquit0"
 14     }
 15     john = {
 16       level = "high"
 17       manager = "steve"
 18     }
 19   }
 20
 21   name = each.key
 22
 23   tags = each.value
 24 }
 25
 26 output "for_each_map_user_arns" {
 27   value = values(aws_iam_user.for_each_map).*.arn
 28 }}

 

위 2개의 코드를 한 파일에서 모두 실행하여 결과를 확인해보면, 아래와 같이 계정과 태그가 정상적으로 생성된 것을 볼 수 있다.

 

- END -

'DevOps > Terraform' 카테고리의 다른 글

Terraform #07 (Backend/State)  (0) 2023.10.23
Terraform #06 (Conditional/For)  (0) 2023.10.19
Terraform #04 (Variable/Output/Local)  (1) 2023.10.09
Terraform #03  (0) 2023.09.27
Terraform #02  (0) 2023.09.26