🛕

これだけ押さえる!Terraformで一時的にリソースを管理対象外にする手順(for_each版)

2024/08/08に公開

概要

Terraformで一時的に特定のリソースを管理対象外にし、予期せぬ変更の適用を除外するための、対象リソースがfor_eachを使っている場合の実施手順。
通常版は、これだけ押さえる!Terraformで一時的にリソースを管理対象外にする手順に書いています。

手順

今回、Slackチャンネル構成のリソース・スキーマであるaws_ram_principal_association(ローカル名: ram_principal)を例に操作していきます。

(1) 初期化

まず、作業ディレクトリを初期化して、リモートの変更等を取り込みます。

実行コマンド
terraform init

(2) 管理対象外としたいリソースのstateを検索

まずは、管理対象外としたいリソースのstateを検索します。
今回、for_eachを使った以下のようなリソースが対象であるものとします。

ram.tf
resource "aws_ram_principal_association" "ram_principal" {
  for_each           = var.principals
  principal          = each.value
  resource_share_arn = aws_ram_resource_share.ram_resource_share.arn
}

出力結果は(3)以降で使うので、しっかりメモしておきましょう。

実行コマンド
# state全て
terraform state list
# リソース・タイプで絞り込む場合
terraform state list | grep aws_ram_principal_association

※以下、コンソール出力結果(resourceで絞り込んだ場合)

コンソール出力結果
module.ram.aws_ram_principal_association.ram_principal["123456789012"]
module.ram.aws_ram_principal_association.ram_principal["234567890123"]
module.ram.aws_ram_principal_association.ram_principal["345678901234"]

(3) stateの詳細確認 → ARNのメモ

(2) の出力結果を用いて、管理対象外とするstateの詳細を確認します。

実行コマンド
terraform state show 'module.ram.aws_ram_principal_association.ram_principal["123456789012"]'

以下のように、リソースブロックが出力されるので、ARN,キー(以下の結果だと、arn:aws:ram:ap-northeast-1:456789012345:resource-share/1a2345b6-7890-12cd-3d4e-567fg89h01h2,123456789012(idの部分に同じ)を控えておきます。

※以下、コンソール出力結果

コンソール出力結果
resource "aws_ram_principal_association" "ram_principal" {
    id                 = "arn:aws:ram:ap-northeast-1:456789012345:resource-share/1a2345b6-7890-12cd-3d4e-567fg89h01h2,123456789012"
    principal          = "123456789012"
    resource_share_arn = "arn:aws:ram:ap-northeast-1:456789012345:resource-share/1a2345b6-7890-12cd-3d4e-567fg89h01h2"
}

ここで、ポイントは以下の通り

通常なら不要ですが、配列形式の場合、'(シングルクォート)が必要になるのが大きなポイント。
以降の手順も同様なので、この点はしっかりおさえておきましょう!

(4) 当該stateを管理対象外に

(2) の出力結果を用いて、stateを削除します

実行コマンド
# 1要素のみ
terraform state rm 'module.ram.aws_ram_principal_association.ram_principal["123456789012"]'
# 配列まるごと
terraform state rm module.ram.aws_ram_principal_association.ram_principal

※以下、コンソール出力結果

コンソール出力結果
# 1要素削除した場合
Removed module.ram.aws_ram_principal_association.ram_principal["123456789012"]
Successfully removed 1 resource instance(s).

(5) resourceブロックをコメントアウト

tfファイルのresourceブロックの対象箇所を選択&「Ctrl + /」でコメントアウトした後、保存。
※ソースコードをGit管理していて上記でコメントアウトできない場合は、当該箇所を削除の上保存。

(6) terraform コマンドの実行

以下のコマンドを順に実行して適用したい変更を反映させます

実行コマンド
# 差分確認
terraform plan
# 適用
terraform apply -auto-approve

※ちなみに、差分がない場合は下数行に以下のように出る

コンソール出力結果
No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

(7) コメントアウトの戻し

変更適用後、(4) で作成したコメントアウトを戻します
tfファイルのresourceブロックの対象箇所を選択&「Ctrl + /」でコメントアウトを外したら、保存。

※ソースコードをGit管理していて、(4) で対象箇所を削除した場合は以下のコマンドを実行して戻す

実行コマンド
git checkout .

(8) 削除したリソースのインポート

(4) で管理対象外としたリソースをインポートして戻します。

実行コマンド
terraform import 'module.ram.aws_ram_principal_association.ram_principal["123456789012"]' arn:aws:ram:ap-northeast-1:456789012345:resource-share/1a2345b6-7890-12cd-3d4e-567fg89h01h2,123456789012

ここで、terraform importの引き数について、

  • 第1引数: (2) の出力結果
  • 第2引数: (3) で控えたARN,キー

となります。
(3) でARNを控え忘れた場合は、AWSコンソール等から確認しましょう。

ポイントは、以下の通り

終わりに

for_eachを使った記述のstateの一時的な除外とimport作業は、トラップがあって通常パターンよりタイヘンでしたが、なんとかできてよかったです。

参考

公式

その他

Discussion