Skip to content

Commit 2230098

Browse files
authored
chore: deploy to AWS (#2)
* chore: deploy to AWS * fix: stabilize preview deployment flow * chore: enable CloudFront access logging * feat: configure production domain and certificate
1 parent 3ed8b9e commit 2230098

File tree

9 files changed

+658
-0
lines changed

9 files changed

+658
-0
lines changed

.github/workflows/deploy.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Deploy Static Site
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
- aws-deploy
8+
workflow_dispatch:
9+
10+
permissions:
11+
id-token: write
12+
contents: read
13+
14+
env:
15+
AWS_REGION: ${{ vars.AWS_REGION }}
16+
S3_BUCKET: ${{ vars.S3_BUCKET }}
17+
CLOUDFRONT_DISTRIBUTION_ID: ${{ vars.CLOUDFRONT_DISTRIBUTION_ID }}
18+
NUXT_PUBLIC_SITE_URL: ${{ github.ref == 'refs/heads/master' && secrets.NUXT_PUBLIC_SITE_URL || vars.PREVIEW_SITE_URL }}
19+
GH_TOKEN: ${{ secrets.GH_TOKEN }}
20+
NUXT_PUBLIC_ASSET_KEY: ${{ secrets.NUXT_PUBLIC_ASSET_KEY }}
21+
22+
jobs:
23+
deploy:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v4
28+
29+
- name: Setup Bun
30+
uses: oven-sh/setup-bun@v1
31+
with:
32+
bun-version: latest
33+
34+
- name: Install dependencies
35+
run: bun install --frozen-lockfile
36+
37+
- name: Show site URL
38+
if: github.ref != 'refs/heads/master'
39+
run: echo "NUXT_PUBLIC_SITE_URL=${NUXT_PUBLIC_SITE_URL}"
40+
41+
- name: Generate reports
42+
run: bun run generate-reports
43+
44+
- name: Generate static site
45+
run: bun run generate
46+
47+
- name: Configure AWS credentials
48+
uses: aws-actions/configure-aws-credentials@v4
49+
with:
50+
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
51+
aws-region: ${{ env.AWS_REGION }}
52+
53+
- name: Sync artifacts to S3
54+
run: aws s3 sync .output/public "s3://${S3_BUCKET}" --delete
55+
56+
- name: Invalidate CloudFront
57+
run: aws cloudfront create-invalidation --distribution-id "${CLOUDFRONT_DISTRIBUTION_ID}" --paths "/*"

infra/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.pulumi/

infra/Pulumi.dev.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
encryptionsalt: v1:W1NLKXoFxV4=:v1:S5quyyMBvgH4qAzD:tYNPw7qdVcUbCoFdkwH+URbo1ukeqQ==
2+
config:
3+
aws:region: us-west-2
4+
projectm-infra:bucketName: prjm
5+
projectm-infra:cloudfrontPriceClass: PriceClass_100
6+
projectm-infra:githubOwner: projectM-visualizer
7+
projectm-infra:githubRefs: '["ref:refs/heads/*","ref:refs/tags/*","ref:refs/pull/*"]'
8+
projectm-infra:githubRepo: projectm-visualizer.org
9+
projectm-infra:primaryDomain: projectm-visualizer.org
10+
projectm-infra:hostedZoneId: Z0970442162ZXM1J1N8GK

infra/Pulumi.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
name: projectm-infra
2+
runtime:
3+
name: nodejs
4+
options:
5+
typescript: true
6+
main: index.ts
7+
description: Infrastructure for the ProjectM static site on AWS.

infra/README.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Infrastructure
2+
3+
Manage the static site infrastructure with Pulumi.
4+
5+
## Prerequisites
6+
7+
- Pulumi CLI
8+
- AWS credentials with permissions to manage S3, CloudFront, ACM, Route53, and IAM
9+
10+
## Setup
11+
12+
1. Install dependencies:
13+
```bash
14+
cd infra
15+
npm install
16+
```
17+
2. Log into the shared S3 backend (only needs to be done once per environment):
18+
```bash
19+
AWS_PROFILE=projectm pulumi login s3://pulumi-state-projectm
20+
```
21+
3. Create a stack (example `dev`) if it does not exist:
22+
```bash
23+
pulumi stack init dev
24+
```
25+
4. Configure required values:
26+
```bash
27+
pulumi config set bucketName prjm
28+
pulumi config set githubOwner projectM-visualizer
29+
pulumi config set githubRepo projectm-visualizer.org
30+
pulumi config set githubRefs '["ref:refs/heads/master"]'
31+
# Allow additional refs as needed, for example:
32+
pulumi config set githubRefs '["ref:refs/heads/master","ref:refs/heads/*","ref:refs/tags/*","ref:refs/pull/*"]'
33+
pulumi config set aws:region your-app-region
34+
```
35+
5. Optional configuration:
36+
- `cloudfrontPriceClass` (`PriceClass_100`, `PriceClass_200`, `PriceClass_All`)
37+
- `primaryDomain` and `alternateDomains` to enable custom domains
38+
- `hostedZoneId` to request an ACM certificate via DNS validation
39+
- `certificateArn` to reuse an existing certificate instead of provisioning one
40+
- `oidcProviderArn` to reference an existing GitHub OIDC provider
41+
- `githubRoleName` to override the IAM role name
42+
43+
6. Deploy:
44+
```bash
45+
AWS_PROFILE=projectm PULUMI_CONFIG_PASSPHRASE=projectm pulumi up
46+
```
47+
48+
Outputs include the CloudFront distribution details and the IAM role ARN.
49+
50+
### State
51+
52+
State lives in `s3://pulumi-state-projectm` (versioned). Set `AWS_PROFILE=projectm` and `PULUMI_CONFIG_PASSPHRASE=projectm` when running Pulumi commands so AWS calls and encrypted config values work consistently.
53+
54+
## GitHub Actions
55+
56+
Set these repository secrets and variables before running the deployment workflow:
57+
58+
- `AWS_ROLE_ARN` (secret): ARN of the IAM role exported by Pulumi.
59+
- `GH_TOKEN` (secret): GitHub token with `repo` scope for `generate-reports`.
60+
- `NUXT_PUBLIC_ASSET_KEY` (secret): Encryption key used by `generate-reports`.
61+
- `vars.PREVIEW_SITE_URL`: CloudFront preview URL (for example, `https://d15wenzbsa5dzp.cloudfront.net`).
62+
- `secrets.NUXT_PUBLIC_SITE_URL`: Production URL used on the `master` branch (for example, `https://projectm-visualizer.org`).
63+
- `vars.AWS_REGION`: AWS region for S3 operations (for example, `us-west-2`).
64+
- `vars.S3_BUCKET`: Target S3 bucket name (`prjm`).
65+
- `vars.CLOUDFRONT_DISTRIBUTION_ID`: Distribution ID exported by Pulumi.
66+
67+
### CloudFront Access Logging
68+
69+
Provision the log bucket and enable CloudFront logging with the helper script (run once per environment):
70+
71+
```bash
72+
cd infra
73+
AWS_PROFILE=projectm AWS_SDK_LOAD_CONFIG=1 node scripts/enable-cloudfront-logging.mjs
74+
```
75+
76+
By default this creates `projectm-visualizer-cloudfront-logs` in `us-west-2` and configures the distribution to write compressed logs (cookies included) under the `cloudfront/` prefix.
77+
78+
79+
The workflow runs on pushes to `master` and can also be triggered manually.

0 commit comments

Comments
 (0)