IAM policy resource/data diff
說明 Terraform 中 aws_iam_policy resource 與 aws_iam_policy_document data source 的差異及拆分的好處。
為啥 terraform 中已經有
aws_iam_policyresource 了,還會需要有aws_iam_policy_documentdata source?
Resource 和 Data Source 本質上的差異
- Resource 會對資源進行新增、刪除、修改
- Data Source 並不會建立新資源,而是生成或查詢現有的資料。因此
aws_iam_policy_documentdata source 只是幫我們組裝出一個 json 文件,並不會新增資源
為什麼要這樣設計?
在 AWS 中,IAM Policy 本質上是一段 JSON。直接手寫 JSON 的缺點是:
- 可讀性差
- 容易出錯(特別是 ARN 拼錯或 JSON 格式錯誤)
- 難以模組化(尤其在多環境、多專案共用時)
因此 Terraform 提供 aws_iam_policy_document data source,用 HCL 語法來描述,最後會輸出一個 JSON 字串給其他資源引用。
data "aws_iam_policy_document" "example" {
statement {
actions = ["s3:ListBucket"]
resources = ["arn:aws:s3:::my-bucket"]
}
}
這段只是在 Terraform 執行期 生成 JSON,通常會再丟給 aws_iam_policy (resource) 或 aws_iam_role_policy 等去使用。
resource "aws_iam_policy" "example" {
name = "example"
policy = data.aws_iam_policy_document.example.json
}
這個才是真正的 AWS IAM Policy 資源。它需要一段 JSON 作為 policy 參數,所以可以選擇:
- 手動寫 JSON(容易出錯)
- 用
aws_iam_policy_document生成 JSON(更乾淨、安全)
這樣的拆分有幾個好處:
- 單一職責:生成 JSON 與操作 API 分開,邏輯更清晰
- 可重複利用:一份 policy document 可以被不同資源引用,而不必重複手寫 JSON
- 抽象化:開發者不用直接面對易錯的 JSON,而是用 HCL block 描述規則
- 靈活性:有些情況不需要獨立的 policy 資源,而是 inline policy(例如
aws_iam_role_policy),此時還是能透過aws_iam_policy_document來產生 JSON