depends_on 메타-인자

depends_on 메타-인자 (depends_on reference)

Terraform이 자동으로 추론할 수 없는 숨은 리소스·모듈 의존성을 명시하는 depends_on 메타-인자를 설명해 드릴게요. 리소스 생성 순서를 보장하는 데 유용하지만 최후의 수단으로만 쓰는 게 좋아요.

출처: 문서

본문

Terraform이 자동으로 추론할 수 없는 숨은 리소스·모듈 의존성을 처리하려면 depends_on 메타-인자를 사용해요. 리소스나 모듈이 다른 리소스의 동작에 의존하지만 그 리소스의 데이터를 인자에서 전혀 접근하지 않을 때만 의존성을 명시적으로 지정하면 돼요.

사용법 (Usage)

depends_on 메타-인자는 리소스 유형과 관계없이 module 블록과 모든 resource 블록에서 사용할 수 있어요. 같은 호출 모듈 안의 다른 리소스나 자식 모듈에 대한 참조 목록을 요구해요. depends_on 값은 Terraform이 리소스 관계를 알기 전에, 따라서 표현식을 안전하게 평가하기 전에 알려져 있어야 하므로 이 목록은 임의 표현식을 포함할 수 없어요.

다음 예시에서 depends_on 인자는 aws_iam_instance_profile.example 리소스에 대한 숨은 의존성을 처리하도록 Terraform에 지시해요:

resource "aws_iam_role" "example" {
  name = "example"

  # assume_role_policy는 이 예시에서는 생략. 전체 예시는 aws_iam_role 문서 참고.
  assume_role_policy = "..."
}

resource "aws_iam_instance_profile" "example" {
  # 이 표현식이 역할을 참조하므로 Terraform은 역할이 먼저 생성되어야
  # 한다는 것을 자동으로 추론함.
  role = aws_iam_role.example.name
}

resource "aws_iam_role_policy" "example" {
  name   = "example"
  role   = aws_iam_role.example.name
  policy = jsonencode({
    "Statement" = [{
      # 이 정책은 EC2 인스턴스에서 실행되는 소프트웨어가 S3 API에
      # 접근할 수 있게 해줌.
      "Action" = "s3:*",
      "Effect" = "Allow",
    }],
  })
}

resource "aws_instance" "example" {
  ami           = "ami-a1b2c3d4"
  instance_type = "t2.micro"

  # Terraform은 인스턴스 프로필이 EC2 인스턴스보다 먼저 생성되어야
  # 한다는 것을 이로부터 추론할 수 있음.
  iam_instance_profile = aws_iam_instance_profile.example

  # 그러나 이 EC2 인스턴스에서 실행되는 소프트웨어가 올바르게 부팅하기
  # 위해 S3 API에 접근해야 한다면, aws_iam_role_policy에 대한 의존성도
  # 있는데 Terraform이 이를 자동으로 추론할 수 없으므로 명시적으로
  # 선언해야 함:
  depends_on = [
    aws_iam_role_policy.example
  ]
}

처리 및 계획 결과 (Processing and planning consequences)

depends_on 메타-인자는 의존성을 선언한 객체에 대한 연산을 수행하기 전에 의존 객체의 모든 작업(read 연산 포함)을 완료하도록 Terraform에 지시해요. 의존 객체가 전체 모듈이면 depends_on은 그 모듈과 연결된 모든 리소스와 데이터 소스를 Terraform이 처리하는 순서에 영향을 줘요. 자세한 내용은 리소스 의존성 지정데이터 리소스 의존성 문서를 참고해요.

depends_on은 필요 이상으로 많은 리소스를 교체하는 더 보수적인 plan을 만들 수 있으므로 최후의 수단으로만 사용해야 해요. 예를 들어 업스트림 객체에서 어떤 변경이 일어날지 불확실하기 때문에 Terraform이 더 많은 값을 알 수 없는 "(known after apply)"로 취급할 수 있어요. 특히 모듈에 depends_on을 사용할 때 그럴 가능성이 높아요.

depends_on 대신 가능하면 표현식 참조로 의존성을 암시하는 것을 권장해요. 표현식 참조를 사용하면 Terraform이 참조가 어떤 값에서 비롯되었는지 이해하고, 업스트림 객체의 다른 부분에 계획된 변경이 있더라도 그 특정 값이 변경되지 않았다면 변경 계획을 피할 수 있어요.

지원되는 구성 (Supported constructs)

