movedブロック
movedブロックはTerraformのリソース名を変更するためのブロック。
既にapply済みでAWS上に作成済みのリソースの名称を変更したい場合に利用する。
以下の形式で記述する。
moved = {
from = 変更前リソース名
to = 変更後リソース名
}
この記述をapplyすると変更前リソースが削除され、変更後リソースが作成される。
リソース名はterraform state list
で確認できる。
» 参考: terraform show, terraform state show, terraform state listでリソースの情報を確認する
利用場面
リソース名を変更すると変更前リソースが削除されてしまう。
例えば以下のようなリソースがあるとする。
resource "aws_instance" "web" {
ami = "ami-xxxxxxxxxxxxxxxxx"
instance_type = "t2.micro"
...
}
上記記述をapply
後に、リソース名のweb
をweb_server
へ変更したいと考え、以下の様に変更したとする。
resource "aws_instance" "web_server" { # ← web を web_server に変更
ami = "ami-xxxxxxxxxxxxxxxxx"
instance_type = "t2.micro"
...
}
この状態でapply
すると、aws_instance.web
で作成したEC2インスタンスは一度削除され、aws_instance.web_server
のEC2インスタンスを新たに作成する。
ただ単にリネームしたいだけの場合はEC2インスタンスが落ちてしまうので稼働が一時的に止まってしまう。
実際にterraform plan
してみると以下のように1台削除(destroy)、1台作成(add)として出力される。
# aws_instance.web will be destroyed
...
# aws_instance.web_server will be created
...
Plan: 1 to add, 0 to change, 1 to destroy.
対象リソースを触らずにリソース名だけを変更したい場合にmoved
ブロックを利用する。
movedブロックの利用
上記の例では以下のようにmoved
ブロックを利用する。
(ただしmoduleではなくルート直下のリソースの場合)
moved {
from = aws_instance.web
to = aws_instance.web_server
}
terraform plan
を実行すると以下のように名前の変更だけが検出される。
# aws_instance.host has moved to aws_instance.web_server
...
Plan: 0 to add, 0 to change, 0 to destroy.
追加・削除ともに0件なのでEC2インスタンスは落ちることなくリソース名だけが変更される。
apply
後にterraform state list
を実行するとリソース名が変更されている。
$ terraform state list | grep aws_instance
aws_instance.web_server
movedブロックの作り方
Terraformの記述を変更し、movedブロックを追加する場合は一度planを実行してみるとよい。
その際、will be destroyed
とwill be created
と出力されている行にリソース名が出力されるので、それをmoved
ブロックのfrom
とto
に記述する。
$ terraform plan -no-color | grep "will be"
# aws_instance.web will be destroyed
# aws_instance.web_server will be created
上記コマンドで一覧し、destroyed
の方をfrom
、created
の方をto
に記述すればよい。
Pull Request、CI/CDを含む開発フローにおけるmovedブロックの利用
チーム開発において開発者の手元でapply
しない運用をしている場合、リソース名の変更があった場合にはmoved
ブロックを利用する。
レビューを受けてからCI/CDでapply
する、というような運用の場合は以下のような手順となる。
(例としてGitHubでPullRequestを作成し、レビューが通ったらマージ→CI/CDでapplyする場合を想定)
- リソース名を変更し、movedブロックも追加する
- Pull Requestを上げてレビューを受ける
- レビューが通ったらマージ→CI/CDでapply
- movedブロックを削除する
- Pull Requestを上げてレビューを受ける
- レビューが通ったらマージ→CI/CDでapply
以上のように、「movedブロック付きのPull Request」とapply後にさらに「movedブロックを削除したPull Request」を作成すればよい。
movedブロックはルートモジュールに書く
moved
ブロックルートモジュールの中に書く。
例えば以下のようなディレクトリ構成の場合を考える。
.
├── envorinments
│ ├── production
│ │ └── main.tf
│ └── staging
│ └── main.tf
└── modules
├── a_module
├── b_module
└── c_module
ルートモジュールがenvironments/production/main.tf
やenvironments/staging/main.tf
で、modules以下のモジュールを利用しているとする。
この構成でモジュールのほうのリソース名を変更した場合movedブロックを変更したモジュール内に書きたくなる。
その場合でもmovedブロックはルートモジュール内に書く必要がある。