본문 바로가기
IaC/Terraform

[Terraform] 2-2. Count 활용과 제약사항

by okms1017 2024. 6. 23.
728x90

✍ Posted by Immersive Builder  Seong

 

 

1. 실습 소개

이번 실습에서는 Count 반복문을 활용해보고 제약사항을 알아봅니다. 

 

  • Count 개념 
  • Count 활용 
  • Count 제약사항 

 


2. Count 활용과 제약사항

Count 개념

list 형태의 값 목록이나 Key-Value 형태의 문자열 집합인 데이터가 있는 경우 동일한 내용에 대해 테라폼 구성 정의를 반복적으로 하지 않고 관리할 수 있습니다. 

 

  • count 인수로 정수가 포함된 경우 선언된 정수 값만큼 리소스 또는 모듈 생성 
  • count.index : count에서 생성되는 참조값 (0,1,2,..)
  • 참조 형식 : <리소스 타입>.<리소스명>[<인덱스 번호>], module.<모듈이름>[<인덱스 번호>] 
  • count 인수로 외부 변수에 식별되는 값으로 구성 가능  ex) length(var.names) 

 

Count 활용

  • IAM User 생성하기 

        provider "aws" {
          region = "ap-northeast-2"
        }

        resource "aws_iam_user" "iam" {
          count = 3
          name  = "user${count.index}"
        }
 

 

IAM User 생성 확인

 

  • Count 입력 변수를 통해 IAM User 생성하기 

./count-iam-user-2/
├── main.tf
├── output.tf
└── values.tf

 

# values.tf
 
        variable "user_names" {
          description = "Create IAM users with these names"
          type        = list(string)
          default     = ["gasida", "seong", "cocoon"]
        }
 

 

# main.tf
  
        provider "aws" {
          region = "ap-northeast-2"
        }

        resource "aws_iam_user" "iam" {
          count = length(var.user_names)
          name  = var.user_names[count.index]
        }
 

 

'user_names' 변수를 선언하고 문자열 값을 리스트 형식으로 받습니다. 

그리고 IAM User를 생성할 때 해당 리스트에 담긴 문자열 개수만큼 반복하도록 length(var.user_names) 내장함수를 사용하였습니다. 

예상하건대 "gasida", "seong", "cocoon" 3개의 IAM User가 생성될 것입니다. 

 

# output.tf 
 
        output "second_arn" {
          value       = aws_iam_user.iam[1].arn
          description = "The ARN for the second user"
        }

        output "all_arns" {
          value       = aws_iam_user.iam[*].arn
          description = "The ARNs for all users"
        }
 

 

output 블록을 선언함으로써 프로비저닝 완료 이후에 결정되는 속성 값을 확인할 수 있습니다. 

 

$ terraform output second_arn

"arn:aws:iam::732659419746:user/seong"

$ terraform output -raw second_arn

arn:aws:iam::732659419746:user/seong

 

$ terraform output all_arns

[
  "arn:aws:iam::732659419746:user/gasida",
  "arn:aws:iam::732659419746:user/seong",
  "arn:aws:iam::732659419746:user/cocoon",
]

$ terraform output -raw all_arns

Error: Unsupported value for raw output

 

참고로 -raw 옵션은 문자열(string), 숫자(numbers), 부울(boolean) 타입만 지원합니다. 

'all_arns' output 값은 튜플 타입이므로 에러가 발생합니다. 

 

IAM User 생성 확인

 

Count 제약사항

Count를 사용함에 있어 두 가지 제약사항이 있습니다. 

 

  • 전체 리소스는 반복 가능하나, 리소스 내에서 인라인 블록은 반복 불가
  • 배열 중간 값을 변경할 시, 의도하지 않은 결과가 발생함 

 


        variable "user_names" {
          description = "Create IAM users with these names"
          type        = list(string)
          default     = ["gasida", "cocoon"]
        }
 

 

위에서 생성한 IAM User 리스트(["gasida", "seong", "cocoon"])에서 두 번째 값("seong")을 삭제하고 실행합니다. 

 

실행 계획을 보면 인덱스 두 번째 계정(aws_iam_user.iam[1])은 재생성되고, 인덱스 세 번째 계정(aws_iam_user.iam[2])은 인덱스 범위를 벗어나므로 삭제한다고 해석합니다. 

 

Count 사용 시 배열 중간 값을 삭제하면 해당 항목 이후로 모든 리소스를 삭제한 후 처음부터 다시 생성합니다. 

 

$ terraform plan 

```

  ~ update in-place
  - destroy

```  

  # aws_iam_user.iam[1] will be updated in-place
  ~ resource "aws_iam_user" "iam" {
        id                   = "seong"
      ~ name                 = "seong" -> "cocoon"
        tags                 = {}
        # (6 unchanged attributes hidden)
    }

  # aws_iam_user.iam[2] will be destroyed
  # (because index [2] is out of range for count)
  - resource "aws_iam_user" "iam" {
      - arn                  = "arn:aws:iam::732659419746:user/cocoon" -> null
      - force_destroy        = false -> null
      - id                   = "cocoon" -> null
      - name                 = "cocoon" -> null
      - path                 = "/" -> null
      - tags                 = {} -> null
      - tags_all             = {} -> null
      - unique_id            = "AIDA2VFPHRJRPXOX5JMI7" -> null
        # (1 unchanged attribute hidden)
    }

 

 

실제로 'terraform apply'를 실행하면 다음과 같은 에러가 발생합니다. 

 

$ terraform apply -auto-approve

│ Error: updating IAM User (seong): operation error IAM: UpdateUser, https response error StatusCode: 409, RequestID: 3c0dfa2d-09a1-40fc-94dc-9eec5c226e46, EntityAlreadyExists: User with name cocoon already exists.

 

콘솔 화면에서도 삭제하고자 시도한 계정("seong")은 그대로 살아 있고, 엉뚱한 계정("cocoon")이 삭제되었음을 확인할 수 있습니다. 

 

Count - 의도하지 않은 결과

 

이것은 Count가 인덱스 기반으로 리소스에 접근하기 때문에 발생하는 현상입니다. 

따라서 배열 중간 값을 삭제하는 경우 세심한 주의가 필요하며, 이런 경우에는 count 대신 for_each를 사용하기를 권장합니다. 

 

 


[출처] 

1) CloudNet@, T1014 실습 스터디 

2) https://developer.hashicorp.com/terraform/tutorials/configuration-language/count

 

Manage similar resources with count | Terraform | HashiCorp Developer

Manage similar Terraform resources using the count argument. Create a VPC with a load balancer and EC2 instances. Then use count to manage a configurable number of similar AWS EC2 instances across multiple subnets.

developer.hashicorp.com

3) 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

728x90