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

Sho*_*orn 49 amazon-web-services amazon-iam terraform

我想将一个预先存在的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"
}
Run Code Online (Sandbox Code Playgroud)

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

Terraform中是否存在对托管策略建模的内容?或者硬编码ARN是"正确"的方式吗?

jor*_*lli 82

IAM策略的数据源是为这个伟大的.数据资源用于描述Terraform未主动管理但由Terraform引用的数据或资源.

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

data "aws_iam_policy" "ReadOnlyAccess" {
  arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
Run Code Online (Sandbox Code Playgroud)

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}"
}
Run Code Online (Sandbox Code Playgroud)

  • 您可以将 ARN 放在只有一个附件块的行中: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" } (3认同)
  • @IkarPohorský,它对您的基础设施没有影响,但它确实对构建在 terraform 之上的工具产生影响。如果您创建数据对象,则依赖关系将与所有其他资源一起在 terraform 中进行跟踪。在内部,Terraform 正在构建基础设施的图表。您可以使用“terraform graph”转储该图。如果数据对象作为数据依赖项进行跟踪,您将在输出中看到该数据对象,但如果您对字符串进行硬编码,则不会看到该数据对象。如果您安装了 GraphViz,请使用“terraform graph |”将其可视化。点-Tsvg > graph.svg`。 (3认同)
  • 您能否解释一下为什么这比将 arn 硬编码到“aws_iam_role_policy_attachment”更好?在这两种情况下都可以对其进行硬编码。 (2认同)

小智 14

我遇到了类似的情况,我不想arn在我的terraform脚本中使用 ,原因有两个:

  • 如果我们在 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
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ins 13

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

第一个,最简单的选择就是像在这里一样硬编码值.如果您希望该值永远不会改变,这是一个简单的答案.鉴于这些"预制策略"已记录在案,内置AWS功能可能符合此标准.

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

第三个选项是将值放在Terraform可以从中检索值的某个位置,例如Consul,然后使用数据源从那里检索它.随着游戏只Terraform,这最终在很大程度上相当于第二个选项,但它意味着Terraform将重新阅读每个刷新,而不是只有当你使用更新的模块terraform init -upgrade,因此这可能是一个更好的选择的值是经常改变.

第四种选择是使用可以直接从真实来源读取值的专用数据源.Terraform目前不具备用于获取有关AWS信息管理政策的数据源,所以这不是你的现状的一个选项,但可用于获取其他AWS定义的数据,如AWS IP地址范围,服务ARNS等.

哪种方法适用于特定情况取决于价值变化的频率,管理变更的人员以及专用Terraform数据源的可用性.