Terraform - 插值后额外字符的问题
Terraform - issue with extra caractere after interpolation
我有一个问题,我很清楚为什么
我正在尝试创建自定义策略,但收到此消息:错误:此行的插值表达式后有额外字符
{
"Effect": "Allow",
"Action": "iam:ChangePassword",
"Resource": "arn:aws:iam::766281746212:user/${aws:username}"
},
它说:
需要一个右括号来结束插值表达式,但发现了额外的
字符。
这是我的代码
resource "aws_iam_policy" "policy" {
name = "AllowManageOwnAccessKeys"
path = "/"
description = "Allow to manage Access key"
policy = <<EOF
{
Version = "2012-10-17"
"Statement": [
{
"Effect": "Allow",
"Action": "iam:GetAccountPasswordPolicy",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:ChangePassword",
"Resource": "arn:aws:iam::766281746212:user/${aws:username}"
},
{
"Sid": "AllowViewAccountInfo",
"Effect": "Allow",
"Action": "iam:ListVirtualMFADevices",
"Resource": "*"
},
{
"Sid": "AllowManageOwnVirtualMFADevice",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice",
"iam:DeleteVirtualMFADevice"
],
"Resource": "arn:aws:iam::766281746212:mfa/${aws:username}"
},
{
"Sid": "AllowManageOwnUserMFA",
"Effect": "Allow",
"Action": [
"iam:DeactivateMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "arn:aws:iam::766281746212:user/${aws:username}"
},
{
"Sid": "DenyAllExceptListedIfNoMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"sts:GetSessionToken"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
},
{
"Sid": "ManageOwnAccessKeys",
"Effect": "Allow",
"Action": [
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:GetAccessKeyLastUsed",
"iam:GetUser",
"iam:ListAccessKeys",
"iam:UpdateAccessKey"
],
"Resource": "arn:aws:iam::766281746212:user/${aws:username}"
}
]
}
EOF
}
如果有人为此提供线索,我们将不胜感激。
感谢
此错误的直接原因是 ${aws:username}
是您希望由 AWS IAM 解释为策略检查的一部分的序列,而不是由 Terraform 解释为模板评估的一部分。不幸的是,IAM 和 Terraform 都使用类似的语法进行插值,因此您需要在 Terraform 中对其进行转义,以便序列按字面意义传递给 IAM:
"Resource": "arn:aws:iam::766281746212:user/$${aws:username}"
Terraform 将 $${
理解为产生文字 ${
的转义序列,因此 Terraform 在构造要发送到AWS 提供商。然后 AWS 提供商将按原样将其发送到 IAM,允许 IAM 对其进行解释。
您的 IAM 策略中还有一个语法错误,说明您指定版本号的方式。到目前为止,这还没有出现错误,因为 Terraform 在将字符串发送到 AWS 提供商之前无法解析您的字符串,但是一旦您修复了上述问题,您可能会看到来自 AWS 提供商的另一个语法错误。要解决这个问题,您需要使用有效的 JSON 语法设置 Version
属性:
"Version": "2012-10-17",
您似乎试图在那里使用 Terraform 对象语法。可以使用 Terraform 自己的表达式语法编写 IAM 策略,然后使用 jsonencode
, and that's pretty helpful in situations where your policy will incorporate some dynamic data computed within Terraform itself, but switching to that syntax from what you have would be quite involved and not directly related to the question you asked here. If you're interested in learning more, you can see a simple example in the aws_iam_policy
documentation.
将其转换为 JSON
我有一个问题,我很清楚为什么
我正在尝试创建自定义策略,但收到此消息:错误:此行的插值表达式后有额外字符
{
"Effect": "Allow",
"Action": "iam:ChangePassword",
"Resource": "arn:aws:iam::766281746212:user/${aws:username}"
},
它说: 需要一个右括号来结束插值表达式,但发现了额外的 字符。
这是我的代码
resource "aws_iam_policy" "policy" {
name = "AllowManageOwnAccessKeys"
path = "/"
description = "Allow to manage Access key"
policy = <<EOF
{
Version = "2012-10-17"
"Statement": [
{
"Effect": "Allow",
"Action": "iam:GetAccountPasswordPolicy",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": "iam:ChangePassword",
"Resource": "arn:aws:iam::766281746212:user/${aws:username}"
},
{
"Sid": "AllowViewAccountInfo",
"Effect": "Allow",
"Action": "iam:ListVirtualMFADevices",
"Resource": "*"
},
{
"Sid": "AllowManageOwnVirtualMFADevice",
"Effect": "Allow",
"Action": [
"iam:CreateVirtualMFADevice",
"iam:DeleteVirtualMFADevice"
],
"Resource": "arn:aws:iam::766281746212:mfa/${aws:username}"
},
{
"Sid": "AllowManageOwnUserMFA",
"Effect": "Allow",
"Action": [
"iam:DeactivateMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ResyncMFADevice"
],
"Resource": "arn:aws:iam::766281746212:user/${aws:username}"
},
{
"Sid": "DenyAllExceptListedIfNoMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"sts:GetSessionToken"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
},
{
"Sid": "ManageOwnAccessKeys",
"Effect": "Allow",
"Action": [
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:GetAccessKeyLastUsed",
"iam:GetUser",
"iam:ListAccessKeys",
"iam:UpdateAccessKey"
],
"Resource": "arn:aws:iam::766281746212:user/${aws:username}"
}
]
}
EOF
}
如果有人为此提供线索,我们将不胜感激。
感谢
此错误的直接原因是 ${aws:username}
是您希望由 AWS IAM 解释为策略检查的一部分的序列,而不是由 Terraform 解释为模板评估的一部分。不幸的是,IAM 和 Terraform 都使用类似的语法进行插值,因此您需要在 Terraform 中对其进行转义,以便序列按字面意义传递给 IAM:
"Resource": "arn:aws:iam::766281746212:user/$${aws:username}"
Terraform 将 $${
理解为产生文字 ${
的转义序列,因此 Terraform 在构造要发送到AWS 提供商。然后 AWS 提供商将按原样将其发送到 IAM,允许 IAM 对其进行解释。
您的 IAM 策略中还有一个语法错误,说明您指定版本号的方式。到目前为止,这还没有出现错误,因为 Terraform 在将字符串发送到 AWS 提供商之前无法解析您的字符串,但是一旦您修复了上述问题,您可能会看到来自 AWS 提供商的另一个语法错误。要解决这个问题,您需要使用有效的 JSON 语法设置 Version
属性:
"Version": "2012-10-17",
您似乎试图在那里使用 Terraform 对象语法。可以使用 Terraform 自己的表达式语法编写 IAM 策略,然后使用 jsonencode
, and that's pretty helpful in situations where your policy will incorporate some dynamic data computed within Terraform itself, but switching to that syntax from what you have would be quite involved and not directly related to the question you asked here. If you're interested in learning more, you can see a simple example in the aws_iam_policy
documentation.