replace_triggered_by — 依存リソースの変更で置換

1. 概要

  • replace_triggered_byとは
  • 依存するリソースが変更されたときに強制的に置換する
  • depends_onとの違い
  • 実際のユースケース

replace_triggered_bylifecycleブロック内で使うメタ引数です。指定したリソースや値が変更されたときに、そのリソース自身を強制的に置換(削除→再作成)します。通常の依存関係では「更新」になるところを、強制的に「再作成」にしたい場合に使います。


2. 基本的な使い方

resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"

  lifecycle {
    # aws_launch_template.appが変更されたとき、このインスタンスを強制的に置換する
    replace_triggered_by = [aws_launch_template.app]
  }
}

3. 実践例: 起動テンプレートの変更でEC2を置換する

terraform {
  required_version = ">= 1.2"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

variable "environment" {
  description = "環境名"
  type        = string
  default     = "dev"
}

variable "app_version" {
  description = "アプリケーションバージョン"
  type        = string
  default     = "1.0.0"
}

data "aws_ami" "amazon_linux_2023" {
  most_recent = true
  owners      = ["amazon"]
  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

# 起動テンプレート(app_versionが変わると更新される)
resource "aws_launch_template" "app" {
  name_prefix   = "${var.environment}-app-"
  image_id      = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"

  user_data = base64encode(<<-EOT
    #!/bin/bash
    echo "VERSION=${var.app_version}" > /etc/app-version
  EOT
  )

  tag_specifications {
    resource_type = "instance"
    tags = {
      Name        = "${var.environment}-app"
      Version     = var.app_version
      Environment = var.environment
      ManagedBy   = "terraform"
    }
  }

  lifecycle {
    create_before_destroy = true
  }
}

# EC2インスタンス
resource "aws_instance" "app" {
  launch_template {
    id      = aws_launch_template.app.id
    version = aws_launch_template.app.latest_version
  }

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true
  }

  lifecycle {
    # 起動テンプレートが更新されたら、このインスタンスを強制置換
    replace_triggered_by = [
      aws_launch_template.app.id,
      aws_launch_template.app.latest_version
    ]
  }

  tags = {
    Name        = "${var.environment}-app"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

4. 変数の変更でも置換できる

variable "deployment_id" {
  description = "デプロイID(変更するとリソースを強制置換)"
  type        = string
  default     = "v1"
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.micro"

  root_block_device {
    volume_size = 20
    volume_type = "gp3"
    encrypted   = true
  }

  lifecycle {
    # deployment_idの値が変わるたびにインスタンスを置換する
    replace_triggered_by = [terraform_data.deployment_trigger]
  }

  tags = {
    Name        = "${var.environment}-web"
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

resource "terraform_data" "deployment_trigger" {
  input = var.deployment_id
}

5. depends_onとの違い

比較depends_onreplace_triggered_by
動作依存リソースの後に作成・更新依存リソースの変更時に強制置換
変更時の挙動更新(in-place)の場合あり常に削除→再作成
用途実行順序の制御強制的な置換のトリガー

6. 関連記事


7. まとめ

  • replace_triggered_by(Terraform 1.2+)は指定したリソースや値が変わったときに強制的に置換する
  • 起動テンプレートの新バージョンでEC2を強制置換・デプロイIDで再起動のトリガーなどに使う
  • depends_onは「順序の制御」、replace_triggered_byは「強制置換のトリガー」
  • terraform_dataリソースと組み合わせると任意の変数変更でトリガーできる

動作確認バージョン: Terraform >= 1.2 公式ドキュメント: https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle#replace_triggered_by