ephemeral 블록 참조

ephemeral 블록 참조 (ephemeral block reference)

ephemeral 블록을 사용해 Terraform이 state나 plan 파일에 저장하지 않는 임시 리소스를 정의하세요.

출처: 문서

본문

배경 (Background)

ephemeral 블록은 현재 Terraform 작업 동안만 존재하는 임시 임시 리소스를 선언해요. Terraform은 ephemeral 리소스를 state나 plan 파일에 저장하지 않으므로, 유지하고 싶지 않은 민감하거나 임시적인 데이터(예: 임시 비밀번호나 다른 시스템과의 연결)를 관리하는 데 이상적이에요.

ephemeral 블록과 그 고유한 수명 주기 및 프로비저닝 순서에 대해 더 알아보려면 민감한 데이터 관리를 참고하세요.

수명 주기 (Lifecycle)

Ephemeral 리소스는 일반 리소스 및 데이터 소스와 비교해 고유한 수명 주기를 가져요. Terraform은 각 ephemeral 리소스에 대해 다음 수명 주기 단계를 수행해요:

  1. Terraform이 리소스의 결과에 접근해야 하면 ephemeral 리소스를 엽니다(open).
  2. Terraform이 원격 시스템의 강제 만료 시간보다 오래 리소스에 접근해야 하면 ephemeral 리소스의 프로바이더에 주기적으로 접근을 갱신(renew)하도록 요청해요.
  3. Terraform은 그 리소스에 의존하는 프로바이더가 현재 실행 단계의 작업을 마친 후 ephemeral 리소스를 닫아요(close).

예를 들어 Terraform 구성이 Vault 시크릿에 대한 ephemeral 리소스를 정의하면, Terraform은 먼저 Vault 프로바이더가 임대(lease)를 얻고 시크릿을 반환하도록 해 리소스를 엽니다. 필요하면 Terraform은 Vault의 임대 갱신 API 엔드포인트를 호출해 만료 시간을 연장해 리소스를 갱신해요. 마지막으로 Terraform은 임대를 명시적으로 종료해 리소스를 닫아 Vault가 연결된 자격 증명을 즉시 폐기하도록 해요.

프로비저닝 순서 (Order of provisioning)

Ephemeral 리소스는 Terraform의 의존성 그래프에서 노드를 형성하며 리소스 및 데이터 소스와 유사하게 상호작용해요. 리소스나 데이터 소스가 ephemeral 리소스의 속성에 의존하면 Terraform은 먼저 ephemeral 리소스를 자동으로 프로비저닝해요.

ephemeral 리소스의 입력 인자가 Terraform이 아직 모르지만 plan 중이나 plan 후에 학습할 수 있는 값을 참조하면 Terraform은 해당 리소스 실행을 apply 단계까지 미뤄요.

Ephemeral 리소스 참조

ephemeral 리소스는 특정 ephemeral 문맥에서만 참조할 수 있어요. 그렇지 않으면 Terraform은 변경 사항을 계획할 때 오류를 발생시켜요. 다음은 ephemeral 리소스를 참조할 수 있는 유효한 문맥이에요:

구성 모델 (Configuration model)

ephemeral 블록은 다음 인자를 지원해요:

완전한 구성 (Complete configuration)

다음 ephemeral 블록은 ephemeral 리소스에 설정할 수 있는 지원되는 모든 내장 인자를 정의해요:

ephemeral "<TYPE>" "<LABEL>" {
  <PROVIDER_ARGUMENTS>
  count = <NUMBER>      # `for_each` and `count` are mutually exclusive
  depends_on = [ <RESOURCE.ADDRESS.EXPRESSION> ]
  for_each = {          # `for_each` accepts a map or a set of strings
    <KEY> = <VALUE>
  }
  for_each = [          # `for_each` accepts a map or a set of strings
    "<VALUE>",
    "<VALUE>"
  ]
  provider = <REFERENCE.TO.ALIAS>
  lifecycle {
    precondition {
      condition = <EXPRESSION>
      error_message = "<STRING>"
    }
    postcondition {
      condition = <EXPRESSION>
      error_message = "<STRING>"
    }
  }
}