depends_on을 다음 Terraform 구성 블록에서 사용할 수 있어요: check 블록, data 블록, ephemeral 블록, module 블록, output 블록, resource 블록. 다음 스택 구성 블록에서도 사용할 수 있어요: component 블록.

예시 사용 사례 (Example use cases)

검증 중 의존성 지정 (Specify a dependency during validation)

데이터 소스가 다른 리소스에 의존하지만 그 리소스를 직접 참조하지 않을 때, check 블록 검증에 중첩된 data 블록에 depends_on 인자를 추가해요.

check 블록은 일반적인 리소스 라이프사이클 밖에서 인프라를 검증해요. check 블록 안에 data 블록을 중첩해 assert 블록에서 참조할 수 있는 정보를 가져올 수 있어요. check 블록에 중첩된 data 블록에 depends_on 인자를 추가하면 Terraform이 검증을 실행하기 전에 필요한 데이터를 가져와요.

예를 들어 웹사이트 API가 200을 반환하는지 확인하는 check를 정의하면, 웹사이트의 인프라가 아직 존재하지 않으므로 Terraform이 구성의 첫 실행에 그 check는 실패해요. depends_on 인자를 로드 밸런서 같은 리소스로 설정하면 Terraform이 웹사이트가 준비된 후에만 check를 실행하게 보장할 수 있어요. 연산을 실행할 때 Terraform은 웹사이트의 핵심 부분이 준비될 때까지 check를 평가하고 known after apply로 경고한 다음 연산을 계속해요.

하지만 이 전략은 data 블록이 depends_on 인자에 지정된 리소스를 직접 참조하지 않을 때만 작동해요. 그렇지 않으면 그 리소스가 변경될 때마다 check 블록이 Terraform이 그 리소스를 업데이트할 때까지 known after apply로 경고해서, check가 잡음이 많고 비효과적일 수 있어요.

다음 예시에서 Terraform은 aws_db_instance.main 데이터베이스를 만들 때까지 check 실행을 기다려요. Terraform은 데이터베이스 생성을 마칠 때까지 거짓 경고를 출력하는 대신 known after apply를 출력해요:

check "database_connection" {
 data "postgresql_database" "app_db" {
   name       = "application"
   depends_on = [aws_db_instance.main]
 }

 assert {
   condition     = data.postgresql_database.app_db.allow_connections
   error_message = "Database is not accepting connections"
 }
}

다른 서비스가 의존하는 데이터베이스 서비스 만들기

다음 예시에서 Terraform은 aws_instance가 연결할 수 있도록 aws_db_instance 서비스를 먼저 시작해야 해요:

provider "aws" {
  region = "us-east-2"
}

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

resource "aws_db_instance" "api" {
  allocated_storage   = 10
  db_name             = "api_db"
  engine              = "postgres"
  engine_version      = "17.4"
  instance_class      = "db.t3.micro"
  username            = "foo"
  password            = "foobarbaz"
  skip_final_snapshot = true
}

resource "aws_instance" "api" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"

  depends_on = [aws_db_instance.api]
}

부모 모듈에 대한 의존성 지정 (Specify a dependency on the parent module)

다음 예시에서 Terraform은 S3 버킷 리소스를 만든 후에만 EC2 인스턴스 모듈을 만들어요:

resource "aws_s3_bucket" "example" {
  bucket = "my-example-bucket-12345"
}

module "ec2_instance" {
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "6.0.2"
  name    = "example-instance"
  ami           = data.aws_ami.latest_amazon_linux.id
  instance_type = "t2.micro"

  depends_on = [aws_s3_bucket.example]
}

값을 출력할 때 의존성 지정 (Specify a dependency when outputting values)

다음 예시에서 instance_ip_addr는 IP 주소를 노출하기 전에 Terraform이 보안 그룹을 만들도록 보안 그룹 규칙에 명시적 의존성을 추가해요:

output "instance_ip_addr" {
  value       = aws_instance.server.private_ip
  description = "The private IP address of the main server instance."

  depends_on = [
    # 보안 그룹 규칙이 이 IP 주소를 노출하기 전에 생성되지 않으면
    # 서비스에 접근할 수 없음.
    aws_security_group_rule.local_access,
  ]
}

output 블록은 보통 명시적 의존성을 요구하지 않으므로, 명시적 의존성을 추가할 때는 왜 필요한지 설명하는 주석을 포함하는 것을 권장해요.

더 알아보기 (Learn more)