IAMポリシーの「JSON地獄」を浄化せよ:Terraformで構築する型安全なIaCの極意
TerraformでIAMポリシーを管理しているとき、ヒアドキュメント(`< `aws_iam_policy` リソースの中でJSONを直書きするのは、現代のインフラ管理において「技術的負債の先払い」でしかない。 これらを解決するための「二つの武器」を紹介する。 — Terraformの `data “aws_iam_policy_document”` は、JSONの構造を「Terraformのコード」として抽象化するデータソースだ。 IAMポリシーを論理的に分割し、データソースとして管理するのがSREの流儀である。 data/iam_policies.tf actions = [ resources = [ resource “aws_iam_policy” “s3_reader” { なぜこれが神なのか? — 「環境ごとにポリシーを微妙に変えたい」という要件に直面したとき、`data` ソースだけでは力不足になることがある。ここで `jsonencode()` の出番だ。 変数をMapで定義し、条件に応じて動的にStatementを構築する。 locals { # 動的なステートメント構築 resource “aws_iam_policy” “dynamic_policy” { この手法を使えば、無理やり `concat()` や `flatten()` を使わずに、クリーンなロジックでポリシーを制御できる。 — どれほど優れたコードも、タイピングが遅ければ意味がない。 1. ポリシーは必ず `data` ソース化する: ベタ書きJSONはPRレビューを通さない。 — IAMポリシーは、クラウドインフラにおける「憲法」だ。これを可読性の低いヒアドキュメントで放置することは、将来の自分とチームに対する冒涜に等しい。 `aws_iam_policy_document` を使い、型安全に、そして論理的にポリシーを記述する。この小さな積み重ねが、障害発生時の切り分け速度を劇的に高め、あなたのチームを「運用に追われるチーム」から「設計を楽しむチーム」へと変貌させる。 今日から、JSON地獄を卒業しよう。あなたのインフラは、もっと美しくなれるはずだ。
2. aws_iam_policy_document:型安全という名の救済
実践:ベストプラクティス構成
data “aws_iam_policy_document” “s3_read_only” {
statement {
sid = “AllowS3Read”
effect = “Allow”
“s3:Get”,
“s3:List”,
]
“arn:aws:s3:::my-secure-bucket”,
“arn:aws:s3:::my-secure-bucket/”,
]
}
}
name = “S3ReadOnlyPolicy”
# jsonencodeを噛ませる必要すらなくなる
policy = data.aws_iam_policy_document.s3_read_only.json
}
1. シンタックスハイライト: エディタが正しく構文を認識する。
2. 型チェック: `actions` に存在しないアクションを記述すると、Terraformがエラーを吐く(AWSプロバイダとの連携による)。
3. Diffの透明性: `sid` を振ることで、ポリシーのどのブロックが変更されたのかがTerraformのPlan上で明確になる。3. jsonencodeと動的生成:複雑な条件分岐の突破口
テクニック:環境別動的ポリシー生成
is_prod = terraform.workspace == “prod”
dynamic_statements = [
{
Effect = “Allow”
Action = [“kms:Decrypt”]
Resource = [var.kms_key_arn]
},
# 本番環境のみ追加の権限を付与
local.is_prod ? {
Effect = “Deny”
Action = [“s3:DeleteBucket”]
Resource = [“”]
} : null
]
}
name = “DynamicPolicy”
policy = jsonencode({
Version = “2012-10-17”
Statement = compact(local.dynamic_statements) # nullを除外して生成
})
}4. プロの現場で生産性を爆上げする環境設定
推奨ツール・設定
チーム開発のルール(マニフェスト)
2. `sid` を強制する: 誰が見ても何の権限かわかるように記述する。
3. ポリシーの分割: 1つのJSONに全て詰め込まず、機能単位(S3用、KMS用など)でデータソースを分ける。最後に:コードは「読み手」のために書く