Skip to main content

AWS Single-VM Terraform Example

Multiforum includes a Terraform example for provisioning the production Compose foundation on one AWS EC2 instance.

It creates:

  • an Ubuntu 24.04 EC2 instance in the default VPC;
  • an encrypted gp3 root volume;
  • an Elastic IP;
  • SSH access restricted to one administrator CIDR;
  • public HTTP, HTTPS, and HTTP/3 rules for Caddy; and
  • cloud-init staging for Docker, the deployment repository, official images, the production environment template, Restic, and backup systemd units.

Terraform intentionally does not receive Auth0 credentials, the Neo4j password, encryption keys, or object-storage credentials. Those values remain out of plans and state.

Provision the host

git clone https://github.com/gennit-project/multiforum-nuxt.git
cd multiforum-nuxt/deploy/terraform/aws-single-vm
cp terraform.tfvars.example terraform.tfvars
$EDITOR terraform.tfvars
terraform init
terraform plan
terraform apply

Set admin_cidr to a trusted /32. Pin repository_ref and all image inputs to tested releases or immutable revisions. The default t3.large and 40 GiB root volume are starting points, not universal sizing recommendations.

Terraform outputs the stable IP, HTTPS URL, SSH command, and DNS A record. Add the DNS record, then wait for cloud-init:

terraform output dns_a_record
ssh ubuntu@PUBLIC_IP
cloud-init status --wait

Complete application setup

On the host:

cd /opt/multiforum
$EDITOR .env.production

Fill the required secrets, configure Auth0, validate Compose, and start the stack using the production installation. Cloud-init deliberately does not start an unconfigured application.

After production verification and a successful manual backup, review /etc/multiforum/backup.env and enable the staged timer:

sudo systemctl start multiforum-backup.service
sudo systemctl enable --now multiforum-backup.timer
systemctl list-timers multiforum-backup.timer

The timer alone creates local backups. Follow Backup and Restore to activate encrypted Restic uploads, monitor freshness, and perform a recovery drill.

Updates and replacement

Terraform provisions infrastructure; it is not the application updater. Use the repository's safe upgrade command for image updates. Changing repository_ref or image variables does not rerun cloud-init on an existing instance.

The host and local Docker volumes are a single point of failure. Back up and verify off-site recovery before replacing the instance. terraform destroy removes the instance and its root volume, including local forum data.