如何在运行时创建新策略并将其附加到角色而不对代码资源中的 policy_document JSON 进行硬编码?

How do I create a new policy on runtime and attach it to a role without hardcoding the policy_document JSON in code resource?

我正在尝试创建一些具有特定角色的服务用户。我不想为我的服务角色硬编码政策文件。

示例:

service-1 需要对 -EC2 实例、Cloudwatch 日志的读取权限和对 s3 存储桶的写入权限。

Service-2 需要 SNS、SQS 和 DynamoDB。

供应商=AWS

任何帮助将不胜感激。

如何在运行时创建新策略并将其附加到角色,而无需在代码资源中对 policy_document JSON 进行硬编码?

除了您的问题,还有一篇关于 HCL 语言的很棒的文档可供阅读。 https://github.com/hashicorp/hcl

据我了解你的问题,你似乎想创建一个权限模块并能够将服务名称和权限传递给它。该特定方法将允许您重用 IAM 角色创建代码。我建议你阅读 https://www.terraform.io/docs/configuration/modules.html.

您可以创建一个像 IAM Permission 这样的模块,然后做一些像

   resource "aws_iam_policy" "policy" {
 name        = "${var.service_name}"
 description = "${var.service_name} access policy"
 policy      = templatefile("${path.module}/ddb_role.tpl", {
   role            = var.role
 })
}

resource "aws_iam_role" "role" {
 name               = "role_${var.env}"
 assume_role_policy = "${file("assumerolelambdapolicy.json")}"
}

resource "aws_iam_role_policy_attachment" "policy_attachment" {
  role    = "${aws_iam_role.role.name}"
  policy_arn = "${aws_iam_policy.policy.arn}"
} 

模板文件:

{
    "Version": "2012-10-17",
    "Statement": [

     {
        "Effect": "Allow",
        "Action": ${role},
        "Resource": "*"
      }
  ]
}

var.tf 您可以存储权限列表

variable "role" {
    type = list
    default = [
 "sqs:*",
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents",
          "ec2:Describe*",
          "ec2:DescribeSecurityGroups",
          "ec2:DescribeSubnets",
          "ec2:DescribeVpcs",
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents",
          "ec2:CreateNetworkInterface",
          "ec2:DescribeNetworkInterfaces",
          "ec2:DeleteNetworkInterface"
]
}

这是您应该能够使用 tfvar 文件覆盖的内容。试试这个,让我知道。

Terraform 模块对于变化的部分具有变量。不需要改变的东西应该作为最佳实践进行硬编码。

否则,您将创建不执行任何操作并将代码作为输入的模块。

Any sufficiently complicated [dynamic Terraform module] contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of [Terraform itself]..

remix of Greenspun's tenth rule

data "aws_iam_policy_document" "assume_role_policy" {
  statement {
    sid    = "AllowAssumeRole"
    effect = "Allow"
    actions = [
      "sts:AssumeRole",
    ]
    resources = var.trusted_arns
  }
}

您可以像这样以变量的形式授予对一组 AWS 存储桶的访问权限:

  statement {
    sid    = "AllowS3Access"
    effect = "Allow"
    actions = [
      "s3:GetBucketLocation",
      "s3:ListBucket",
      "s3:ListBucketMultipartUploads",
      "s3:GetObject",
      "s3:ListMultipartUploadParts",
      "s3:AbortMultipartUpload",
    ]
    resources = var.allowed_read_only_s3_bucket_arns
  }

如果您一心想制定动态政策,您可以这样做:

data "aws_iam_policy_document" "meta_policy" {
  dynamic "statement" {
    for_each = var.statements
    content { 
      sid       = each.key
      effect    = each.value.effect
      actions   = each.value.actions
      resources = each.value.resources
    }
  }
}

将与这样的变量一起使用:

variable "statements" {
  description = "I didn't want to use resources, so I made meta-Terraform"
  type        = map(object(
    {
      sid       = string
      effect    = string
      actions   = list(string)
      resources = list(string)
    }
  ))
}

查看此类模块的人无法知道它需要什么,并且会完全依赖输入变量。也许这适合您的用例,但我建议不要这样做。

如果您接受实际上不会改变的硬编码,您的同事,包括您未来的自己,将会感谢您。