Skip to content

Commit 34feedb

Browse files
authored
Merge pull request #199 from SSDALab/anshul-infra-docs-reconciliation
Add Pulumi infrastructure page to docs site
2 parents 9210347 + c61015a commit 34feedb

File tree

8 files changed

+140
-4
lines changed

8 files changed

+140
-4
lines changed

docs/about/project-overview.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Key capabilities:
3636
| Auth | Twilio Verify (OTP), JWT |
3737
| Permissions | CASL (role + attribute-based) |
3838
| Hosting | Azure App Service |
39+
| Infrastructure | Pulumi (TypeScript), Azure |
3940
| QR Scanning | Html5QrcodeScanner, QRCodeCanvas |
4041

4142
## Open Source and Reuse

docs/getting-started/getting-started.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
- **GitHub** — to fork the repository and use GitHub Actions for CI/CD. [Fork the repository](https://github.com/SSDALab/respondent-driven-sampling/fork).
88
- **MongoDB** — all survey data is stored in MongoDB. [MongoDB Atlas](https://www.mongodb.com/atlas) (free M0 tier) is recommended. The connection string (`MONGO_URI`) and database name (`MONGO_DB_NAME`) come from the chosen provider.
99
- **Twilio** — OTP authentication for volunteer logins via Twilio Verify. Requires `TWILIO_ACCOUNT_SID`, `TWILIO_AUTH_TOKEN`, and a Verify service SID (`TWILIO_VERIFY_SID`). `TWILIO_PHONE_NUMBER` is only needed for outbound bulk SMS.
10-
- **Azure App Service** (or any Node.js host) — King County uses Azure; see [Deployment](../how-to/deployment.md) for specifics.
10+
- **Azure App Service** (or any Node.js host) — King County uses Azure; see [Infrastructure](../how-to/infrastructure.md) for provisioning with Pulumi and [Deployment](../how-to/deployment.md) for deploying application code.
1111

1212
**Local tools:**
1313

@@ -122,4 +122,4 @@ For a pre-deployment end-to-end test, see the checklist in [Setting Up a Survey]
122122

123123
## 8. Deploy
124124

125-
See [Deployment](../how-to/deployment.md) for Azure App Service instructions.
125+
To deploy to Azure App Service, first provision the required Azure resources (see [Infrastructure](../how-to/infrastructure.md)), then deploy the application code (see [Deployment](../how-to/deployment.md)).

docs/how-to/deployment.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
This page covers deploying the RDS App to Azure App Service, the hosting platform used by King County. Complete the [Getting Started](../getting-started/getting-started.md) guide before proceeding.
44

5+
!!! tip "Need to provision Azure resources first?"
6+
If the Azure Resource Group, MongoDB cluster, App Service Plan, and Web App do not exist yet, see [Infrastructure](infrastructure.md) to provision them with Pulumi before deploying application code.
7+
58
The app is a monorepo: the React frontend (`client/`) is built to static files, copied into the `server/` folder, and served by the Express backend as a single Node.js service.
69

710
## Deployment via GitHub Actions (recommended)
@@ -60,7 +63,9 @@ cp -r client/dist server/dist
6063

6164
## Environment Variables in Production
6265

63-
On Azure App Service, environment variables are set as **Application settings** (not in a `.env` file):
66+
On Azure App Service, environment variables are set as **Application settings** (not in a `.env` file).
67+
68+
If the infrastructure was provisioned with Pulumi (see [Infrastructure](infrastructure.md)), these settings are configured automatically during `pulumi up`. Otherwise, set them manually:
6469

6570
Azure Portal > App Service > **Configuration** > **Application settings** > add each variable as a key-value pair > Save > restart the service.
6671

docs/how-to/infrastructure.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Infrastructure Provisioning
2+
3+
The `infra/` directory contains a [Pulumi](https://www.pulumi.com/) project (TypeScript) that provisions all Azure resources required to run the RDS App. No Pulumi Cloud account is required — state is stored locally.
4+
5+
## What Gets Created
6+
7+
Running `pulumi up` provisions four Azure resources:
8+
9+
| Resource | Purpose |
10+
|---|---|
11+
| **Resource Group** | Logical container for all RDS resources |
12+
| **MongoDB vCore Cluster** (Cosmos DB) | Application database |
13+
| **App Service Plan** (Linux) | Compute plan for the web app |
14+
| **Web App** (Node.js on Linux) | Hosts the Express server and React frontend |
15+
16+
Pulumi also configures the Web App's **Application settings** (environment variables) automatically, including `MONGO_URI`, `AUTH_SECRET`, and the Twilio credentials. See [Environment Variables](../reference/environment-variables.md) for the meaning of each variable.
17+
18+
## Prerequisites
19+
20+
- [Node.js](https://nodejs.org/) (>=20.17.0)
21+
- [Pulumi CLI](https://www.pulumi.com/docs/install/)
22+
- [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)
23+
- An Azure subscription
24+
25+
## Quick Start
26+
27+
From the repository root:
28+
29+
```bash
30+
# 1. Install dependencies
31+
cd infra
32+
npm install
33+
34+
# 2. Log in to Azure
35+
az login
36+
37+
# 3. Use local Pulumi state (no account needed)
38+
pulumi login --local
39+
40+
# 4. Create a stack
41+
pulumi stack init prod
42+
43+
# 5. Set required config
44+
pulumi config set location westus2
45+
pulumi config set resourceGroupName my-rds-rg
46+
pulumi config set mongoClusterName my-rds-db
47+
pulumi config set mongoDbName main
48+
pulumi config set appServicePlanName my-rds-plan
49+
pulumi config set webAppName my-rds-app
50+
pulumi config set skuName B1
51+
52+
# 6. Set secrets
53+
pulumi config set --secret mongoAdminLogin <your-admin-user>
54+
pulumi config set --secret mongoAdminPassword <your-admin-password>
55+
pulumi config set --secret authSecret <your-auth-secret>
56+
pulumi config set --secret twilioAccountSid <your-sid>
57+
pulumi config set --secret twilioAuthToken <your-token>
58+
pulumi config set --secret twilioVerifySid <your-verify-sid>
59+
60+
# 7. Deploy
61+
pulumi up
62+
```
63+
64+
!!! warning "Secrets"
65+
`mongoAdminPassword`, `authSecret`, and the Twilio credentials contain sensitive values. Always use `pulumi config set --secret` so they are encrypted in the stack state file.
66+
67+
## Config Reference
68+
69+
| Key | Required | Default | Description |
70+
|-----|----------|---------|-------------|
71+
| `resourceGroupName` | Yes || Azure Resource Group name |
72+
| `location` | Yes || Azure region (e.g. `westus2`) |
73+
| `mongoClusterName` | Yes || MongoDB vCore cluster name |
74+
| `mongoDbName` | Yes || MongoDB database name (e.g. `main`) |
75+
| `appServicePlanName` | Yes || App Service Plan name |
76+
| `webAppName` | Yes || Web App name (globally unique) |
77+
| `skuName` | Yes || App Service Plan SKU (e.g. `B1`, `P1v2`) |
78+
| `mongoAdminLogin` | Yes (secret) || MongoDB admin username |
79+
| `mongoAdminPassword` | Yes (secret) || MongoDB admin password |
80+
| `authSecret` | Yes (secret) || Auth secret for JWT signing |
81+
| `twilioAccountSid` | Yes (secret) || Twilio Account SID |
82+
| `twilioAuthToken` | Yes (secret) || Twilio Auth Token |
83+
| `twilioVerifySid` | Yes (secret) || Twilio Verify Service SID |
84+
| `nodeVersion` | No | `22-lts` | Node.js version for App Service |
85+
| `nodeEnv` | No | `production` | `NODE_ENV` value |
86+
| `mongoServerVersion` | No | `8.0` | MongoDB server version |
87+
| `mongoSku` | No | `M20` | MongoDB vCore cluster SKU |
88+
| `mongoDiskSizeGb` | No | `128` | MongoDB disk size in GB |
89+
90+
!!! note "App settings managed by Pulumi"
91+
When infrastructure is provisioned with Pulumi, the Web App's Application settings (`MONGO_URI`, `MONGO_DB_NAME`, `AUTH_SECRET`, Twilio credentials, etc.) are set automatically. There is no need to configure them manually in the Azure Portal.
92+
93+
## Importing Existing Resources
94+
95+
If Azure resources already exist (e.g. from a previous Terraform setup), they can be imported instead of recreated:
96+
97+
1. Find each resource's Azure ID (from the Azure Portal or `az` CLI).
98+
2. Add `{ import: "<azure-resource-id>" }` as the third argument to each Pulumi resource constructor in `index.ts`.
99+
3. Run `pulumi up` — Pulumi adopts the resources without modifying them.
100+
4. Remove the `import` options and run `pulumi up` again to verify no changes are detected.
101+
102+
Import order: Resource Group → MongoDB Cluster → App Service Plan → Web App.
103+
104+
## Tear Down
105+
106+
```bash
107+
pulumi destroy
108+
pulumi stack rm prod
109+
```
110+
111+
## Troubleshooting
112+
113+
- **`az login` errors** — Verify `az account show` returns a valid subscription. Set the `ARM_SUBSCRIPTION_ID` environment variable if needed.
114+
- **Name conflicts**`mongoClusterName` and `webAppName` must be globally unique across Azure.
115+
- **SKU not available** — Some SKUs are region-specific. Try `B1` or `P1v2` in the chosen region.
116+
- **Node version format** — Use `22-lts` (not `v22` or `22.x`). This maps to `NODE|22-lts` in the App Service config.
117+
118+
---
119+
120+
After provisioning, proceed to [Deployment](deployment.md) to push the application code to the new Azure App Service.

docs/reference/architecture.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ respondent-driven-sampling/
3232
├── client/ # React SPA (Vite + TypeScript + MUI)
3333
├── server/ # Express API (TypeScript + MongoDB)
3434
├── docs/ # Documentation source (this site)
35+
├── infra/ # Azure infrastructure (Pulumi + TypeScript)
3536
├── mkdocs.yml # MkDocs configuration
3637
└── .github/ # CI/CD workflows, issue templates
3738
```
@@ -133,6 +134,8 @@ Permissions are defined in `server/src/permissions/abilityBuilder.ts` and the sa
133134

134135
## Deployment Architecture
135136

137+
Azure resources (Resource Group, MongoDB vCore cluster, App Service Plan, and Web App) are provisioned via Pulumi in the `infra/` directory. See [Infrastructure](../how-to/infrastructure.md) for setup instructions.
138+
136139
In production (Azure App Service):
137140

138141
```

docs/reference/environment-variables.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ Common timezone values: `America/Los_Angeles`, `America/Denver`, `America/Chicag
3333

3434
## Production Setup on Azure
3535

36-
On Azure App Service, environment variables are set as **Application settings** rather than in a `.env` file:
36+
On Azure App Service, environment variables are set as **Application settings** rather than in a `.env` file.
37+
38+
If the infrastructure was provisioned with Pulumi, these variables are configured automatically as App Service settings via `infra/index.ts`. See [Infrastructure](../how-to/infrastructure.md) for details.
39+
40+
For manual configuration:
3741

3842
Azure Portal → App Service → Configuration → Application settings → add each variable as a key-value pair → Save → restart the service.

infra/getting-started.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
> **Canonical docs:** [Infrastructure Provisioning](https://ssdlab.github.io/respondent-driven-sampling/how-to/infrastructure/) — this file is a quick-reference for the `infra/` directory; the full documentation lives on the docs site.
2+
13
# RDS Infrastructure (Pulumi + Azure)
24

35
Deploy the full Azure stack for the Respondent-Driven Sampling app using **Pulumi with TypeScript**.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ nav:
5050

5151
- How-To:
5252
- Deployment: how-to/deployment.md
53+
- Infrastructure: how-to/infrastructure.md
5354
- Setting Up a Survey: how-to/setting-up-a-survey.md
5455
- Adding Survey Locations: how-to/adding-survey-locations.md
5556
- Debugging: how-to/debugging.md

0 commit comments

Comments
 (0)