arrow_back
Back

Terraform: infrastructure as code, state, and providers

Andrew Dorokhov Andrew Dorokhov schedule 4 min read
menu_book Table of Contents

open_in_new Terraform is an infrastructure-as-code (IaC) tool from HashiCorp. You declare the desired state of cloud and on-premises resources in .tf files; Terraform computes a plan and applies changes through each provider’s API. The same workflow works across AWS, Azure, GCP, and Kubernetes.

Core ideas

  • Configuration language (HCL) — describe resources, data sources, variables, and outputs in declarative blocks.
  • Providers — plugins that map Terraform resources to real APIs (e.g. azurerm, aws, kubernetes).
  • State — Terraform stores which real-world objects match your code (often terraform.tfstate). State enables updates and destroys; for teams, use open_in_new remote state in cloud storage with locking.
  • Plan / applyterraform plan shows proposed changes; terraform apply executes them. This keeps reviews and CI gates predictable.

Minimal example

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "example" {
  name     = "example-rg"
  location = "West Europe"
}

Typical commands:

terraform init
terraform plan
terraform apply

Structure example

You can organize your infrastructure by dividing it into multiple .tf files. Terraform loads all *.tf files in a directory, so you can split the configuration for resources, variables, outputs, and providers as needed. This modular structure helps with readability, maintenance, and collaboration.

# Example directory:
#
# ├── main.tf           # core resources
# ├── variables.tf      # input variables
# ├── outputs.tf        # outputs
# └── provider.tf       # provider settings

Or:

# Example directory:
#
# ├── 001-setup.tf           # initial setup
# ├── 002-resource-group.tf  # resource group definition
# ├── 003-networking.tf      # networking resources
# ├── 004-storage.tf         # storage resources
# ├── 005-database.tf        # database resources
# ├── 006-vm-admin.tf        # admin VM config
# ├── 007-vmss-web.tf        # web VM scale set
# ├── 098-outputs.tf         # outputs
# └── 099-variables.tf       # input variables

HCL

HCL (HashiCorp Configuration Language) is a declarative language used by Terraform to define infrastructure resources. It emphasizes readability and simplicity: you describe what you want to provision, not how to do it. Resources, variables, and modules are defined using blocks and key-value pairs, making configurations easy to understand and maintain. HCL is designed for both machines and humans—its syntax is straightforward, and many tools and editors provide syntax highlighting and linting support.

Example: Declaring a resource

resource "azurerm_resource_group" "example" {
  name     = "example-rg"
  location = "West Europe"
}

Example: Using variables

variable "location" {
  description = "Azure region"
  type        = string
  default     = "West Europe"
}

resource "azurerm_resource_group" "example" {
  name     = "example-rg"
  location = var.location
}

Example: Outputting values

output "resource_group_name" {
  value = azurerm_resource_group.example.name
}

An output in Terraform is a way to display values from your infrastructure after an apply operation. Outputs are defined with the output block in HCL and can reveal useful data such as resource names, IP addresses, or connection strings, making integration with other systems or debugging easier.

HCL is block-based, with each block defined by a type (such as resource, variable, or output) and a set of named arguments or inner blocks. This makes it easy to compose and maintain infrastructure as code.

Declaring resources

resource "azurerm_resource_group" "example" {
  name     = "example-rg"
  location = "West Europe"
}

Using modules

Modules in Terraform are reusable, shareable configurations that let you organize infrastructure code for easier maintenance and composition. A module consists of a collection of .tf files in a directory that defines related resources, variables, and outputs. You use modules to encapsulate common patterns (like networking, compute, or security groups) and reference them in your root configuration—promoting reuse and consistency across projects. Modules can be local to your repository or published to remote registries for broader sharing.

module "azure_region" {
  source       = "claranet/region/azurerm"
  azure_region = var.location
}

When to use it

Terraform shines when you want one toolchain for multi-cloud or hybrid infrastructure, reviewable diffs in Git, and repeatable environments (dev/stage/prod). Pair it with CI/CD to plan on pull requests and apply from protected branches. For app config on top of clusters, you may combine Terraform (clusters, networks) with Helm, Ansible, or Kubernetes manifests as needed.

code

Need Help with Development?

Happy to help — reach out via the contacts or go straight to my Upwork profile.

work View Upwork Profile arrow_forward
Next Article

Microsoft Azure: cloud setup, resources, and configuration

arrow_forward