Effective Terraform Variable Management in GitHub Actions
Tags: terraform, githubactions
Published: 2024-05-11 18:38:29

Managing variables in Terraform is crucial for flexibility and security in infrastructure automation. Terraform offers several methods to define and prioritize variables, which is particularly important in environments where configurations must be dynamic and secure, such as in continuous integration/continuous deployment (CI/CD) pipelines

In this article, we'll delve into the practical use of these variable management strategies in Terraform, especially focusing on a typical CI/CD setup using GitHub Actions. We'll also clarify how Terraform decides which variable values to use when different methods are combined.

### **Different Methods to Add Variables in Terraform**

Terraform supports multiple methods for variable definition, each suitable for different scenarios:

1. **Variable Definitions in Configuration Files (`variables.tf`)**:
This is the most straightforward method where variables are defined with possible default values.
    
    ```go
    variable "machine_type" {
      description = "The type of the GCP instance"
      type        = string
      default     = "e2-micro"
    }
    ```
    
2. **Using `terraform.tfvars` Files**:
These files are used for setting variable values that override the defaults specified in **`variables.tf`**. Terraform automatically loads these values unless specified otherwise.
    
    ```go
    machine_type = "n1-standard-1"
    ```
    
3. **Environment Variables**:
Terraform can also read from environment variables prefixed with **`TF_VAR_`**. This is useful for passing sensitive data or for overriding values in CI/CD pipelines without changing code.
    
    ```bash
    export TF_VAR_machine_type="n1-standard-1"
    ```
    
4. **Command-line Flags**:
For temporary overrides, such as during a manual deployment, you can specify variables directly on the command line.
    
    ```bash
    terraform apply -var="machine_type=n1-standard-1"
    ```
    

### **Order of Precedence in Terraform Variables**

Terraform evaluates these variable sources according to a specific order of precedence:

1. **Command-line flags**
2. **Environment variables**
3. **Terraform configuration files (`terraform.tfvars` or `.auto.tfvars`)**
4. **Variable defaults in `variables.tf`**

Understanding this hierarchy is essential for effectively managing variable values across different environments and deployment phases.

### **Example: Using Variables in GitHub Actions**

Let’s consider a GitHub Actions workflow designed to deploy infrastructure on Google Cloud Platform using Terraform:

```yaml
name: Deploy GCP Infrastructure
on: [push]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout code
      uses: actions/checkout@v4
    - name: Set up Terraform
      uses: hashicorp/setup-terraform@v3
    - name: Set up Google Cloud credentials
      uses: google-github-actions/setup-gcloud@v2
      with:
        service_account_key: ${{ secrets.GCP_SA_KEY }}
        export_default_credentials: true
    - name: Create terraform.tfvars
      run: |
        echo "machine_type=\"n1-standard-1\"" > terraform.tfvars
        echo "region=\"us-central1\"" >> terraform.tfvars
    - name: Terraform Apply
      run: terraform apply -auto-approve
      env:
        TF_VAR_machine_type: ${{ secrets.MACHINE_TYPE }}
        TF_VAR_region: ${{ secrets.REGION }}
```

In this workflow:

- **`terraform.tfvars`** is generated dynamically in one of the steps. It sets **`machine_type`** and **`region`** for the Terraform apply.
- **Environment variables** (**`TF_VAR_machine_type`** and **`TF_VAR_region`**) are set in the Terraform Apply step using GitHub Secrets.

Given the order of precedence, the environment variables will override the values set in the **`terraform.tfvars`** file. This setup allows the workflow to configure defaults in **`terraform.tfvars`** while overriding these with more specific values securely managed through GitHub Secrets, ideal for different deployment environments or sensitive configurations.

Understanding how to manage and prioritize variable definitions in Terraform is key to deploying secure and adaptable infrastructure, particularly in automated environments like CI/CD pipelines. By strategically using GitHub Actions and Terraform together, developers can ensure that infrastructure deployments are both efficient and secure, aligning with best practices in DevOps environments.