Updates the tool product name across the app UI (header, page title, section labels, form buttons, success/error states, report stat labels), README, deployment docs, and the CiviCRM email template guidance. Custom domain references move from check-in.fci.coop to survey.fci.coop (DNS update still required). The underlying CiviCRM "Check-in (organizing)" activity type, custom group machine names (Check_in_data__organizing_), health-check ids, and the internal org_engagement_check_in form id are unchanged -- those are CiviCRM contract surfaces, not product copy.
8.3 KiB
Deploying to AWS Amplify Hosting
First-time walkthrough for shipping this app on AWS Amplify Hosting. Amplify
auto-detects Next.js, runs the build, and routes SSR pages + API routes
through managed Lambda behind a CloudFront CDN. The amplify.yml and
.nvmrc in this repo are the only pieces Amplify needs from the codebase.
Before you start
- An AWS account with billing enabled. Amplify Hosting has a free tier (1,000 build minutes + 15 GB served + 100 GB-hours of SSR Lambda per month for the first year) — typical traffic for this app stays comfortably inside it.
- GitHub access to
joelbrock/WebForm-mw. Amplify connects via OAuth or a GitHub App; either works. - The three required CiviCRM env vars in hand:
CIVI_BASE_URL,CIVI_API_KEY,CIVI_SITE_KEY. Plus the optionalCIVI_HTTP_AUTH_*pair if CiviCRM sits behind webserver-level Basic Auth.
Step 1 — Create the Amplify app
- Open the Amplify console: https://console.aws.amazon.com/amplify/
- Pick a region near you / near CiviCRM.
us-east-1(N. Virginia) is the default and has the lowest cold-start latency for most setups.
- Pick a region near you / near CiviCRM.
- Click Create new app → Host web app.
- Choose GitHub as the source. Authorize Amplify if prompted.
The first time, AWS will install a GitHub App on your account; grant
it access just to
joelbrock/WebForm-mw(not "all repos"). - Pick the repo
joelbrock/WebForm-mwand themainbranch. - App name: something like
coop-checkin(this becomes the*.amplifyapp.comsubdomain). - Amplify reads
amplify.ymlautomatically; you do not need to edit the build spec on this screen. Click Next.
Step 2 — Environment variables and Secrets
Amplify Gen 2 splits configuration across two separate pages in the console sidebar (under Hosting):
- Environment variables — plaintext-at-rest, intended for non-sensitive
config. Readable by anyone with
amplify:GetApppermission on the AWS account. - Secrets — values stored in AWS Systems Manager Parameter Store as SecureString, encrypted at rest. Injected into the build/runtime as normal environment variables under the same name, so application code doesn't need to know the difference.
Add each variable to the page indicated below:
| Variable | Page | Notes |
|---|---|---|
CIVI_BASE_URL |
Environment variables | e.g. https://crm.fci.coop |
CIVI_API_KEY |
Secrets | Required |
CIVI_SITE_KEY |
Secrets | Required |
CIVI_HTTP_AUTH_USER |
Environment variables | Only if CiviCRM has webserver-level Basic Auth in front of it |
CIVI_HTTP_AUTH_PASS |
Secrets | Only if above set |
HEALTH_TOKEN |
Secrets | Optional; gates /api/health in production |
PREVIEW_ADMIN_TOKEN |
Secrets | Optional; gates /api/preview-link |
Rule of thumb: if leaking the value would let someone impersonate the app to CiviCRM, or bypass a gate, it goes in Secrets. Hostnames and usernames are fine in plaintext Environment variables.
Don't set
NODE_ENV=productionin either page. Amplify and Next already set it correctly at runtime; setting it at build time causesnpm cito skip devDependencies, which breaks the Tailwind/PostCSS step. Theamplify.ymlin this repo guards against this with--include=dev, but it's cleaner not to set it at all.
Don't duplicate names across both pages. If the same variable name appears in both Environment variables and Secrets, Amplify's precedence is undefined in Gen 2.
Click through, review, Save and deploy.
Step 3 — First build
The first build takes about 4–6 minutes (later builds are 2–3 with cache). You can watch progress in the Hosting environments view. When it completes, three things are confirmed:
- The build succeeded →
next buildproduced.next/. - SSR functions deployed → API routes and dynamic pages have a Lambda function behind them.
- The app is reachable at
https://main.<random>.amplifyapp.com.
Smoke-test the deploy:
https://main.<random>.amplifyapp.com/healthz
Should return 200 OK (lightweight platform check, doesn't hit CiviCRM).
If you set HEALTH_TOKEN, the richer diagnostic at
/api/health?token=<value> will probe the CiviCRM connection itself —
useful to confirm env vars are wired correctly.
Step 4 — Custom domain (optional)
Amplify can attach a custom domain (e.g. survey.fci.coop) with
auto-issued TLS in a few minutes:
- In the app, Hosting → Custom domains → Add domain.
- Enter the apex (
fci.coop) or a subdomain. - Amplify suggests DNS records (CNAME / ALIAS). Add them at your DNS provider (Cloudflare, Route53, Namecheap, etc.).
- Wait 5–15 minutes for validation and certificate issuance.
The *.amplifyapp.com URL keeps working alongside the custom domain.
Step 5 — Per-PR previews (optional, recommended)
Amplify can build a preview environment for every pull request:
- Hosting → Previews → enable for the
joelbrock/WebForm-mwrepo. - PRs get their own
https://pr-<num>.<random>.amplifyapp.comURL, posted as a comment on the PR. - Previews inherit the main branch's environment variables unless you override on the preview branch.
Useful for reviewing form changes against live CiviCRM DEV before merging.
What it'll cost
Realistic estimate for this app's expected traffic (a few hundred form/report loads per month, very modest API throughput):
- Hosting (CDN + static): pennies. Free tier covers it.
- SSR Lambda: ~$0.05–$0.50/month depending on traffic. Each form load triggers a couple of API calls into CiviCRM via Lambda; each call is a short-lived invocation.
- Build minutes: free tier covers up to ~300 small builds/month.
Expect <$5/month total at launch traffic. If usage grows significantly, the costs scale roughly linearly with Lambda invocations.
Things to know going in
- Cold starts. First request after a quiet period adds 500–1500ms of Lambda init. Subsequent requests reuse the warm container. For an internal-use form this is fine; users see the loading state during init.
- Outbound IPs are not static. Amplify SSR Lambda functions egress through AWS-managed IPs that change. If CiviCRM has an IP allowlist on its API, this won't work out of the box — you'd need a VPC + NAT Gateway + Elastic IP setup (significantly more complex). Most CiviCRM auth uses API keys, not IP allowlisting, so this usually isn't an issue.
- No Render-style background workers. Amplify is request/response only. Anything cron-shaped needs EventBridge + a separate Lambda. The current app doesn't have background jobs, so this doesn't apply.
- Logs live in CloudWatch. Each SSR function has its own log group; click into the function from the Amplify app view to jump to logs. Retention defaults to "never expire" — switch to 30 days unless you need more.
- Secrets rotate manually. No auto-rotation. To rotate
CIVI_API_KEY, update it in Amplify env vars → trigger a redeploy. render.yamlis now informational. It's still in the repo for the Render path; Amplify ignores it. If you commit fully to Amplify and abandon Render, therender.yamland the Render section ofDEPLOYMENT.mdcan be removed.
When something breaks
- Build fails on
npm ci→ usually a Node version mismatch. The.nvmrcpins Node 20; if Amplify's build image doesn't have it, theamplify.ymlnvm installfalls back. Open the build log, search for "Node version". - Build fails on
next build→ typecheck or lint error. Reproduce locally withnpm run build. - Site builds but routes 503 → SSR Lambda misconfig. Check the
function's CloudWatch logs for the actual error. Most common cause:
missing required env var (the app refuses to boot in production stub
mode and the
lib/env.tsvalidator throws). - CiviCRM calls fail with 401 → API key or Basic Auth credentials
wrong. Re-check
CIVI_API_KEYandCIVI_HTTP_AUTH_*in the Amplify env-vars panel; redeploy after changes.
After the first successful deploy
- Bookmark the Amplify app URL and the CloudWatch log group.
- Run the email/link smoke test from
EMAIL_DELIVERY.mdagainst the Amplify URL to confirm/api/preview-linkproduces working tokenized URLs end-to-end. - Update any docs / staff runbooks pointing at the old Render URL.