LogoLogo
  • Welcome to Release
  • Getting started
    • Quickstart
    • Create an account
    • Prepare to use Release
    • Create an application
      • Create custom application
      • Create from template
      • Servers vs runnables
    • Create an environment
  • Guides and examples
    • Domains and DNS
      • Manage domains
      • DNS and nameservers
        • Configure GoDaddy
        • Configure Cloudflare
        • Configure Namecheap
        • Other DNS hosts
      • Routing traffic
    • Example applications
      • Full stack voting app
      • Flask and RDS counter app
      • Static site with Gatsby
      • Golang with Postgres and Nginx
      • WordPress with MySQL
      • Spring and PostgreSQL
      • Terraform and Flask
      • OpenTelemetry demo
      • Load balancer with hostname
      • Static JavaScript service
      • SSH bastion access to services
      • ngrok and OAuth for private tunnels
      • Using OAuth Proxy
      • Hybrid Docker and static site
      • App Imports: Connecting two applications
      • Example library
    • Running instances
      • Cron jobs
      • Jobs
      • Using Helm charts
      • Using terminal
      • Viewing logs
      • Troubleshooting
        • ImagePullBackoff error
        • CrashLoopBackoff error
        • Exit codes
        • OOM: out of memory
    • Advanced guides
      • Containers guide
      • Application guide
      • Kubernetes guide
      • Create a cluster
      • Upgrade a cluster
      • Managing node groups
      • Patch node groups
      • Hostnames and rules
      • Serve traffic on multiple ports
      • Configure access to your K8s cluster
      • Designing for multiple environments
      • Microservices architecture
      • Monitoring your clusters
      • Performance tuning
      • Visibility and monitoring
      • Working with data
        • Container-based data
        • Seeding and migration
        • Cloud-provided data
        • Golden images
        • Third party
      • Pausing Instant Datasets
        • Application pausing schedules
        • Pause/resume environments
      • Infrastructure as code
        • Terraform
  • Reference documentation
    • Account settings
      • Account info
      • Managing users
      • Build settings
        • Build arguments
        • Build SSH keys
      • Add integrations
      • View clusters and cloud integrations
      • Add datasets
      • Environment handles
    • Workflows in Release
      • Stages of workflows
      • Serial deployments
      • Parallel deployments
      • Rolling deployments
      • Rainbow deployments
    • Networking
      • Network architecture (AWS)
      • Network architecture (GCP)
      • Ingresses
      • IP addresses
      • Cloud-provided services
      • Third-party services
    • Release environment versioning
    • Application settings
      • Application Template
        • Schema definition
      • Default environment variables
      • GitHub
      • Pull requests
      • GitOps
      • Just-in-time file mounts
      • Primary App Link
      • Create application FAQ
      • App-level build arguments
      • Parameters
      • Workspaces
    • End-to-end testing
    • Environment settings
      • Environment configuration
      • Environment variables
        • Environment variable mappings
        • Secrets vaults
        • Using Secrets with GitOps
        • Kubernetes Secrets as environment variables
        • Managing legacy Release Secrets
    • Environment expiration
    • Environment presets
    • Instant datasets on AWS
    • Instant datasets on GCP
    • Instant dataset tasks
      • Tonic Cloud
      • Tonic On-Premise
    • Cloud resources
    • Static service deployment
    • Helm
      • Getting started
      • Version-controlled Helm charts
      • Open-source charts
      • Building Docker images
      • Ingress and networking
      • Configuration
    • GitOps
    • The .release.yaml file
    • Docker Compose conversion support
    • Reference examples
      • Adding and removing services
      • Managing service resources
      • Adding database containers to the Application Template
      • Stock Off-The-Shelf Examples
    • Release API
      • Account Authentication
      • Environments API
        • Create
        • Get
        • Setup
        • Patch
      • User Authentication
      • Environment Presets API
        • Get Environment Preset List
        • Get Environment Preset
        • Put Environment Preset
  • Background concepts
    • How Release works
  • Frequently asked questions
    • Release FAQ
    • AWS FAQ
    • Docker FAQ
    • JavaScript FAQ
  • Integrations
    • Integrations overview
      • Artifactory integration
      • Cloud integrations (AWS)
        • AWS guides
        • Grant access to AWS resources
        • AWS how to increase EIP quota
        • Control your EKS fleet with systems manager
        • Managing STS access
        • AWS Permissions Boundaries
        • Private ECR Repositories
        • Using an Existing AWS VPC
        • Using an Existing EKS Cluster
      • Docker Hub integration
      • LaunchDarkly integration
      • Private registries
      • Slack integration
      • Cloud integrations (GCP)
        • GCP Permissions Boundary
      • Datadog Agent
      • Doppler Secrets Manager
      • AWS Secrets Management
    • Source control integrations
      • GitHub
        • Pull request comments
        • Pull request labels
        • GitHub deployments
        • GitHub statuses
        • Remove GitHub integration
      • Bitbucket
      • GitLab
    • Monitoring and logging add-ons
      • Datadog
      • New Relic
      • ELK (Elasticsearch, Logstash, and Kibana)
  • Release Delivery
    • Create new customer integration
    • Delivery guide
    • Release to customer account access controls
    • Delivery FAQs
  • Release Instant Datasets
    • Introduction
    • Quickstart
    • Security
      • AWS Instant Dataset security
    • FAQ
    • API
  • CLI
    • Getting started
    • Installation
    • Configuration
    • CLI usage example
    • Remote development environments
    • Command reference
      • release accounts
        • release accounts list
        • release accounts select
      • release ai
        • release ai chat
        • release ai config-delete
        • release ai config-init
        • release ai config-select
        • release ai config-upsert
      • release apps
        • release apps list
        • release apps select
      • release auth
        • release auth login
        • release auth logout
      • release builds
        • release builds create
      • release clusters
        • release clusters exec
        • release clusters kubeconfig
        • release clusters shell
      • release datasets
        • release datasets list
        • release datasets refresh
      • release deploys
        • release deploys create
        • release deploys list
      • release development
        • release development logs
        • release development start
      • release environments
        • release environments config-get
        • release environments config-set
        • release environments create
        • release environments delete
        • release environments get
        • release environments list
        • release environments vars-get
      • release gitops
        • release gitops init
        • release gitops validate
      • release instances
        • release instances exec
        • release instances logs
        • release instances terminal
  • Release.ai
    • Release.ai Introduction
    • Getting Started
    • Release.ai Templates
    • Template Configuration Basics
    • Using GPU Resources
    • Custom Workflows
    • Fine Tuning LlamaX
    • Serving Inference
