Skip to content

Website

We use S3 buckets to host files, and Amazon CloudFront to servce the files.

CloudFront to S3

CloudFront to S3

Minimal working example

The following code creates a client application that will be reachable from https://kattehotell.dev.bymoslo.net:

main.tf
module "application" {
  source           = "git@github.com:BYM-IKT/terraform-byks-module.git"
  team             = var.team
  account_id       = var.account_id
  environment      = var.environment
  region           = var.region
  application_name = var.application_name

  cloudfront_distributions = {
    kattehotell = {}
  }

  providers = {
    aws.route53   = aws.route53
    aws.us-east-1 = aws.us-east-1
    aws.ses       = aws.ses
  }
}

Note

The domain resulting is automatically inferred using the value of environment, i.e.:

`dev`  => `dev.bymoslo.net`
`test` => `test.bymoslo.net`
`prod` => `bymoslo.no`

Tutorial

These steps assume that your repository has a project structure as follows:

GitHub repository containing your source code
├── src/
│   ├── ...
│   └── main.tsx
├── ...
├── package.json
└── index.html

Step 1: Create a S3 bucket + CloudFront

Add the following code snippet to your Terraform project:

main.tf
module "application" {
  source      = "git@github.com:BYM-IKT/terraform-byks-module.git"
  environment = "test"
  ...
  cloudfront_distributions = {
    kattehotell = {}
  }
}

Create a Pull Request to Terraform apply this change.

This will provision two resources:

  • A new S3 bucket named ${environment}-${application_name}-${service}. In this example: test-kattehotell-kattehotell.
  • A CloudFront distribution that serves the content of the S3 bucket. The resulting FQDN is generated from the key used (here: kattehotell). In this example, the resulting FQDN will therefore become: https://kattehotell.test.bymoslo.net.

Step 2: Compile and push the code to S3 Bucket

  1. Create a GitHub Actions workflow file .github/workflows/deploy-to-test.yml:
    .
    ├── .github/
    │   └── workflows/
    │       └── deploy-to-test.yml
    ├── src/
    │   ├── ...
    │   └── main.tsx
    ├── ...
    ├── package.json
    └── index.html
    
    with the following content:
    ./.github/workflows/deploy-to-test.yml
    name: Build and deploy website to TEST
    
    on:
      push:
        branches: [master]
      workflow_dispatch:
    
    jobs:
      deploy-to-test:
        name: Build app and deploy to TEST
        runs-on: ubuntu-latest
        permissions:
          id-token: write
          contents: read
        environment: 
          name: testing
          url:  https://kattehotell.test.bymoslo.net
        steps:
          - uses: actions/checkout@v4
    
          - uses: pnpm/action-setup@v4
            with:
              version: 10
              package_json_file: ./package.json
    
          - uses: actions/setup-node@v4
            with:
              node-version: 24
    
          - name: Install dependencies
            run: pnpm install
    
          - name: Build
            env:
              CI: false
            run: pnpm build --emptyOutDir --outDir 'build'
    
          - name: Upload to S3 and invalidate CloudFront cache
            uses: BYM-IKT/github-actions/upload-to-s3-and-invalidate-cloudfront@master
            with:
              aws-account-id:                      "<<AWS_ACCOUNT_ID>>"
              s3-bucket-name:                      test-kattehotell-kattehotell
              build-directory:                     ./build
              cloudfront-distribution-domain-name: https://kattehotell.test.bymoslo.net
    
    where <<AWS_ACCOUNT_ID>> is replaced with the Id of your AWS Account.
  2. Run the pipeline.
  3. Verify that the website is online.