Back to notes

Everything is defined. S3, CloudFront, CodePipeline, CodeBuild, Route 53, security headers. Time to deploy the site stack. This follows the same Sync from Git process from post 5, but with a bigger template and more parameters.

The Deployment File

Your repo needs a deployment file for the site stack, separate from the cert stack’s deployment file. This file tells CloudFormation which template to use and what parameter values to pass.

template-file-path: infra.yaml
parameters:
  DomainName: example.net
  GitHubRepository: your-org/your-repo
  HostedZoneId: your-hostedzone-id

template-file-path points to your site template relative to the repo root.

DomainName is your domain. This value flows into the S3 bucket naming, CloudFront aliases, Route 53 records, and the certificate import.

GitHubRepository is the owner/repo format for your GitHub repository. The pipeline’s Source stage uses it to pull from GitHub.

HostedZoneId is the Route 53 hosted zone ID for your domain. Same value you used for the cert stack. Find it in the Route 53 console under Hosted zones.

The connection ARN is not a parameter. The site stacks import it from the connection stack (post 2) using !ImportValue Example-GitHubConnectionArn.

Creating the Stack

The process is the same as post 5.

  1. Go to CloudFormation > Create stack and choose Sync from Git.
  2. Select the same CodeConnection from post 2.
  3. Enter your repository name, branch (main), and the deployment file path for the site stack.
  4. Select the IAM role (CloudFormationGitSyncRole from post 4). This is the same role you used for the cert stack, with all the permission additions from posts 6 through 12.
  5. CloudFormation reads the deployment file, finds the template, and starts the deployment.

What Happens

CloudFormation creates the resources in dependency order:

  1. S3 buckets for the site and pipeline artifacts.
  2. IAM roles for CodePipeline, CodeBuild, and the deploy project.
  3. CloudFront OAC and the security headers policy.
  4. CloudFront distribution with the OAC, certificate, and security headers attached.
  5. S3 bucket policy granting CloudFront read access.
  6. CodeBuild projects for build and deploy.
  7. CodePipeline with Source, Build, and Deploy stages.
  8. Route 53 alias record pointing your domain to CloudFront.

The stack takes a few minutes. Once it reaches CREATE_COMPLETE, the pipeline triggers automatically on the next push to main.

Verifying

Push a change to your repo’s main branch. Then check:

  1. CodePipeline in the console shows the pipeline running through Source, Build, and Deploy stages.
  2. CodeBuild logs show the build output and the S3 sync commands.
  3. Your site loads at https://your-domain.com with the custom domain and HTTPS.
  4. Browser DevTools (Network tab) shows the security headers on responses.

If the pipeline fails at the Deploy stage, check the CodeBuild logs for the deploy project. Common issues are missing S3 permissions or an incorrect bucket name.

Updating on Push

From here on, pushing changes to main does two things. Template changes trigger CloudFormation to update the stack through Git Sync. Application code changes trigger the pipeline to build and deploy your site. Both are fully automated.

Outputs (React Template)

The React example template includes an Outputs section that the static and Astro templates omit. Outputs surface useful values in the CloudFormation console after deployment.

Outputs:
  CloudFrontDistributionId:
    Description: CloudFront distribution ID
    Value: !Ref CloudFrontDistribution

  CloudFrontDomainName:
    Description: CloudFront distribution domain name
    Value: !GetAtt CloudFrontDistribution.DomainName

  WebsiteBucketName:
    Description: S3 bucket hosting the website assets
    Value: !Ref S3WebsiteBucket

  SiteUrl:
    Description: Live site URL
    Value: !Sub 'https://${DomainName}'

CloudFrontDistributionId and CloudFrontDomainName are handy for debugging cache or DNS issues. WebsiteBucketName shows the auto-generated bucket name, which you’d otherwise have to dig through the Resources tab to find. SiteUrl gives you a clickable link to the live site. These are optional. You can add the same Outputs block to the static or Astro templates if you want.

Complete Templates

Five example repos consolidate every resource from the series into a single deployable template per stack. Pick the site repo that matches your framework.

Deploy the connection and cert stacks first. The site stacks import their exports.