http2 for one origin in aws cloudfront - amazon-web-services

I have two origins, one refers to k8s, and the second I redirected the page from another site .
I tried to include in general http2 , but I need only one origin project with http2 ,
this is my clouformation
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Comment: !Sub Frontend (${Stage})
Aliases:
- !If
- isProd
- !Sub ${Domain}
- !Sub ${Stage}.${Domain}
Origins:
- DomainName: !Ref LBEndpoint
Id: LBEndpoint
CustomOriginConfig:
OriginProtocolPolicy: http-only
OriginCustomHeaders:
- HeaderName: cdn_header
HeaderValue: !Ref CndHeader
- DomainName: !If
- isProd
- site.com
- staging.site.com
Id: project
CustomOriginConfig:
OriginProtocolPolicy: https-only
OriginCustomHeaders:
- HeaderName: cdn_header
HeaderValue: !Ref CndHeader
where should it be inserted ``` HTTPVersion: HTTP2```so that it works correctly?
can i not pass such values ​​only for one origin ?
so question - how to enable http2 for one origin in aws cloudfront using aws cloudfront or simply in the web panel

Related

Cloudfront differentiate origin based on hostname of the request

I have a Cloudfront distribution that I want to use it to serve two different hostnames (let's say 1.hostname.com and 2.hostname.com). In my CloudFormation template, I include these as aliases like below.
AppDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName: !Ref ALBDomainName1
Id: ALBOrigin1
CustomOriginConfig:
OriginProtocolPolicy: https-only
OriginSSLProtocols:
- TLSv1.2
- DomainName: !Ref ALBDomainName2
Id: ALBOrigin2
CustomOriginConfig:
OriginProtocolPolicy: https-only
OriginSSLProtocols:
- TLSv1.2
Aliases:
- "1.hostname.com"
- "2.hostname.com"
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- OPTIONS
- PUT
- PATCH
- POST
- DELETE
TargetOriginId: ALBOrigin1
ForwardedValues:
QueryString: False
Cookies:
Forward: none
ViewerProtocolPolicy: redirect-to-https
MinTTL: 0
DefaultTTL: 60
MaxTTL: 60
ResponseHeadersPolicyId: "123123"
I want to configure the cloudformation to use one origin if the request is coming to 1.hostname.com and the other origin if the request is coming to 2.hostname.com. The path pattern can be the same in both cases. Is there a way to add CacheBehaviors achieve this?

How to get the CloudFront distribution ARN in a CloudFormation stack for WebACLAssociation?

I've setup a CloudFront distribution in CloudFormation and I'm building an AWS WAF ACL to act as a firewall for it. To associate the ACL to the CloudFront distribution, I've added a AWS::WAFv2::WebACLAssociation entry which requires the ARN of the CloudFront distribution for the ResourceArn entry. However, I can't seem to find out how to get the CloudFront distribution ARN from the official documentation. I thought I could use !Ref however it used the CloudFront ID as per the documentation instead of the ARN.
How do I reference the CloudFront distribution ARN from the WebACLAssociation entry?
Example below (other resources omitted for brevity):
---
AWSTemplateFormatVersion: 2010-09-09
Description: CloudFront
Parameters:
# ...
CloudFront:
Type: AWS::CloudFront::Distribution
DependsOn:
- IssuedCertificate
- S3Bucket
Properties:
DistributionConfig:
Origins:
- DomainName: !Sub
- ${S3Bucket}.${S3WebEndpoint}
- {
S3Bucket: !Ref S3Bucket,
S3WebEndpoint:
!FindInMap [RegionMap, !Ref "AWS::Region", websiteendpoint],
}
Id: S3origin
CustomOriginConfig:
OriginProtocolPolicy: http-only
Enabled: "true"
Comment: !Sub Distribution for ${DomainName}
HttpVersion: http2
Aliases:
- !Ref DomainName
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- OPTIONS
TargetOriginId: S3origin
Compress: True
DefaultTTL: 604800
ForwardedValues:
QueryString: "false"
Cookies:
Forward: none
ViewerProtocolPolicy: redirect-to-https
PriceClass: PriceClass_100
ViewerCertificate:
AcmCertificateArn: !Ref Certificate
SslSupportMethod: sni-only
# ...
AWSWAF:
Type: AWS::WAFv2::WebACL
Properties:
Name: allowlist
Description: Allowlist
Scope: CLOUDFRONT
DefaultAction:
Block: {}
Rules:
- Name: ipset-rule
Priority: 0
Action:
Allow: {}
Statement:
IPSetReferenceStatement:
Arn: # <ARN>
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: ipset-metrics
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: allowlist-metrics
AWSWAFAssociation:
Type: AWS::WAFv2::WebACLAssociation
Properties:
ResourceArn: !Ref CloudFront
WebACLArn: !Ref AWSWAF
There is no direct Attribute for the same but you can construct it:
arn:aws:cloudfront::${AWS::AccountId}:distribution/${CloudFront}
Turns out I had been approaching the problem wrong all along. Diving into the docs, I found that AWS details how to deploy an ACL for a CloudFront distribution here under the ResouceArn entry.
To fix this issue, all I had to do was add the following to the CloudFront distribution DistributionConfig and remove the WebACLAssociation entry:
WebACLId: !GetAtt AWSWAF.Arn
So the final CloudFront entry looked like this:
CloudFront:
Type: AWS::CloudFront::Distribution
DependsOn:
- IssuedCertificate
- S3Bucket
Properties:
DistributionConfig:
Origins:
- DomainName: !Sub
- ${S3Bucket}.${S3WebEndpoint}
- {
S3Bucket: !Ref S3Bucket,
S3WebEndpoint:
!FindInMap [RegionMap, !Ref "AWS::Region", websiteendpoint],
}
Id: S3origin
CustomOriginConfig:
OriginProtocolPolicy: http-only
Enabled: "true"
Comment: !Sub Distribution for ${DomainName}
HttpVersion: http2
Aliases:
- !Ref DomainName
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- OPTIONS
TargetOriginId: S3origin
Compress: True
DefaultTTL: 604800
ForwardedValues:
QueryString: "false"
Cookies:
Forward: none
ViewerProtocolPolicy: redirect-to-https
PriceClass: PriceClass_100
ViewerCertificate:
AcmCertificateArn: !Ref Certificate
SslSupportMethod: sni-only
WebACLId: !GetAtt AWSWAF.Arn

AWS Route 53 message forbidden while trying to add A record to cloud front

I am deploying a React.js application using the server less framework on cloudfront.
The architecture is very simple, I have an S3 bucket and a CloudFront CDN.
CloudFormation ends without any error setting up my configuration and I'm able to visit my react page using the CloudFront Distribution domain name using https and default certificate.
Now I bought a domain in Route 53 and I would like to link it to my CloudFront.
I tried everything but I did not succeed. Can anyone please give me some hint?
Action I already tried:
Adding the certificate's are (after creating it) on my resources.CloudFrontDistribution.ViewerCertificate.AcmCertificateArn
Adding manually an A record to point to my CloudFront. This generates the following JSON error on my browser: {"message":"Forbidden"}
Manually adding the certificate through AWS Console on my CloudFront
None of those action gave me any hint about how to solve or even debug the problem.
This is my current serverless.yml:
service: my-app-react
provider:
name: aws
runtime: nodejs12.x
region: eu-south-1
memorySize: 512
timeout: 6
logRetentionInDays: 7
plugins:
- serverless-s3-sync
custom:
bucketName: my-app-react-33333
s3Sync:
- bucketName: ${self:custom.bucketName}
localDir: build/
domains:
dev:
domainName: <my-domain>
certificateName: <my-domain>
resources:
Resources:
ReactAppBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.bucketName}
AccessControl: PublicRead
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: index.html
S3AccessPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: ReactAppBucket
PolicyDocument:
Statement:
- Sid: PublicReadGetObject
Effect: Allow
Principal: "*"
Action:
- s3:GetObject
Resource:
- arn:aws:s3:::${self:custom.bucketName}/*
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
Origins:
- DomainName: ${self:custom.bucketName}.s3.eu-south-1.amazonaws.com
Id: ReactApp
CustomOriginConfig:
HTTPPort: 80
HTTPSPort: 443
OriginProtocolPolicy: https-only
DefaultRootObject: index.html
CustomErrorResponses:
- ErrorCode: 404
ResponseCode: 200
ResponsePagePath: /index.html
DefaultCacheBehavior:
AllowedMethods:
- HEAD
- GET
- DELETE
- OPTIONS
- PATCH
- POST
- PUT
TargetOriginId: ReactApp
ForwardedValues:
QueryString: false
Cookies:
Forward: none
ViewerProtocolPolicy: redirect-to-https
ViewerCertificate:
AcmCertificateArn: <my-certificate-arn>
SslSupportMethod: sni-only
MinimumProtocolVersion: TLSv1.2_2021
Oh, now I think I may know your issue. Cluodfront distributions can only use ACM certs created in us-east-1. See Requirements for using SSL/TLS certificates with CloudFront.
I didn't pick up on that before, but it is likely your issue. You don't have to have your distribution or any other resources there, just the certificates.
When I create certs using cloudformation, I set up the certificate handler templates in us-east-1 and the rest of the resource templates in my local region. With terraform, as another example, I have a separate provider just for these resources.

Creating a CNAME AWS RecordSet/Custom Domain connection to an API in SAM

I am trying to use Route53 and Custom Domains to link a URL I have and the API gateway that is a Lambda Proxy underneath it.
This is what I have so far in my SAM file:
MyApiCertificate:
Type: 'AWS::CertificateManager::Certificate'
Properties:
DomainName: example.com
MyApiDomainName:
Type: 'AWS::ApiGateway::DomainName'
Properties:
RegionalCertificateArn: !Ref MyApiCertificate
DomainName: example.com
MyApiBasePathMapping:
Type: 'AWS::ApiGateway::BasePathMapping'
Properties:
RestApiId: !Ref PublicApi
DomainName: !Ref MyApiDomainName
BasePath: /
Stage: stage
MyApiRoute53RecordSetGroup:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneName: example.com
RecordSets:
- Name: example.com
Type: A
AliasTarget:
EvaluateTargetHealth: false
HostedZoneId: !GetAtt MyApiDomainName.DistributionHostedZoneId
DNSName: !GetAtt MyApiDomainName.DistributionDomainName
I would like to make this of type CNAME and have the URL be stage.example.com
The following Code does not work.
MyApiCertificate:
Type: 'AWS::CertificateManager::Certificate'
Properties:
DomainName: example.com
MyApiDomainName:
Type: 'AWS::ApiGateway::DomainName'
Properties:
RegionalCertificateArn: !Ref MyApiCertificate
DomainName: example.com
MyApiBasePathMapping:
Type: 'AWS::ApiGateway::BasePathMapping'
Properties:
RestApiId: !Ref PublicApi
DomainName: !Ref MyApiDomainName
BasePath: /
Stage: stage
MyApiRoute53RecordSetGroup:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneName: example.com
RecordSets:
- Name: stage.example.com
Type: CNAME
AliasTarget:
EvaluateTargetHealth: false
HostedZoneId: !GetAtt MyApiDomainName.DistributionHostedZoneId
DNSName: !GetAtt MyApiDomainName.DistributionDomainName
I am getting this error: Cannot import certificates for REGIONAL while EDGE is active. (Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: XXXXXXXXXXXXXXXXXXXXXXXX)
Although nothing I have is an EDGE Api Gateway and Nothing has the name I want (Stage.example.com)
Any help on this issue would be appreciated!
I came across the same error using Terraform, and the issue was that I was specifying regional_certificate_arn rather than certificate_arn. API Gateway defaults to edge-optimized, which means you're specifying a RegionalCertificateArn with an edge-optimized API here - try using CertificateArn instead.

CloudFormation Circular Dependency Between Route53, Certificate Manager & CloudFront

The following code is my attempt at creating a SPA (Single Page Application) CloudFormation template. I understand there are probably many flaws but I can't conceptually understand how to break the circular dependency error I am getting. In my head, it only makes sense that Route53 depends on CloudFront because it needs to know the AliasTarget, it also makes sense that CloudFront needs to depend on Certificate Manager because it needs AcmCertificateArn and CertificateManager needs to depend on Route53 (for obvious reasons but I have a feeling someone is going to tell me this is where I break the chain).
AWSTemplateFormatVersion: '2010-09-09'
Description: Creates an S3 bucket configured for hosting a static website, and a Route
53 DNS record pointing to the bucket
Parameters:
DomainName:
Type: String
Description: The DNS name of an existing Amazon Route 53 hosted zone e.g. jevsejev.io
AllowedPattern: (?!-)[a-zA-Z0-9-.]{1,63}(?<!-)
ConstraintDescription: must be a valid DNS zone name.
FullDomainName:
Type: String
Description: The full domain name e.g. development.jevsejev.io
AllowedPattern: (?!-)[a-zA-Z0-9-.]{1,63}(?<!-)
ConstraintDescription: must be a valid DNS zone name.
Resources:
Route53:
Type: AWS::Route53::RecordSet
DependsOn:
- Cloudfront
Properties:
HostedZoneName: !Ref 'DomainName'
RecordSets:
Name: !Ref 'FullDomainName'
Type: A
AliasTarget:
DNSName: !GetAtt [Cloudfront, WebsiteURL]
CertificateManager:
Type: AWS::CertificateManager::Certificate
DependsOn:
- Route53
Properties:
DomainName: !Ref 'FullDomainName'
Cloudfront:
Type: AWS::CloudFront::Distribution
DependsOn:
- S3
Properties:
DistributionConfig:
Origins:
- DomainName: !GetAtt [S3, WebsiteURL]
Id: S3Origin
CustomOriginConfig:
HTTPPort: '80'
HTTPSPort: '443'
OriginProtocolPolicy: http-only
Enabled: true
HttpVersion: 'http2'
DefaultRootObject: index.html
Aliases:
- !Ref 'FullDomainName'
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
Compress: true
TargetOriginId: S3Origin
ForwardedValues:
QueryString: true
Cookies:
Forward: none
ViewerProtocolPolicy: redirect-to-https
PriceClass: PriceClass_All
ViewerCertificate:
AcmCertificateArn: !Ref CertificateManager
SslSupportMethod: sni-only
S3:
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref 'FullDomainName'
AccessControl: PublicRead
WebsiteConfiguration:
IndexDocument: index.html
I also have this problem and just get fixed.
Hope this it's helpful for people
The Certificate part once you have this property DomainValidationOptions and use your own HostedZone Id as Value of HostedZoneId, Certificate will get created without hanging there.
Below are my code for reference:
CldoudFrontHostedZoneId is a fixed value from AWS documents
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-aliastarget.html
DefaultHostedZoneId is my HostedZone Id
Parameters:
DefaultHostedZoneId:
Description: Default own HostedZone Id
Type: String
Default: xxxxxxxxxxxxxx
CldoudFrontHostedZoneId:
Description: AWS only use this hosted zone Id for cloudfront
Type: String
Default: Z2FDTNDATAQYW2
Resources:
StagingCloudFrontCertificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: yyyyy.xxxxxxxx.company.com
ValidationMethod: DNS
DomainValidationOptions:
- DomainName: yyyyy.xxxxxxxx.company.com
HostedZoneId: !Ref DefaultHostedZoneId
StagingCloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName: !GetAtt StagingPublishedS3.DomainName
Id: !Ref StagingPublishedS3
S3OriginConfig:
OriginAccessIdentity: !Join ['', ['origin-access-identity/cloudfront/', !Ref StagingCloudFrontOriginAccessIdentity]]
Enabled: 'true'
Comment: Staging CloudFront Distribution
HttpVersion: http2
IPV6Enabled: true
PriceClass: PriceClass_100
Aliases:
- yyyyy.xxxxxxxx.company.com
ViewerCertificate:
MinimumProtocolVersion: TLSv1.2_2021
AcmCertificateArn: !Ref StagingCloudFrontCertificate
SslSupportMethod: sni-only
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- OPTIONS
CachePolicyId: !Ref AWSmanagedCachePolicy
# ForwardedValues:
# QueryString: false
ViewerProtocolPolicy: 'redirect-to-https'
TargetOriginId: !Ref StagingPublishedS3
TrustedKeyGroups:
- !Ref StagingCloudFrontKeyGroup
CacheBehaviors:
- AllowedMethods:
- GET
- HEAD
PathPattern: /favicon.ico
TargetOriginId: !Ref StagingPublishedS3
ViewerProtocolPolicy: 'redirect-to-https'
CachePolicyId: !Ref AWSmanagedCachePolicy
StagingCloudfrontDNS:
Type: AWS::Route53::RecordSetGroup
Properties:
HostedZoneName: xxxxxxxx.company.com.
Comment: Zone apex alias targeted to CloudFront
RecordSets:
- Name: yyyyy.xxxxxxxx.company.com.
Type: A
AliasTarget:
HostedZoneId: !Ref CldoudFrontHostedZoneId
DNSName: !GetAtt StagingCloudFrontDistribution.DomainName
- Name: yyyyy.xxxxxxxx.company.com.
Type: AAAA
AliasTarget:
HostedZoneId: !Ref CldoudFrontHostedZoneId
DNSName: !GetAtt StagingCloudFrontDistribution.DomainName