我看过几个链接,但我必须看一个例子。 我有:
resource "aws_iam_role" "role" {
name = "role"
assume_role_policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1590217939125",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::wwe"
},
{
"Sid": "Stmt1590217939125",
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::wwe/*"
},
{
"Sid": "Stmt1577967806846",
"Action": [
"secretsmanager:DescribeSecret",
"secretsmanager:GetRandomPassword",
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecretVersionIds",
"secretsmanager:ListSecrets"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
tags = {
Name = wwe
Environment = STAGE
}
}
在制作时
terraform apply
我看到了:
# aws_iam_role.role will be created
+ resource "aws_iam_role" "role" {
+ arn = (known after apply)
+ assume_role_policy = jsonencode(
{
+ Statement = [
+ {
+ Action = "s3:*"
+ Effect = "Allow"
+ Resource = "arn:aws:s3:::wwe"
+ Sid = "Stmt1590217939125"
},
+ {
+ Action = "s3:*"
+ Effect = "Allow"
+ Resource = "arn:aws:s3:::wwe/*"
+ Sid = "Stmt1590217939125"
},
+ {
+ Action = [
+ "secretsmanager:DescribeSecret",
+ "secretsmanager:GetRandomPassword",
+ "secretsmanager:GetResourcePolicy",
+ "secretsmanager:GetSecretValue",
+ "secretsmanager:ListSecretVersionIds",
+ "secretsmanager:ListSecrets",
]
+ Effect = "Allow"
+ Resource = "*"
+ Sid = "Stmt1577967806846"
},
]
+ Version = "2012-10-17"
}
)
+ create_date = (known after apply)
+ force_detach_policies = false
+ id = (known after apply)
+ max_session_duration = 3600
+ name = "role"
+ path = "/"
+ tags = {
+ "Environment" = "STAGE"
+ "Name" = "wwe"
}
+ unique_id = (known after apply)
}
之后,当我写yes
时,我看到:
Error: Error creating IAM Role role: MalformedPolicyDocument: Has prohibited field Resource
status code: 400
我在哪里出错?请不要发布指向相同问题的链接。我不明白,如果有错误,请问您有没有错误的例子? 感谢您的关注。
答案 0 :(得分:1)
一个问题是,您有两个带有 Sid 相同的语句:ExpressionMethodAttribute
。
Sid必须为唯一。来自docs:
在IAM中,JSON策略中的Sid值必须唯一。
第二个问题是Stmt1590217939125
用于信任策略。信任策略没有资源。它们具有不同的形式。对于instance:
assume_role_policy
要将策略添加到角色,必须使用aws_iam_role_policy_attachment。例如,您可以这样做:
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
答案 1 :(得分:1)
aws_iam_role resource的 assume_role_policy 属性不是用于授予对除 sts:AssumeRole 以外的调用API的权限:
assume_role_policy-(必填)该策略授予实体承担角色的权限。
注意:此假定_角色_策略与标准IAM策略非常相似,但略有不同,并且不能使用aws_iam_policy资源。但是,它可以使用aws_iam_policy_document数据源,有关如何工作的信息,请参见下面的示例。
因此,假设您希望该角色可由EC2承担,则可以使用 aws_iam_role 声明IAM角色及其 assume_role_policy :
resource "aws_iam_role" "role" {
name = "role"
assume_role_policy = <<-EOF
EOF
tags = {
Name = wwe
Environment = STAGE
}
}
然后使用 aws_iam_role_policy 将内联策略附加到您希望授予该角色的IAM操作上(以及资源和可能的条件):
resource "aws_iam_role_policy" "policy" {
name = "policy"
role = aws_iam_role.role.id
policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::wwe"
},
{
"Action": "s3:*",
"Effect": "Allow",
"Resource": "arn:aws:s3:::wwe/*"
},
{
"Action": [
"secretsmanager:DescribeSecret",
"secretsmanager:GetRandomPassword",
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecretVersionIds",
"secretsmanager:ListSecrets"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
您无需将JSON留在空白处,可以缩进JSON以提高可读性:
Terraform还接受由<<-序列引入的indented heredoc string变体:
block { value = <<-EOT hello world EOT }
我建议使用aws_iam_policy_document数据源来构建IAM策略。它避免了令人讨厌的JSON怪异现象(例如没有结尾的逗号),并更好地支持了您需要在构建策略时使用变量的情况(在所有情况下都很难正确地逃避它们):
resource "aws_iam_role_policy" "policy" {
name = "policy"
policy = data.aws_iam_policy_document.policy_doc.json
}
data "aws_iam_policy_document" "policy_doc" {
statement {
actions = [
"s3:*",
]
resources = [
"arn:aws:s3:::wwe",
]
}
statement {
actions = [
"s3:*",
]
resources = [
"arn:aws:s3:::wwe/*",
]
}
statement {
actions = [
"secretsmanager:DescribeSecret",
"secretsmanager:GetRandomPassword",
"secretsmanager:GetResourcePolicy",
"secretsmanager:GetSecretValue",
"secretsmanager:ListSecretVersionIds",
"secretsmanager:ListSecrets",
]
resources = [
"*",
]
}
}