如何在CommaDelimitedList为空时跳过CloudFormation的Fn::ForEach循环
问题:空CommaDelimitedList参数导致CloudFormation Fn::ForEach循环执行失败
场景与需求
需要基于CommaDelimitedList类型的UnauthDomains参数,通过Fn::ForEach循环创建对应数量的AWS CloudFront分发(例如列表含5个逗号分隔字符串则创建5个分发)。但该参数在部分环境中可能为空,要求空列表时完全跳过Fn::ForEach循环,不执行任何相关资源创建逻辑。
尝试过的方案及问题
已尝试以下两种方案,但均未解决问题:
- 为
UnauthDomains参数设置默认值为空字符串 - 在循环内的CloudFront资源上添加
Condition判断
创建变更集时仍报错,原因是空字符串被视为列表中的一个元素,CloudFormation尝试在Mappings中查找空字符串对应的属性,最终失败。报错信息如下:
Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state: For expression "Status" we matched expected path: "FAILED" Status: FAILED. Reason: Transform AWS::LanguageExtensions failed with: Mappings not found in template for key //customerDomain on resourceType Fn::ForEach::DistributionAndRecordSet field forEach
解决方案
核心是让Fn::ForEach在空列表场景下遍历空数组,而非包含空字符串的列表,从而直接跳过循环。具体修改如下:
1. 调整循环的源列表
通过!If函数动态生成循环的源列表:当HasUnauthDomains条件为真时,使用原参数值;否则传入空数组[],让循环直接终止。
2. 修改后的模板关键代码
AWSTemplateFormatVersion: 2010-09-09 Transform: AWS::LanguageExtensions Parameters: UnauthDomains: Type: CommaDelimitedList Description: UnauthDomains to be managed Default: "" # 保留其他参数内容... Mappings: # 保留原有Mappings内容... Conditions: HasUnauthDomains: !Not [!Equals [!Join ['', !Ref UnauthDomains], '']] Resources: 'Fn::ForEach::DistributionAndRecordSet': - UnauthClientDomainIdentifier # 关键修改:用If函数生成安全的循环源列表 - !If - HasUnauthDomains - !Ref UnauthDomains - [] - 'CfDistribution${UnauthClientDomainIdentifier}': Type: AWS::CloudFront::Distribution Condition: HasUnauthDomains Properties: # 保留原有Properties内容...
说明
- 当
UnauthDomains为空时,!Join会把[""]转换成空字符串,HasUnauthDomains条件为假,!If返回空数组[],Fn::ForEach遍历空数组时不会生成任何资源,彻底跳过循环。 - 原有的
Condition可保留作为双重保险,但核心是通过空数组避免循环执行无效的遍历逻辑。
内容的提问来源于stack exchange,提问作者Amol Kshirsagar
相关产品推荐
相关产品推荐

