Skip to content

Medplum Initial Install & IaC Build Plan

Last updated: 2026-05-29T20:14:58Z

Goal

Stand up VIM's self-hosted Medplum dev environment on AWS using Medplum's official AWS CDK path, with all infrastructure represented as code and deployable through GitHub Actions.

Current fixed inputs

Input Value
AWS account VIM Dev child account 342624924188
Region us-east-1
Medplum environment dev
Parent domain vimmedicine.app
Dev Medplum zone medplum-dev.vimmedicine.app
API endpoint api.medplum-dev.vimmedicine.app
App endpoint app.medplum-dev.vimmedicine.app
Storage endpoint storage.medplum-dev.vimmedicine.app

Create a private repo under the VIM GitHub organization:

vim-medplum-infra

This should become the canonical backend/IaC repo for Medplum environments.

Recommended contents:

README.md
cdk.json
package.json
package-lock.json
medplum.dev.config.template.json
medplum.dev.config.json              # only if confirmed non-secret
scripts/
  validate-config.sh
  check-dns.sh
  preflight-dev.sh
docs/
  architecture.md
  runbooks/deploy-dev.md
  runbooks/teardown-dev.md
.github/workflows/
  validate.yml
  cdk-diff-dev.yml
  deploy-dev.yml
  destroy-dev.yml

Deployment model

Use GitHub Actions with AWS OIDC, not long-lived AWS access keys.

Workflows:

  1. Validate — runs on PR/push; installs dependencies, validates JSON, runs secret scan, and eventually runs CDK synth.
  2. CDK Diff — runs on PR/manual; assumes AWS diff role and produces cdk diff for review.
  3. Deploy Dev — manual only; protected by GitHub Environment dev; deploys CDK and Medplum app after approval.
  4. Destroy Dev — manual only; protected; used for controlled teardown when needed.

Initial install phases

Phase 0 — confirm final deploy inputs

Before actual deploy, VIM still needs to confirm:

  • SES sender identity.
  • Access model: IP-allowlist/VPN/public-WAF.
  • Budget alarm threshold and owner.
  • Security/compliance reviewer.
  • Clinical reviewer before any real-data use.

Recommended defaults:

  • SES: no-reply@vimmedicine.app or no-reply@medplum-dev.vimmedicine.app.
  • Access: IP-allowlisted if VIM has stable office/VPN egress IPs; otherwise public WAF-protected dev with synthetic-only policy.
  • Budget: start with a $250/month dev alarm and adjust after baseline.

Phase 1 — GitHub repo

  • Create private repo vim-medplum-infra.
  • Push current Medplum CDK scaffold.
  • Add branch protection on main.
  • Add GitHub Environment dev with required reviewers for deploy/destroy.

Phase 2 — AWS bootstrap IaC

Create a small bootstrap stack for:

  • GitHub OIDC provider.
  • GitHub Actions deploy/diff IAM role(s).
  • Budget alarm.
  • WAF/IP set if IP allowlist is chosen.

Use local AWS profile vim-medplum-dev only for this first bootstrap, because GitHub OIDC will not exist yet.

Phase 3 — Medplum config generation

Run:

cd /Users/robbie/vim-projects/medplum-aws-dev-cdk
AWS_PROFILE=vim-medplum-dev npx medplum aws init

Then inspect generated config before committing. If it contains secrets or private key material, keep only a sanitized template in git and store sensitive values securely.

Phase 4 — CDK bootstrap/synth/diff

Run:

AWS_PROFILE=vim-medplum-dev npx cdk bootstrap -c config=medplum.dev.config.json
AWS_PROFILE=vim-medplum-dev npx cdk synth -c config=medplum.dev.config.json
AWS_PROFILE=vim-medplum-dev npx cdk diff -c config=medplum.dev.config.json

Review IAM, VPC, RDS, Redis, ALB/CloudFront, WAF, S3, DNS, SES, CloudWatch, and cost impact before deploying.

Phase 5 — deploy after approval

Run only after approved diff/security/cost review:

AWS_PROFILE=vim-medplum-dev npx cdk deploy --all -c config=medplum.dev.config.json
AWS_PROFILE=vim-medplum-dev npx medplum aws deploy-app dev

Then verify API/app/storage DNS, TLS, health checks, logs, alarms, email, database, Redis, and storage behavior.

Phase 6 — move deploy control to GitHub Actions

Once OIDC and workflows are verified, all future dev changes should flow through:

PR -> validate -> cdk diff -> review -> merge -> manual deploy-dev workflow

Duplication/spin-up/spin-down strategy

To duplicate environments:

  • Use separate config files per environment: medplum.dev.config.json, medplum.staging.config.json, etc.
  • Use separate delegated zones: medplum-dev.vimmedicine.app, medplum-staging.vimmedicine.app.
  • Prefer separate AWS child accounts for staging/prod later.
  • Keep deploy/destroy workflows parameterized by environment.
  • Document retained resources during destroy: S3, RDS snapshots, Secrets Manager recovery, CloudWatch logs, Route 53 zones.

Safety rule

Dev remains synthetic-only. No PHI, patient identifiers, production credentials, or production integrations until engineering, security/compliance, and clinical review are complete.