Powered by GitBook
On this page
  • How Terraform works
  • How Release works with Terraform
  • Authenticate Release to execute Terraform
  • How to authenticate with non-AWS Terraform providers
  • How to define infrastructure as code using Terraform
  • How to add Terraform runners to your application in Release
  • Add an infrastructure section to the Application Template
  • Add a workflow section to the Application Template
  • How to provide values to Terraform
  • Method 1: Using a custom values file
  • Method 2: Using environment variables prefixed with TF_VAR_ in your Release environments
  • Method 3: Using Release-specific environment variables
  • Use AWS SSM parameters to store output values from Terraform
  • How to use Terraform modules from private GitHub repositories
  • Step-by-step summary
  • Example application with Terraform

Was this helpful?

  1. Guides and examples
  2. Advanced guides
  3. Infrastructure as code

Terraform

PreviousInfrastructure as codeNextAccount settings

Last updated 2 years ago

Was this helpful?

is a popular infrastructure-as-code (IaC) tool that you can use to define cloud infrastructure in a concise configuration language called HashiCorp Configuration Language (HCL). Release can apply your Terraform configuration as part of your application's workflow steps.

Terraform is extensible and can plan and execute infrastructure updates for many cloud and on-premises resources. To keep this guide simple, we'll focus on AWS resources only.

Jump to the section you need:

How Terraform works

Terraform's workflow is commonly described in three distinct stages:

  1. Write: You add Terraform configuration to a repository, specifying what your infrastructure should look like.

  2. Plan: You run Terraform's plan script. Terraform compares live infrastructure with the configuration to output a plan to update infrastructure to represent your configuration.

  3. Apply: You run Terraform's apply script to approve and execute Terraform's plan.

Each time you change (write or update) your Terraform configuration, you will need to run the plan and apply scripts again to update existing infrastructure to be in line with your desired configuration.

