Open12
Terraform の removed ブロックと import ブロックでリソースの管理単位(state)を分離する
背景
- ライフサイクルの異なる一部のリソースを別の state で管理したい
- 具体的には、サービスを提供するために必要なリソース(「サービス用リソース」)と、そのサービスをメンテナンス作業のために一時的に必要なリソース(「メンテ用リソース」)が1つの state に同居している状況だった。
- メンテ用リソースの更新頻度は低いが、サービス用リソースの方は比較的更新頻度は高い。
- Terraform Cloud で GitHub と VCS 連携 ( デフォルトブランチへのマージで Apply ) している
作業方針
- サービス用リソースの state からメンテ用リソースを削除する
- メンテ用リソースを管理する workspace を用意する
- メンテ用リソースの state に既存リソースを import する
removed
ブロックの使い方をざっくり確認する
公式ドキュメント
ほか参考ページ
from で state から削除する対象リソースのアドレスを指して、 lifecycle では実際のリソースを削除するかどうかを指定する。( false
ならリソースは削除しない )
removed {
from = aws_instance.example
lifecycle {
destroy = false
}
}
対象がモジュールの場合、 from がその対象のモジュールを指す
-module {
- src = "../modules/example"
-}
+removed {
+ from = module.example
+
+ lifecycle {
+ destroy = false
+ }
+}
removed でリソースを削除する
まずは、removed で対象リソースを Terraform の管理から外す。( apply まで実行する )
(TBD)
import 先となる workspace を用意する
(TBD)
import ブロックでリソースの現在の state を Terraform に import する
旧 workspace からリーソースが切り離し移動先となる workspace が用意できたら、今度は対象リソースを新しい workspace に import する。
terraform plan
を実行して差分を確認する
# module.hoge.aws_instance.fuga will be created
+ resource "aws_iam_role" "fuga" {
... ( 略 ) ...
上記のようにリソースを作成 (create) する plan が出てくるので、これらが import するべきリソースを指している
plan を参考に root モジュールに import ブロックを記述していく
import {
id = ""
to = module.hoge.aws_iam_role.fuga
}
-
to
は{resource address} will be created
の{resouce address}
の部分 -
id
は対象のリソースタイプによって異なるので、都度 Provider のドキュメントを確認する- 上の例だと aws_instance のページで import の項目を参照する
-
to import instances using the 'id'
と書いてあるので、リソースのid
の値を記述する、ものによってはname
だったり IP アドレスだったりするので注意すること
次に plan を実行したときに以下のように will be imported
になっているとOK
# module.hoge.aws_instance.fuga will be imported
+ resource "aws_iam_role" "fuga" {
... ( 略 ) ...
一部のリソースは import でリソースの作り直し ( delete & create ) となるケースもある。
自分のケースだと keypair とそれに紐づく EC2 instance がそうだった