명세 (Specification)

ephemeral 블록은 다음 구성을 지원해요.

ephemeral "<TYPE>" "<LABEL>"

모든 ephemeral 블록에 대해 다음을 설정해야 해요:

  • TYPE: 생성할 ephemeral 리소스의 타입을 지정해요. 프로바이더 개발자가 사용 가능한 ephemeral 리소스 타입을 정의해요. 특정 ephemeral 리소스 타입에 대한 자세한 내용은 프로바이더 문서를 참고하세요.
  • LABEL: ephemeral 리소스의 이름을 지정해요. Terraform은 현재 작업 동안 리소스를 추적하는 데 이 라벨을 사용해요. 라벨은 실제 인프라 리소스의 설정에 영향을 주지 않아요. 라벨 문법 및 권장 사항은 이름 있는 값 참조리소스 명명을 참고하세요.

ephemeral.<TYPE>.<LABEL> 문법으로 ephemeral 리소스를 참조하세요.

프로바이더 특정 인자

ephemeral 리소스에 대해 정의할 수 있는 인자는 프로바이더 개발자가 결정해요. 사용 가능한 인자와 값 형식에 대한 자세한 내용은 프로바이더 문서를 참고하세요.

요약
  • 데이터 타입: 프로바이더에 따라 다양함
  • 기본값: 없음, 그러나 요구 사항은 프로바이더마다 다름
  • 필수: 프로바이더에 따라 다름

count

count 메타-인자는 Terraform이 동일하거나 유사한 구성으로 같은 ephemeral 리소스의 여러 인스턴스를 프로비저닝하도록 지시해요.

ephemeral "<TYPE>" "<LABEL>" {
  count = <number>
}

count메타-인자예요. 메타-인자는 Terraform 언어에 내장되어 있으며 Terraform이 리소스를 생성하는 방법을 제어해요. 자세한 내용은 count 참조를 참고하세요.

depends_on

depends_on 메타-인자는 ephemeral 리소스가 의존하는 업스트림 리소스를 지정해요. plan을 만들 때 Terraform은 depends_on 메타-인자로 구성된 ephemeral 리소스에 대한 작업을 수행하기 전에 업스트림 리소스의 모든 작업을 순서화해요.

ephemeral "<TYPE>" "<LABEL>" {
  depends_on = [ <resource reference> ]
}

depends_on메타-인자예요. 메타-인자는 Terraform 언어에 내장되어 있으며 Terraform이 리소스를 생성하는 방법을 제어해요. 자세한 내용은 depends_on 참조를 참고하세요.

for_each

for_each 메타-인자는 각 리소스에 대해 별도의 구성 블록을 요구하지 않고 유사한 ephemeral 리소스를 프로비저닝하도록 Terraform에 지시해요.

값 리스트키-값 쌍의 맵

ephemeral "<TYPE>" "<LABEL>" {
  for_each = [ "<VALUE>" ]
  # ...
}
ephemeral "<TYPE>" "<LABEL>" {
  for_each = {
    "<KEY>" = "<VALUE>"
  }
}

for_each메타-인자예요. 메타-인자는 Terraform 언어에 내장되어 있으며 Terraform이 리소스를 생성하는 방법을 제어해요. 자세한 내용은 for_each 참조를 참고하세요.

provider

provider 인자는 ephemeral 리소스를 프로비저닝하기 위해 대체 프로바이더 구성을 사용하도록 Terraform에 지시해요.

ephemeral "<TYPE>" "<LABEL>" {
  provider = <PROVIDER>.<ALIAS>
}

provider메타-인자예요. 메타-인자는 Terraform 언어에 내장되어 있으며 Terraform이 리소스를 생성하는 방법을 제어해요. 자세한 내용은 provider 참조를 참고하세요.

lifecycle

lifecycle 블록은 Terraform이 ephemeral 리소스에 대해 어떻게 작업하는지에 대한 수명 주기 규칙을 정의해요.

