terminalRows
18

terramate-runme-example

Based on terramate-example-code-generation.

CI Status Join Discord

This project shows an example file/dir structure you can use with Terramate to keep your Terraform code DRY.

Be sure to read through the Terramate documentation to understand the features of Terramate used here.

The example is organized as two environments, each environment will have:

The Cloud Run applications are simple echo servers that will be reachable through public URLs provided by Cloud Run.

Note: This code is solely for demonstration purposes. This is not production-ready code, so use it at your own risk.

How to use this project?

Pre-Requisites

How is the code organized?

This is the overall structure of the project:

├── modules
│   ├── cloud-run
│   └── service-account
└── stacks
    ├── prod
    │   ├── cloud-runs
    │   │   ├── app1
    │   │   ├── app2
    │   └── service-accounts
    │       └── cloud-run
    └── staging
        ├── cloud-runs
        │   ├── app1
        │   ├── app2
        └── service-accounts
            └── cloud-run
  • modules/cloud-run: Local module, useful to showcase change detection and DRY code generation.
  • modules/service-account: Local Terramate config that keeps code generation DRY between environments.
  • stacks/prod: All stacks belonging to the prod environment.
  • stacks/staging: All stacks belonging to the staging environment.
  • stacks/<env>/service-accounts/cloud-run: Stack that creates service accounts used to execute the cloud run services.
  • stacks/<env>/cloud-runs/{app1,app2}: Stacks that create Cloud Run services.

As you navigate the project you will find multiple Terramate configuration files. Each file will have documentation guiding you through its purpose and usage.

Listing Stacks

To check if your Terramate installation is working and get an overview of the available stacks just run:

terramate list

To check how each stack is defined in detail you can use terramate run:

terramate run -- cat stack.tm.hcl

This will run on each stack directory the command cat stack.tm.hcl. The output will be the definition of all stacks.

Later we are going to use the same mechanism to create and destroy all stacks.

Deploying Stacks

Before we try to deploy any stacks, beware that this will require you to have Google Cloud credentials and deploying infrastructure will incur costs (check the pre-requisites section for more details).

On stacks/config.tm.hcl you will find the terraform_google_provider_project global which configures the project where infrastructure will be created.

It is important to change that to a Google Cloud project where you have appropriate permissions.

Once the configuration is changed we need to update the generated code by running: At this point, since our project has uncommitted changes Terramate will prevent us from running any commands. Create a branch (or use the flag --disable-check-git-uncommitted to disable the git checks):

export BRANCH_NAME="runme-cloud-renderers"
git checkout -b $BRANCH_NAME

Generate code again (this steps was missing?):

terramate generate

And commit all the changed files. Select a stage prod or staging and deploy the stacks:

export STAGE="prod"
echo "Deploying stack/${STAGE}"

Now we initialize all our stacks:

terramate run -C stacks/${STAGE} -- terraform init

Check how their plans look like:

terramate run -C stacks/${STAGE} -- terraform plan

And apply them:

terramate run -C stacks/${STAGE} -- terraform apply

Inspect the deployed resources

https://console.cloud.google.com/run/detail/us-central1/terramate-app2-prod/revisions?project=runme-cloud-renderers

💡 For each Cloud Run service deployed, there will be an output with the URL to the deployed service, like this: url = "https://terramate-app1-<env>-<hash>-lz.a.run.app"

You can check the outputs with:

# Run with Runme to store output in $APP_URL2
terramate run -C stacks/${STAGE} -C stacks/${STAGE} \
  terraform output -json 2>/dev/null \
  | jq -r '.url.value' \
  | grep -v null \
  | tail -n 1 \
  | tr -d '\n'

Go ahead and issue a GET to terramate-app2 via cURL:

curl -i $APP_URL2

Optionally you can open the URL on the browser to check the running service.

To avoid unnecessary charges to your account let's destroy all stacks:

terramate run -C stacks/${STAGE} --reverse -- terraform destroy

The --reverse flag runs all stacks in reversed order, which is desirable when destroying resources.

More Examples

Check out following links to learn more about embedding cloud resources: