How can I provision an AWS API Gateway, fronted by CloudFront (so that I can have HTTP to HTTPS redirects) and backed by an AWS Lambda function using the AWS_PROXY
integration type using CloudFormation?
Below is a CloudFormation template showing what I've tried. It includes
AWS_PROXY
mode.
isBase64Encoded
set to True.AWS::ApiGateway::RestApi
CloudFormation resource that includes a BinaryMediaTypes
property containing a value of *~1*
.
*/*
is suggested in this AWS doc page and the CloudFormation docs explain that Slashes must be escaped with ~1. For example, image/png would be image~1png in the BinaryMediaTypes list
I've read through this AWS Forum post, AWS_PROXY and binary responses but haven't figured out what I'm doing wrong. The forum post includes people posting both about AWS_PROXY
mode as well as other modes so it gets a bit confusing.
This AWS doc page, Support Binary Payloads in API Gateway
, is, I believe, talking about modes other than AWS_PROXY
as it talks about setting the IntegrationResponses property which requires using a StatusCode which matches a MethodResponse StatusCode.
Here is a CloudFormation template that exhibits the problem. You can reproduce it with these steps
curl
the URL of the API GatewayIf this worked correctly you'd get back a binary png HTTP response, instead you get back a base64 response.
AWSTemplateFormatVersion: 2010-09-09
Description: Test binary responses with AWS_PROXY mode
Parameters:
CustomDomainName:
Type: String
Description: The custom domain name to use for the API
Default: ''
# AWS::ApiGateway::DomainName can not contain any uppercase characters
AllowedPattern: '^[^A-Z]*$'
ConstraintDescription: must not contain any uppercase characters
DomainNameZone:
Type: String
Description: The Route53 DNS zone containing the custom domain name
Default: ''
CertificateArn:
Type: String
Description: The ARN of the AWS ACM Certificate for your custom domain name
Default: ''
Resources:
TestFunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: AllowLambdaLogging
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
TestFunction:
Type: AWS::Lambda::Function
Properties:
Description: Test Function
Code:
ZipFile: |
def lambda_handler(event, context):
body = 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAKCAYAAABSfLWiAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA0gAAANIBBp0MHQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHgSURBVCiRlY47aFNxGEfP97/p05SWYhXfEHMjNZobuChYk1iwUCKKiqSjj0XpIM46uDgUQdxqk0lUHJwsiEPtoEmtgxhMIx2StFJBhA4tOCTVPO7n0C5uesbDj8NPAEJO4oXCLqDHU3PbktYJhM/lwty07SRmEHlQKWRn7Uh8VlRvqDFpoEdgo7yQO+0DqP80V1ZW3v0KOcMxI95dMFOqnD8YGfoAckCUZMCNlWhKvxoGxaNWLuZGAQUQwNhOfEJFjhqPugo7u7RzZEN+50HvgO4R5KKKPkVlb9VXfbit5X+Cp2FBn5WLc/dNyBkeAkksFXJnWurdA6xi8U0VqIBc89R6q0hVPLmgtF7+yOdrlUI2ZdXb4hhzKRQ95frENL6qZ+2zo/FHqHQAA6RSlpZWp0WYWC5mF4NO4j3C1aWF+UXbiZ0VZKxFo4pitTcbywAE3JHeQDRhAxIOh9vZxITDw34A13Xbdrtu95Yn4Mb2HzoSjwSDyQ4A0SlOyjjz/Af6mE7q3AQGgW4D1DTDc01zWTP0/lPlG02ULxgmUfoEQCfx4+MWMI5SQvi0NVpDWcejC6EfsBGOA4cR0vh4RZNz8tfNzVgSYRTlGLADGADWge/AR4QZ+ngtY9Q1w3aus/YHPCW0c1bW92YAAAAASUVORK5CYII='
return {
'headers': {'Content-Type': 'image/png'},
'statusCode': 200,
'isBase64Encoded': True,
'body': body}
Handler: index.lambda_handler
Runtime: python3.7
Role: !GetAtt TestFunctionRole.Arn
Timeout: 900
TestFunctionLogGroup:
Type: AWS::Logs::LogGroup
Properties:
# Let's hope that the Lambda function doesn't execute before this LogGroup
# resource is created, creating the LogGroup with no expiration and
# preventing this resource from creating
LogGroupName: !Join [ '/', ['/aws/lambda', !Ref 'TestFunction' ] ]
RetentionInDays: 1
TestRoute53RecordSet:
Type: AWS::Route53::RecordSet
Properties:
AliasTarget:
DNSName: !GetAtt TestCloudFrontDistribution.DomainName
HostedZoneId: Z2FDTNDATAQYW2 # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget-1.html
Comment: Bind the custom domain name to the Test CloudFront fronted API Gateway
HostedZoneName: !Ref DomainNameZone
Name: !Ref CustomDomainName
Type: A
TestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: Test
BinaryMediaTypes:
- '*~1*'
Description: Test API
FailOnWarnings: true
EndpointConfiguration:
Types:
- REGIONAL
TestApiGatewayDomainName:
# The ApiGateway requires a custom domain name, despite sitting behind
# CloudFront. This is because we want to pass all ( * ) HTTP headers
# through CloudFront and onto API Gateway. If we didn't set a custom domain
# name on the API Gateway, the "Host" header passed through from CloudFront
# to API Gateway would be for the custom domain, but API Gateway, which uses
# SNI, wouldn't know which TLS certificate to use in the handshake because
# API Gateway would have no record of that Host header. This would result in
# API Gateway being unable to setup a TLS connection with the inbound
# CloudFront connection attempt, API Gateway writing no logs about this
# fact, and CloudFront returning to the user an error of
# {"message":"Forbidden"}
# If we weren't passing the "Host" header from CloudFront to API Gateway
# this resource wouldn't be needed
Type: AWS::ApiGateway::DomainName
Properties:
# Uppercase letters are not supported in DomainName
DomainName: !Ref CustomDomainName
EndpointConfiguration:
Types:
- REGIONAL
RegionalCertificateArn: !Ref CertificateArn
SecurityPolicy: TLS_1_2
TestBasePathMapping:
Type: AWS::ApiGateway::BasePathMapping
Properties:
# BasePath: # Not specifying this so that we have no base path
DomainName: !Ref TestApiGatewayDomainName
RestApiId: !Ref TestApi
Stage: !Ref TestApiStage
TestLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:invokeFunction
FunctionName: !GetAtt TestFunction.Arn
Principal: apigateway.amazonaws.com
SourceArn: !Join [ '', [ 'arn:aws:execute-api:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref 'TestApi', '/*/*' ] ]
TestApiStage:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId: !Ref TestApiDeployment
MethodSettings:
- DataTraceEnabled: true
HttpMethod: '*'
ResourcePath: /*
RestApiId: !Ref TestApi
TestApiDeployment:
Type: AWS::ApiGateway::Deployment
DependsOn:
- TestRequest
Properties:
RestApiId: !Ref TestApi
StageName: DummyStage
# Deployment with an Empty Embedded Stage
# The following instructional text is no longer present in the AWS
# documentation for AWS::ApiGateway::Deployment StageName and it's not
# clear if it still applies.
#
# "Note This property is required by API Gateway. We recommend that you
# specify a name using any value (see Examples) and that you don’t use
# this stage. We recommend not using this stage because it is tied to
# this deployment, which means you can’t delete one without deleting the
# other. For example, if you delete this deployment, API Gateway also
# deletes this stage, which you might want to keep. Instead, use the
# AWS::ApiGateway::Stage resource to create and associate a stage with
# this deployment."
TestResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApi
ParentId: !GetAtt TestApi.RootResourceId
PathPart: '{proxy+}'
TestRequest:
DependsOn: TestLambdaPermission
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: GET
Integration:
Type: AWS_PROXY
# IntegrationHttpMethod is POST regardless of the HttpMethod for this resource
# https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
# "For Lambda integrations, you must use the HTTP method of POST for the
# integration request, according to the specification of the Lambda service
# action for function invocations."
IntegrationHttpMethod: POST
Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
ResourceId: !Ref TestResource
RestApiId: !Ref TestApi
TestPOSTRequest:
DependsOn: TestLambdaPermission
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: POST
Integration:
Type: AWS_PROXY
# https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
# "For Lambda integrations, you must use the HTTP method of POST for the
# integration request, according to the specification of the Lambda service
# action for function invocations."
IntegrationHttpMethod: POST
Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
ResourceId: !Ref TestResource
RestApiId: !Ref TestApi
TestRootRequest:
# This resource is necessary to get API Gateway to respond to requests for the '/' path
# Without it API Gateway will respond to requests for '/' with the error
# {"message":"Missing Authentication Token"}
# https://stackoverflow.com/q/46578615/168874
# https://stackoverflow.com/q/52909329/168874
DependsOn: TestLambdaPermission
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: GET
Integration:
Type: AWS_PROXY
# IntegrationHttpMethod is POST regardless of the HttpMethod for this resource
# https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
# "For Lambda integrations, you must use the HTTP method of POST for the
# integration request, according to the specification of the Lambda service
# action for function invocations."
IntegrationHttpMethod: POST
Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
# ResourceId must use the RootResourceId attribute of the AWS::ApiGateway::RestApi
# https://stackoverflow.com/a/56121914/168874
ResourceId: !GetAtt TestApi.RootResourceId
RestApiId: !Ref TestApi
TestCloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Comment: !Join [ ':', [!Ref 'AWS::StackName', 'Test']]
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- POST
- DELETE
- OPTIONS
- PUT
- PATCH
Compress: true
DefaultTTL: 0
MinTTL: 0
MaxTTL: 0
ForwardedValues:
Cookies:
Forward: all
QueryString: true
Headers:
- '*'
TargetOriginId: TestCloudFrontOriginId
ViewerProtocolPolicy: redirect-to-https
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-defaultrootobject
DefaultRootObject: '' # "If you don't want to specify a default root object when you create a distribution, include an empty DefaultRootObject element."
Enabled: true
Aliases:
- !Ref CustomDomainName
HttpVersion: http2
IPV6Enabled: true
#Logging:
# Logging
Origins:
- CustomOriginConfig:
OriginProtocolPolicy: https-only
OriginSSLProtocols:
- TLSv1.2
DomainName: !GetAtt TestApiGatewayDomainName.RegionalDomainName
Id: TestCloudFrontOriginId
# OriginPath: !Join [ '', [ '/', !Ref 'TestApiStage' ] ]
PriceClass: PriceClass_100 # US, Canada, Europe, Israel
ViewerCertificate:
AcmCertificateArn: !Ref CertificateArn
MinimumProtocolVersion: TLSv1.2_2018
SslSupportMethod: sni-only
I contacted AWS Support and after many back and forths found that the problem is in the AWS documentation.
The documentation page on the AWS::ApiGateway::RestApi
CloudFormation resource type incorrectly states
Slashes must be escaped with ~1. For example, image/png would be image~1png in the BinaryMediaTypes list.
It turns out this is not true and the value that you should put in the BinaryMediaTypes
field is */*
not *~1*
. This makes the field look like this
Resources:
TestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: Test
BinaryMediaTypes:
- '*/*'
So with that change to the template in the question, the resulting stack correctly serves up binary resources.
I've confirmed that this AWS doc page, Support Binary Payloads in API Gateway
, is indeed talking about modes other than AWS_PROXY
and doesn't apply to my question.
The template with the fix that I've confirmed works is this
AWSTemplateFormatVersion: 2010-09-09
Description: Test binary responses with AWS_PROXY mode
Parameters:
CustomDomainName:
Type: String
Description: The custom domain name to use for the API
Default: ''
# AWS::ApiGateway::DomainName can not contain any uppercase characters
AllowedPattern: '^[^A-Z]*$'
ConstraintDescription: must not contain any uppercase characters
DomainNameZone:
Type: String
Description: The Route53 DNS zone containing the custom domain name
Default: ''
CertificateArn:
Type: String
Description: The ARN of the AWS ACM Certificate for your custom domain name
Default: ''
Resources:
TestFunctionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: AllowLambdaLogging
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
TestFunction:
Type: AWS::Lambda::Function
Properties:
Description: Test Function
Code:
ZipFile: |
def lambda_handler(event, context):
body = 'iVBORw0KGgoAAAANSUhEUgAAABEAAAAKCAYAAABSfLWiAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAA0gAAANIBBp0MHQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHgSURBVCiRlY47aFNxGEfP97/p05SWYhXfEHMjNZobuChYk1iwUCKKiqSjj0XpIM46uDgUQdxqk0lUHJwsiEPtoEmtgxhMIx2StFJBhA4tOCTVPO7n0C5uesbDj8NPAEJO4oXCLqDHU3PbktYJhM/lwty07SRmEHlQKWRn7Uh8VlRvqDFpoEdgo7yQO+0DqP80V1ZW3v0KOcMxI95dMFOqnD8YGfoAckCUZMCNlWhKvxoGxaNWLuZGAQUQwNhOfEJFjhqPugo7u7RzZEN+50HvgO4R5KKKPkVlb9VXfbit5X+Cp2FBn5WLc/dNyBkeAkksFXJnWurdA6xi8U0VqIBc89R6q0hVPLmgtF7+yOdrlUI2ZdXb4hhzKRQ95frENL6qZ+2zo/FHqHQAA6RSlpZWp0WYWC5mF4NO4j3C1aWF+UXbiZ0VZKxFo4pitTcbywAE3JHeQDRhAxIOh9vZxITDw34A13Xbdrtu95Yn4Mb2HzoSjwSDyQ4A0SlOyjjz/Af6mE7q3AQGgW4D1DTDc01zWTP0/lPlG02ULxgmUfoEQCfx4+MWMI5SQvi0NVpDWcejC6EfsBGOA4cR0vh4RZNz8tfNzVgSYRTlGLADGADWge/AR4QZ+ngtY9Q1w3aus/YHPCW0c1bW92YAAAAASUVORK5CYII='
return {
'headers': {'Content-Type': 'image/png'},
'statusCode': 200,
'isBase64Encoded': True,
'body': body}
Handler: index.lambda_handler
Runtime: python3.7
Role: !GetAtt TestFunctionRole.Arn
Timeout: 900
TestFunctionLogGroup:
Type: AWS::Logs::LogGroup
Properties:
# Let's hope that the Lambda function doesn't execute before this LogGroup
# resource is created, creating the LogGroup with no expiration and
# preventing this resource from creating
LogGroupName: !Join [ '/', ['/aws/lambda', !Ref 'TestFunction' ] ]
RetentionInDays: 1
TestRoute53RecordSet:
Type: AWS::Route53::RecordSet
Properties:
AliasTarget:
DNSName: !GetAtt TestCloudFrontDistribution.DomainName
HostedZoneId: Z2FDTNDATAQYW2 # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget-1.html
Comment: Bind the custom domain name to the Test CloudFront fronted API Gateway
HostedZoneName: !Ref DomainNameZone
Name: !Ref CustomDomainName
Type: A
TestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: Test
BinaryMediaTypes:
- '*/*'
Description: Test API
FailOnWarnings: true
EndpointConfiguration:
Types:
- REGIONAL
TestApiGatewayDomainName:
# The ApiGateway requires a custom domain name, despite sitting behind
# CloudFront. This is because we want to pass all ( * ) HTTP headers
# through CloudFront and onto API Gateway. If we didn't set a custom domain
# name on the API Gateway, the "Host" header passed through from CloudFront
# to API Gateway would be for the custom domain, but API Gateway, which uses
# SNI, wouldn't know which TLS certificate to use in the handshake because
# API Gateway would have no record of that Host header. This would result in
# API Gateway being unable to setup a TLS connection with the inbound
# CloudFront connection attempt, API Gateway writing no logs about this
# fact, and CloudFront returning to the user an error of
# {"message":"Forbidden"}
# If we weren't passing the "Host" header from CloudFront to API Gateway
# this resource wouldn't be needed
Type: AWS::ApiGateway::DomainName
Properties:
# Uppercase letters are not supported in DomainName
DomainName: !Ref CustomDomainName
EndpointConfiguration:
Types:
- REGIONAL
RegionalCertificateArn: !Ref CertificateArn
SecurityPolicy: TLS_1_2
TestBasePathMapping:
Type: AWS::ApiGateway::BasePathMapping
Properties:
# BasePath: # Not specifying this so that we have no base path
DomainName: !Ref TestApiGatewayDomainName
RestApiId: !Ref TestApi
Stage: !Ref TestApiStage
TestLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:invokeFunction
FunctionName: !GetAtt TestFunction.Arn
Principal: apigateway.amazonaws.com
SourceArn: !Join [ '', [ 'arn:aws:execute-api:', !Ref 'AWS::Region', ':', !Ref 'AWS::AccountId', ':', !Ref 'TestApi', '/*/*' ] ]
TestApiStage:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId: !Ref TestApiDeployment
MethodSettings:
- DataTraceEnabled: true
HttpMethod: '*'
ResourcePath: /*
RestApiId: !Ref TestApi
TestApiDeployment:
Type: AWS::ApiGateway::Deployment
DependsOn:
- TestRequest
Properties:
RestApiId: !Ref TestApi
StageName: DummyStage
# Deployment with an Empty Embedded Stage
# The following instructional text is no longer present in the AWS
# documentation for AWS::ApiGateway::Deployment StageName and it's not
# clear if it still applies.
#
# "Note This property is required by API Gateway. We recommend that you
# specify a name using any value (see Examples) and that you don’t use
# this stage. We recommend not using this stage because it is tied to
# this deployment, which means you can’t delete one without deleting the
# other. For example, if you delete this deployment, API Gateway also
# deletes this stage, which you might want to keep. Instead, use the
# AWS::ApiGateway::Stage resource to create and associate a stage with
# this deployment."
TestResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref TestApi
ParentId: !GetAtt TestApi.RootResourceId
PathPart: '{proxy+}'
TestRequest:
DependsOn: TestLambdaPermission
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: GET
Integration:
Type: AWS_PROXY
# IntegrationHttpMethod is POST regardless of the HttpMethod for this resource
# https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
# "For Lambda integrations, you must use the HTTP method of POST for the
# integration request, according to the specification of the Lambda service
# action for function invocations."
IntegrationHttpMethod: POST
Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
ResourceId: !Ref TestResource
RestApiId: !Ref TestApi
TestPOSTRequest:
DependsOn: TestLambdaPermission
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: POST
Integration:
Type: AWS_PROXY
# https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
# "For Lambda integrations, you must use the HTTP method of POST for the
# integration request, according to the specification of the Lambda service
# action for function invocations."
IntegrationHttpMethod: POST
Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
ResourceId: !Ref TestResource
RestApiId: !Ref TestApi
TestRootRequest:
# This resource is necessary to get API Gateway to respond to requests for the '/' path
# Without it API Gateway will respond to requests for '/' with the error
# {"message":"Missing Authentication Token"}
# https://stackoverflow.com/q/46578615/168874
# https://stackoverflow.com/q/52909329/168874
DependsOn: TestLambdaPermission
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: GET
Integration:
Type: AWS_PROXY
# IntegrationHttpMethod is POST regardless of the HttpMethod for this resource
# https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#set-up-lambda-proxy-integration-using-cli
# "For Lambda integrations, you must use the HTTP method of POST for the
# integration request, according to the specification of the Lambda service
# action for function invocations."
IntegrationHttpMethod: POST
Uri: !Join [ '', [ 'arn:aws:apigateway:', !Ref 'AWS::Region', ':lambda:path/2015-03-31/functions/', !GetAtt 'TestFunction.Arn', '/invocations' ] ]
# ResourceId must use the RootResourceId attribute of the AWS::ApiGateway::RestApi
# https://stackoverflow.com/a/56121914/168874
ResourceId: !GetAtt TestApi.RootResourceId
RestApiId: !Ref TestApi
TestCloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Comment: !Join [ ':', [!Ref 'AWS::StackName', 'Test']]
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- POST
- DELETE
- OPTIONS
- PUT
- PATCH
Compress: true
DefaultTTL: 0
MinTTL: 0
MaxTTL: 0
ForwardedValues:
Cookies:
Forward: all
QueryString: true
Headers:
- '*'
TargetOriginId: TestCloudFrontOriginId
ViewerProtocolPolicy: redirect-to-https
# https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-defaultrootobject
DefaultRootObject: '' # "If you don't want to specify a default root object when you create a distribution, include an empty DefaultRootObject element."
Enabled: true
Aliases:
- !Ref CustomDomainName
HttpVersion: http2
IPV6Enabled: true
#Logging:
# Logging
Origins:
- CustomOriginConfig:
OriginProtocolPolicy: https-only
OriginSSLProtocols:
- TLSv1.2
DomainName: !GetAtt TestApiGatewayDomainName.RegionalDomainName
Id: TestCloudFrontOriginId
# OriginPath: !Join [ '', [ '/', !Ref 'TestApiStage' ] ]
PriceClass: PriceClass_100 # US, Canada, Europe, Israel
ViewerCertificate:
AcmCertificateArn: !Ref CertificateArn
MinimumProtocolVersion: TLSv1.2_2018
SslSupportMethod: sni-only
In case AWS updates this documentation page to fix this you can see the original page here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With