Introduction to Terraform
IaC - Managing Infrastructure with Code

Table of Contents

  1. Introduction to Terraform
  2. Getting Started
  3. Terraform Basics
  4. Dependency Management
  5. State Management
  6. Infrastructure Provisioning
  7. Advanced Concepts
  8. Best Practices
  9. Integration
  10. Conclusion



Introduction to Terraform

What is Terraform?

Terraform is an open-source tool that allows you to manage infrastructure as code (IaC). Developed by HashiCorp, Terraform enables you to programmatically configure and manage infrastructure provided by cloud service providers (AWS, Azure, GCP, etc.) and even on-premise environments.

Why Use It?

Automation: Using Terraform, you can write infrastructure configurations as code and automatically deploy them, reducing manual errors and maintaining consistency.

Efficiency: Easily manage complex infrastructure and reduce deployment time. Code can be reused across multiple environments, increasing efficiency.

Version Control: Terraform configuration files can be managed as code, allowing you to use version control systems like Git.

Code Review: Facilitates communication, review, and approval among team members.

Key Concepts

Providers: Supports integration with various clouds like AWS, Azure, GCP, etc. Providers offer APIs for interacting with specific cloud services.

Modules: Similar to Python modules. Terraform modules allow code reuse and managing complex infrastructure in smaller, manageable units. Modules can be easily shared and version-controlled.

State Files: Terraform uses state files to store the current state of the infrastructure, tracking changes and managing configurations. This helps in detecting and correcting drifts (configuration mismatches).

Plan and Apply: Use terraform plan to preview changes and terraform apply to apply them. This helps in verifying changes before deployment.

Workspaces: Workspaces allow you to use the same configuration across multiple environments (development, staging, production) easily.



Getting Started

Installing Terraform

Refer to the download page to install Terraform according to your OS.
Official Terraform Download Page

Setting Up Terraform

Set up the initial configuration for the provider you intend to use (GCP/AWS/AZURE, etc.). Here, we explain the setup using GCP as an example.

  1. Create a Project in Google Cloud Console and issue a Service Key.
  2. Install gcloud CLI gcloud CLI Documentation
  3. Set up authentication
    # Run this command to log in to GCP, then configure your project settings.
    $ gcloud auth application-default login
    



Terraform Basics

Understanding Terraform Configuration Files

Terraform helps define infrastructure as code. The files used have a .tf extension and are written in HCL (HashiCorp Configuration Language).

Key Elements

Provider: Defines settings for cloud service providers (AWS, Azure, GCP, etc.) or other APIs that Terraform interacts with.

Resource: Defines individual components of the infrastructure, such as virtual machines, databases, network settings, etc.

Variable: Defines reusable values within configuration files.

Output: Displays values created after Terraform is applied.

Data Source: Allows importing external data to use in resource creation.

Code Examples

Here’s a simple example of a Terraform configuration file that creates a Compute Engine instance in GCP.

Provider and Resource

# Set up the GCP Provider.
provider "google" {
  credentials = file("<path-to-your-service-account-key>.json")
  project     = "<your-gcp-project-id>"
  location    = "us-central1"
}

# Define a google_compute_instance resource provided by the GCP Provider.
resource "google_compute_instance" "default" {
  name         = "vm-instance"
  machine_type = "n1-standard-1"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = "default"
    access_config {
    }
  }
}

Variables

Define variables in a variables.tf file.

variable "project_id" {
  description = "The GCP project ID"
  type        = string
}

variable "region" {
  description = "The GCP region"
  type        = string
  default     = "us-central1"
}

variable "instance_name" {
  description = "The name of the compute instance"
  type        = string
}

Use the defined variables in the main.tf file.

provider "google" {
  credentials = file("<path-to-your-service-account-key>.json")
  project     = var.project_id
  region      = var.region
}

resource "google_compute_instance" "default" {
  name         = var.instance_name
  machine_type = "n1-standard-1"
  zone         = "${var.region}-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = "default"
    access_config {
    }
  }
}

Set variable values in a terraform.tfvars file or pass them via command line.

project_id     = "your-gcp-project-id"
instance_name  = "vm-instance"

Output

Outputs display values created after applying Terraform configurations.

output "instance_ip" {
  description = "The IP address of the compute instance"
  value       = google_compute_instance.default.network_interface[0].access_config[0].nat_ip
}

After running terraform apply, check the output values.

Outputs:
instance_ip = "34.68.194.64"

Data Source

Data sources import external data for resource creation.

# Example: Importing the current available network in a GCP project 
# and using it to create an instance.
data "google_compute_network" "default" {
  name = "default"
}

resource "google_compute_instance" "default" {
  name         = var.instance_name
  machine_type = "n1-standard-1"
  zone         = "${var.region}-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = data.google_compute_network.default.name
    access_config {
    }
  }
}
# In this example, data "google_compute_network" "default" fetches the default network information from GCP
# and uses it in the google_compute_instance resource.

# These examples demonstrate how to use variables, outputs, and data sources in Terraform.
# Utilizing these can make Terraform configuration files more flexible and reusable.



Dependency Management

In Terraform, dependencies refer to defining the order of Terraform components so that resources are created, modified, or deleted in the correct order. Terraform automatically detects dependencies between resources but in some cases, you may need to explicitly define dependencies.

Implicit Dependencies

Terraform manages implicit dependencies automatically. For instance, if a resource’s attribute references the output value of another resource, Terraform will automatically detect the dependency.

Example

