Déployer un site web statique en https sur AWS
Création du domaine et de son certificat
La première étape consiste à créer un domain et son certificat.
aws cloudformation deploy –stack-name domain-stack –template-file domain.cfn.yml –parameter-overrides DomainName=example.com –capabilities CAPABILITY_IAM –region us-east-1
AWSTemplateFormatVersion: "2010-09-09"
Description: Route53 Hosted Zone + Certificate
Parameters:
DomainName:
Type: String
Description: The DNS name of an Amazon Route 53 hosted zone
AllowedPattern: (?!-)[a-zA-Z0-9-.]{1,63}(?<!-)
ConstraintDescription: must be a valid DNS zone name.
Resources:
DNS:
Type: AWS::Route53::HostedZone
Properties:
HostedZoneConfig:
Comment: !Join ['', ['Hosted zone for ', !Ref DomainName]]
Name: !Ref DomainName
DomainCertificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: !Ref DomainName
DomainValidationOptions:
- DomainName: !Ref DomainName
ValidationDomain: !Ref DomainName
- DomainName: !Join [ '', ['*.', !Ref DomainName ]]
ValidationDomain: !Ref DomainName
SubjectAlternativeNames:
- !Join [ '', ['*.', !Ref DomainName ]]
Lors du traitement de cette stack, il faut penser à vérifier ses mails afin de valider la création du certificat.
Une fois la stack créée, il est nécessaire de manuellement modifier les noms des serveurs DNS du domaine, je ne connais pas de solution industrialisée.
Création du sous domain
Maintenant qu’on a un domain valide, il est possible de créer autant de sous domaines qu’on veut aussi bien le www que rien.
Pour récupérer l’arn du certificat que l’on vient de créer :
aws acm list-certificates –region us-east-1
La stack suivante permet de fournir un S3 qui est un dépôt de fichiers statiques, un CDN (CloudFront) et de lier le tout au domaine.
aws cloudformation deploy –stack-name subdomain-stack –template-file subdomain.cfn.yml –parameter-overrides AcmCertificateArn=arn:aws:cloudfront::99999999999:distribution/XXXXXXXXXXXX HostedZone=example.com Subdomain=www.example.com –capabilities CAPABILITY_IAM –region eu-west-3
AWSTemplateFormatVersion: '2010-09-09'
Description: Route53 Subdomain
Parameters:
AcmCertificateArn:
Type: String
Description: Domain certificate arn.
AllowedPattern: "arn:aws:acm:.*"
HostedZone:
Type: String
Description: The DNS name of an existing Amazon Route 53 hosted zone.
AllowedPattern: (?!-)[a-zA-Z0-9-.]{1,63}(?<!-)
ConstraintDescription: must be a valid DNS zone name.
Subdomain:
Type: String
Description: The DNS name of an existing Amazon Route 53 hosted zone.
AllowedPattern: (?!-)[a-zA-Z0-9-.]{1,63}(?<!-)
ConstraintDescription: must be a valid subdomain name.
Mappings:
Region2S3WebsiteSuffix:
us-east-1:
Suffix: .s3-website-us-east-1.amazonaws.com
us-west-1:
Suffix: .s3-website-us-west-1.amazonaws.com
us-west-2:
Suffix: .s3-website-us-west-2.amazonaws.com
eu-west-1:
Suffix: .s3-website-eu-west-1.amazonaws.com
ap-northeast-1:
Suffix: .s3-website-ap-northeast-1.amazonaws.com
ap-northeast-2:
Suffix: .s3-website-ap-northeast-2.amazonaws.com
ap-southeast-1:
Suffix: .s3-website-ap-southeast-1.amazonaws.com
ap-southeast-2:
Suffix: .s3-website-ap-southeast-2.amazonaws.com
ap-south-1:
Suffix: .s3-website-ap-south-1.amazonaws.com
us-east-2:
Suffix: .s3-website-us-east-2.amazonaws.com
sa-east-1:
Suffix: .s3-website-sa-east-1.amazonaws.com
cn-north-1:
Suffix: .s3-website.cn-north-1.amazonaws.com.cn
eu-central-1:
Suffix: .s3-website.eu-central-1.amazonaws.com
Resources:
WebsiteBucket:
Type: AWS::S3::Bucket
Properties:
AccessControl: PublicRead
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: error.html
WebsiteBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref WebsiteBucket
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: PublicReadForGetBucketObjects
Effect: Allow
Principal: '*'
Action: s3:GetObject
Resource: !Join ['', ['arn:aws:s3:::', !Ref WebsiteBucket, /*]]
WebsiteCDN:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Comment: !Join ['', ['CDN for ', !Ref Subdomain, ' website']]
Aliases:
- !Ref Subdomain
Enabled: true
DefaultRootObject: index.html
IPV6Enabled: false
DefaultCacheBehavior:
AllowedMethods:
- DELETE
- GET
- HEAD
- OPTIONS
- PATCH
- POST
- PUT
TargetOriginId: S3Origin
ForwardedValues:
QueryString: false
Cookies:
Forward: none
ViewerProtocolPolicy: redirect-to-https
PriceClass: PriceClass_100
Restrictions:
GeoRestriction:
RestrictionType: whitelist
Locations:
- FR
ViewerCertificate:
AcmCertificateArn: !Ref AcmCertificateArn
SslSupportMethod: sni-only
Origins:
- DomainName: !Join ['', [!Ref WebsiteBucket, '.s3.amazonaws.com']]
Id: S3Origin
S3OriginConfig: {}
WebsiteDNSName:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneName: !Join ['', [!Ref HostedZone, .]]
Name: !Ref Subdomain
Type: A
AliasTarget:
HostedZoneId: Z2FDTNDATAQYW2
DNSName: !GetAtt [WebsiteCDN, DomainName]
La création du CDN est long, il faut s’armer de patience, mais c’est aussi le bon moment pour débuter le transfert du site vers S3.
Une fois la stack créée, le site est disponible à la fois en http et en https. Pour être exact, les requêtes http seront redirigées en https.
Transférer ses données vers S3 peut se faire facilement via l’interface ou bien en ligne de commande.
aws s3 ls –region eu-west-3
aws s3 sync ./ s3://${WEBSITE_BUCKET} –region eu-west-3