この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、岩本です。
Terraformを利用する際にある一部のリソースを変更すると、再作成となってしまう場合、
もしくは、変更を無視したい場合などがあると思います。
そこで、テンプレートのアップデートの際に、特定のリソースの変更を無視する方法です。
結論
コマンド実行時に-target=を指定する。
-target=
とは? plan/applyのオプションで、特定のリソースを指定し、適用を実施することができます。
つまり適用されるリソースは指定したもののみとなるため、それ以外は除外されます。
lifecycle を利用する。
lifecycle
とは?
対象となるリソースに記載することで、そのリソースに変更が発生する際の挙動を変更できます。lifecycle
には下記にある3通りの挙動を選択できます。-
create_before_destroy
(bool)- 既存のリソースが有った場合に、一旦削除してから作り直すようになります。
prevent_destroy
(bool)- この値があるリソースを削除しようとするとエラーになります。
ignore_changes
(list of strings)- 実際のリソースとTerraform管理下のリソースの差分があった際、指定したリソースの変更が無視される様になります。
lifecycle ignore_changes の挙動を試してみる
検証
下記のようにAMIの指定を変数で行い、2台のEC2を作成します。
variable "ec2_ami" {
default = "ami-56d4ad31"
}
resource "aws_instance" "web-ec2_01" {
ami = "${var.ec2_ami}"
instance_type = "${var.ec2_instance_type}"
key_name = "${var.ssh_keypaer_name}"
lifecycle {
ignore_changes = [
"ami",
]
}
resource "aws_instance" "web-ec2_02" {
ami = "${var.ec2_ami}"
instance_type = "${var.ec2_instance_type}"
key_name = "${var.ssh_keypaer_name}"
指定したAMIを元に2台のEC2が作成されました。
次に、AMIを変更します。
#ec2_ami = "ami-56d4ad31"
ec2_ami = "ami-1bfdb67c"
- 実行結果の確認
terraform plan
~ aws_eip.eip_web-ec2_02
instance: "i-0e4810f1a843abcca" => "${aws_instance.web-ec2_02.id}"
-/+ aws_instance.web-ec2_02
ami: "ami-56d4ad31" => "ami-1bfdb67c" (forces new resource)
...
Plan: 1 to add, 1 to change, 1 to destroy.
lifecycle
を指定したEC2はAMIの変更が無視され、指定しなかった02のみがリソース変更の対象となっています。
- 適用
terraform apply
Apply complete! Resources: 1 added, 1 changed, 1 destroyed.
実行結果の確認通りlifecycle
を指定しなかったEC2のみが再作成となりました。
まとめ
Terraformを使って、環境を構築後に環境のアップデートが発生する場合があるかと思います。
その際特にしていなくアップデートが可能なリソースもありますが、
意図しないアップデート・削除を防ぐためlifecycle
を指定することで、
より安全なAWS環境の利用ができるかと思います。