본문 바로가기

Devops 솔루션/Terraform

[Terraform] for_each, for loop 란

반응형

[Terraform] for_each, for loop란?

Checkbox
Date

요약

  • For_each : 맵핑된 인덱스 값을 통한 특정 리소스만 변경할 수 있는 배열을 만들 수 있음
  • For loop : 정수 형태의 인덱스 값을 통해 간단하고 빠르게 리소스를 만들 수 있으나, 배열 형태로 관리되기 때문에 리소스 변경에 배열 전체가 영향을 받기도 한다.
  • Terraform도 nested loop가 가능하다. 다만 동시성 문제가 발생하는 경우가 있다

내용

  • 매 번 반복되는 리소스를 조금 더 간편히 관리 할 수 없을까?
    • 어느 정도 안정기로 들어서면, 인프라의 변경이 잦지 않기 때문에 테라폼을 수정하는 일은 빈번하지 않다
    • 매번 반복하는 코드가 많기 때문에, 테라그런트 등의 솔루션 등을 통해 반복되는 코드를 관리한다.
    • 반복성을 줄이고 json 같은 데이터포맷을 통해 관리할 수 있다면 어떨까?

      → 반복되는 리소스를 만들 때, 사용할 수 있는 방법은 for loop와 for_each를 자주 사용한다.

      → 단순한 사용 방법은 테라폼 공식 도큐먼트를 확인해보자

  • 리소스 생성을 위한 테라폼 코드 생성
    • VPC 대상으로 사용한 JSON 포맷
    • 사용한 Nested loop 모듈 샘플
    • 코드 기능 : route 키에 존재하는 public, private 값 조정을 통해 해당 Public 라우팅 테이블에 붙을지, Private 라우팅 테이블에 붙을지 조정을 할 수 있다.
  • for_each 와 for loop 중 왜 for_each를 사용했는지?
    • 각 각 기능을 통해 생성 후 tfstate를 자세히 보면 index_key에 데이터 타입이 다른 것을 볼 수 있다.
      • for_each 는 index_key 옆 데이터 타입이 string 형식으로 Map 형식으로 관리
      • for loop는 index_key 옆 데이터 타입이 number 형식으로 Array 형식으로 관리
    • 이 데이터 타입의 차이는 크다. Array 타입의 경우는 배열 내의 0 번째 인덱스에 영향을 받아서 삭제 재생성등이 되면 다른 인덱스에 연결되어 있는 값에 영향을 주지만, Map 형식은 배열 내 인덱스 위치와 상관 없이 독립적으로 적용이 된다. (Array 형식은 운이 없으면 배열 전체가 밀리면서 삭제되었다가 다시 생성되는 플랜을 보여주는 경우도 있다.)
  • Nested loop 사용 팁
    • flatten과 concat을 혼합하면 필요한 값만 가져오는 배열을 만들 수도 있다.
    • JSON 포맷을 정의 할 때, 한 키에 한 Value를 관리 할 수 있게 하는 것이 깔끔하다. ( 포맷을 복잡하게 만들어도 코드가 길어지지 불가능하진 않다.)
    • 예시 처럼 원하는 맵핑 값을 사용해서 값을 추후에 호출 할 수 있다.
    • local 변수에 필요한 변수를 만들어놓고 가져와서 사용하는 것이 편하다.
  • 하면서 발생한 문제 → 동시성 문제
    • 테라폼을 Apply 시켜보면서 Already Used 라는 코드를 많이 봤다
    • 그 이유는, for_each 같은 loop는 테라폼에서 병렬로 같이 돌리기 때문에 테라폼의 parallelism 값에 영향을 받는다. 나 같은 경우는 테라폼에서 동시에 같은 라우터의 API를 호출해서 발생하는 문제였다.
    • 적당한 값을 지정해서 해결할 수 있었다. ( 그냥 에러가 뜨고 다시 한 번 돌려도 문제가 해결되긴 한다 )
  • 해결책
    • 테라폼의 command config를 확인하면 아래의 두가지 환경 변수 지정을 통해, PLAN과 APPLY의 병렬 처리 갯수를 조정할 수 있다.
    • PLAN은 여러개가 같이 돌아도 문제 없기 때문에 많이 두어 시간을 줄이고, Apply는 2 정도로 작은 값을 두어, 동시성 발생 확률을 줄였더니 문제 없이 작동하였다. (다만 속도는 느려지기 때문에 다른 방법이 있을지는 확인해봐야겠다)
      • export TF_CLI_ARGS_PLAN="-parallelism=n”
      • export TF_CLI_ARGS_APPLY="-parallelism=n”
  • 추후 모니터링 할 내용
    • 이렇게 loop의 병렬처리에 불만이 많은 사람이 커뮤니티에 많은가보다, 아직 로드맵에 들어가진 않았지만 커뮤티니에 종종 나오는 내용이다보니, loop내에 실행 순서를 지정해주는 기능이 나오지 않을까 기대해본다.

배울 점

  • for loop와 for_each에 대해서 모호하게 아는 부분이 있었는 데 완벽하게 정리된 점
  • Nested loop가 발생해도 해결 할 수 있다는 것을 알 수 있었다.
  • JSON 형태로 관리할 수 있게 하는 방향으로 적용할 수 있는 가능성을 봤다.

    → JSON 형태로 관리할 수 있게 된다면, Python의 diagram 모듈을 통해 자동으로 아키텍처 그림을 그려준다. or 정보를 통해 예상 비용을 알려줄 수 있다던지 등의 부가적인 기능이 가능하게 된다.

    → 간단하게 만들어볼 예정 (해보고 싶은 것 참 많다..)

추후 해야할 것

  • EC2, ECS, IAM 모듈 작성
  • 아키텍처 다이어그램 자동화, 예상 비용 자동화 가능한 소프트웨어가 있는지 확인

참고자료

Command: apply | Terraform | HashiCorp Developer
The terraform apply command executes the actions proposed in a Terraform plan to create, update, or destroy infrastructure.
https://developer.hashicorp.com/terraform/cli/commands/apply
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.
https://developer.hashicorp.com/terraform/language/meta-arguments/for_each
Functions - Configuration Language | Terraform | HashiCorp Developer
An introduction to the built-in functions that you can use to transform and combine values in expressions.
https://developer.hashicorp.com/terraform/language/functions
728x90
반응형

'Devops 솔루션 > Terraform' 카테고리의 다른 글

[Terraform] terraform_remote_state 이란  (0) 2023.03.23
Terraform+CSV로 SecurityGroup 관리  (0) 2022.04.14