FindInMap 可以返回列表吗?

use*_*040 11 amazon-web-services amazon-cloudformation

我正在使用 CloudFormation 将 ELB 部署到具有预先存在的子网的预先存在的 VPC。我已经在模板的 Mappings 部分列出了子网,并根据 Environment 参数选择了映射。如果 Mapping 用于单个值,这可以正常工作,但我希望 Mapping 返回一个列表,因为我希望 ELB 是多可用区。我已经尝试了下面示例的各种组合,但我总是得到相同的错误Value of property Subnets must be of type List of String。FindInMap 有没有办法返回值列表?

ELB 配置示例

"ElasticLoadBalancerAPI": {
            "Properties": {
                "ConnectionDrainingPolicy": {
                    "Enabled": true,
                    "Timeout": 30
                },
                "ConnectionSettings": {
                    "IdleTimeout": 60
                },
                "CrossZone": "false",
                "Subnets" : [
                    {
                        "Fn::FindInMap": [
                            "AWSEnv2PublicSubnets",
                            {
                                "Ref": "Env"
                            },
                            "subList"
                        ]
                    }
                ],
                "SecurityGroups" : [ { "Ref" : "LoadBalancerSecurityGroup" }],
etc...
Run Code Online (Sandbox Code Playgroud)

示例参数

"Parameters": {
  "Env": {
            "Description": "Environment",
            "Type": "String",
            "Default": "DEV",
            "AllowedValues": [
                "DEV",
                "TEST"
            ]
        }
}
Run Code Online (Sandbox Code Playgroud)

示例映射

"Mappings": {
  "AWSEnv2PublicSubnets": {
            "DEV": {
                "subList": ["subnet-1111","subnet-2222","subnet-3333"]
            },
            "TEST": {
                "subList": ["subnet-4444"]
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

gre*_*mac 14

使用拆分功能有效:

JSON

"Mappings": {
   "AWSEnv2PublicSubnets": {
        "DEV": {
            "subList": "subnet-1111,subnet-2222,subnet-3333"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

"Subnets" : { 
  "Fn::Split" : [
    ",", 
    { "Fn::FindInMap": [
      "AWSEnv2PublicSubnets",
      { "Ref": "Env" },
      "subList"
    ] }
  ]
}
Run Code Online (Sandbox Code Playgroud)

YAML

Mappings: 
  AWSEnv2PublicSubnets:
    DEV:
      subList: subnet-1111,subnet-2222,subnet-3333
Run Code Online (Sandbox Code Playgroud)

然后:

Subnets: !Split [",", !FindInMap [ AWSEnv2PublicSubnets, !Ref Env, subList] ]
Run Code Online (Sandbox Code Playgroud)

我使用逗号 ( ,) 作为我的分隔符,但您可以使用任何您想要的东西,只要它不也用作值的一部分。


小智 7

我认为 Mappings 值支持List类型(至少到目前为止)。

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html

Mappings 部分由键名 Mappings 组成。映射中的键必须是文字字符串。值可以是StringList类型。

这是用 YAML 编写的示例。

Parameters:
  Env:
    Type: String
    AllowedValues: [dev, qa, prod]

Mappings:
  Environment:
    dev:
      Groups:
        - Developer
        - QA
    qa:
      Groups:
        - Developer
        - QA
    prod:
      Groups:
        - Operations

Resources:
  Policy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: iam-manage-role
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action:
              - iam:*Role*
            Resource: "*"
      Groups: !FindInMap [Environment, !Ref Env, Groups]
Run Code Online (Sandbox Code Playgroud)