종속 항목 관리에 관한 권장사항

이 문서에서는 Terraform 구성의 리소스 간 종속 항목을 표현하기 위한 권장사항을 제공합니다.

명시적 종속 항목보다 암시적 종속 항목 선호

리소스 종속성은 한 리소스가 다른 리소스의 존재에 의존할 때 발생합니다. Terraform은 리소스가 올바른 순서로 생성되도록 하기 위해 이러한 종속성을 이해할 수 있어야 합니다. 예를 들어 리소스 A가 리소스 B에 의존하면 리소스 B가 리소스 A보다 먼저 생성됩니다.

Terraform 구성 종속 항목은 암시적 및 명시적 종속 항목 선언을 통해 설정될 수 있습니다. 암시적 종속 항목은 표현식 참조를 통해 선언되는 반면 명시적 종속 항목은 depends_on 메타 인수를 사용하여 지정됩니다. depends_on 인수는 Terraform이 종속된 객체에 대한 작업을 진행하기 전에 리소스 또는 모듈이 종속된 객체에 대한 모든 작업을 완료해야 함을 지정합니다.

두 접근방식 모두 올바른 작업 순서를 보장하지만, 암시적 종속 항목은 리소스의 업데이트 및 교체를 계획할 때 더 효율적인 경우가 많습니다. Terraform이 암시적 종속 항목과 관련된 특정 필드를 지능적으로 추적하여 종속 항목 내에서 특정 필드가 변경되지 않은 경우 종속된 리소스의 변경을 피할 수 있기 때문입니다.

암시적 종속 항목에 비해 명시적 종속 항목은 덜 구체적인 정보를 전달합니다. 즉, Terraform은 종속 항목을 구성하는 특정 속성에 대한 지식이 없는 경우 리소스 생성, 업데이트, 교체에 대한 보다 보수적인 계획만 수립할 수 있습니다. 실제로 이는 Terraform에서 리소스를 생성하는 순서와 Terraform이 리소스에 업데이트 또는 교체가 필요한지 여부를 결정하는 방식에 영향을 미칩니다.

두 리소스 간의 종속 항목이 숨겨져 있어 암시적 종속 항목으로 표현할 수 없는 경우 최후의 수단으로 depends_on 메타 인수와 함께 명시적 종속 항목을 사용하는 것이 좋습니다.

다음 예시에서는 BigQuery 데이터 세트를 만들기 전에 필수 프로젝트 서비스를 활성화해야 합니다. 이 종속 항목은 명시적으로 선언됩니다.

다음은 권장하지 않습니다.

module "project_services" {
  source  = "terraform-google-modules/project-factory/google//modules/project_services"
  version = "~> 14.4"

  project_id = var.project_id
  activate_apis = [
    "bigquery.googleapis.com",
    "bigquerystorage.googleapis.com",
  ]
}

module "bigquery" {
  source       = "terraform-google-modules/bigquery/google"
  version      = "~> 5.4"

  dataset_id   = "demo_dataset"
  dataset_name = "demo_dataset"
  project_id   = var.project_id
  depends_on = [module.project_services] # <- explicit dependency
}

다음 예시에서는 project_id 인수를 project_services 리소스의 project_id 출력 속성으로 참조하여 명시적 종속 항목을 암시적 종속 항목으로 바꿉니다.

다음을 권장합니다.

module "bigquery" {
  source       = "terraform-google-modules/bigquery/google"
  version      = "~> 5.4"

  dataset_id   = "demo_dataset"
  dataset_name = "demo_dataset"
  project_id   = module.project_services.project_id # <- implicit dependency
}

암시적 종속 항목을 사용하면 업스트림 객체에서 수집해야 하는 정확한 정보를 지정하는 등 종속 항목을 정확하게 선언할 수 있습니다. 또한 여러 위치에서 변경해야 할 필요성이 줄어들어 오류의 위험도 줄어듭니다.

종속 리소스의 출력 속성 참조

업스트림 리소스의 값을 참조하여 암시적 종속 항목을 만들 때는 출력 속성, 특히 아직 알려지지 않은 값만 참조해야 합니다. 이렇게 하면 Terraform이 현재 리소스를 프로비저닝하기 전에 업스트림 리소스가 생성될 때까지 기다릴 수 있습니다.

다음 예시에서 google_storage_bucket_object 리소스는 google_storage_bucket 리소스의 이름 인수를 참조합니다. 인수는 Terraform 계획 단계에서 알려진 값을 갖습니다. 즉, Terraform이 google_storage_bucket_object 리소스를 만들 때 알려진 인수(버킷 이름)를 참조하면 google_storage_bucket_objectgoogle_storage_bucket 간에 암시적 종속 항목이 생성되지 않으므로 google_storage_bucket 리소스가 생성될 때까지 기다리지 않습니다. 이렇게 하면 두 리소스 간에 암시적 종속 항목 선언의 목적이 무효화됩니다.

다음은 권장하지 않습니다.

# Cloud Storage bucket
resource "google_storage_bucket" "bucket" {
  name = "demo-bucket"
  location = "US"
}

resource "google_storage_bucket_object" "bucket_object" {
  name   = "demo-object"
  source = "./test.txt"
  bucket = google_storage_bucket.bucket.name # name is an input argument
}

대신 google_storage_bucket_object 리소스는 google_storage_bucket_object 리소스의 id 출력 속성을 참조해야 합니다. id 필드는 출력 속성이므로 해당 리소스 생성이 실행된 후에만 값이 설정됩니다. 따라서 Terraform은 google_storage_bucket_object 리소스 생성을 시작하기 전에 google_storage_bucket_object 리소스 생성이 완료될 때까지 기다립니다.

다음을 권장합니다.

resource "google_storage_bucket_object" "bucket_object" {
  name   = "demo-object"
  source = "./test.txt"
  bucket = google_storage_bucket.bucket.id # id is an output attribute
}

참조할 명백한 출력 속성이 없는 경우가 있습니다. 예를 들어 module_a가 생성된 파일의 이름을 입력으로 사용하는 다음 예시를 생각해 보세요. module_a 내에서 파일 이름은 파일을 읽는 데 사용됩니다. 이 코드를 그대로 실행하면 no such file or directory 예외가 발생합니다. 이는 Terraform이 아직 파일이 생성되지 않은 계획 단계에서 파일을 읽으려고 시도하기 때문에 발생합니다. 이 경우 local_file 리소스의 출력 속성을 살펴보면 파일 이름 입력 인수 대신 사용할 수 있는 명백한 필드가 없다는 것을 알 수 있습니다.

다음은 권장하지 않습니다.

resource "local_file" "generated_file" {
 filename = "./generated_file.text"
 content = templatefile("./template.tftpl", {
   project_id = var.project_id
 })
}

module "module_a" {
 source = "./modules/module-a"
 root_config_file_path = local_file.generated_file.filename
}

이 문제는 명시적 종속 항목을 도입하여 해결할 수 있습니다. 명시적 종속 항목이 필요한 이유에 대한 주석을 추가하는 것이 좋습니다.

다음을 권장합니다.

module "module_a" {
 source = "./modules/module-a"
 root_config_file_path = local_file.generated_file.filename
 depends_on = [local_file.generated_file] # waiting for generated_file to be created
}

다음 단계