Terraform:将 AWS 托管策略附加到角色的正确方法?

Posted

技术标签:

【中文标题】Terraform:将 AWS 托管策略附加到角色的正确方法?【英文标题】:Terraform: correct way to attach AWS managed policies to a role? 【发布时间】:2017-12-13 14:41:37 【问题描述】:

我想将预先存在的 AWS 托管角色之一附加到策略中,这是我当前的代码:

resource "aws_iam_role_policy_attachment" "sto-readonly-role-policy-attach" 
  role       = "$aws_iam_role.sto-test-role.name"
  policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"

是否有更好的方法来对托管策略进行建模然后引用它而不是硬编码 ARN?似乎每当我对 ARN/路径或其他类似的东西进行硬编码时,我通常会在以后发现有更好的方法。

Terraform 中是否已经存在对托管策略进行建模的东西?还是对 ARN 进行硬编码是“正确”的做法?

【问题讨论】:

是的,具有预先存在的 AWS 托管角色的核心是正确的方法,否则,您可以定义类似的策略并附加它。 【参考方案1】:

IAM Policy data source 非常适合这个。数据资源用于描述未被 Terraform 主动管理但被 Terraform 引用的数据或资源。

对于您的示例,您将为托管策略创建一个数据资源,如下所示:

data "aws_iam_policy" "ReadOnlyAccess" 
  arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"

在这种情况下,数据源的名称 ReadOnlyAccess 完全由您决定。对于托管策略,为了保持一致性,我使用与策略名称相同的名称,但如果适合您,您也可以轻松地将其命名为 readonly

然后,您将 IAM 策略附加到您的角色,如下所示:

resource "aws_iam_role_policy_attachment" "sto-readonly-role-policy-attach" 
  role       = "$aws_iam_role.sto-test-role.name"
  policy_arn = "$data.aws_iam_policy.ReadOnlyAccess.arn"

【讨论】:

有一些service-linked的角色,比如样本是arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole。有人提出了功能请求:github.com/terraform-providers/terraform-provider-aws/issues/… 您可以将 ARN 放在只有一个块用于附件的行中:resource "aws_iam_role_policy_attachment" "sto-readonly-role-policy-attach" role = "$aws_iam_role.sto-test-角色名称" policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess" 我可以确认它适用于AWSLambdaVPCAccessExecutionRole 您能解释一下为什么这比将 arn 硬编码到 aws_iam_role_policy_attachment 更好吗?您在这两种情况下都对其进行硬编码。 @IkarPohorský 它对您的基础设施没有影响,但它对构建在 terraform 之上的工具确实有影响。如果您创建数据对象,则会在 terraform 中与您的所有其他资源一起跟踪依赖关系。在内部,terraform 正在构建您的基础架构图。您可以使用terraform graph 转储此图表。如果将数据对象作为数据依赖项进行跟踪,您将在输出中看到该数据对象,但如果您对字符串进行硬编码,则不会。如果您安装了 GraphViz,请使用 terraform graph | dot -Tsvg > graph.svg 将其可视化。【参考方案2】:

当使用 Terraform 本身不直接管理的值时,您有几个选择。

第一个也是最简单的选项是像您在此处所做的那样对值进行硬编码。如果您希望该值永远不会改变,这是一个简单的答案。鉴于这些“固定策略”已记录在案,内置 AWS 功能很可能符合此标准。

第二个选项是创建一个 Terraform 模块并将值硬编码到 that 中,然后从其他几个模块中引用该模块。这使您可以集中管理价值并多次使用它。仅包含输出的模块是此类事情的常见模式,尽管您也可以选择创建一个包含 aws_iam_role_policy_attachment 资源的模块,并从变量中设置角色。

第三种选择是将值放在 Terraform 可以从中检索值的某个位置,例如 Consul,然后使用数据源从那里检索它。只有在使用 Terraform 时,这最终在很大程度上等同于第二个选项,尽管这意味着 Terraform 将在每次刷新时重新读取它,而不是仅在您使用 terraform init -upgrade 更新模块时重新读取它,因此这可能是一个更好的选择对于经常变化的价值观。

第四个选项是使用可以直接从真实来源读取值的专用数据源。 Terraform 目前没有用于获取有关 AWS 托管策略的信息的数据源,因此这不是您当前情况的选项,但可用于获取其他 AWS 定义的数据,例如 AWS IP地址范围、服务 ARN 等。

哪些适合特定情况取决于值更改的频率、管理更改的人员以及专用 Terraform 数据源的可用性。

【讨论】:

以上是关于Terraform:将 AWS 托管策略附加到角色的正确方法?的主要内容,如果未能解决你的问题,请参考以下文章

Terraform 和 AWS:修改现有策略

Terraform:附加非托管 IAM 角色

使用 terraform 创建 IAM 角色并将其附加到 EC2

如何使用 AWS API 创建内联策略

在 AWS 中使用 Terraform 创建角色,并附加 SAML 提供程序

Terraform 依赖于 aws_iam_policy