我想将一个预先存在的 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 进行硬编码是"正确"的方法?
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}"
}
当使用Terraform本身不直接管理的值时,您有几个选择。
第一个也是最简单的选项是像此处所做的那样对值进行硬编码。如果您期望值永远不会改变,这是一个直截了当的答案。鉴于这些"预制策略"已记录在案,内置 AWS 功能可能符合此标准。
第二个选项是创建一个 Terraform 模块并将值硬编码到该模块中,然后从其他几个模块引用此模块。这使您可以集中管理值并多次使用它。仅包含输出的模块是此类事情的常见模式,尽管您也可以选择创建一个包含aws_iam_role_policy_attachment
资源的模块,该模块具有从变量设置的角色。
第三个选项是将值放置在 Terraform 可以从中检索值的某个位置(如 Consul(,然后使用数据源从该位置检索它。由于只有 Terraform 在发挥作用,这最终在很大程度上等同于第二个选项,尽管这意味着 Terraform 将在每次刷新时重新读取它,而不是仅在您使用terraform init -upgrade
更新模块时重新读取它,因此对于经常更改的值来说,这可能是一个更好的选择。
第四个选项是使用可以直接从事实来源读取值的专用数据源。Terraform 目前没有用于获取有关 AWS 托管策略的信息的数据源,因此这不是您当前情况的选项,但可用于获取其他 AWS 定义的数据,例如 AWS IP 地址范围、服务 ARN 等。
其中哪一种适合给定情况将取决于值更改的频率、管理更改的人员以及专用 Terraform 数据源的可用性。
我遇到了类似的情况,我不想在我的terraform
脚本中使用arn
,原因有两个,
- 如果我们在 Web 控制台上执行此操作,我们并没有真正查看
arn
,我们搜索角色名称,然后将其附加到角色 arn
不容易记住,看起来不适合人类
我宁愿使用策略名称,而不是arn
,这是我的示例
# Get the policy by name
data "aws_iam_policy" "required-policy" {
name = "AmazonS3FullAccess"
}
# Create the role
resource "aws_iam_role" "system-role" {
name = "data-stream-system-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Sid = ""
Principal = {
Service = "ec2.amazonaws.com"
}
},
]
})
}
# Attach the policy to the role
resource "aws_iam_role_policy_attachment" "attach-s3" {
role = aws_iam_role.system-role.name
policy_arn = data.aws_iam_policy.required-policy.arn
}