ephemeral "<TYPE>" "<LABEL>" {
  lifecycle {
    <lifecycle>
  }
}

다음 수명 주기 규칙을 지정해 ephemeral 리소스에 대한 Terraform 작업 수행 방식을 관리할 수 있어요:

  • precondition: ephemeral 리소스를 만들기 전에 Terraform이 평가하는 조건을 지정해요. 자세한 내용은 테스트 및 검증을 참고하세요.
  • postcondition: ephemeral 리소스를 만든 후 Terraform이 평가하는 조건을 지정해요. 자세한 내용은 테스트 및 검증을 참고하세요.

같은 lifecycle 블록에 preconditionpostcondition 블록을 모두 포함할 수 있고, 같은 lifecycle 블록에 여러 preconditionpostcondition 블록을 정의할 수 있어요.

lifecycle메타-인자예요. 메타-인자는 Terraform 언어에 내장되어 있으며 Terraform이 리소스를 생성하는 방법을 제어해요. 자세한 내용은 lifecycle 참조를 참고하세요.

precondition

precondition 블록은 Terraform이 ephemeral 리소스를 평가하고 작업을 수행하기 전에 true를 반환해야 하는 조건을 지정해요. 조건이 false를 반환할 때 Terraform이 출력할 오류 메시지도 지정할 수 있어요.

ephemeral "<TYPE>" "<LABEL>" {
  lifecycle {
    precondition {
      condition           = <expression>
      error_message       = "<message>"
    }
  }
}

preconditionlifecycle 메타-인자에서 사용할 수 있는 지시자예요. 메타-인자는 Terraform 언어에 내장되어 있으며 Terraform이 리소스를 생성하는 방법을 제어해요. 자세한 내용은 lifecycle 참조를 참고하세요.

postcondition

postcondition 블록은 Terraform이 ephemeral 리소스에 대한 작업을 수행한 후 true를 반환해야 하는 조건을 지정해요. 조건이 false를 반환할 때 Terraform이 콘솔에 출력할 오류 메시지도 지정할 수 있어요.

ephemeral "<TYPE>" "<LABEL>" {
  lifecycle {
    postcondition {
      condition = <expression>
      error_message = "<message>"
    }
  }
}

postconditionlifecycle 메타-인자에서 사용할 수 있는 지시자예요. 메타-인자는 Terraform 언어에 내장되어 있으며 Terraform이 리소스를 생성하는 방법을 제어해요. 자세한 내용은 lifecycle 참조를 참고하세요.

예제 (Examples)

다음 예제는 ephemeral 블록의 일반적인 사용 사례를 보여줘요.

기본 ephemeral 리소스

다음 예제에서 aws_secretsmanager_secret_version ephemeral 리소스는 PostgreSQL 프로바이더를 구성하는 자격 증명을 제공해요:

ephemeral "aws_secretsmanager_secret_version" "db_master" {
  secret_id = aws_secretsmanager_secret_version.db_password.secret_id
}

locals {
  credentials = jsondecode(ephemeral.aws_secretsmanager_secret_version.db_master.secret_string)
}

provider "postgresql" {
  host     = aws_db_instance.example.address
  port     = aws_db_instance.example.port
  username = local.credentials["username"]
  password = local.credentials["password"]
# …
}

ephemeral 리소스가 자격 증명을 처리하므로 Terraform은 이를 절대 state나 plan 파일에 저장하지 않아요. locals 블록에서 ephemeral 리소스를 참조하면 Terraform이 그 값을 state나 plan 파일에 저장하기를 원하지 않는다는 것을 직관적으로 이해하므로 locals 블록의 해당 값도 저장되지 않아요.

쓰기 전용 인자와 함께 ephemeral 값 사용

쓰기 전용 인자는 작업 중에 임시 값을 관리형 리소스에 안전하게 전달할 수 있게 해주며, 해당 리소스 값을 state나 plan 파일에 지속하지 않아요. 다음 예제에서 random_password ephemeral 리소스는 임시 비밀번호를 생성해 password_wo 쓰기 전용 인자에 전달해요:

