AWSTemplateFormatVersion: 2010-09-09 Description: 0.3 - Using Amazon CloudFront to cache and route static requests directly to S3. Transform: AWS::Serverless-2016-10-31 ########################################################################## # Parameters & Globals # ########################################################################## Globals: Function: Timeout: 3 Resources: ########################################################################## # API Gateway with stage name # ########################################################################## HttpApi: Type: AWS::Serverless::HttpApi Properties: StageName: dev ########################################################################## # S3 Bucket to store static assets # ########################################################################## Assets: Type: AWS::S3::Bucket Properties: BucketName: !Sub 'cf-origin-${AWS::AccountId}-${AWS::StackName}' # The policy that makes the bucket publicly readable AssetsBucketPolicy: Type: AWS::S3::BucketPolicy Properties: Bucket: Ref: Assets # References the bucket we defined above PolicyDocument: Statement: Effect: Allow Action: s3:GetObject # to read Principal: CanonicalUser: Fn::GetAtt: S3OriginIdentityExample.S3CanonicalUserId Resource: # things in the bucket 'arn:aws:s3:::/*' Fn::Join: - "" - - "arn:aws:s3:::" - Ref: Assets - "/*" ########################################################################## # Lambda function with PHP runtime provided by layers # ########################################################################## CatchAllLambdaFunction: Type: AWS::Serverless::Function Properties: Description: Lambda function to hosts entire application codebase CodeUri: . Runtime: provided.al2 # the layer and runtime need to be the same Handler: index.php MemorySize: 1024 Timeout: 30 Tracing: Active Layers: - !Sub 'arn:aws:lambda:${AWS::Region}:209497400698:layer:php-81-fpm:19' Events: DynamicRequestsRoot: Type: HttpApi Properties: ApiId: !Ref HttpApi Path: / Method: ANY DynamicRequestsProxy: Type: HttpApi Properties: ApiId: !Ref HttpApi Path: /{proxy+} Method: ANY ########################################################################## # CloudFront configuration # ########################################################################## Cloudfrontdistribution: Type: AWS::CloudFront::Distribution Properties: DistributionConfig: Enabled: true Origins: - Id: Website DomainName: !Sub '${HttpApi}.execute-api.${AWS::Region}.${AWS::URLSuffix}' # This is the stage OriginPath: "/dev" CustomOriginConfig: OriginProtocolPolicy: 'https-only' # API Gateway only supports HTTPS # The assets (S3) - Id: Assets DomainName: !GetAtt Assets.RegionalDomainName S3OriginConfig: OriginAccessIdentity: !Sub 'origin-access-identity/cloudfront/${S3OriginIdentityExample}' # The default behavior is to send everything to AWS Lambda DefaultCacheBehavior: AllowedMethods: [GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE] TargetOriginId: Website # the PHP application ForwardedValues: QueryString: true Cookies: Forward: all # Forward cookies to use them in PHP # We must *not* forward the `Host` header else it messes up API Gateway Headers: - 'Accept' - 'Accept-Language' - 'Origin' - 'Referer' ViewerProtocolPolicy: redirect-to-https CacheBehaviors: # Assets will be served under the `/assets/` prefix - PathPattern: 'assets/*' TargetOriginId: Assets # the static files on S3 AllowedMethods: [GET, HEAD] ViewerProtocolPolicy: redirect-to-https ForwardedValues: # No need for all that with assets QueryString: false Cookies: Forward: none #ViewerProtocolPolicy: redirect-to-https Compress: true S3OriginIdentityExample: Type: AWS::CloudFront::CloudFrontOriginAccessIdentity Properties: CloudFrontOriginAccessIdentityConfig: Comment: Cloudfront OAI ########################################################################## # Stack Outputs # ########################################################################## Outputs: BucketName: Description: 'S3 Bucket Name' Value: !Ref Assets DistributionId: Description: 'CloudFront Distribution ID' Value: !Ref Cloudfrontdistribution Domain: Description: 'Cloudfront Domain' Value: !GetAtt Cloudfrontdistribution.DomainName