DEV Community

Cover image for How to create a website using S3 + Certificate Manager + Cloud Front with CDK ?
Sergio Kaz
Sergio Kaz

Posted on

How to create a website using S3 + Certificate Manager + Cloud Front with CDK ?

Prerequisites

Before start we need a few things installed on our computer.

1) npm
2) NodeJs + TypeScript(2.7 or later)
3) CDK

After that we have to set up your aws credentials, to achieve that you can follow this link

The last one, you should have created a hosted zone in AWS and delegate your domain.

Well, we can start!!

Configure SSL certificate

const hostedZone = HostedZone.fromLookup(this,"myZone", {
    domainName: "example.com"
 });

const certificate = new acm.Certificate(this, `myCertificate`, {
      domainName: "example.com",
      subjectAlternativeNames: ["www.example.com"],
      validation: acm.CertificateValidation.fromDns(hostedZone),
});

Enter fullscreen mode Exit fullscreen mode

On the first part we got the hosted zone related to your domain.
After that we created the SSL certificate using Certificate Manager. Adding the key validation into the CM, AWS automatically add the necessary records to validate your domain.

Set up bucket

const bucket = new Bucket(this, `myBucket`, {
      encryption: BucketEncryption.S3_MANAGED,
      bucketName: `your-bucket-name`,
      cors: [
        {
          allowedMethods: [HttpMethods.GET, HttpMethods.HEAD],
          allowedOrigins: ["*"],
          allowedHeaders: ["*"],
        },
      ],
});
Enter fullscreen mode Exit fullscreen mode

In this way we create the bucket. It's recommended to use the domain's name as bucket's name and use a prefix to difference the environments.

Set up policy and CDNOAI

In this part, I am going to explain step by step, because It could be a bit confuse.

const CDNOAI = new CfnCloudFrontOriginAccessIdentity(
      this, "myCDNOAI", {
        cloudFrontOriginAccessIdentityConfig: {
          comment: "S3 OAI",
        },
      }
);
Enter fullscreen mode Exit fullscreen mode

What is cloud front origin access identity ?

An Origin Access Identity (OAI) is used for sharing private content via CloudFront. The OAI is a virtual user identity that will be used to give your CF distribution permission to fetch a private object from your origin server (e.g. S3 bucket).

const policy = new iam.PolicyStatement({
      actions: ["s3:Get*"],
      effect: Effect.ALLOW,
      resources: [bucket.bucketArn, bucket.arnForObjects("*")],
});
Enter fullscreen mode Exit fullscreen mode

We created a policy to allow get object on the whole bucket.

policy.addCanonicalUserPrincipal(CDNOAI.attrS3CanonicalUserId);
Enter fullscreen mode Exit fullscreen mode

We add our CDNOAI to our policy.

const bucketPolicy = new BucketPolicy(this, `myBucketPolicy`, { 
  bucket,
});

bucketPolicy.document.addStatements(policy);

Enter fullscreen mode Exit fullscreen mode

The last step of this section is create a bucket policy and attach to it our policy.

Set up Cloud front


const cloudFront = new cloudfront.Distribution(
      this,
      `myCloudFront`,
      {
        defaultBehavior: {
          origin: new origins.S3Origin(bucket),
          allowedMethods: AllowedMethods.ALLOW_GET_HEAD,
          viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
        },
        certificate,
        defaultRootObject: "index.html",
        domainNames: ["example.com"],
        enabled: true,
        errorResponses: [
          {
            ttl: Duration.days(1),
            httpStatus: 404,
            responseHttpStatus: 200,
            responsePagePath: "/index.html",
          },
          {
            ttl: Duration.days(1),
            httpStatus: 403,
            responseHttpStatus: 200,
            responsePagePath: "/index.html",
          },
        ],
      }
    );
Enter fullscreen mode Exit fullscreen mode

This is a basic cloudfront configuration.

I want to highlight the certificate variable. It is the same certificate that we previously created.

Create A record

new ARecord(this, `myARecord`, {
      zone: hostedZone,
      ttl: Duration.minutes(5),
      target: RecordTarget.fromAlias(new targets.CloudFrontTarget(cloudFront)),
      recordName: "example.com",
    });
Enter fullscreen mode Exit fullscreen mode

In this part we are going to create an A record within our hosted zone, and reference it with our cloud front.

GITHUB

This is my github, and here you are going to find a full complete example using CDK to create and deploy powerfull webapps!!

https://github.com/skaznowiecki/cdk-s3-cloudfront

Top comments (0)