개발하자

잘못된 for_each 인수로 테라폼 실패 / 지정된 "for_each" 인수 값이 적합하지 않습니다

Cuire 2023. 6. 27. 06:34
반응형

잘못된 for_each 인수로 테라폼 실패 / 지정된 "for_each" 인수 값이 적합하지 않습니다

실행 중이거나 오류에 제공된 목록과 함께 다음과 같은 오류가 발생할 때

Error: Invalid for_each argument

  on main.tf line 2, in resource "aws_ssm_parameter" "foo":
  2:   for_each = ["a", "b"]

The given "for_each" argument value is unsuitable: the "for_each" argument
must be a map, or set of strings, and you have provided a value of type tuple.

이 오류를 재현하는 최소 예는 다음과 같습니다:

resource "aws_ssm_parameter" "foo" {
  for_each = ["a", "b"]

  name  = "foo-${each.value}"
  type  = "String"
  value = "bar-${each.value}"
}



설명.

이 오류는 에 목록을 전달할 때 종종 발생하지만 순서가 지정되지 않은 데이터 유형(예: 집합 및 맵)에서만 작동합니다.

해결책

해상도는 상황에 따라 다릅니다.

문자열 목록

만약 목록이 단지 문자열 목록이라면, 가장 쉬운 해결책은 목록을 for_each가 처리할 수 있는 집합으로 변환하는 -call을 추가하는 것이다

resource "aws_ssm_parameter" "foo" {
  for_each = toset(["a", "b"])

  name  = "foo-${each.value}"
  type  = "String"
  value = "bar-${each.value}"
}

지도로 재배열할 수 있는 목록

입력이 목록이지만 지도로 쉽게 재배열할 수 있는 경우 일반적으로 이 방법이 가장 좋습니다. 우리가 이런 목록을 가지고 있다고 해주세요

locals {
  animals = [
    {
      name = "Bello"
      age = 3
      type = "dog"
    },
    {
      name = "Minga"
      age = 4
      type = "cat"
    },
  ]
}

그렇다면 적절한 재구성은 다음과 같습니다

locals {
  animals = {
    Bello : {
      age = 3
      type = "dog"
    },
    Minga : {
      age = 4
      type = "cat"
    }
  }
}

그런 다음 정의할 수 있습니다

resource "aws_ssm_parameter" "foo" {
  for_each = local.animals

  name  = each.key
  type  = string
  value = "This is a ${each.value.type}, ${each.value.age} years old."
}

재정렬하지 않을 목록

때때로 목록을 갖는 것은 당연하다. 예를 들어 제어하지 않는 모듈의 출력이나 로 정의된 리소스에서 나오는 것이다. 그런 상황에서, 사람들은 이렇게 숫자를 세면서 일할 수 있다

resource "aws_ssm_parameter" "foo" {
  count = length(local.my_list)

  name  = my_list[count.index].name
  type  = "String"
  value = my_list[count.index].value
}

이름과 값을 키로 포함하는 맵 목록에 대해 작동합니다. 그러나 종종, 이렇게 대신에 목록을 지도로 변환하는 것이 더 적절하다

resource "aws_ssm_parameter" "foo" {
  for_each = { for x in local.my_list: x.id => x }

  name  = each.value.name
  type  = "String"
  value = each.value.value
}

여기서는 적절한 것을 선택해야 한다. 만약 객체의 목록이라면, 보통 이름이나 키와 같은 공통된 필드가 사용될 수 있다. 위와 같이 사용하는 것을 선호하는 이 접근법의 장점은 이것이 목록에서 요소를 삽입하거나 제거할 때 더 잘 동작한다는 것입니다. 삽입이나 삭제를 인식하지 못하고 삽입이 발생한 위치에 따라 모든 리소스를 업데이트합니다, 새 ID 또는 삭제된 ID를 가진 리소스만 추가하거나 제거합니다.


반응형