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


76

我想将一个预先存在的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进行硬编码是“正确”的方式?


7
是的,具有预先存在的AWS托管角色的铁杆是正确的方法,否则,您可以定义类似的策略并将其附加。
宝马

Answers:


115

IAM策略的数据源是为这个伟大的。数据资源用于描述不是由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}"
}

1
有一些service-linked作用,例如,示例是arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole。已经有人提出了功能请求:github.com/terraform-providers/terraform-provider-aws/issues/…–
比尔(Bill)

1
您可以将ARN放在只有一个块的附件行中:resource“ aws_iam_role_policy_attachment”“ sto-readonly-role-policy-attach” {角色=“ $ {aws_iam_role.sto-test-role.name}” policy_arn =“ arn:aws:iam :: aws:policy / ReadOnlyAccess“}
Arcones

1
我可以确认它与AWSLambdaVPCAccessExecutionRole
Daniel

1
您能否解释一下为什么这比将arn硬编码更好aws_iam_role_policy_attachment?在这两种情况下都可以对其进行硬编码。
IkarPohorský20年

3
@IkarPohorský它对您的基础结构没有任何影响,但对基于terraform之上构建的工具的影响却有所不同。如果创建数据对象,则依赖关系会与所有其他资源一起以Terraform形式进行跟踪。在内部,terraform正在构建您的基础架构图。您可以使用来转储该图terraform graph。如果将数据对象作为数据依赖项进行跟踪,则会在输出中看到该数据对象,但是如果您对字符串进行硬编码,则不会看到该数据对象。如果安装了GraphViz,请使用进行可视化terraform graph | dot -Tsvg > graph.svg
jorelli

14

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

第一个最简单的选择是像在此一样对值进行硬编码。如果您希望该值永远不变,这是一个简单的答案。鉴于已记录了这些“罐头策略”,内置的AWS功能可能符合此条件。

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

第三种选择是将值放置在Terraform可以从中检索值的某个位置(例如Consul),然后使用数据源从那里检索值。仅在使用Terraform时,这最终基本上等同于第二个选项,尽管这意味着Terraform将在每次刷新时重新读取它,而不是仅在使用来更新模块时重新读取它terraform init -upgrade,因此对于值经常改变。

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

对于给定的情况,哪种方法合适,将取决于值的更改频率,由谁来管理更改,以及特定Terraform数据源的可用性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.