Using Terraform
This guide is not actively maintained. See the DSS CI/CD guide for the most up-to-date deployment steps.
If you have already finished the Google Cloud Platform (GCP) tutorial and are looking for a more programmatic deployment process, this guide will show you how to use Terraform to deploy the Econia DSS via declarative configurations.
This guide is for a specific use case, the Econia testnet trading competition leaderboard backend, but you can adapt as needed for your particular use case.
Configure project
Install (if you don't already have):
Clone the Econia repository and navigate to the
leaderboard-backend
project directory:git clone https://github.com/econia-labs/econia.git
cd econia
git submodule update --init --recursive
cd src/terraform/leaderboard-backendConfigure a billable GCP project:
PROJECT_NAME=leaderboard-backend
echo $PROJECT_ID
echo $PROJECT_NAME
echo $ORGANIZATION_ID
echo $BILLING_ACCOUNT_IDgcloud projects create $PROJECT_ID \
--name $PROJECT_NAME \
--organization $ORGANIZATION_ID
gcloud alpha billing projects link $PROJECT_ID \
--billing-account $BILLING_ACCOUNT_ID
gcloud config set project $PROJECT_IDPick a database root password:
DB_ROOT_PASSWORD=<DB_ROOT_PASSWORD>
echo $DB_ROOT_PASSWORD
tipAvoid using the special characters
@
,/
,.
, or:
, which are used in connection strings.Store your public IP address:
MY_IP=$(curl --silent http://checkip.amazonaws.com)
echo $MY_IPGenerate keys for a service account:
gcloud iam service-accounts create terraform
SERVICE_ACCOUNT_NAME=terraform@$PROJECT_ID.iam.gserviceaccount.com
echo $SERVICE_ACCOUNT_NAMEgcloud iam service-accounts keys create gcp-key.json \
--iam-account $SERVICE_ACCOUNT_NAMEGenerate SSH keys:
rm -rf ssh
mkdir ssh
ssh-keygen -t rsa -f ssh/gcp -C bootstrapper -b 2048 -q -N ""Store variables in a Terraform variable file, then format and initialize the directory:
echo "project = \"$PROJECT_ID\"" > terraform.tfvars
echo "db_admin_public_ip = \"$MY_IP\"" >> terraform.tfvars
echo "db_root_password = \"$DB_ROOT_PASSWORD\"" >> terraform.tfvarsterraform fmt
echo "\n\nContents of terraform.tfvars:\n\n"
cat terraform.tfvarsterraform init
Build infrastructure
Update
/src/docker/processor/config.yaml
.tipDon't worry about
postgres_connection_string
, this will be automatically handled later.Create
competition-metadata.json
andcompetition-additional-exclusions.json
in/src/rust/dbv2
per the README.Apply the configuration:
terraform apply --parallelism 20
View outputs:
terraform output
Set up load balancing with a custom domain, then update your DNS records for the custom domain.
CUSTOM_DOMAIN=<MY_CUSTOM_DOMAIN>
echo $CUSTOM_DOMAIN
gcloud beta run integrations create \
--parameters set-mapping=$CUSTOM_DOMAIN:postgrest \
--type custom-domainsgcloud beta run integrations describe custom-domains
tipCompared with the more complex generic load balancing setup process, this streamlined process is a GCP Cloud Run beta feature that is not yet supported by Terraform.
If you want to instead use the generic public
run.app
URL, then before you runterraform apply
remove the following line from thepostgrest
service inmain.tf
, then skip this and all remaining steps:ingress = "INGRESS_TRAFFIC_INTERNAL_ONLY"
Create a security policy for the load balancer:
gcloud compute backend-services list
BACKEND_SERVICE=<custom-domains-x-y-postgrest-z-be>
echo $BACKEND_SERVICE
gcloud compute backend-services update $BACKEND_SERVICE \
--global \
--security-policy public-traffic
Take down infrastructure
Destroy project resources:
terraform destroy
tipThis might not destroy quite everything, since GCP has a Cloud SQL deletion waiting period that blocks the deletion of private service networking. This issue was supposed to be resolved as of the Google Provider 5.0.0 release for Terraform, but it appears not to be resolved per https://github.com/hashicorp/terraform-provider-google/issues/16275.
If
terraform destroy
gets stuck on deleting the network connection, you can manually delete the network connection in the GCP console then runterraform destroy
again.Or you can simply delete the project even if Terraform has not destroyed all resources.
Delete GCP project:
gcloud projects delete $PROJECT_ID
Deploy second parallel project
Clear cache:
rm *tfstate*
rm -rf .terraform
rm .terraform*tipIf you delete
*tfstate*
files, then you will lose configuration state and will only be able to modify the primary project viagcloud commands
.If you want to be able to do more than just delete the primary project once you've started a parallel one, keep backups of your
*tfstate*
files.After creating a new project, use a different credentials filename and add your
credentials_file
toterraform.tfvars
(for examplecredentials_file = gcp-key-2.json
).tip.gitignore
ignores any files of patterngcp-key-*.json
.Use the same SSH keys as the main deployment (no need to recreate).
Diagnostics
Connect to PostgreSQL
Connect:
psql $(terraform output -raw db_conn_str_admin)
Target a specific resource
Apply:
terraform apply -target <RESOURCE_NAME>
Destroy:
terraform destroy -target <RESOURCE_NAME>
Generate a dependency graph
Check that you have
dot
:which dot
terraform graph | dot -Tsvg > graph.svg
Check resource metadata
terraform show
terraform state list
terraform state show <RESOURCE_TYPE.RESOURCE_NAME>