如何在云形成模板中使用 Fn::If 和数组值
How to use Fn::If with array values in cloud formation templates
我正在为 KMS 密钥制作云形成模板。在政策文件中,我想根据阶段(无论是生产还是测试)设置主体。如果两个阶段只有一个主体,我可以轻松使用 Fn:If
。但是我每个stage的principal不止一个,而且Fn:If只允许你赋值,按我的理解不是collection(有错请指正)
我已尝试将集合分配给该值,但在使用 AWS 帐户中的 CloudFormation 设计器验证模板时出现 "map keys must be strings; received a collection instead" 错误。
"MyEncryptionKey": {
"DeletionPolicy": "Retain",
"Properties": {
"Description": "MyEncryptionKey",
"EnableKeyRotation": true,
"Enabled": true,
"KeyPolicy": {
"Statement": [
{
"Action": "kms:*",
"Effect": "Allow",
"Principal": {
"AWS": "root"
},
"Resource": "*"
},
{
"Action": "kms:Decrypt",
"Effect": "Allow",
"Principal": {
"AWS": [
{
"Fn::If": [
"IsProd",
{["arn1","arn2"]},
"arn2"
]
}
]
},
"Resource": "*"
}
]
}
},
"Version": "2012-10-17",
"Type": "AWS::KMS::Key"
}
理想情况下,密钥策略中的第二条语句应该有两个 arn 值(如果是 prod)和一个 arn 值(如果不是 prod)。
我也愿意探索是否有任何其他方法可以实现此目的,而不是在这里使用 Fn::If
与其将 Fn::If 评估的值视为单个数组项,不如将其视为一个数组。将 Principal 替换为以下内容,它将起作用。
JSON
{
"Principal": {
"AWS": {
"Fn::If": [
"IsProd",
[
"arn1"
],
[
"arn1",
"arn2"
]
]
}
}
}
在yaml中看起来会很简单
Principal:
AWS:
Fn::If:
- IsProd
- - arn1
- - arn1
- arn2
实际上,如果您在数组中插入一个空元素 (AWS::NoValue
),CloudFormation 将忽略它。所以你可以这样做而不是复制数组的所有公共元素:
Principal:
AWS:
- "arn1"
- "Fn::If":
- "IsProd"
- Ref: "AWS::NoValue"
- "arn2"
我不确定它是否适用于您的特定用例,但我只是用它来有条件地添加 CloudFront 缓存行为和源,并且它有效。
我正在为 KMS 密钥制作云形成模板。在政策文件中,我想根据阶段(无论是生产还是测试)设置主体。如果两个阶段只有一个主体,我可以轻松使用 Fn:If
。但是我每个stage的principal不止一个,而且Fn:If只允许你赋值,按我的理解不是collection(有错请指正)
我已尝试将集合分配给该值,但在使用 AWS 帐户中的 CloudFormation 设计器验证模板时出现 "map keys must be strings; received a collection instead" 错误。
"MyEncryptionKey": {
"DeletionPolicy": "Retain",
"Properties": {
"Description": "MyEncryptionKey",
"EnableKeyRotation": true,
"Enabled": true,
"KeyPolicy": {
"Statement": [
{
"Action": "kms:*",
"Effect": "Allow",
"Principal": {
"AWS": "root"
},
"Resource": "*"
},
{
"Action": "kms:Decrypt",
"Effect": "Allow",
"Principal": {
"AWS": [
{
"Fn::If": [
"IsProd",
{["arn1","arn2"]},
"arn2"
]
}
]
},
"Resource": "*"
}
]
}
},
"Version": "2012-10-17",
"Type": "AWS::KMS::Key"
}
理想情况下,密钥策略中的第二条语句应该有两个 arn 值(如果是 prod)和一个 arn 值(如果不是 prod)。
我也愿意探索是否有任何其他方法可以实现此目的,而不是在这里使用 Fn::If
与其将 Fn::If 评估的值视为单个数组项,不如将其视为一个数组。将 Principal 替换为以下内容,它将起作用。
JSON
{
"Principal": {
"AWS": {
"Fn::If": [
"IsProd",
[
"arn1"
],
[
"arn1",
"arn2"
]
]
}
}
}
在yaml中看起来会很简单
Principal:
AWS:
Fn::If:
- IsProd
- - arn1
- - arn1
- arn2
实际上,如果您在数组中插入一个空元素 (AWS::NoValue
),CloudFormation 将忽略它。所以你可以这样做而不是复制数组的所有公共元素:
Principal:
AWS:
- "arn1"
- "Fn::If":
- "IsProd"
- Ref: "AWS::NoValue"
- "arn2"
我不确定它是否适用于您的特定用例,但我只是用它来有条件地添加 CloudFront 缓存行为和源,并且它有效。