This Terraform project manages the Google Cloud Platform infrastructure necessary for operating the Interledger Foundation's Mastodon instance. This repository is intended to be reusable by other people who want to operate a Mastodon instance using GCP.
Mastodon requires:
- a domain name (Cloud DNS)
- a PostgreSQL database (Cloud SQL)
- a Redis database (Memorystore)
- an S3-compatible object storage (Cloud Storage)
- a Kubernetes cluster (Kubernetes Engine in Autopilot mode)
Additional GCP-specific functionality:
- Global external Application Load Balancer for ingress
- Google-managed TLS certificates
- Ingress rule to redirect
http
traffic tohttps
This project was tested on 2024-09-30 with:
- GKE 1.30.3-gke.1969001
- helm 3.16.1
- Mastodon chart 5.4.0 (* see below)
- Mastodon app 4.2.12
This project assumes you have gcloud
and helm
installed locally.
This project assumes the use of automated deployments, so a service account is used to apply the Terraform. Grant the service account (terraform-sa
) the roles of Compute Network Admin, Editor, and Security Admin. Download the JSON credentials and set the credentials_file_path
in terraform.tfvars
. Alternatively, you can run this Terraform code locally with your Google account and authenticate using the gcloud
CLI.
This project sets the DNS records for the Mastodon instance. The domain name must be pointed to Google Cloud DNS name servers and the service account (or Google account running the Terraform) must be an owner for the domain name in the Google Search Console.
Create a Cloud Storage bucket dedicated to storing the Terraform state. This must be provisioned manually or independently of these modules, as it is a dependency for running this Terraform.
Elastic Cloud’s Elasticsearch Service (ESS) is used because GCP does not offer managed Elasticsearch. Generate an API key to use. Blocked by Mastodon chart issue
Terraform best practices dictate Kubernetes clusters and Kubernetes resources not co-exist. The dependencies
module must be applied before and separately from the mastodon
module.
The dependencies
Terraform module provisions GCP-managed resources and Google Kubernetes Engine in autopilot mode.
The mastodon
Terraform module deploys the official Mastodon Helm chart with GCP-specific amendments.
Run terraform init
in both module directories.
-
Create a
terraform.tfvars
file in./dependencies/
with the necessary variables. See thedependencies/terraform.tfvars.example
file for guidance. -
cd ./dependencies && terraform apply
-
Clone the Mastodon Helm chart into
./charts
because it is not published anywhere yet.cd ./charts && git clone https://github.com/mastodon/chart.git --single-branch --branch=main --depth=1 && cd chart && helm dep update
-
Create a
terraform.tfvars
file in./mastodon/
with the necessary variables. See themastodon/terraform.tfvars.example
file for guidance. -
cd ./mastodon && terraform apply
-
As of 2023-06, Google Cloud's IPv6 support is a work in progress. IPv6 support will be added once GCP resolves several outstanding issues with its Terraform provider.
-
WEB_DOMAIN
is not supported, but could be. Contribution welcomed.
If you get HTTPS-related errors, but everything else seems ok, check the status of the certificate with kubectl get ManagedCertificate mastodon-cert -n mastodon
. Provisioning a Google-managed certificate can take up to an hour.
You must generate encryption secrets environment variables before upgrading.
kubectl -n mastodon get pods
to list the pods. Look for something with "mastodon-web".kubectl -n mastodon exec --stdin --tty mastodon-web-99z999z9z9-99zz9 -- /bin/bash
to connect to the container.bin/rails db:encryption:init
to generate the new encryption secrets environment variables.- Add the credentials to your
terraform.tfvars
file asactive_record_encryption_primary_key
,active_record_encryption_deterministic_key
, andactive_record_encryption_key_derivation_salt
.
This is configuration code. This work is marked with CC0 1.0 Universal. It is dedicated to the public domain. See LICENSE file.
Contributions welcomed.