MCO Newsletter System — Implementation Brief for Claude Code

Mission

Build an email-subscription system for the Montana Climate Office website (climate.umt.edu, a Jekyll site in the mt-climate-office/mco-website repo). When a new post is published under _posts/, subscribers should automatically receive a well-formatted, responsive HTML email of that news item.

The stack and high-level design are already decided (see “Decisions already made”). Your job is to implement it inside our existing AWS + Terraform conventions, not to invent a parallel way of running infrastructure.

How to use this brief

  1. Do Phase 0 first. Understand how our AWS infrastructure is currently orchestrated before you create anything. Conform to what you find.
  2. Everything that can be Terraform, must be Terraform. We manage AWS as code. Do not click resources together in the console. The only acceptable manual steps are the ones explicitly flagged below (SES production-access request, and any DNS changes that a human must approve).
  3. Confirm the open questions with me before provisioning anything that costs money or touches DNS. Present a short plan and wait for a go-ahead.
  4. Work in phases. After each phase, summarize what changed and what you need from me next.

Decisions already made (the architecture)

Why this shape: it’s fully open-source, keeps subscriber PII in our control, and the only stateful component is one small always-on host.

Phase 0 — Understand the existing AWS infrastructure (do this first)

Locate and read our Terraform before writing any. Produce a short written summary of how we currently orchestrate AWS, then a recommendation for where this new service fits. Specifically identify:

Deliverable for this phase: a INFRA-NOTES.md summary + a recommended deployment target for Listmonk (see Phase 1), with rationale.

Phase 1 — Provision the host (Terraform)

Default recommendation, if our conventions don’t dictate otherwise: the smallest sensible always-on Docker host — an EC2 t4g.small (ARM) in a public subnet with an Elastic IP, or Lightsail if that’s already a pattern we use. Run Listmonk + Postgres on it via Docker Compose with a persistent volume.

However: if we standardize on ECS Fargate + RDS, use that instead — Listmonk container on Fargate, Postgres on a small RDS instance. It costs more (~$15+/mo for RDS) but may be required by our governance. Decide based on Phase 0 and confirm with me.

Provision via Terraform in our existing repo/module style:

Phase 2 — Deploy and configure Listmonk

Phase 3 — Amazon SES (Terraform + one manual step)

Phase 4 — Email template (MJML)

Phase 5 — GitHub Actions workflow (mco-website repo)

Security & compliance — non-negotiable

Open questions to confirm with me before provisioning

  1. Deployment target: single EC2/Lightsail Docker host (default) or ECS Fargate + RDS to match our governance? (Your Phase 0 findings should inform the recommendation.)
  2. Exact sending address — news@mail.climate.umt.edu? Something else?
  3. Is climate.umt.edu (or a delegated subdomain) in Route 53 in our account, or do DNS records need to go through UM IT manually?
  4. Which AWS account/region and which Terraform repo should this live in?

Acceptance criteria

Out of scope (unless asked)

Advanced analytics beyond Listmonk’s built-ins, multi-list segmentation, multi-language emails, and migrating any existing contact lists.

Rough cost expectation

~$12/month for a single small always-on host, plus near-zero SES at our volume. The ECS Fargate + RDS route runs higher (RDS from ~$15/month).