AWS CloudFormation CloudFront CDN Overview Create production-ready CDN infrastructure using AWS CloudFormation templates. This skill covers CloudFront distributions, multiple origins (ALB, S3, Lambda@Edge, VPC Origins), CacheBehaviors, Functions, SecurityHeaders, and best practices for parameters, outputs, and cross-stack references. When to Use Use this skill when: Creating new CloudFront distributions with CloudFormation Configuring multiple origins (ALB, S3, API Gateway, Lambda@Edge, VPC Origins) Implementing caching strategies with CacheBehaviors and Cache Policies Configuring custom domains with ACM certificates Implementing SecurityHeaders (CSP, HSTS, XSS protection) Configuring CloudFront Functions and Lambda@Edge Managing Geo-restrictions and Price Classes Integrating WAF with CloudFront Organizing templates with Parameters, Outputs, Mappings, Conditions Implementing cross-stack references with export/import Using Transform for macros and reuse CloudFormation Template Structure Standard Format Base Template AWSTemplateFormatVersion : 2010-09-09 Description : CloudFront distribution with multiple origins Metadata : AWS::CloudFormation::Interface : ParameterGroups : - Label : default : Distribution Configuration Parameters : - DomainName - CertificateArn - PriceClass - Label : default : Origin Settings Parameters : - OriginDomainName - OriginPath - OriginProtocolPolicy Parameters : DomainName : Type : String Default : cdn.example.com Description : Custom domain name for CloudFront distribution CertificateArn : Type : AWS : : ACM : : Certificate : : Arn Description : ACM certificate ARN for HTTPS PriceClass : Type : String Default : PriceClass_All AllowedValues : - PriceClass_All - PriceClass_100 - PriceClass_200 Description : CloudFront price class OriginDomainName : Type : String Description : Domain name of the origin (ALB or S3) OriginPath : Type : String Default : "" Description : Optional origin path Mappings : EnvironmentConfig : us-east-1 : CertificateRegion : us - east - 1 other : CertificateRegion : us - east - 1 Conditions : IsUsEast1 : !Equals [ !Ref AWS : : Region , us - east - 1 ] HasOriginPath : !Not [ !Equals [ !Ref OriginPath , "" ] ] Transform : - AWS : : Serverless - 2016-10-31 Resources :
CloudFront Distribution
CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CallerReference : !Sub "${AWS::StackName}-${AWS::AccountId}" Comment : !Sub "CloudFront distribution for ${DomainName}" DomainNames : - !Ref DomainName Enabled : true PriceClass : !Ref PriceClass IPV6Enabled : true DefaultRootObject : index.html Origins : - Id : !Sub "${DomainName}-origin" DomainName : !Ref OriginDomainName OriginPath : !If [ HasOriginPath , !Ref OriginPath , !Ref AWS : : NoValue ] CustomOriginConfig : HTTPPort : 80 HTTPSPort : 443 OriginProtocolPolicy : https - only OriginSSLProtocols : - TLSv1.2 DefaultCacheBehavior : TargetOriginId : !Sub "${DomainName}-origin" ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD CachedMethods : - GET - HEAD Compress : true ForwardedValues : QueryString : false Cookies : Forward : none MinTTL : 0 DefaultTTL : 86400 MaxTTL : 31536000 ViewerCertificate : AcmCertificateArn : !Ref CertificateArn MinimumProtocolVersion : TLSv1.2_2021 SslSupportMethod : sni - only Outputs : DistributionDomainName : Description : CloudFront distribution domain name Value : !GetAtt CloudFrontDistribution.DomainName Export : Name : !Sub "${AWS::StackName}-DistributionDomainName" DistributionId : Description : CloudFront distribution ID Value : !Ref CloudFrontDistribution Export : Name : !Sub "${AWS::StackName}-DistributionId" Best Practices for Parameters AWS-Specific Parameter Types Parameters :
ACM Certificate for domain
CertificateArn : Type : AWS : : ACM : : Certificate : : Arn Description : ACM certificate for the domain
S3 Bucket origins
StaticAssetsBucket : Type : AWS : : S3 : : Bucket Description : S3 bucket for static assets StaticAssetsBucketDomainName : Type : AWS : : S3 : : Bucket : : RegionalDomainName Description : Regional domain name of the S3 bucket
ALB origins
LoadBalancerArn : Type : AWS : : ElasticLoadBalancingV2 : : LoadBalancer : : Arn Description : ARN of the Application Load Balancer LoadBalancerDNSName : Type : AWS : : ElasticLoadBalancingV2 : : LoadBalancer : : DnsName Description : DNS name of the ALB
Lambda function origins
LambdaFunctionArn : Type : AWS : : Lambda : : Function : : Arn Description : ARN of the Lambda function for Lambda@Edge
VPC Origin
VPCOriginEndpoint : Type : AWS : : GlobalAccelerator : : Endpoint : : EndpointId Description : VPC Origin endpoint ID
IAM Role for Lambda@Edge
LambdaEdgeRoleArn : Type : AWS : : IAM : : Role : : Arn Description : IAM role for Lambda@Edge execution Parameter Constraints Parameters : DomainName : Type : String Default : cdn.example.com Description : Custom domain name for CloudFront ConstraintDescription : Must be a valid domain name MinLength : 4 MaxLength : 253 AllowedPattern : "a-z0-9?(\.a-z0-9?)*" PriceClass : Type : String Default : PriceClass_All Description : CloudFront price class AllowedValues : - PriceClass_All - PriceClass_100 - PriceClass_200 DefaultTTL : Type : Number Default : 86400 Description : Default cache TTL in seconds MinValue : 0 MaxValue : 31536000 ConstraintDescription : Must be between 0 and 31536000 seconds MaxTTL : Type : Number Default : 31536000 Description : Maximum cache TTL in seconds MinValue : 0 MaxValue : 31536000 MinTTL : Type : Number Default : 0 Description : Minimum cache TTL in seconds MinValue : 0 MaxValue : 31536000 SSM Parameter References Parameters : WafWebAclArn : Type : AWS : : SSM : : Parameter : : Value<String
Default : /cloudfront/waf - webacl - arn Description : WAF Web ACL ARN from Parameter Store CloudFrontKeyId : Type : AWS : : SSM : : Parameter : : Value<String
Default : /cloudfront/keys/cloudfront - key - id Description : CloudFront key pair ID for signed URLs Outputs and Cross-Stack References Export/Import Patterns
Stack A - Network/Infrastructure Stack
AWSTemplateFormatVersion : 2010-09-09 Description : Infrastructure stack exporting CloudFront resources Resources :
S3 Bucket for static content
StaticAssetsBucket : Type : AWS : : S3 : : Bucket Properties : BucketName : !Sub "static-assets-${AWS::AccountId}-${AWS::Region}" PublicAccessBlockConfiguration : BlockPublicAcls : true BlockPublicPolicy : true IgnorePublicAcls : true RestrictPublicBuckets : true BucketEncryption : ServerSideEncryptionConfiguration : - ServerSideEncryptionByDefault : SSEAlgorithm : AES256 VersioningConfiguration : Status : Enabled CorsConfiguration : CorsRules : - AllowedHeaders : - "" AllowedMethods : - GET - HEAD AllowedOrigins : - "" MaxAge : 3600
OAI for CloudFront access
CloudFrontOAI : Type : AWS : : CloudFront : : CloudFrontOriginAccessIdentity Properties : CloudFrontOriginAccessIdentityConfig : Comment : !Sub "OAI for ${StaticAssetsBucket}" Outputs : StaticAssetsBucketName : Description : S3 bucket name for static assets Value : !Ref StaticAssetsBucket Export : Name : !Sub "${AWS::StackName}-StaticAssetsBucketName" StaticAssetsBucketArn : Description : S3 bucket ARN Value : !GetAtt StaticAssetsBucket.Arn Export : Name : !Sub "${AWS::StackName}-StaticAssetsBucketArn" StaticAssetsBucketRegionalDomainName : Description : Regional domain name of the S3 bucket Value : !GetAtt StaticAssetsBucket.RegionalDomainName Export : Name : !Sub "${AWS::StackName}-StaticAssetsBucketRegionalDomainName" CloudFrontOAIId : Description : CloudFront OAI ID Value : !Ref CloudFrontOAI Export : Name : !Sub "${AWS::StackName}-CloudFrontOAIId" CloudFrontOAIArn : Description : CloudFront OAI ARN Value : !GetAtt CloudFrontOAI.Arn Export : Name : !Sub "${AWS::StackName}-CloudFrontOAIArn"
Stack B - Application Stack (imports from Infrastructure Stack)
AWSTemplateFormatVersion : 2010-09-09 Description : Application stack importing from infrastructure stack Parameters : InfrastructureStackName : Type : String Default : infrastructure - stack Description : Name of the infrastructure stack DomainName : Type : String Default : cdn.example.com Description : Custom domain name CertificateArn : Type : AWS : : ACM : : Certificate : : Arn Description : ACM certificate ARN Resources : CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CallerReference : !Sub "${AWS::StackName}-${AWS::AccountId}" Comment : !Sub "CloudFront for ${DomainName}" Enabled : true IPV6Enabled : true DefaultRootObject : index.html Origins : - Id : StaticAssetsOrigin DomainName : !ImportValue !Sub "$ { InfrastructureStackName } - StaticAssetsBucketRegionalDomainName" S3OriginConfig : OriginAccessIdentity : !Sub "origin-access-identity/cloudfront/${InfrastructureStackName}-CloudFrontOAIId" DefaultCacheBehavior : TargetOriginId : StaticAssetsOrigin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD CachedMethods : - GET - HEAD Compress : true ForwardedValues : QueryString : false Cookies : Forward : none MinTTL : 0 DefaultTTL : 86400 MaxTTL : 31536000 ViewerCertificate : AcmCertificateArn : !Ref CertificateArn MinimumProtocolVersion : TLSv1.2_2021 SslSupportMethod : sni - only Nested Stacks for Modularity AWSTemplateFormatVersion : 2010-09-09 Description : Main stack with nested CloudFront stacks Resources :
Nested stack for static assets distribution
StaticAssetsDistributionStack : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : https : //s3.amazonaws.com/bucket/cloudfront - static.yaml TimeoutInMinutes : 15 Parameters : DomainName : !Ref DomainName CertificateArn : !Ref CertificateArn StaticAssetsBucketName : !Ref StaticAssetsBucketName Environment : !Ref Environment
Nested stack for API distribution
ApiDistributionStack : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : https : //s3.amazonaws.com/bucket/cloudfront - api.yaml TimeoutInMinutes : 15 Parameters : DomainName : !Ref ApiDomainName CertificateArn : !Ref CertificateArn LoadBalancerDnsName : !Ref LoadBalancerDnsName Environment : !Ref Environment S3 Origins S3 Origin with OAI AWSTemplateFormatVersion : 2010-09-09 Description : CloudFront distribution with S3 origin Resources :
S3 Bucket
StaticBucket : Type : AWS : : S3 : : Bucket Properties : BucketName : !Sub "static-assets-${AWS::AccountId}-${AWS::Region}" PublicAccessBlockConfiguration : BlockPublicAcls : true BlockPublicPolicy : true IgnorePublicAcls : true RestrictPublicBuckets : true
CloudFront OAI
CloudFrontOAI : Type : AWS : : CloudFront : : CloudFrontOriginAccessIdentity Properties : CloudFrontOriginAccessIdentityConfig : Comment : !Sub "OAI for ${StaticBucket}"
S3 Bucket Policy - Allow CloudFront OAI
S3BucketPolicy : Type : AWS : : S3 : : BucketPolicy Properties : Bucket : !Ref StaticBucket PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : CanonicalUser : !GetAtt CloudFrontOAI.S3CanonicalUserId Action : s3 : GetObject Resource : !Sub "${StaticBucket.Arn}/" - Effect : Deny Principal : "" Action : s3 : GetObject Resource : !Sub "${StaticBucket.Arn}/*" Condition : Bool : aws:SecureTransport : false
CloudFront Distribution
CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CallerReference : !Sub "${AWS::StackName}-${AWS::AccountId}" Comment : !Sub "Static assets CDN" Enabled : true IPV6Enabled : true Origins : - Id : S3Origin DomainName : !GetAtt StaticBucket.RegionalDomainName S3OriginConfig : OriginAccessIdentity : !Sub "origin-access-identity/cloudfront/${CloudFrontOAI}" DefaultCacheBehavior : TargetOriginId : S3Origin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD CachedMethods : - GET - HEAD Compress : true ForwardedValues : QueryString : false Cookies : Forward : none MinTTL : 0 DefaultTTL : 86400 MaxTTL : 31536000 Outputs : DistributionDomainName : Value : !GetAtt CloudFrontDistribution.DomainName S3 Origin with Origin Access Control (OAC) Resources : StaticBucket : Type : AWS : : S3 : : Bucket Properties : BucketName : !Sub "static-assets-oac-${AWS::AccountId}-${AWS::Region}" OwnershipControls : Rules : - ObjectOwnership : BucketOwnerPreferred PublicAccessBlockConfiguration : BlockPublicAcls : true BlockPublicPolicy : true IgnorePublicAcls : true RestrictPublicBuckets : true
S3 Bucket Policy for OAC
S3BucketPolicy : Type : AWS : : S3 : : BucketPolicy Properties : Bucket : !Ref StaticBucket PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : Service : cloudfront.amazonaws.com Action : s3 : GetObject Resource : !Sub "${StaticBucket.Arn}/*" Condition : StringEquals : AWS:SourceArn : !Sub "arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFrontDistribution}" CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : Origins : - Id : S3Origin DomainName : !GetAtt StaticBucket.RegionalDomainName S3OriginConfig : OriginAccessIdentity : ""
For OAC, use OriginAccessControl instead of S3OriginConfig
but CloudFormation supports both
ALB Origins Application Load Balancer Origin AWSTemplateFormatVersion : 2010-09-09 Description : CloudFront with ALB origin Resources :
Application Load Balancer
ApplicationLoadBalancer : Type : AWS : : ElasticLoadBalancingV2 : : LoadBalancer Properties : Name : !Sub "${AWS::StackName}-alb" Scheme : internet - facing SecurityGroups : - !Ref ALBSecurityGroup Subnets : - !Ref PublicSubnet1 - !Ref PublicSubnet2 Type : application
ALB Security Group
ALBSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupDescription : ALB security group VpcId : !Ref VPCId SecurityGroupIngress : - IpProtocol : tcp FromPort : 80 ToPort : 80 SourceSecurityGroupId : !Ref CloudFrontSecurityGroup - IpProtocol : tcp FromPort : 443 ToPort : 443 SourceSecurityGroupId : !Ref CloudFrontSecurityGroup
CloudFront Security Group (for ALB ingress)
CloudFrontSecurityGroup : Type : AWS : : EC2 : : SecurityGroup Properties : GroupDescription : CloudFront security group for ALB VpcId : !Ref VPCId SecurityGroupEgress : - IpProtocol : tcp FromPort : 80 ToPort : 80 DestinationSecurityGroupId : !Ref ALBSecurityGroup - IpProtocol : tcp FromPort : 443 ToPort : 443 DestinationSecurityGroupId : !Ref ALBSecurityGroup
CloudFront Distribution
CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CallerReference : !Sub "${AWS::StackName}-${AWS::AccountId}" Comment : !Sub "CloudFront with ALB origin" Enabled : true Origins : - Id : ALBOrigin DomainName : !GetAtt ApplicationLoadBalancer.DNSName CustomOriginConfig : HTTPPort : 80 HTTPSPort : 443 OriginProtocolPolicy : https - only OriginSSLProtocols : - TLSv1.2 DefaultCacheBehavior : TargetOriginId : ALBOrigin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD - OPTIONS CachedMethods : - GET - HEAD Compress : true ForwardedValues : QueryString : true Headers : - Origin - Access - Control - Request - Method - Access - Control - Request - Headers Cookies : Forward : all QueryStringSettings : - Name : "*" MinTTL : 0 DefaultTTL : 0 MaxTTL : 0 Multiple Origins and CacheBehaviors Multi-Origin with Path Patterns AWSTemplateFormatVersion : 2010-09-09 Description : CloudFront with multiple origins and cache behaviors Resources :
S3 Bucket for static assets
StaticAssetsBucket : Type : AWS : : S3 : : Bucket Properties : BucketName : !Sub "static-assets-${AWS::AccountId}-${AWS::Region}" CloudFrontOAI : Type : AWS : : CloudFront : : CloudFrontOriginAccessIdentity Properties : CloudFrontOriginAccessIdentityConfig : Comment : !Sub "OAI for ${StaticAssetsBucket}"
Application Load Balancer for API
ApplicationLoadBalancer : Type : AWS : : ElasticLoadBalancingV2 : : LoadBalancer Properties : Name : !Sub "${AWS::StackName}-api-alb" Scheme : internet - facing SecurityGroups : - !Ref ALBSecurityGroup Subnets : !Ref PublicSubnets Type : application
CloudFront Distribution
CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CallerReference : !Sub "${AWS::StackName}-${AWS::AccountId}" Comment : !Sub "Multi-origin CloudFront distribution" Enabled : true IPV6Enabled : true DefaultRootObject : index.html Origins :
Static assets origin
- Id : StaticAssetsOrigin DomainName : !GetAtt StaticAssetsBucket.RegionalDomainName S3OriginConfig : OriginAccessIdentity : !Sub "origin-access-identity/cloudfront/${CloudFrontOAI}"
API origin
- Id : ApiOrigin DomainName : !GetAtt ApplicationLoadBalancer.DNSName CustomOriginConfig : HTTPPort : 80 HTTPSPort : 443 OriginProtocolPolicy : https - only
Lambda origin
- Id : LambdaOrigin DomainName : !Sub "${LambdaFunction}.execute-api.${AWS::Region}.amazonaws.com" CustomOriginConfig : HTTPPort : 443 HTTPSPort : 443 OriginProtocolPolicy : https - only DefaultCacheBehavior :
Default: static assets
TargetOriginId : StaticAssetsOrigin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD CachedMethods : - GET - HEAD Compress : true ForwardedValues : QueryString : false Cookies : Forward : none MinTTL : 0 DefaultTTL : 86400 MaxTTL : 31536000 CacheBehaviors :
API cache behavior
- PathPattern : "/api/*" TargetOriginId : ApiOrigin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD - OPTIONS - PUT - POST - PATCH - DELETE CachedMethods : - GET - HEAD Compress : true ForwardedValues : QueryString : true Headers : - Accept - Accept - Language - Authorization Cookies : Forward : all MinTTL : 0 DefaultTTL : 0 MaxTTL : 0
Lambda function path
- PathPattern : "/lambda/" TargetOriginId : LambdaOrigin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD - OPTIONS CachedMethods : - GET - HEAD Compress : true ForwardedValues : QueryString : true Cookies : Forward : none MinTTL : 0 DefaultTTL : 0 MaxTTL : 0 Cache Policies Managed Cache Policy Resources : CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CacheBehaviors : - PathPattern : "/static/" TargetOriginId : StaticAssetsOrigin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD CachedMethods : - GET - HEAD Compress : true CachePolicyId : !Ref ManagedCachingOptimizedPolicyId FunctionAssociations : - FunctionARN : !GetAtt CloudFrontFunction.FunctionARN EventType : viewer - request - PathPattern : "/api/*" TargetOriginId : ApiOrigin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD - OPTIONS CachedMethods : - GET - HEAD Compress : true CachePolicyId : !Ref ManagedSecurityHeadersPolicyId Custom Cache Policy Resources :
Custom Cache Policy
StaticAssetsCachePolicy : Type : AWS : : CloudFront : : CachePolicy Properties : CachePolicyConfig : Name : !Sub "${AWS::StackName}-static-assets-policy" DefaultTTL : 86400 MaxTTL : 31536000 MinTTL : 0 ParametersInCacheKeyAndForwardedToOrigin : CookiesConfig : CookieBehavior : none HeadersConfig : HeaderBehavior : none QueryStringsConfig : QueryStringBehavior : none EnableAcceptEncodingBrotli : true EnableAcceptEncodingGzip : true
Custom Cache Policy for API
ApiCachePolicy : Type : AWS : : CloudFront : : CachePolicy Properties : CachePolicyConfig : Name : !Sub "${AWS::StackName}-api-cache-policy" DefaultTTL : 300 MaxTTL : 600 MinTTL : 60 ParametersInCacheKeyAndForwardedToOrigin : CookiesConfig : CookieBehavior : all HeadersConfig : HeaderBehavior : whitelist Headers : - Authorization - Content - Type - Accept QueryStringsConfig : QueryStringBehavior : all EnableAcceptEncodingBrotli : true EnableAcceptEncodingGzip : true CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : Origins : - Id : StaticAssetsOrigin DomainName : !GetAtt StaticAssetsBucket.RegionalDomainName S3OriginConfig : OriginAccessIdentity : !Sub "origin-access-identity/cloudfront/${CloudFrontOAI}" CacheBehaviors : - PathPattern : "/static/*" TargetOriginId : StaticAssetsOrigin CachePolicyId : !GetAtt StaticAssetsCachePolicy.Id Origin Request Policies Resources :
Origin Request Policy
StaticAssetsOriginRequestPolicy : Type : AWS : : CloudFront : : OriginRequestPolicy Properties : OriginRequestPolicyConfig : Name : !Sub "${AWS::StackName}-static-assets-origin-request" CookiesConfig : CookieBehavior : none HeadersConfig : HeaderBehavior : none QueryStringsConfig : QueryStringBehavior : none ApiOriginRequestPolicy : Type : AWS : : CloudFront : : OriginRequestPolicy Properties : OriginRequestPolicyConfig : Name : !Sub "${AWS::StackName}-api-origin-request" CookiesConfig : CookieBehavior : all HeadersConfig : HeaderBehavior : whitelist Headers : - Authorization - Content - Type - X - Request - ID QueryStringsConfig : QueryStringBehavior : all CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CacheBehaviors : - PathPattern : "/api/*" TargetOriginId : ApiOrigin CachePolicyId : !GetAtt ApiCachePolicy.Id OriginRequestPolicyId : !GetAtt ApiOriginRequestPolicy.Id Response Headers Policies (Security Headers) Resources :
Security Headers Policy
SecurityHeadersPolicy : Type : AWS : : CloudFront : : ResponseHeadersPolicy Properties : ResponseHeadersPolicyConfig : Name : !Sub "${AWS::StackName}-security-headers" SecurityHeadersConfig : ContentTypeOptions : Override : true FrameOptions : FrameOption : DENY Override : true ReferrerPolicy : ReferrerPolicy : strict - origin - when - cross - origin Override : true StrictTransportSecurity : AccessControlMaxAgeSec : 31536000 IncludeSubdomains : true Override : true Preload : true XSSProtection : ModeBlock : true Override : true Protection : true CorsConfig : AccessControlAllowCredentials : false AccessControlAllowHeaders : Items : - "*" AccessControlAllowMethods : Items : - GET - HEAD - OPTIONS AccessControlAllowOrigins : Items : - !Ref AllowedOrigin AccessControlMaxAgeSec : 600 OriginOverride : true CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : DefaultCacheBehavior : TargetOriginId : StaticAssetsOrigin ResponseHeadersPolicyId : !GetAtt SecurityHeadersPolicy.Id CloudFront Functions Viewer Request Function Resources :
CloudFront Function
RewritePathFunction : Type : AWS : : CloudFront : : Function Properties : Name : !Sub "${AWS::StackName}-rewrite-path" FunctionCode : | function handler(event) { var request = event.request; var uri = request.uri; // Remove trailing slash if (uri.endsWith('/')) { request.uri = uri.substring(0 , uri.length - 1); } // Add .html extension for HTML pages if ( !uri.includes('.') && !uri.endsWith('/')) { request.uri = uri + '.html'; } return request; } Runtime : cloudfront - js - 1.0 AutoPublish : true CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : DefaultCacheBehavior : TargetOriginId : StaticAssetsOrigin FunctionAssociations : - FunctionARN : !GetAtt RewritePathFunction.FunctionARN EventType : viewer - request Lambda@Edge Functions Resources :
Lambda@Edge Function
LambdaEdgeFunction : Type : AWS : : Lambda : : Function Properties : FunctionName : !Sub "${AWS::StackName}-lambda-edge" Code : S3Bucket : !Ref CodeBucket S3Key : lambda/edge - function.zip Handler : index.handler Runtime : nodejs20.x Role : !GetAtt LambdaEdgeRole.Arn
Lambda Version for Lambda@Edge
LambdaEdgeVersion : Type : AWS : : Lambda : : Version Properties : FunctionName : !Ref LambdaEdgeFunction Description : Lambda@Edge version CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : Origins : - Id : Origin DomainName : !Ref OriginDomainName CustomOriginConfig : HTTPPort : 443 HTTPSPort : 443 OriginProtocolPolicy : https - only DefaultCacheBehavior : TargetOriginId : Origin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD CachedMethods : - GET - HEAD LambdaFunctionAssociations : - FunctionARN : !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaEdgeFunction}:${LambdaEdgeVersion}" EventType : origin - request Geo-Restrictions and Price Class Resources : CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CallerReference : !Sub "${AWS::StackName}-${AWS::AccountId}" Comment : !Sub "CloudFront with geo restrictions" Enabled : true IPV6Enabled : true
Price Class - optimize costs
PriceClass : PriceClass_200
Geo Restrictions
GeoRestriction : RestrictionType : whitelist Locations : - US - CA - GB - DE - FR - IT - JP - AU Origins : - Id : Origin DomainName : !Ref OriginDomainName CustomOriginConfig : HTTPPort : 443 HTTPSPort : 443 OriginProtocolPolicy : https - only DefaultCacheBehavior : TargetOriginId : Origin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD CachedMethods : - GET - HEAD Compress : true ForwardedValues : QueryString : false Cookies : Forward : none MinTTL : 0 DefaultTTL : 86400 MaxTTL : 31536000 WAF Integration Resources :
WAF Web ACL
CloudFrontWebACL : Type : AWS : : WAFv2 : : WebACL Properties : Name : !Sub "${AWS::StackName}-waf-acl" Scope : CLOUDFRONT DefaultAction : Allow : { } Rules :
AWS Managed Rule - Common
- Name : AWSCommonRule Priority : 1 Statement : ManagedRuleGroupStatement : VendorName : AWS Name : AWSManagedRulesCommonRuleSet ExcludedRules : - Name : SizeRestrictions_BODY OverrideAction : None : { } VisibilityConfig : SampledRequestsEnabled : true CloudWatchMetricsEnabled : true MetricName : AWSCommonRule
Rate-based rule
- Name : RateLimitRule Priority : 2 Statement : RateBasedStatementKey : SingleHeader : Name : ip AggregateKeyType : IP Limit : 1000 OverrideAction : None : { } VisibilityConfig : SampledRequestsEnabled : true CloudWatchMetricsEnabled : true MetricName : RateLimitRule
SQL Injection protection
- Name : SQLInjectionRule Priority : 3 Statement : SqliMatchStatement : FieldToMatch : QueryString : { } UriPath : { } TextTransformations : - Priority : 1 Type : URL_DECODE - Priority : 2 Type : LOWERCASE OverrideAction : None : { } VisibilityConfig : SampledRequestsEnabled : true CloudWatchMetricsEnabled : true MetricName : SQLInjectionRule
XSS protection
- Name : XSSRule Priority : 4 Statement : XssMatchStatement : FieldToMatch : QueryString : { } UriPath : { } TextTransformations : - Priority : 1 Type : URL_DECODE - Priority : 2 Type : LOWERCASE OverrideAction : None : { } VisibilityConfig : SampledRequestsEnabled : true CloudWatchMetricsEnabled : true MetricName : XSSRule VisibilityConfig : SampledRequestsEnabled : true CloudWatchMetricsEnabled : true MetricName : CloudFrontWAFACL CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CallerReference : !Sub "${AWS::StackName}-${AWS::AccountId}" Comment : !Sub "CloudFront with WAF" Enabled : true WebACLId : !GetAtt CloudFrontWebACL.Arn Origins : - Id : Origin DomainName : !Ref OriginDomainName CustomOriginConfig : HTTPPort : 443 HTTPSPort : 443 OriginProtocolPolicy : https - only DefaultCacheBehavior : TargetOriginId : Origin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD CachedMethods : - GET - HEAD ForwardedValues : QueryString : false Cookies : Forward : none MinTTL : 0 DefaultTTL : 86400 MaxTTL : 31536000 Real-Time Logs Resources :
Kinesis Data Stream
CloudFrontLogsStream : Type : AWS : : Kinesis : : Stream Properties : Name : !Sub "${AWS::StackName}-cloudfront-logs" ShardCount : 1 RetentionPeriodHours : 24
IAM Role for CloudFront
CloudFrontLoggingRole : Type : AWS : : IAM : : Role Properties : RoleName : !Sub "${AWS::StackName}-cloudfront-logging" AssumeRolePolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Principal : Service : cloudfront.amazonaws.com Action : sts : AssumeRole Policies : - PolicyName : KinesisPutRecord PolicyDocument : Version : "2012-10-17" Statement : - Effect : Allow Action : - kinesis : PutRecord - kinesis : PutRecords Resource : !GetAtt CloudFrontLogsStream.Arn CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CallerReference : !Sub "${AWS::StackName}-${AWS::AccountId}" Comment : !Sub "CloudFront with real-time logs" Enabled : true RealTimeConfig : Endpoint : !GetAtt CloudFrontLogsStream.Arn RoleArn : !GetAtt CloudFrontLoggingRole.Arn Fields : - timestamp - c - ip - cs - method - cs - uri - sc - status - time - taken Origins : - Id : Origin DomainName : !Ref OriginDomainName CustomOriginConfig : HTTPPort : 443 HTTPSPort : 443 OriginProtocolPolicy : https - only DefaultCacheBehavior : TargetOriginId : Origin ViewerProtocolPolicy : redirect - to - https AllowedMethods : - GET - HEAD CachedMethods : - GET - HEAD ForwardedValues : QueryString : false Cookies : Forward : none MinTTL : 0 DefaultTTL : 86400 MaxTTL : 31536000 Conditions and Transform Conditions for Environment-Specific Configuration AWSTemplateFormatVersion : 2010-09-09 Description : CloudFront with conditional configuration Parameters : Environment : Type : String Default : dev AllowedValues : - dev - staging - production Description : Deployment environment EnableWAF : Type : String Default : false AllowedValues : - true - false Description : Enable WAF protection Conditions : IsProduction : !Equals [ !Ref Environment , production ] IsStaging : !Equals [ !Ref Environment , staging ] EnableWAFProtection : !And - !Equals [ !Ref EnableWAF , true ] - !Or - [ !Equals [ !Ref Environment , staging ] ] - [ !Equals [ !Ref Environment , production ] ] Resources : CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CallerReference : !Sub "${AWS::StackName}-${AWS::AccountId}" Comment : !Sub "CloudFront for ${Environment}" Enabled : true IPV6Enabled : true PriceClass : !If [ IsProduction , PriceClass_All , PriceClass_100 ] WebACLId : !If [ EnableWAFProtection , !Ref CloudFrontWebACL , !Ref AWS : : NoValue ] Origins : - Id : Origin DomainName : !Ref OriginDomainName CustomOriginConfig : HTTPPort : 443 HTTPSPort : 443 OriginProtocolPolicy : https - only DefaultCacheBehavior : TargetOriginId : Origin ViewerProtocolPolicy : !If [ IsProduction , redirect - to - https , allow - all ] AllowedMethods : - GET - HEAD CachedMethods : - GET - HEAD Compress : !If [ IsProduction , true , false ] ForwardedValues : QueryString : false Cookies : Forward : none MinTTL : !If [ IsProduction , 0 , 0 ] DefaultTTL : !If [ IsProduction , 86400 , 3600 ] MaxTTL : !If [ IsProduction , 31536000 , 86400 ]
WAF only for staging and production
CloudFrontWebACL : Type : AWS : : WAFv2 : : WebACL Condition : EnableWAFProtection Properties : Name : !Sub "${AWS::StackName}-waf-acl" Scope : CLOUDFRONT DefaultAction : Allow : { } Rules : [ ] VisibilityConfig : SampledRequestsEnabled : true CloudWatchMetricsEnabled : true MetricName : CloudFrontWAFACL VPC Origins AWSTemplateFormatVersion : 2010-09-09 Description : CloudFront with VPC Origin Resources :
VPC Origin Endpoint
VPCOriginEndpoint : Type : AWS : : GlobalAccelerator : : EndpointGroup Properties : EndpointGroupRegion : !Ref VPCOriginRegion ListenerArn : !Ref AcceleratorListener EndpointConfigurations : - EndpointId : !Ref VPCEndpointService Weight : 128
CloudFront Distribution
CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : CallerReference : !Sub "${AWS::StackName}-${AWS::AccountId}" Comment : !Sub "CloudFront with VPC Origin" Enabled : true IPV6Enabled : true Origins : - Id : VPCOrigin DomainName : !Ref VPCOriginDomain CustomOriginConfig : HTTPPort : 443 HTTPSPort : 443 OriginProtocolPolicy : https - only OriginKeepaliveTimeout : 60 OriginReadTimeout : 30 DefaultCacheBehavior : TargetOriginId : VPCOrigin ViewerProtocolPolicy : https - only AllowedMethods : - GET - HEAD - OPTIONS CachedMethods : - GET - HEAD Compress : true ForwardedValues : QueryString : true Headers : - "*" Cookies : Forward : all MinTTL : 0 DefaultTTL : 3600 MaxTTL : 86400 Best Practices Security Always use HTTPS with minimum TLS 1.2 Implement SecurityHeaders with HSTS, XSS protection Use WAF for protection against common attacks Configure appropriate Access-Control for CORS Limit origin access with OAI/OAC Use Signed URLs for private content Implement rate limiting Configure geo-restrictions if needed Performance Use appropriate PriceClass to optimize costs Configure Cache TTL based on content type Enable compression (Gzip/Brotli) Use CloudFront Functions for lightweight operations Optimize header forwarding (do not forward unnecessary headers) Consider Origin Shield to reduce load on origins Use multiple origins with path patterns Monitoring Enable CloudWatch metrics and alarms Configure real-time logs for troubleshooting Monitor cache hit ratio Configure alerts for error rate and latency Use CloudFront reports for traffic analysis Deployment Use change sets before deployment Test templates with cfn-lint Organize stacks by lifecycle and ownership Implement blue/green deployments with weighted aliases Use StackSets for multi-region deployment CloudFormation Best Practices Stack Policies Stack Policies prevent accidental updates to critical resources during stack updates. AWSTemplateFormatVersion : 2010-09-09 Description : CloudFront distribution with stack policy Resources : CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : Enabled : true
... configuration
CloudFrontWebACL : Type : AWS : : WAFv2 : : WebACL Properties : Name : !Sub "${AWS::StackName}-waf" Scope : CLOUDFRONT DefaultAction : Allow : { } Rules : [ ] VisibilityConfig : SampledRequestsEnabled : true CloudWatchMetricsEnabled : true MetricName : CloudFrontWAF
Stack Policy - protect critical resources
Metadata : AWS::CloudFormation::StackPolicy : Statement : - Effect : Allow Action : Update : * Resource : "" - Effect : Deny Action : - Update : Replace - Update : Delete Resource : "LogicalID=CloudFrontDistribution" Principal : "" - Effect : Deny Action : - Update : Replace - Update : Delete Resource : "LogicalID=CloudFrontWebACL" Principal : "*" Termination Protection Enable termination protection to prevent accidental stack deletion. AWSTemplateFormatVersion : 2010-09-09 Description : CloudFront with termination protection Resources : CloudFrontDistribution : Type : AWS : : CloudFront : : Distribution Properties : DistributionConfig : Enabled : true
... configuration
Note: Termination protection is enabled via AWS Console or CLI
AWS CLI: aws cloudformation update-termination-protection --enable-termination-protection --stack-name my-stack
Or set it in a separate stack update after creation
Drift Detection Detect when infrastructure has been modified outside of CloudFormation.
AWS CLI commands for drift detection
Detect drift on a stack
aws cloudformation detect
stack
drift
- stack - name my - cloudfront - stack
Get drift detection status
aws cloudformation describe
stack
drift
detection
status
- stack - drift - detection - id <detection - id
Get resources that have drifted
aws cloudformation describe
stack
resource
drifts
- stack - name my - cloudfront - stack
Example drift detection output format
{
"StackResourceDrifts": [
{
"ResourceType": "AWS::CloudFront::Distribution",
"LogicalResourceId": "CloudFrontDistribution",
"PhysicalResourceId": "E1X2Y3Z4W5X6Y7",
"ResourceStatus": "UPDATE",
"PropertyDifferences": [
{
"PropertyPath": "$.DistributionConfig.Enabled",
"ExpectedValue": "true",
"ActualValue": "false"
}
],
"StackResourceDriftStatus": "MODIFIED"
}
]
}
Change Sets Preview and review changes before executing stack updates.
AWS CLI commands for change sets
1. Create a change set (preview)
aws cloudformation create
change
set \
- stack - name my - cloudfront - stack \ - - template - body file : //cloudfront - template.yaml \ - - change - set - name my - changeset \ - - capabilities CAPABILITY_IAM \ - - parameters ParameterKey=Environment , ParameterValue=production
2. Describe the change set to review changes
aws cloudformation describe
change
set \
- stack - name my - cloudfront - stack \ - - change - set - name my - changeset
3. Execute the change set if changes are acceptable
aws cloudformation execute
change
set \
- stack - name my - cloudfront - stack \ - - change - set - name my - changeset
Or delete if changes are not desired
aws cloudformation delete
change
set \
- stack - name my - cloudfront - stack \ - - change - set - name my - changeset
Change set with nested stacks example
AWSTemplateFormatVersion : 2010-09-09 Description : CloudFront infrastructure with nested stacks for change set management Resources :
Parent stack managing multiple CloudFront distributions
CloudFrontParentStack : Type : AWS : : CloudFormation : : Stack Properties : TemplateURL : !Sub "https://${ArtifactBucket}.s3.amazonaws.com/cloudfront-parent.yaml" TimeoutInMinutes : 30 Parameters : Environment : !Ref Environment CertificateArn : !Ref CertificateArn DomainName : !Ref DomainName Tags : - Key : Environment Value : !Ref Environment - Key : Project Value : !Ref ProjectName - Key : ManagedBy Value : CloudFormation
Change set will show impacts across all nested stacks
When updating, CloudFormation will show:
- Which nested stacks will be updated
- Resources being added, modified, or deleted
- IAM changes requiring special attention
Related Resources AWS CloudFront Documentation AWS CloudFormation User Guide CloudFront Developer Guide CloudFront Best Practices CloudFormation Stack Policies CloudFormation Drift Detection CloudFormation Change Sets Additional Files For complete details on resources and their properties, see: REFERENCE.md - Detailed reference guide for all CloudFormation resources EXAMPLES.md - Complete production-ready examples