はじめに
この記事では三ヶ月ほどTerraformに触れてきた人間が、Terraformにおけるlifesycleついてまとめていく記事である。
lifesycleとは
Terraformリソースの中でライフサイクルルールを定義するために用いるものである。
対象となるリソースに記載することで、そのリソースに何か変更が発生した場合の挙動を制御することができる。
公式ドキュメントでも詳細に記載されているがこの内容をまとめていく。
現在のversionまでに4つのlifesycleが存在する。
- create_before_destroy
- prevent_destroy
- ignore_changes
- replace_triggered_by
上の四つについて説明していく。
create_before_destroy
create_before_destroyは新しいリソースを作成してから古いリソースを削除するようにするルールである。
ゼロダウンタイムの更新が必要だったりする場合に使用する。
ただし、一時的にリソースが重複するため特定の名前が被ってしまう等同時に存在できないリソースを扱う場合には注意する必要がある。
resource "aws_instance" "example" {
ami = "ami-12345"
instance_type = "t2.micro"
lifecycle {
create_before_destroy = true
}
}
prevent_destroy
prevent_destroyはリソースの破棄を防止するルールである。
terraform destroy
コマンドを行った際などにこのルールを付与しているリソースは破棄されない。
ただ、terraform経由ではない操作を防止することはできないのでその場合には別途設定が必要になる。
Production環境のリソースだったり重要なリソースの保護に用いることができる。
resource "aws_instance" "example" {
ami = "ami-12345"
instance_type = "t2.micro"
lifecycle {
prevent_destroy = true
}
}
ignore_changes
ignore_changesでは指定した属性の変更をterraformの管理対象から除外するものである。
これは外部での変更や動的な変更を許容するということであり、例えば自動スケーリングによる変更などが行われるリソースにはこのルールを適応すると良いのだと思う。
resource "aws_instance" "example" {
ami = "ami-12345"
instance_type = "t2.micro"
tags = {
Stage = "Integration"
Project = "hogehoge"
}
lifecycle {
ignore_changes = [
tags
]
}
}
ちなみに全ての属性を一括で無視したい場合にはignore_changes = all
のようにも記述することができる。
replace_triggered_by
このルールはTerraform 1.2で導入された新機能であり、指定したリソースの変更時にこのルールを記述したリソースを再作成するというものである。
resource "aws_instance" "example" {
ami = "ami-12345"
instance_type = "t2.micro"
lifecycle {
replace_triggered_by = [
aws_key_pair.example.public_key,
]
}
}
例えば上のような例だと、awsのキーペアに変更が生じた場合にaws_instance.example
は再作成が行われる。
依存関係のある設定変更の更新時や、セキュリティ更新、バージョンアップデート時の確実なリソース更新等に用いることができる。
lifesycleの組み合わせ
これらは一つしか設定できないわけではなく複数を組み合わせて設定することも可能である。
状況に応じて使い分けていい感じのインフラ管理をできるようコードを書いていこう。
resource "aws_instance" "example" {
ami = "ami-12345"
instance_type = "t2.micro"
tags = {
Stage = "Integration"
Project = "hogehoge"
}
lifecycle {
create_before_destroy = true
ignore_changes = [tags]
replace_triggered_by = [aws_key_pair.example.public_key]
}
}