When working with ephemeral infrastructure, we recommend you add a less-often described fourth stage to your workflow: Destroy. When you no longer need the infrastructure created by Terraform, you can run Terraform's destroy script, which executes a plan that destroys the infrastructure.

Keep in mind that Release skips over the plan stage in the standard Terraform workflow and changes are applied without manual approval. This could start up services that incur a cost, so it is important to review Terraform configuration changes before merging with a branch tracked by Release.

To avoid surprise costs, limit dynamic configuration determined by environment variables as much as possible. For example, rather than reading an environment variable to determine the size of an RDS database in Terraform, add an explicit value for this to your Terraform configuration.

How Release works with Terraform

Release adds override files to partially override Terraform's backend setting and two blocks in your Terraform configuration: the AWS assume_role and region.

The backend override file looks like this:

terraform {
  backend "local" {}
}

The AWS assume_role and region override file is as follows:

provider "aws" {
  assume_role {
    # ARN for the AWS role with elevated permissions
    role_arn     = "arn:aws:iam::111111111111:role/release/release-elevated-perms-role"

    # AWS session name is set to your environment ID
    session_name = "RELEASE_ENV_ID"
  }

  # AWS region for your application's cluster
  region = "us-west-2"
}

Release does not override any other sections besides AWS assume_role, AWS region, and Terraform backend. This means that you can still, for example, add tagging to your AWS provider.

Authenticate Release to execute Terraform

To create services in your AWS account, Terraform needs to know how to authenticate as a user on your AWS account.

To begin using Terraform for AWS with Release, contact your Release technical account manager to request that they add an AWS role with elevated privileges to your account.

Release's infrastructure runner will assume this privileged role when executing your Terraform configuration.

How to authenticate with non-AWS Terraform providers

How to define infrastructure as code using Terraform

By default, during the plan or apply stages, Terraform looks for files with the .tf extension in the current folder.

This simple Terraform configuration example uses the aws provider to add a VPC called example to the user's AWS account in the us-east-1 region:

# Specify which providers to use
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

# Configure the AWS provider (simplified for this example)
provider "aws" {
  region = "us-east-1"
}

# Create a VPC
resource "aws_vpc" "example" {
  cidr_block = "10.0.0.0/16"
}

You could add this file to your repository, as main.tf, then run terraform plan (Terraform will output the plan to update your AWS account), followed by terraform apply (Terraform will update your AWS account).

How to add Terraform runners to your application in Release

When using Terraform with your Release environments, Release can run terraform plan, terraform apply, and terraform destroy on your behalf.

This enables you to start up cloud infrastructure specific to your Release environments when an environment is created, update infrastructure when an environment is patched, or destroy infrastructure when Release tears down an environment.

Modify your Application Template to instruct Release to run Terraform:

  • Add steps to your workflows section to execute the Terraform runners.

Add an infrastructure section to the Application Template

Here's an example infrastructure section, with two Terraform runners:

infrastructure:
- name: dynamodb-table1
  type: terraform
- name: dynamodb-table2
  type: terraform
  directory: "./dynamodb"
  values: ".release/dynamodb2_values.tfvar"

Add a workflow section to the Application Template

Release's infrastructure runner is only executed during one of Release's three predefined workflow stages.

Release workflows consist of three stages:

  1. Setup: When an environment is created or updated.

  2. Patch: When your code (or in this case, Terraform configuration) is changed.

  3. Teardown: When an environment is destroyed.

During setup and patch, Release executes terraform apply -auto-approve.

During teardown, Release executes terraform destroy -auto-approve.

Here is an example of workflow steps that run infrastructure tasks:

workflows:
- name: setup
  parallelize:
  - step: apply_infrastructure
    halt_on_error: true
    tasks:
    - infrastructure.dynamodb-table1
    - infrastructure.dynamodb-table2
- name: patch
  parallelize:
  - step: apply_infrastructure
    halt_on_error: true
    tasks:
    - infrastructure.dynamodb-table1
    - infrastructure.dynamodb-table2
- name: teardown
  parallelize:
  - step: destroy_infrastructure
    halt_on_error: true
    tasks:
    - infrastructure.dynamodb-table1
    - infrastructure.dynamodb-table2
  - step: remove_environment
    tasks:
    - release.remove_environment

