I need to create AWS Cloudfront distributions in a ForEach loop based on the strings coming in a parameter named UnauthDomains of type CommaDelimitedList.So 5 comma seperated strings in the list and we create 5 CF Distributions.
The Issue is that the commadelimitedlist can be empty in some environment.
I want to skip the ForEach loop completely if the commadelimitedlist is ""
I have tried
- Passing the default value as "" to the cloudformation template
- Using Condition in the For::Each under the type
But still while creating the changeset it picks up the "" string as if its passed as part of the commadelimitedlist and tries to find properties for the empty string in Mappings and fails with error below
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
AWSTemplateFormatVersion: 2010-09-09
# add this back when you add the ForEach
Transform: AWS::LanguageExtensions
Parameters:
UnauthDomains:
Type: CommaDelimitedList
Description: UnauthDomains to be managed
Default: ""
Environment:
Description: Lifecycle environment.
Type: String
AllowedValues:
- dev
- test
- uat
- preprod
- prod
AppName:
Description: Application name.
Type: String
AllowedValues:
- ob-nonprod
- ob-prod
- ob-uat
- ob-preprod
- ob-test
HostedZoneId:
Description: Public R53 hosted zone id
Type : String
Default: ZSSSSSSS
CFHostedZoneId:
Description: Hosted zone id for CF Distribution targets
Type : String
Default: ZFFFFFF
Mappings:
dev:
defaultClient:
# try to use the same domain name as the api gateway custom domains and check
apiGatewayDomain: "5677777.execute-api.ap-southeast-2.amazonaws"
domain: dev1-api.dev.cds.cuscal.au
ttl: "200"
acmCertArn: arn:aws:acm:us-east-1:6666666:certificate/0bc98068-70ee-4752-b806-8724d34d2832
type: "CNAME"
customerDomain: dev1-api.dev.cds.cuscal.au
bluelake:
apiGatewayDomain: "5677777.execute-api.ap-southeast-2.amazonaws"
domain: dev-api.dev.cds.cuscal.au
acmCertArn: arn:aws:acm:us-east-1:6666666:certificate/ba1fd688-65d6-42a5-8e56-b4b6aa03988a
type: "A"
customerDomain: dev-api.dev.cds.cuscal.au
Conditions:
HasUnauthDomains: !Not [!Equals [!Join ['', !Ref UnauthDomains], '']]
Resources:
'Fn::ForEach::DistributionAndRecordSet':
- UnauthClientDomainIdentifier
- !Ref UnauthDomains
- 'CfDistribution${UnauthClientDomainIdentifier}':
Type: AWS::CloudFront::Distribution
Condition: HasUnauthDomains
Properties:
DistributionConfig:
Aliases:
- !FindInMap [!Ref Environment, !Ref UnauthClientDomainIdentifier, customerDomain]
Comment: !Sub "${AppName}-${Environment}-${UnauthClientDomainIdentifier}"
Origins:
-
ConnectionAttempts: 3
ConnectionTimeout: 10
CustomOriginConfig:
HTTPPort: 80
HTTPSPort: 443
OriginKeepaliveTimeout: 5
OriginProtocolPolicy: "https-only"
OriginReadTimeout: 30
OriginSSLProtocols:
- "TLSv1.2"
DomainName: !FindInMap [!Ref Environment, !Ref UnauthClientDomainIdentifier, apiGatewayDomain]
Id: "APIGateway"
DefaultCacheBehavior:
AllowedMethods:
- "HEAD"
- "DELETE"
- "POST"
- "GET"
- "OPTIONS"
- "PUT"
- "PATCH"
CachedMethods:
- "HEAD"
- "GET"
# .html
CachePolicyId: "4135ea2d-6df8-44a3-9df3-4b5a84be39ad"
# .html
OriginRequestPolicyId: "33f36d7e-f396-46d9-90e0-52428a34d9dc"
Compress: true
DefaultTTL: 0
MaxTTL: 1
MinTTL: 0
SmoothStreaming: false
TargetOriginId: "APIGateway"
ViewerProtocolPolicy: "redirect-to-https"
FunctionAssociations:
- EventType: "viewer-request"
FunctionARN: !GetAtt CloudFrontFunction.FunctionMetadata.FunctionARN
PriceClass: "PriceClass_All"
Enabled: true
# /
ViewerCertificate:
# TODO: Refer the certificate from the other stacks output
AcmCertificateArn: !FindInMap [!Ref Environment, !Ref UnauthClientDomainIdentifier, acmCertArn]
MinimumProtocolVersion: "TLSv1.2_2021"
SslSupportMethod: "sni-only"
Restrictions:
GeoRestriction:
RestrictionType: "none"
#add this back
#WebACLId: "91d641fd-66c5-4719-912c-1d05b95cfc45"
HttpVersion: "http2"
DefaultRootObject: ""
IPV6Enabled: true
Logging:
Bucket: !Sub "${AppName}-${Environment}-cloudfront-access-logs-${AWS::AccountId}.s3.amazonaws"
IncludeCookies: false
#parameterise this as per the environment
Prefix: !Sub "CLOUDFRONTLogs/${Environment}/cdr/unauthapi"