A simple trick to handling environments in Terraform
Tags: technology, terraform
Published: 2020-10-13 13:44:05

---
title: A simple trick to handling environments in Terraform
published: true
date: 2020-10-13 09:00:00 UTC
tags: Technology,Terraform
canonical_url: 
---

So for a short post, I wanted to share a good habit to get into with TerraForm. More specifically this is an easy way to handle the configuration and deployment of multiple environments and making it easier to manage in your Terraform scripts.

It doesn’t take long working with TerraForm to see the immediate value in leveraging it to build out brand new environments, but that being said it never fails to amaze me how many people I talk to, who don’t craft their templates to be highly reusable. There are lots of ways to do this, but I wanted to share a practice that I use.

The idea starts by leveraging this pattern. My projects all contain the following key files for “.tf”:

- main.tf: This file contains the provider information, and maps up the service principal (if you are using one) to be used during deployment. 
- variables.tf: This file contains a list of all the variables leveraged in my solution, with a description for their definition. 

The “main.tf” file is pretty basic:

```
provider "azurerm" { subscription\_id = var.subscription\_id version = "~> 2.1.0" client\_id = var.client\_id client\_secret = var.client\_secret tenant\_id = var.tenant\_id features {} }
```

Notice that the above is already wired up for the variables of Subscription\_id, client\_id, client\_secret, and tenant\_id.

Now for my variables file, I have things like the following:

```
variable "subscription\_id" { description = "The subscription being deployed." } variable "client\_id" { description = "The client id of the service prinicpal" } variable "client\_secret" { description = "The client secret for the service prinicpal" } variable "tenant\_id" { description = "The client secret for the service prinicpal" }
```

Now what this enables is the ability to then have a separate “.tfvars” file for each individual environment:

```
primarylocation = "..." secondarylocation = "..." subscription\_id = "..." client\_id = "..." client\_secret = "..." tenant\_id = "..."
```

From here the process of creating the environment in TerraForm is as simple as:

```
terraform apply -var-file {EnvironmentName}.tfvars
```

And then for new environments all I have to do is create a new .tfvars file to contain the configuration for that environment. This enables me to manage the configuration for my environment locally.

NOTE: I usually recommend that you add “\*.tfvars” to the gitignore, so that these files are not necessarily checked in. This prevents configuration from being checked into source control.

Another step this then makes relatively easy is the automated deployment, as I can add the following for a YAML task:

```
- script: | touch variables.tfvars echo -e "primarylocation = \""$PRIMARYLOCATION"\"" >> variables.tfvars echo -e "secondarylocation = \""$SECONDARYLOCATION"\"" >> variables.tfvars echo -e "subscription\_id = \""$SUBSCRIPTION\_ID"\"" >> variables.tfvars echo -e "client\_id = \""$SP\_APPLICATIONID"\"" >> variables.tfvars echo -e "tenant\_id = \""$SP\_TENANTID"\"" >> variables.tfvars echo -e "client\_secret = \""$SP\_CLIENTSECRET"\"" >> variables.tfvars displayName: 'Create variables Tfvars'
```

The above script then takes the build variables for the individual environment, and builds the appropriate “.tfvars” file to run for that environment.

Now this is sort of the manual approach, ideally you would leverage keyvault or vault to access the necessary deployment variables.