How to provide values to Terraform

Terraform modules often take input variables and you can specify input variables for your Terraform configuration.

You can pass variables to Terraform in three ways:

  1. Using a custom values file.

  2. Using environment variables prefixed with TF_VAR_ in your Release environments.

  3. Using Release-specific environment variables.

Let's look at each method in more detail:

Method 1: Using a custom values file

If you declare a values file as part of your infrastructure runner, Release will substitute environment variables with matching names in the values file before running Terraform.

In the following infrastructure runner declaration, the values key points to a file in the repository at .release/dynamodb2_values.tfvar:

infrastructure:
- name: dynamodb-table2
  type: terraform
  directory: "./dynamodb"
  values: ".release/dynamodb2_values.tfvar"

The contents of the values file could look as follows:

table_name = "test-${RELEASE_ENV_ID}-2"

In this example, before running Terraform, Release will replace ${RELEASE_ENV_ID} with the current Release environment ID and run Terraform with the -var-file= option pointing to this values file.

Method 2: Using environment variables prefixed with TF_VAR_ in your Release environments

Terraform can access environment variables that start with TF_VAR_.

Add environment variables with the TF_VAR_ prefix in their names to your Release environments. Then add Terraform variable blocks for these variables to your configuration, omitting TF_VAR_ from the names.

For example, to use an environment variable called TF_VAR_TEST_TAG, add a Terraform variable block to your configuration:

variable "TEST_TAG" {
  type        = string
  description = "Custom tag for testing"
}

You can use this input when configuring resources, for example:

# Create a VPC with test tag
resource "aws_vpc" "example" {
  cidr_block = "10.0.0.0/16"
  tags = {
    "testing/test-tag" = "${var.TEST_TAG}"
  }
}

Method 3: Using Release-specific environment variables

For convenience, Release automatically prefixes all environment variables that start with RELEASE_ with TF_VAR_. Access these variables by adding Terraform variable blocks.

This means you can reference all environment variables that start with RELEASE_ by adding them to a values file or by declaring variable blocks for them.

Use AWS SSM parameters to store output values from Terraform

To save values from Terraform for use in your applications, we recommend using AWS SSM parameters.

The example below saves a Redis cluster address to an SSM parameter, prefixed with your Release environment's ID:

# Create an SSM parameter for the Redis address
resource "aws_ssm_parameter" "redis_address" {
  name        = "/${var.RELEASE_ENV_ID}/redis/address"
  description = "Redis address"
  type        = "String"
  value       = aws_elasticache_cluster.redis.cache_nodes[0].address
}

How to use Terraform modules from private GitHub repositories

Release can download Terraform modules from private GitHub repositories if you have added the Release GitHub app and given it access to the repositories.

In the Terraform configuration example below, Release will automatically add an access token to the Git configuration and download your private repository:

module "dynamodb" {
  source = "github.com/YOUR-GH-ACCOUNT/private-repository//dynamodb"
}

Step-by-step summary

To summarize, add Terraform to your application on Release by following these steps:

  1. Add your Terraform configuration to your repository.

  2. Add an infrastructure section with a terraform runner to your Application Template.

  3. Create workflow steps in the application template to execute your infrastructure runners.

  4. Map any environment variables you would like to use with Terraform in your Release application's default environment variables file.

  5. Deploy a new environment to test your Terraform configuration.

Example application with Terraform

are merged with existing configuration instead of completely replacing configuration.

You can add authentication details for other providers to your Terraform configuration. We recommend using to store authentication strings such as usernames and passwords and marking passwords and other auth tokens as secret.

See for an overview of how to use environment variables in your Terraform configuration.

Add an .

View the infrastructure schema in our .

To learn how to authorize Release to access your repositories, read our documentation about .

To see Terraform in action, work through our .

Terraform override files
environment variables
integrating GitHub with Release
Terraform, Flask, and Redis example
Terraform by HashiCorp
How Terraform works
How Release works with Terraform
Authenticate Release to execute Terraform
How to define infrastructure as code using Terraform
How to add Terraform runners to your application in Release
How to provide values to Terraform
Use AWS SSM parameters to store output values from Terraform
How to use Terraform modules from private GitHub repositories
Step-by-step summary
How to provide values to Terraform
infrastructure section
schema documentation