如何在运行时创建新策略并将其附加到角色而不对代码资源中的 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)
}
))
}
查看此类模块的人无法知道它需要什么,并且会完全依赖输入变量。也许这适合您的用例,但我建议不要这样做。
如果您接受实际上不会改变的硬编码,您的同事,包括您未来的自己,将会感谢您。
我正在尝试创建一些具有特定角色的服务用户。我不想为我的服务角色硬编码政策文件。
示例:
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)
}
))
}
查看此类模块的人无法知道它需要什么,并且会完全依赖输入变量。也许这适合您的用例,但我建议不要这样做。
如果您接受实际上不会改变的硬编码,您的同事,包括您未来的自己,将会感谢您。