#...

ephemeral "random_password" "db_password" {
  length           = 16
  override_special = "!#$%&*()-_=+[]{}<>:?"
}

resource "aws_db_instance" "example" {
  instance_class       = "db.t3.micro"
  allocated_storage    = "5"
  engine               = "postgres"
  username             = "example"
  skip_final_snapshot  = true
  publicly_accessible  = true
  db_subnet_group_name = aws_db_subnet_group.example.name
  password_wo          = ephemeral.random_password.db_password.result
  password_wo_version  = 1
}

쓰기 전용 인자도 ephemeral 리소스도 현재 Terraform 실행 외부에 지속되지 않으므로 ephemeral.random_password.db_password.result 값이 state와 plan 파일에서 완전히 생략되도록 보장해요.

Terraform은 ephemeral.random_password.db_password.result의 생성 값을 저장하지 않지만, 값을 잃지 않도록 다른 리소스에 캡처할 수 있어요. 임시 비밀번호를 생성, 저장, 검색, 사용하는 예제는 쓰기 전용 인자를 참고하세요.

여러 ephemeral 리소스 생성

다음 예제에서 for_each 인자는 여러 데이터베이스 환경에 대한 여러 비밀번호를 생성해요:

locals {
  environments = toset(["dev", "staging", "prod"])
}

ephemeral "random_password" "db_passwords" {
  for_each = local.environments

  length           = 16
  override_special = "!#$%&*()-_=+[]{}<>:?"
}

resource "aws_db_instance" "databases" {
  for_each = local.environments

  identifier                = "${each.key}-database-${var.environment_suffix}"
  db_name                   = "${each.key}db"
  username                  = "dbadmin"
  password_wo               = ephemeral.random_password.db_passwords[each.key].result
 # …
}

ephemeral 블록은 local.environments set의 각 환경에 대해 random_password ephemeral 리소스를 생성해요. aws_db_instance 리소스는 각 데이터베이스 인스턴스에 대해 생성된 비밀번호를 사용해요.

Terraform은 생성된 db_passwords 값을 저장하지 않지만, 값을 잃지 않도록 다른 리소스에 캡처할 수 있어요. 임시 비밀번호를 생성, 저장, 검색, 사용하는 예제는 쓰기 전용 인자를 참고하세요.

대체 프로바이더 구성 사용

다음 예제에서 ephemeral 리소스는 대체 AWS 프로바이더 구성을 사용해요:

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

provider "aws" {
  alias  = "west"
  region = "us-west-2"
}

ephemeral "aws_secretsmanager_secret_version" "db_password" {
  provider  = aws.west
  secret_id = aws_secretsmanager_secret.db_password.id
}

Terraform은 aws.west 프로바이더 구성을 사용해 us-west-2 리전에 aws_secretsmanager_secret_version 리소스를 생성해요.

Ephemeral 리소스 검증

다음 예제에서 aws_ssm_parameter ephemeral 리소스는 프로덕션 시크릿을 보호하기 위해 컴플라이언스 모드가 활성화되도록 하는 precondition과 생성된 비밀번호가 비밀번호 요구 사항을 충족하는지 확인하는 postcondition이 있어요:

variable "environment" {
  description = "Deployment environment"
  type        = string
}

variable "compliance_mode" {
  description = "Enable compliance requirements for production"
  type        = bool
  default     = false
}

ephemeral "aws_ssm_parameter" "database_password" {
  name = "/secrets/${var.environment}/database/password"

  lifecycle {
    precondition {
      condition     = var.environment != "prod" || var.compliance_mode == true
      error_message = "Enable compliance mode to assess production secrets."
    }

    postcondition {
      condition     = can(regex("^[A-Za-z0-9!@#$%^&*()_+=-]{16,}$", self.value))
      error_message = "Password from external source must meet security requirements."
    }
  }
}

더 알아보기 (Learn more)