git:20260223.c6d4db1 to git:20260323.935227a

88 added, 1585 removed. Audit A to A.

---
name: aws-cloudformation-cloudfront
description: Provides AWS CloudFormation patterns for CloudFront distributions, origins (ALB, S3, Lambda@Edge, VPC Origins), CacheBehaviors, Functions, SecurityHeaders, parameters, Outputs and cross-stack references. Use when creating CloudFront distributions with CloudFormation, configuring multiple origins, implementing caching strategies, managing custom domains with ACM, configuring WAF, and optimizing performance.
allowed-tools: Read, Write, Bash
---
# 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.
+ Create production-ready CDN infrastructure using AWS CloudFormation templates. This skill covers CloudFront distributions, multiple origins (ALB, S3, API Gateway, 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
## Instructions
Follow these steps to create CloudFront distributions with CloudFormation:
- 1. **Define Distribution Parameters**: Specify domain names, ACM certificates, and price class
- 2. **Configure Origins**: Add S3 buckets, ALBs, API Gateway, or custom origins
- 3. **Set Up Default Cache Behavior**: Configure viewer request/response policies
- 4. **Add Additional Cache Behaviors**: Create path-specific caching rules
- 5. **Configure Security Settings**: Implement security headers and WAF integration
- 6. **Add Lambda@Edge Functions**: Configure functions for request/response manipulation
- 7. **Set Up Custom Error Pages**: Define error responses for specific HTTP status codes
- 8. **Create Monitoring**: Configure logging and access logs to S3
-
- For complete examples, see the [EXAMPLES.md](references/examples.md) file.
-
- ## Examples
-
- The following examples demonstrate common CloudFront patterns:
-
- ### Example 1: CloudFront Distribution with S3 Origin
-
- ```yaml
- CloudFrontDistribution:
- Type: AWS::CloudFront::Distribution
- Properties:
- DistributionConfig:
- Origins:
- - DomainName: !GetAtt S3Bucket.RegionalDomainName
- Id: S3Origin
- S3OriginConfig:
- OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${OAI}"
- DefaultCacheBehavior:
- TargetOriginId: S3Origin
- ViewerProtocolPolicy: redirect-to-https
- CachePolicyId: !Ref CachePolicy
- Enabled: true
- HttpVersion: http2and3
- IPV6Enabled: true
- ```
-
- ### Example 2: Cache Policy Configuration
-
- ```yaml
- CachePolicy:
- Type: AWS::CloudFront::CachePolicy
- Properties:
- CachePolicyConfig:
- Name: !Sub "${AWS::StackName}-cache-policy"
- DefaultTTL: 86400
- MaxTTL: 31536000
- MinTTL: 0
- ParametersInCacheKeyAndForwardedToOrigin:
- CookiesConfig:
- CookieBehavior: none
- HeadersConfig:
- HeaderBehavior: none
- QueryStringsConfig:
- QueryStringBehavior: none
- ```
-
- ### Example 3: Origin Request Policy
-
- ```yaml
- OriginRequestPolicy:
- Type: AWS::CloudFront::OriginRequestPolicy
- Properties:
- OriginRequestPolicyConfig:
- Name: !Sub "${AWS::StackName}-origin-request"
- CookiesConfig:
- CookieBehavior: all
- HeadersConfig:
- HeaderBehavior: whitelist
- Headers:
- - Origin
- - Access-Control-Request-Method
- - Access-Control-Request-Headers
- QueryStringsConfig:
- QueryStringBehavior: all
- ```
-
- For complete production-ready examples, see [EXAMPLES.md](references/examples.md).
-
- ## CloudFormation Template Structure
+ ### 1. Define Distribution Parameters
- ### Standard Format Base Template
+ Specify domain names, ACM certificates, price class, and origin settings:
```yaml
- 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
-
- ```yaml
- 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
-
- ```yaml
- 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-]*[a-z0-9])?(\\.[a-z0-9]([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
-
- ```yaml
- 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
-
- ```yaml
- # 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"
- ```
-
- ```yaml
- # 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
-
- ```yaml
- 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
+ ### 2. Configure Origins
- ### S3 Origin with OAI
+ Add S3 buckets, ALBs, API Gateway, or custom origins. For S3 origins, use OAI (legacy) or OAC (recommended):
```yaml
- 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
+ # Origin Access Control (recommended)
+ OriginAccessControl:
+ Type: AWS::CloudFront::OriginAccessControl
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
+ OriginAccessControlConfig:
+ Name: !Sub "${AWS::StackName}-oac"
+ OriginAccessControlOriginType: s3
+ SigningBehavior: always
+ SigningProtocol: sigv4
```
- ### S3 Origin with Origin Access Control (OAC)
+ ### 3. Set Up Default Cache Behavior
+ Configure viewer request/response policies and caching:
+
```yaml
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
+ AccessControlId: !Ref OriginAccessControl
S3OriginConfig:
OriginAccessIdentity: ""
- # For OAC, use OriginAccessControl instead of S3OriginConfig
- # but CloudFormation supports both
- ```
-
- ## ALB Origins
-
- ### Application Load Balancer Origin
-
- ```yaml
- 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
-
- ```yaml
- 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
+ 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
- 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
+ CachePolicyId: !Ref CachePolicy
```
- ## Cache Policies
-
- ### Managed Cache Policy
-
- ```yaml
- 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
- ```
+ ### 4. Add Additional Cache Behaviors
- ### Custom Cache Policy
+ Create path-specific caching rules for different content types:
```yaml
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"
+ Name: !Sub "${AWS::StackName}-api-cache"
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
-
- ```yaml
- 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
+ AllowedMethods:
+ - GET
+ - HEAD
+ - OPTIONS
+ - PUT
+ - POST
```
- ## Response Headers Policies (Security Headers)
+ ### 5. Configure Security Settings
+ Implement security headers and WAF integration:
+
```yaml
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
+ FrameOptions:
+ FrameOption: DENY
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
+ WAFWebACL:
+ Type: AWS::WAFv2::WebACL
Properties:
- DistributionConfig:
- DefaultCacheBehavior:
- TargetOriginId: StaticAssetsOrigin
- ResponseHeadersPolicyId: !GetAtt SecurityHeadersPolicy.Id
+ Name: !Sub "${AWS::StackName}-waf"
+ Scope: CLOUDFRONT
+ DefaultAction:
+ Allow: {}
```
- ## CloudFront Functions
+ ### 6. Add CloudFront Functions
- ### Viewer Request Function
+ Configure functions for request/response manipulation:
```yaml
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';
- }
-
+ // Function code here
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
-
- ```yaml
- 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
-
- ```yaml
- 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
-
- ```yaml
- 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
- ```
+ ### 7. Configure Monitoring
- ## Real-Time Logs
+ Set up logging and access logs to S3:
```yaml
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
+ AccessLogsBucket:
+ Type: AWS::S3::Bucket
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
+ BucketName: !Sub "cloudfront-logs-${AWS::AccountId}"
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
+ Logging:
+ Bucket: !Ref AccessLogsBucket
+ Prefix: cloudfront-logs/
+ IncludeCookies: false
```
- ## Conditions and Transform
-
- ### Conditions for Environment-Specific Configuration
-
- ```yaml
- 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
- ```
+ ### 8. Create Outputs
- ## VPC Origins
+ Export distribution details for cross-stack references:
```yaml
- 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
+ Outputs:
+ DistributionDomainName:
+ Description: CloudFront distribution domain name
+ Value: !GetAtt CloudFrontDistribution.DomainName
+ Export:
+ Name: !Sub "${AWS::StackName}-DistributionDomainName"
- # 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
+ DistributionId:
+ Description: CloudFront distribution ID
+ Value: !Ref CloudFrontDistribution
+ Export:
+ Name: !Sub "${AWS::StackName}-DistributionId"
```
## 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.
-
- ```yaml
- 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.
-
- ```yaml
- 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.
-
- ```yaml
- # 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
+ ### Template Structure
- # 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"
- # }
- # ]
- # }
- ```
+ - Use AWS-specific parameter types (AWS::ACM::Certificate::Arn, AWS::S3::Bucket::RegionalDomainName)
+ - Implement parameter constraints (MinLength, MaxLength, AllowedValues, AllowedPattern)
+ - Use Conditions for environment-specific configuration
+ - Leverage Mappings for region-specific configuration
+ - Apply Metadata for parameter grouping and labels
+ - Use nested stacks for modularity
- ### Change Sets
+ ### Cache Strategy
- Preview and review changes before executing stack updates.
+ - Use Cache Policies for different content types
+ - Configure Origin Request Policies to control what's sent to origin
+ - Set appropriate TTL values:
+ - Static assets: 86400-31536000 seconds (1 day to 1 year)
+ - API responses: 60-600 seconds (1-10 minutes)
+ - Dynamic content: 0 seconds (no caching)
+ - Enable compression for text-based content
+ - Use versioned paths for cache busting
- ```yaml
- # AWS CLI commands for change sets
+ ## References
- # 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
+ For detailed implementation guidance, see:
- # 2. Describe the change set to review changes
- aws cloudformation describe-change-set \
- --stack-name my-cloudfront-stack \
- --change-set-name my-changeset
+ - **[template-structure.md](references/template-structure.md)** - Complete template structure, AWS-specific parameter types, parameter constraints, SSM parameter references, metadata for parameter grouping, transform for macros, conditions for environment-specific configuration, nested stacks, and cross-stack references with export/import patterns
- # 3. Execute the change set if changes are acceptable
- aws cloudformation execute-change-set \
- --stack-name my-cloudfront-stack \
- --change-set-name my-changeset
+ - **[origins.md](references/origins.md)** - Origin configuration including S3 origins with OAI/OAC, ALB origins with security groups, API Gateway origins (REST and HTTP APIs), Lambda@Edge origins, VPC origins with Global Accelerator, custom origins, and multi-origin configurations with path patterns
- # Or delete if changes are not desired
- aws cloudformation delete-change-set \
- --stack-name my-cloudfront-stack \
- --change-set-name my-changeset
- ```
+ - **[caching.md](references/caching.md)** - Cache policies (managed, custom, images, videos), origin request policies, response headers policies, cache behaviors configuration, forwarded values (query strings, headers, cookies), cache key configuration, and TTL configuration best practices
- ```yaml
- # Change set with nested stacks example
- AWSTemplateFormatVersion: 2010-09-09
- Description: CloudFront infrastructure with nested stacks for change set management
+ - **[security.md](references/security.md)** - Security headers (CSP, HSTS, XSS protection), CORS configuration, WAF integration with managed and custom rules, origin access control (OAI vs OAC), signed URLs and signed cookies, geo-restrictions, HTTPS enforcement, TLS configuration, and field-level encryption
- 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
+ - **[advanced-features.md](references/advanced-features.md)** - CloudFront Functions (viewer request, viewer response, origin request), Lambda@Edge for authentication and URL rewriting, geo-restrictions, price class optimization, compression (Gzip and Brotli), real-time logs to Kinesis and S3, custom error pages, function associations, and Origin Shield configuration
- # 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
- ```
+ - **[constraints.md](references/constraints.md)** - Resource limits (200 distributions max, 25 origins max, 25 cache behaviors max), DNS and certificate constraints (ACM in us-east-1, 300 alternate domain names), operational constraints (15 invalidations max, 30 min deployment), security constraints (HTTPS, CSP, WAF), and cost considerations (data transfer, regional pricing, Lambda@Edge costs)
## Related Resources
- [AWS CloudFront Documentation](https://docs.aws.amazon.com/cloudfront/)
- [AWS CloudFormation User Guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/)
- [CloudFront Developer Guide](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/)
- [CloudFront Best Practices](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html)
- [CloudFormation Stack Policies](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html)
- [CloudFormation Drift Detection](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/detect-drift-stack.html)
- [CloudFormation Change Sets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-changesets.html)
-
- ## Constraints and Warnings
-
- ### Resource Limits
-
- - **Distribution Limits**: Maximum 200 CloudFront distributions per AWS account
- - **Origins Limits**: Maximum 25 origins per distribution
- - **Cache Behaviors**: Maximum 25 cache behaviors per distribution
- - **Custom Headers**: Maximum 10 custom headers per origin
-
- ### DNS and Certificate Constraints
-
- - **Domain Registration**: Custom domains must be registered and verified before use
- - **ACM Certificate Limits**: Certificates must be in us-east-1 for CloudFront regardless of distribution region
- - **DNS Propagation**: DNS changes can take up to 24 hours to propagate globally
- - **Alternate Domain Names**: Maximum 300 alternate domain names per distribution
-
- ### Operational Constraints
-
- - **Invalidation Limits**: Maximum 15 invalidation requests in progress at once
- - **Deployment Time**: Distribution deployment can take up to 30 minutes
- - **Edge Location Caching**: Changes at origins may not be reflected immediately due to caching
- - **Geo Restriction Accuracy**: Geo restriction based on IP addresses may not be 100% accurate
-
- ### Security Constraints
-
- - **HTTPS Only**: Modern browsers block HTTP-only content on HTTPS pages
- - **CSP Headers**: Content Security Policy headers can break functionality if misconfigured
- - **WAF Integration**: WAF rules add latency and may block legitimate traffic
- - **Origin Access**: OAI/OAC restrictions prevent direct S3 access but complicate testing
-
- ### Cost Considerations
-
- - **Data Transfer Out**: CloudFront charges for data transfer out to internet
- - **Regional Pricing**: Costs vary significantly by edge location
- - **HTTPS Requests**: Encrypted requests have higher CPU utilization cost
- - **Lambda@Edge**: Lambda@Edge functions add significant per-invocation cost
-
- ## Additional Files
-
- For complete details on resources and their properties, see:
- - [REFERENCE.md](references/reference.md) - Detailed reference guide for all CloudFormation resources
- - [EXAMPLES.md](references/examples.md) - Complete production-ready examples