resource "google_compute_network" "default" {
  name = "my-network"
}

resource "google_compute_subnetwork" "subnet" {
  name          = "my-subnet"
  ip_cidr_range = "10.0.0.0/16"
  region        = "us-central1"
  network       = google_compute_network.default.name
}

# In this example, the google_compute_subnetwork resource references the 
# google_compute_network resource, so Terraform will ensure the network is 
# created before the subnetwork.

Explicit Dependencies

In some cases, Terraform might not automatically detect dependencies. Use the depends_on argument to explicitly define dependencies.

resource "google_compute_network" "default" {
  name = "my-network"
}

resource "google_compute_subnetwork" "subnet" {
  name          = "my-subnet"
  ip_cidr_range = "10.0.0.0/16"
  region        = "us-central1"
  network       = google_compute_network.default.name
}

resource "google_compute_instance" "default" {
  name         = "vm-instance"
  machine_type = "n1-standard-1"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = google_compute_network.default.name
  }

  depends_on = [google_compute_subnetwork.subnet]
}
# In this example, the google_compute_instance resource explicitly 
# depends on the google_compute_subnetwork resource. 
# Therefore, the instance is created after the subnetwork.



State Management

State files are used to track and store the current state of managed infrastructure. This enables Terraform to detect changes and efficiently manage configurations.

What is Terraform State?

Terraform state is how Terraform keeps track of the state of your infrastructure. The state file (terraform.tfstate) contains information about all resources managed by Terraform, allowing it to compare the current state with the configuration files to determine necessary changes. The state file is crucial for Terraform to manage resource attributes and handle infrastructure changes effectively.

State files include:

Properly managing Terraform state files is essential. By default, Terraform stores state files locally, but for better collaboration and efficient management, using remote state storage is recommended.



Infrastructure Provisioning

When using Terraform to provision infrastructure, you can apply configurations to create or update resources and destroy unneeded resources.

Key Commands

Here are some key commands frequently used in Terraform:

Error Handling and Debugging

Here are some methods for handling and debugging errors while using Terraform:



Advanced Concepts

Modules: Reusable Configurations

Modules make Terraform configurations reusable. Using modules, you can manage complex infrastructure configurations in smaller, manageable units. This enhances code reusability and maintainability.

Module Example

To define a module, create Terraform configuration files in a separate directory.

Directory Structure

modules/
  vpc/
    main.tf
    variables.tf
    outputs.tf

modules/vpc/main.tf

resource "google_compute_network" "vpc_network" {
  name = var.network_name
}

output "network_name" {
  value = google_compute_network.vpc_network.name
}

main.tf

module "vpc" {
  source       = "./modules/vpc"
  network_name = "my-vpc-network"
}

Workspaces: Managing Multiple Environments

Using Terraform workspaces, you can easily manage the same configuration across multiple environments. Workspaces help in separating development, testing, and production environments.

Workspace Commands



Best Practices

Writing Clean and Maintainable Code

Follow these principles to improve the readability and maintainability of your Terraform code:

  1. Modularization: Divide infrastructure components into modules for reusability and easier management. Each module should operate independently and focus on a specific function.
  2. Commenting: Add comments to the code to make it easy for others or your future self to understand. Comments should explain the intent and behavior of the code.
  3. Consistent Code Style: Maintain a consistent code style within the team. Terraform’s HCL has a simple structure, so establish guidelines for variable names, indentation, line breaks, etc., and follow them.
  4. Use Variables and Outputs: Use variables to manage repeated values centrally and outputs to easily check important information.

Version Control for Terraform Code

Managing Terraform code with a version control system (like Git) helps track changes and facilitates collaboration.

  1. Use Git: Store Terraform code in a Git repository and commit changes. This helps in tracking the history of the code.
    git init
    git add .
    git commit -m "Initial commit"
    
  2. Branching Strategy: Create branches for each feature. For example, create a branch for adding a new feature or fixing a bug, and merge it into the main branch after completing the work.
    git checkout -b feature/new-feature
    
  3. Code Review: Conduct code reviews through Pull Requests to maintain code quality and share understanding within the team.

Team Collaboration

Teams using Terraform can collaborate effectively using these methods:

  1. Standardized Configuration: Use standardized Terraform modules and configuration files within the team to maintain consistency.
  2. Documentation: Document Terraform code and infrastructure configurations to make it easy for team members to understand and use.
  3. Mutual Review: Conduct regular code reviews to maintain code quality and share best practices within the team.



Integration

Integrating Terraform with CI/CD Pipelines

Integrating Terraform into CI/CD pipelines automates infrastructure deployment and efficiently manages changes.

  1. Choose CI/CD Tools: Select CI/CD tools like Jenkins, GitLab CI, GitHub Actions, etc.
  2. Set Up Pipelines: Set up pipelines that include Terraform commands (terraform init, terraform plan, terraform apply) to automatically deploy infrastructure on code changes.

Example: GitHub Actions

name: Terraform

on:
  push:
    branches:
      - main

jobs:
  terraform:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Set up Terraform
      uses: hashicorp/setup-terraform@v1

    - name: Terraform Init
      run: terraform init

    - name: Terraform Plan
      run: terraform plan

    - name: Terraform Apply
      if: github.ref == 'refs/heads/main'
      run: terraform apply -auto-approve



Conclusion

Terraform is a powerful tool that helps manage infrastructure as code (IaC). With Terraform, you can efficiently create, manage, and destroy infrastructure across various cloud environments.

*****
© 2025 Jaeyoung Heo.