1. 概要
ignore_changesを使う目的と注意点- 「all」指定の危険性
ignore_changesが効かないケース- 正しい使い方とアンチパターン
ignore_changesは「Terraformの管理外で変更された属性を無視する」ためのメタ引数です。便利ですが、使い方を誤るとTerraformが変更を検知しなくなり、意図しない設定のドリフトが発生します。
2. ignore_changes の基本
terraform {
required_version = ">= 1.9"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
variable "environment" {
description = "環境名"
type = string
default = "dev"
}
data "aws_ami" "amazon_linux_2023" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
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 {
# AMIが変わっても既存インスタンスを維持する
ignore_changes = [ami]
}
tags = {
Name = "${var.environment}-web"
Environment = var.environment
ManagedBy = "terraform"
}
}
3. ignore_changes = all の危険性
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 {
# ❌ 危険: すべての変更をTerraformが無視する
# → Terraformでのコード変更が一切反映されない
# → セキュリティ設定の変更も反映されない
ignore_changes = all
}
tags = {
Name = "${var.environment}-web"
Environment = var.environment
ManagedBy = "terraform"
}
}
ignore_changes = allは「一時的な回避策」として使っても、実質的にTerraformでリソースを管理しないのと同じ状態になります。使用する場合はコメントで理由を明記し、計画的に外します。
4. ignore_changesが効かないケース
# ⚠️ ignore_changesは「更新(update in-place)」には効くが
# 「置換(destroy then create)」には効かない場合がある
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 {
ignore_changes = [instance_type]
# ↑ instance_typeをignoreしても、AMI変更(forces replacement)には無力
}
tags = {
Name = "${var.environment}-web"
Environment = var.environment
ManagedBy = "terraform"
}
}
5. 正しい使いどころ
# ✅ 有効な使いどころ1: Auto Scalingでインスタンス数が外から変わる
resource "aws_autoscaling_group" "web" {
min_size = 1
max_size = 10
desired_capacity = 2
# desired_capacityはAuto Scalingポリシーが変更するため無視
lifecycle {
ignore_changes = [desired_capacity]
}
tag {
key = "Name"
value = "${var.environment}-web-asg"
propagate_at_launch = true
}
tag {
key = "Environment"
value = var.environment
propagate_at_launch = true
}
tag {
key = "ManagedBy"
value = "terraform"
propagate_at_launch = true
}
}
# ✅ 有効な使いどころ2: 外部ツールが変更するタグを無視
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 {
# コスト管理ツールが自動追加するタグを無視
ignore_changes = [
tags["LastScanned"],
tags["PatchStatus"],
]
}
tags = {
Name = "${var.environment}-web"
Environment = var.environment
ManagedBy = "terraform"
}
}
6. ignore_changes のアンチパターン
| アンチパターン | 問題 | 代替案 |
|---|---|---|
ignore_changes = all | すべての変更を無視 | 具体的な属性を指定する |
| 管理すべき属性を永続的に無視 | ドリフトを検知できない | 問題を根本解決する |
| デバッグ中に追加したまま忘れる | 意図しない設定が永続化 | 解決後に必ず削除する |
7. 関連記事
- lifecycle メタ引数 — ignore_changes・create_before_destroy・prevent_destroy
- err_unintended_replace — 意図しない置換 — 置換を防ぐ方法
- ephemeral変数 — stateに残さない機密値 — パスワード管理の代替策
- よくあるエラー集 — common_errors — 他のエラー一覧
- sensitive変数 — 機密値のマスクとstate記録
- replace_triggered_by — 依存リソースの変更で置換
8. まとめ
ignore_changesはTerraform管理外で変更される属性(Auto Scalingのdesired_capacity・外部ツールのタグ)に使うignore_changes = allはすべての変更を無視し、実質的にTerraform管理外になる(危険)- 置換(forces replacement)には
ignore_changesは効かない - 使用する際は必ずコメントで理由を書き、不要になったら削除する
- 根本的にはドリフトを許容せず、Terraform以外がリソースを変更しない設計を目指す
動作確認バージョン: Terraform >= 1.9 公式ドキュメント: https://developer.hashicorp.com/terraform/language/resources/lifecycle#ignore_changes