Automate Building a Unique Domain Hosting Environment with AWS CloudFormation

dayjournal

Yasunori Kirimoto

Posted on February 28, 2022

Automate Building a Unique Domain Hosting Environment with AWS CloudFormation

img

I automated building a unique domain hosting environment with AWS CloudFormation 🎉

In my previous article, "Build a Unique Domain Hosting Environment with Amazon Route 53, AWS WAF, Amazon CloudFront, and Amazon S3," I tried to implement the contents of that article with AWS CloudFormation.

I've made the template available on GitHub, so please use it!

aws-cloudformation-templates-showcase

certificate-create.yml

AWSTemplateFormatVersion: 2010-09-09
Description: Certificate creation
Parameters:
  DomainName:
    Description: Domain Name
    Type: String
  HostedZoneId:
    Description: Host Zone ID
    Type: String
Resources:
  CertificateManagerCertificate:
    Type: AWS::CertificateManager::Certificate
    Properties:
      DomainName: !Sub ${DomainName}
      DomainValidationOptions:
        -
          DomainName: !Sub ${DomainName}
          HostedZoneId: !Sub ${HostedZoneId}
      ValidationMethod: DNS
Enter fullscreen mode Exit fullscreen mode

hosting.yml

AWSTemplateFormatVersion: 2010-09-09
Description: Build a Unique Domain Hosting Environment with Amazon Route 53, Amazon CloudFront, and Amazon S3
Parameters:
  DomainName:
    Description: Domain Name
    Type: String
  HostedZoneId:
    Description: Host Zone ID
    Type: String
  CertificateId:
    Description: Certificate ID
    Type: String
Resources:
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub ${AWS::StackName}-${AWS::Region}-${AWS::AccountId}
  S3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    DependsOn:
      - CloudFrontOriginAccessIdentity
    Properties:
      Bucket: !Sub ${S3Bucket}
      PolicyDocument:
        Statement:
          -
            Sid: PolicyForCloudFrontPrivateContent
            Effect: Allow
            Principal:
              AWS: !Sub arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOriginAccessIdentity}
            Action: s3:GetObject
            Resource: !Sub arn:aws:s3:::${S3Bucket}/*
  CloudFrontOriginAccessIdentity:
    Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
    Properties:
      CloudFrontOriginAccessIdentityConfig:
        Comment: Unique Domain Hosting Environment
  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    DependsOn:
      - S3Bucket
      - CloudFrontOriginAccessIdentity
    Properties:
      DistributionConfig:
        Aliases:
          - !Sub ${DomainName}
        Origins:
          -
            DomainName: !Sub ${S3Bucket}.s3.${AWS::Region}.amazonaws.com
            Id: !Sub ${S3Bucket}.s3.${AWS::Region}.amazonaws.com
            S3OriginConfig:
              OriginAccessIdentity: !Sub origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}
        DefaultCacheBehavior:
          TargetOriginId: !Sub ${S3Bucket}.s3.${AWS::Region}.amazonaws.com
          Compress: true
          AllowedMethods:
            - HEAD
            - GET
          CachedMethods:
            - HEAD
            - GET
          ViewerProtocolPolicy: redirect-to-https
          CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6
        CustomErrorResponses:
          -
            ErrorCode: 403
            ResponsePagePath: /index.html
            ResponseCode: 200
            ErrorCachingMinTTL: 0
          -
            ErrorCode: 404
            ResponsePagePath: /index.html
            ResponseCode: 200
            ErrorCachingMinTTL: 0
        PriceClass: PriceClass_All
        Enabled: true
        ViewerCertificate:
          AcmCertificateArn: !Sub arn:aws:acm:us-east-1:${AWS::AccountId}:certificate/${CertificateId}
          MinimumProtocolVersion: TLSv1.2_2021
          SslSupportMethod: sni-only
        Restrictions:
          GeoRestriction:
            RestrictionType: none
        HttpVersion: http2
        DefaultRootObject: index.html
        IPV6Enabled: true
  Route53RecordSet:
    Type: AWS::Route53::RecordSet
    DependsOn:
      - CloudFrontDistribution
    Properties:
      Name: !Sub ${DomainName}
      HostedZoneId: !Sub ${HostedZoneId}
      Type: A
      AliasTarget:
        DNSName: !GetAtt CloudFrontDistribution.DomainName
        HostedZoneId: Z2FDTNDATAQYW2
Enter fullscreen mode Exit fullscreen mode

Advance Preparation

Get a unique domain using Amazon Route 53
Make a note of the target domain name and host zone ID

img

How to build

  1. Auto-deploy SSL certificate in the specified region
  2. Auto-deploy unique domain hosting environment in any region

Auto-Deploy SSL Certificate in the Specified Region

First, we will auto-deploy an SSL certificate in the specified region. We need to create in the "us-east-1" region to use the SSL certificate with CloudFront.

Access CloudFormation with the region "us-east-1," and click "Stack" → “Create Stack” → "Use New Resource."
img

Select "Template ready" as a prerequisite. To specify the template, select "Upload template file" and upload the file → Click "Next." Use the CloudFormation template "certificate-create.yml."
img

Set the desired stack name, domain name, and host zone ID → Click "Next."
img

Set the stack options as default → Click "Next."
img

Confirm the settings → Click "Create Stack."
img

Confirm that the stack has been created.
img

Check the AWS Certificate Manager for the "us-east-1" region, and you will see that the SSL certificate has been created automatically. Note down the target "Certificate ID" for use in the next template.
img

Auto-Deploy Unique Domain Hosting Environment in Any Region

Finally, we will auto-deploy a unique domain hosting environment in any region.

Access CloudFormation in the region you want to deploy to. Click “Stack” → “Create Stack” → "Use New Resource."
img

For prerequisites, select "Template is ready." To specify the template, select "Upload template file" and upload the file → Click "Next." Use "hosting.yml" as the CloudFormation template.
img

Set the desired stack name, certificate ID, domain name, and host zone ID → Click "Next."
img

Set the stack options as default this time → Click "Next."
img

Confirm the settings → Click "Create Stack."
img

Confirm that the stack has been created.
img

Confirm that it has been automatically deployed to Amazon CloudFront.
img

Confirm that it has been automatically deployed to Amazon S3.
img

Upload the set of files you want to publish to the deployed S3 bucket.
img

When you access a unique domain, you will see the uploaded WebSite.
img

Using AWS CloudFormation, it is possible to automate the build of various resources such as unique domain hosting 💡

In the future, I'd like to experiment with AWS CDK, etc. to see how far each service configuration can be defined.

Related Articles

💖 💪 🙅 🚩
dayjournal
Yasunori Kirimoto

Posted on February 28, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related