Create a S3 bucket + CloudFront
These steps assume that your repository has a project structure as follows:
├── src/
│ ├── ...
│ └── main.tsx
├── ...
├── package.json
└── index.html
Step 1: Provision the S3 bucket and CloudFront distribution
Infrastructure at BYM is provisioned through Terraform, not the AWS console. You add a small configuration block to your product's Terraform Infrastruktur-repo and a pipeline applies it.
-
Add the following to
main.tfin your Infrastruktur-repo:main.tfmodule "application" { source = "git@github.com:BYM-IKT/terraform-byks-module.git?ref=v12" team = var.team account_id = var.account_id environment = var.environment application_name = var.application_name cloudfront_distributions = { kattehotell = {} # Replace 'kattehotell' with your domain name } providers = { aws.route53 = aws.route53 aws.us-east-1 = aws.us-east-1 aws.ses = aws.ses } } -
Set
application_nameandenvironmentinenvironment.tf: -
Open a pull request against the Infrastruktur-repo and merge it.
Merging provisions two resources:
- An S3 bucket named
${environment}-${application_name}-${domain_name}, for exampletest-katteapp-kattehotell. - A CloudFront distribution that serves the bucket's content over HTTPS at a domain generated from the key used above, for example
https://kattehotell.test.bymoslo.net.
See adding more domains if the app needs to answer on more than one URL.
Step 2: Request pipeline access from Team Cloud
The GitHub Actions workflow in the next step needs permission to write to
your AWS account and invalidate the CloudFront cache. Contact Team Cloud on
the #cloud-infrastructure Slack channel and provide:
- The full name of your GitHub repository, for example
BYM-IKT/KatteApp - The AWS account names that need access, for example
BYM-DP-Katteapp-TestandBYM-DP-Katteapp-Prod
See GitHub Actions OIDC for how this access works.
Step 3: Add the GitHub Actions workflow file
In your application's source code, create a workflow file at .github/workflows/deploy-to-test.yml:
.
├── .github/
│ └── workflows/
│ └── deploy-to-test.yml
├── src/
│ ├── ...
│ └── main.tsx
├── ...
├── package.json
└── index.html
with the following content:
name: Build and deploy website to TEST
on:
push:
branches: [main]
env:
APP_URL: https://kattehotell.test.bymoslo.net # Replace with your application URL without quotes
AWS_ACCOUNT_ID: "<<AWS_ACCOUNT_ID>>"
S3_BUCKET_NAME: "<<S3_BUCKET_NAME>>"
PROJECT_DIRECTORY: "."
BUILD_PATH: "build"
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: ${{ env.APP_URL }}
steps:
- name: Check out repository
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set up pnpm
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
with:
version: 10
package_json_file: ./package.json
- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: 24
- name: Install dependencies
run: pnpm install
- name: Build
env:
CI: false
run: pnpm build --emptyOutDir --outDir '${{ env.BUILD_PATH }}'
- name: Upload to S3 and invalidate CloudFront cache
uses: BYM-IKT/github-actions/upload-to-s3-and-invalidate-cloudfront@master
with:
aws-account-id: ${{ env.AWS_ACCOUNT_ID }}
s3-bucket-name: ${{ env.S3_BUCKET_NAME }}
build-directory: ${{ env.PROJECT_DIRECTORY }}/${{ env.BUILD_PATH }}
cloudfront-distribution-domain-name: ${{ env.APP_URL }}
Replace <<AWS_ACCOUNT_ID>> with the ID of your AWS account and <<S3_BUCKET_NAME>>
with the bucket name from Step 1.
Tip
Not sure about the AWS account ID? Look for the default-account.tf file in your product's Terraform Infrastruktur-repo. The AWS account ID is the 12-digit number used for the account_id variable.
You can also log in to the AWS Access Portal to find the account ID.
Step 4: Push and verify
Push to main. The workflow builds the app and uploads it to S3, then
invalidates the CloudFront cache.
- Open the Actions tab in the application repository and confirm the workflow run succeeds.
- Visit
APP_URLfrom the workflow and confirm the app loads.