如何在云形成模板中将 Fn::If 与数组值一起使用

San*_*anD 6 amazon-web-services aws-cloudformation aws-kms

我正在研究 KMS 密钥的云形成模板。在政策文件中,我想根据阶段(无论是生产还是测试)设置委托人。Fn:If如果两个阶段只有一个主体,我可以轻松使用。但是我每个阶段都有不止一个principal和Fn:If只允许你赋值,根据我的理解不是集合(如果我错了,请纠正我)。

我曾尝试为该值分配一个集合,但在使用 AWS 帐户中的 CloudFormation 设计器验证模板时,它给了我“映射键必须是字符串;收到一个集合”错误。

"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"
        }
Run Code Online (Sandbox Code Playgroud)

理想情况下,密钥策略中的第二个语句应该有两个 arn 值 if prod 和一个 arn value if not prod。

我也愿意探索是否有任何其他方法可以实现这一目标而不是在Fn::If这里使用

小智 12

与其将 Fn::If 计算的值视为单个数组项,不如将其视为数组。将 Principal 替换为以下内容,它将起作用。

JSON

{
  "Principal": {
    "AWS": {
      "Fn::If": [
        "IsProd",
        [
          "arn1"
        ],
        [
          "arn1",
          "arn2"
        ]
      ]
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在 yaml 中看起来很简单

Principal:
  AWS:
    Fn::If:
    - IsProd
    - - arn1
    - - arn1
      - arn2
Run Code Online (Sandbox Code Playgroud)


Max*_*ini 6

AWS::NoValue实际上,如果您在数组中插入空元素 ( ),CloudFormation 将忽略它。因此,您可以这样做,而不是复制数组的所有公共元素:

Principal:
  AWS:
    - "arn1"
    - "Fn::If":
      - "IsProd"
      - Ref: "AWS::NoValue"
      - "arn2"
Run Code Online (Sandbox Code Playgroud)

我不确定它是否适用于您的特定用例,但我只是用它来有条件地添加 CloudFront 缓存行为和来源,并且它有效。