CloudFormation借助FindInMap构造安全组列表的报错解决方法
问题根因
- 核心类型不匹配问题:当前Mappings中把
SecurityGroups的值存储为逗号分隔的纯字符串(如sg-123,sg-124),后续通过!Join拼接后输出的仍然是单字符串,但AWS::AutoScaling::LaunchConfiguration的SecurityGroups属性要求入参为字符串列表类型,不符合类型规则就会直接触发参数校验报错。 - 常见认知误区:很多用户误以为
!Join拼接出的逗号分隔字符串会被CloudFormation自动拆分为列表,实际上CloudFormation内置函数的返回值类型是固定的,!Join永远返回字符串类型,不会自动完成列表转换。
修正步骤
- 第一步:调整Mappings的存储结构,保持原有映射层级不变,把原来逗号分隔的字符串值替换为YAML原生列表结构,这样
!FindInMap取出的值本身就是列表类型,不需要额外拆分映射内的字符串。
修正后的Mappings片段:
"123456": us-east-1: #VPC1 VpcId: vpc-xxxx VpcCidr: 10.78.160.0/20 SecurityGroups: - sg-123 AvailabilityZones: - us-east-1a - us-east-1b - us-east-1c "123457": us-east-1: #VPC VpcId: vpc-xxxx VpcCidr: 10.78.160.0/20 SecurityGroups: - sg-123 - sg-124 AvailabilityZones: - us-east-1a - us-east-1b - us-east-1c
- 第二步:实现两份安全组列表的合并,利用
!Join+!Split的固定组合逻辑,把多来源的安全组ID先统一拼接为带固定分隔符的字符串,再显式拆回为字符串列表,满足属性的类型要求。
修正后的LaunchConfiguration资源片段:
LaunchConfig: Type: AWS::AutoScaling::LaunchConfiguration Metadata: AWS::CloudFormation::Init: config: Properties: InstanceType: Ref: InstanceType SecurityGroups: !Split - "," - !Join - "," - - !FindInMap [ !Ref "AWS::AccountId", !Ref "AWS::Region", SecurityGroups ] - !Ref EC2SG IamInstanceProfile:
注意事项
- 分隔符选择:采用英文逗号作为拆分/拼接的分隔符即可,AWS安全组ID的合法字符集不包含逗号,拆分后不会出现内容截断或拆分错误。
- 多列表兼容:如果自定义的
EC2SG入参本身就是List<String>类型的安全组列表,直接把对应引用放到!Join的元素列表中即可,!Join会自动遍历展开列表元素完成拼接,不需要额外做类型转换。 - 同场景问题复用:当前Mappings中的
AvailabilityZones字段也存在同样的存储问题,如果后续要把这个值传入要求可用区列表的资源属性(如AWS::EC2::Subnet的AvailabilityZoneList),同样建议改成原生列表存储,避免重复出现类型不匹配的报错。
内容的提问来源于stack exchange,提问作者Umar
相关产品推荐
相关产品推荐

