의존성 그래프

의존성 그래프 (Dependency Graph)

Terraform이 구성에서 만드는 의존성 그래프에 대해 설명해요. 이 문서는 고급 주제라서 Terraform을 사용하는 데 반드시 필요한 건 아니지만, 그래프가 어떻게 구성되고 걷는지 이해하면 내부 동작을 알 수 있어요.

출처: 문서

본문

이 주제는 Terraform이 구성에서 만드는 의존성 그래프를 설명해요. 고급 주제이며 Terraform 사용법을 이해하는 데 필요하지는 않아요.

소개

Terraform은 의존성 그래프를 만들고 이를 사용해 계획(plan) 생성이나 상태 새로고침과 같은 작업을 수행해요.

그래프 이론에 대한 배경과 Terraform이 이를 어떻게 적용하는지에 대한 요약은 HashiCorp 2016 프레젠테이션 Applying Graph Theory to Infrastructure as Code를 참조하세요.

그래프 노드

그래프 안에는 다음과 같은 노드 유형이 존재할 수 있어요:

  • 리소스 노드 (Resource Node) - 단일 리소스를 나타내요. count 메타파라미터가 설정되어 있다면 count마다 하나의 리소스 노드가 있어요. 변경 대상 리소스의 구성, diff, 상태 등이 이 노드에 연결돼요.

  • 프로바이더 구성 노드 (Provider Configuration Node) - 프로바이더를 완전히 구성할 시점을 나타내요. 즉 프로바이더 구성 블록이 프로바이더에 전달되는 때예요. 예를 들어 AWS 보안 자격 증명 같은 것이죠.

  • 리소스 메타 노드 (Resource Meta-Node) - 리소스 그룹을 나타내지만 그 자체로는 어떤 작업도 나타내지 않아요. 의존성의 편의와 더 보기 좋은 그래프를 위해 만들어져요. 이 노드는 count 매개변수가 1보다 큰 리소스에만 존재해요.

terraform graph로 구성을 시각화하면 이러한 모든 노드가 표시되는 것을 볼 수 있어요.

그래프 만들기

그래프 만들기는 일련의 순차적 단계로 이루어져요:

  • 구성에 따라 리소스 노드가 추가돼요. diff(계획) 또는 상태가 있으면 그 메타데이터가 각 리소스 노드에 연결돼요.

  • 리소스에 프로비저너가 정의되어 있으면 리소스가 프로비저너에 매핑돼요. 동일한 프로비저너 유형을 가진 리소스가 프로비저너 구현을 공유할 수 있도록 모든 리소스 노드를 만든 뒤에 이 작업을 수행해야 해요.

  • depends_on 메타파라미터의 명시적 의존성을 사용해 리소스 사이에 엣지(edge)가 생성돼요.

  • 상태가 있으면 "고아(orphan)" 리소스가 그래프에 추가돼요. 고아 리소스는 더 이상 구성에 없지만 상태 파일에는 있는 리소스를 말해요. 상태 파일은 구성을 저장하지 않으므로 고아 리소스에는 구성이 연결되어 있지 않아요.

  • 리소스가 프로바이더에 매핑돼요. 이 프로바이더에 대한 프로바이더 구성 노드가 생성되고, 리소스가 각자의 프로바이더가 구성되는 것에 의존하도록 엣지가 생성돼요.

  • 리소스 및 프로바이더 구성의 보간(interpolation)이 파싱되어 의존성을 결정해요. 리소스 속성에 대한 참조는 보간이 있는 리소스에서 참조되는 리소스로의 의존성으로 바뀌어요.

  • 루트 노드가 생성돼요. 루트 노드는 모든 리소스를 가리키며 의존성 그래프에 단일 루트가 있도록 생성돼요. 그래프를 탐색할 때 루트 노드는 무시돼요.

  • diff가 있으면 모든 리소스 노드를 탐색해 파괴되는 리소스를 찾아요. 이 리소스 노드는 두 개로 분할돼요. 하나는 리소스를 파괴하는 노드이고 다른 하나는 (재생성되는 경우) 리소스를 생성하는 노드예요. 파괴 순서가 생성 순서와 다른 경우가 많아 단일 그래프 노드로 표현할 수 없기 때문에 노드를 분할해야 해요.

  • 그래프에 사이클이 없고 단일 루트가 있는지 검증해요.

그래프 걷기

그래프를 걷기 위해 표준 깊이 우선 탐색(depth-first traversal)이 수행돼요. 그래프 걷기는 병렬로 이루어져요. 노드의 모든 의존성이 걷혀지면 그 노드가 걷혀져요.

병렬 처리량은 세마포어로 제한되어 Terraform을 실행하는 머신의 리소스를 너무 많은 동시 작업이 압도하지 않도록 해요. 기본적으로 그래프에서 최대 10개의 노드가 동시에 처리돼요. 이 숫자는 plan, apply, destroy 명령의 -parallelism 플래그로 설정할 수 있어요.

-parallelism 설정은 고급 작업으로 간주되며 Terraform을 정상적으로 사용할 때 필요하지 않아요. 특정 특수 사용 사례에서 도움이 되거나 Terraform 문제를 디버깅하는 데 도움이 될 수 있어요.

AWS 같은 일부 프로바이더는 각자 API 클라이언트에 우아한 백오프/재시도(graceful backoff/retry)를 구현해 더 낮은 수준에서 API 속도 제한 문제를 처리한다는 점에 유의하세요. 이런 이유로 Terraform은 API 속도 제한을 직접 해결하기 위해 이 parallelism 기능을 사용하지 않아요.

더 알아보기 (Learn more)