aws-cloudformation-cloudfront
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAWS CloudFormation CloudFront CDN
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.
使用AWS CloudFormation模板创建生产就绪的CDN基础设施。本内容涵盖CloudFront分发、多源站(ALB、S3、Lambda@Edge、VPC源站)、CacheBehaviors、Functions、SecurityHeaders,以及参数、输出和跨栈引用的最佳实践。
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创建新的CloudFront分发
- 配置多源站(ALB、S3、API Gateway、Lambda@Edge、VPC源站)
- 结合CacheBehaviors和缓存策略实施缓存方案
- 使用ACM证书配置自定义域名
- 实施SecurityHeaders(CSP、HSTS、XSS防护)
- 配置CloudFront Functions和Lambda@Edge
- 管理地域限制和价格等级
- 将WAF与CloudFront集成
- 使用参数、输出、映射、条件组织模板
- 通过导出/导入实现跨栈引用
- 使用Transform实现宏和复用
CloudFormation Template Structure
CloudFormation模板结构
Standard Format Base Template
标准格式基础模板
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"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
AWS特定参数类型
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 executionyaml
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 executionParameter 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: 31536000yaml
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: 31536000SSM Parameter References
SSM参数引用
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 URLsyaml
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 URLsOutputs and Cross-Stack References
输出与跨栈引用
Export/Import Patterns
导出/导入模式
yaml
undefinedyaml
undefinedStack A - Network/Infrastructure Stack
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"
```yamlAWSTemplateFormatVersion: 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"
```yamlStack B - Application Stack (imports from Infrastructure Stack)
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
undefinedAWSTemplateFormatVersion: 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
undefinedNested 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 Environmentyaml
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 EnvironmentS3 Origins
S3源站
S3 Origin with OAI
带OAI的S3源站
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
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.DomainNameyaml
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.DomainNameS3 Origin with Origin Access Control (OAC)
带Origin Access Control (OAC)的S3源站
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
S3OriginConfig:
OriginAccessIdentity: ""
# For OAC, use OriginAccessControl instead of S3OriginConfig
# but CloudFormation supports bothyaml
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 bothALB Origins
ALB源站
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: 0yaml
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: 0Multiple Origins and CacheBehaviors
多源站与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
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: 0yaml
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: 0Cache 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 ManagedSecurityHeadersPolicyIdyaml
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 ManagedSecurityHeadersPolicyIdCustom Cache Policy
自定义缓存策略
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"
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.Idyaml
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.IdOrigin 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.Idyaml
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.IdResponse Headers Policies (Security Headers)
响应头策略(安全头)
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
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.Idyaml
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.IdCloudFront Functions
CloudFront Functions
Viewer Request Function
查看器请求函数
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';
}
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-requestyaml
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-requestLambda@Edge Functions
Lambda@Edge函数
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-requestyaml
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-requestGeo-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: 31536000yaml
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: 31536000WAF Integration
WAF集成
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: 31536000yaml
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: 31536000Real-Time Logs
实时日志
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
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: 31536000yaml
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: 31536000Conditions and Transform
条件与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: CloudFrontWAFACLyaml
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: CloudFrontWAFACLVPC Origins
VPC源站
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
# 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: 86400yaml
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: 86400Best 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
- 始终使用HTTPS,最低TLS版本为1.2
- 实施包含HSTS、XSS防护的SecurityHeaders
- 使用WAF防护常见攻击
- 配置适当的CORS访问控制
- 使用OAI/OAC限制源站访问
- 对私有内容使用签名URL
- 实施速率限制
- 必要时配置地域限制
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
- 使用合适的PriceClass优化成本
- 根据内容类型配置缓存TTL
- 启用压缩(Gzip/Brotli)
- 使用CloudFront Functions执行轻量级操作
- 优化头转发(不转发不必要的头)
- 考虑使用Origin Shield减少源站负载
- 使用带路径模式的多源站
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
- 启用CloudWatch指标和告警
- 配置实时日志用于故障排查
- 监控缓存命中率
- 配置错误率和延迟告警
- 使用CloudFront报告进行流量分析
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
- 部署前使用变更集
- 使用cfn-lint测试模板
- 按生命周期和归属组织栈
- 使用加权别名实现蓝绿部署
- 使用StackSets进行多区域部署
CloudFormation Best Practices
CloudFormation最佳实践
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栈策略可防止在栈更新期间意外更新关键资源。
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: CloudFrontWAFStack Policy - protect critical resources
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: "*"
undefinedMetadata:
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: "*"
undefinedTermination 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启用终止保护以防止意外删除栈。
yaml
AWSTemplateFormatVersion: 2010-09-09
Description: CloudFront with termination protection
Resources:
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
# ... configurationNote: Termination protection is enabled via AWS Console or CLI
Note: Termination protection is enabled via AWS Console or CLI
AWS CLI: aws cloudformation update-termination-protection --enable-termination-protection --stack-name my-stack
AWS CLI: aws cloudformation update-termination-protection --enable-termination-protection --stack-name my-stack
Or set it in a separate stack update after creation
Or set it in a separate stack update after creation
undefinedundefinedDrift Detection
漂移检测
Detect when infrastructure has been modified outside of CloudFormation.
yaml
undefined检测基础设施是否在CloudFormation之外被修改。
yaml
undefinedAWS CLI commands for drift detection
AWS CLI commands for drift detection
Detect drift on a stack
Detect drift on a stack
aws cloudformation detect-stack-drift --stack-name my-cloudfront-stack
aws cloudformation detect-stack-drift --stack-name my-cloudfront-stack
Get drift detection status
Get drift detection status
aws cloudformation describe-stack-drift-detection-status --stack-drift-detection-id <detection-id>
aws cloudformation describe-stack-drift-detection-status --stack-drift-detection-id <detection-id>
Get resources that have drifted
Get resources that have drifted
aws cloudformation describe-stack-resource-drifts --stack-name my-cloudfront-stack
aws cloudformation describe-stack-resource-drifts --stack-name my-cloudfront-stack
Example drift detection output format
Example drift detection output format
{
{
"StackResourceDrifts": [
"StackResourceDrifts": [
{
{
"ResourceType": "AWS::CloudFront::Distribution",
"ResourceType": "AWS::CloudFront::Distribution",
"LogicalResourceId": "CloudFrontDistribution",
"LogicalResourceId": "CloudFrontDistribution",
"PhysicalResourceId": "E1X2Y3Z4W5X6Y7",
"PhysicalResourceId": "E1X2Y3Z4W5X6Y7",
"ResourceStatus": "UPDATE",
"ResourceStatus": "UPDATE",
"PropertyDifferences": [
"PropertyDifferences": [
{
{
"PropertyPath": "$.DistributionConfig.Enabled",
"PropertyPath": "$.DistributionConfig.Enabled",
"ExpectedValue": "true",
"ExpectedValue": "true",
"ActualValue": "false"
"ActualValue": "false"
}
}
],
],
"StackResourceDriftStatus": "MODIFIED"
"StackResourceDriftStatus": "MODIFIED"
}
}
]
]
}
}
undefinedundefinedChange Sets
变更集
Preview and review changes before executing stack updates.
yaml
undefined在执行栈更新前预览和审查变更。
yaml
undefinedAWS CLI commands for change sets
AWS CLI commands for change sets
1. Create a change set (preview)
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
--stack-name my-cloudfront-stack
--template-body file://cloudfront-template.yaml
--change-set-name my-changeset
--capabilities CAPABILITY_IAM
--parameters ParameterKey=Environment,ParameterValue=production
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
--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
2. Describe the change set to review changes
aws cloudformation describe-change-set
--stack-name my-cloudfront-stack
--change-set-name my-changeset
--stack-name my-cloudfront-stack
--change-set-name my-changeset
aws cloudformation describe-change-set
--stack-name my-cloudfront-stack
--change-set-name my-changeset
--stack-name my-cloudfront-stack
--change-set-name my-changeset
3. Execute the change set if changes are acceptable
3. Execute the change set if changes are acceptable
aws cloudformation execute-change-set
--stack-name my-cloudfront-stack
--change-set-name my-changeset
--stack-name my-cloudfront-stack
--change-set-name my-changeset
aws cloudformation execute-change-set
--stack-name my-cloudfront-stack
--change-set-name my-changeset
--stack-name my-cloudfront-stack
--change-set-name my-changeset
Or delete if changes are not desired
Or delete if changes are not desired
aws cloudformation delete-change-set
--stack-name my-cloudfront-stack
--change-set-name my-changeset
--stack-name my-cloudfront-stack
--change-set-name my-changeset
```yamlaws cloudformation delete-change-set
--stack-name my-cloudfront-stack
--change-set-name my-changeset
--stack-name my-cloudfront-stack
--change-set-name my-changeset
```yamlChange set with nested stacks example
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
undefinedAWSTemplateFormatVersion: 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
undefinedRelated Resources
相关资源
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
有关资源及其属性的完整详细信息,请参阅:
- REFERENCE.md - 所有CloudFormation资源的详细参考指南
- EXAMPLES.md - 完整的生产就绪示例