I am working on a cloud formation template for a KMS key. In the policy document I want to set the the principals depending on the stage (whether it is prod or test). I can use Fn:If
easily if there is only one principal for both stages. But I have more than one principals for each stage and Fn:If only allows you to assign a value, not a collection according to my understanding (correct me if I am wrong).
I have tried assigning a collection to the value and it gives me "map keys must be strings; received a collection instead" error when validating the template using the CloudFormation designer in AWS accounnt.
"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"
}
Ideally the second statement in key policy should have a two arn values if prod and one arn value if not prod.
I am also open to explore if there is any other way of achieving this instead of using Fn::If
here
Instead of considering value evaluated from Fn::If as a single array item, consider it an array. Replace the Principal with the following and it will work.
JSON
{
"Principal": {
"AWS": {
"Fn::If": [
"IsProd",
[
"arn1"
],
[
"arn1",
"arn2"
]
]
}
}
}
It will look simple in yaml
Principal:
AWS:
Fn::If:
- IsProd
- - arn1
- - arn1
- arn2