|
| 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. |
0 commit comments