Infrastructure

🏗️ Complete Guide to Terraform and Infrastructure as Code (IaC)

Terraform (developed by HashiCorp) is the world's most popular Infrastructure as Code (IaC) tool. It allows you to define, provision and update cloud infrastructure resources (AWS, Azure, GCP, Kubernetes, etc.) using declarative and interpretable configuration files for both humans and CI/CD systems.

1. What is IaC and why use Terraform?

Before IaC, infrastructure was created manually from web consoles (by clicking on graphical interfaces) or imperative Bash/Python scripts. This led to serious problems such as lack of auditing, unexplained differences between environments (configuration drift), and non-repeatable human errors.

Declarative vs Imperative Approach: In Terraform you specify what end state you want (example: "I want 3 EC2 instances and a PostgreSQL database") and Terraform takes care of calculating the exact steps needed to achieve it.

2. Fundamental Concepts

  • Provider: Plugin that translates the HCL code into calls to the APIs of cloud providers (AWS, Azure, GCP, Cloudflare, etc.).
  • Resource: The fundamental block of infrastructure that Terraform will create or manage (example: an S3 bucket, an Azure VNet, a virtual machine).
  • Data Source: Allows you to consult or read existing infrastructure information outside of our Terraform template.
  • State: File (terraform.tfstate) that acts as a local or remote database linking the HCL code blocks with the real IDs in the cloud.
  • Variables & Outputs: Dynamic input parameters and return values ​​(such as a public IP address or DNS) after provisioning.

3. Basic HCL Syntax (HashiCorp Configuration Language)

Terraform uses files with extension .tf written in HCL. A typical project contains files organized by purpose (main.tf, variables.tf, outputs.tf, providers.tf).

hcl
# Configuración del proveedor de AWS
terraform {
  required_version = ">= 1.5.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

# Declaración de variables
variable "aws_region" {
  type        = string
  default     = "us-east-1"
  description = "Región de AWS para los recursos"
}

variable "environment" {
  type        = string
  default     = "dev"
  description = "Entorno de ejecución (dev, staging, prod)"
}

# Creación de un recurso (Bucket S3)
resource "aws_s3_bucket" "app_storage" {
  bucket = "mc-app-data-${var.environment}-2026"

  tags = {
    Environment = var.environment
    ManagedBy   = "Terraform"
  }
}

# Output: Retorna la URL del bucket tras crearlo
output "s3_bucket_arn" {
  value       = aws_s3_bucket.app_storage.arn
  description = "ARN del bucket S3 creado"
}

4. Terraform CLI Lifecycle

To work effectively with Terraform in your terminal or in a CI/CD pipeline, you must know the essential commands of its workflow:

bash
terraform init

# 2. Formatea el código automáticamente según el estándar oficial HCL
terraform fmt

# 3. Valida la sintaxis del código sin conectarse a la nube
terraform validate

# 4. Muestra un plan de ejecución (compara código vs infraestructura real)
terraform plan -out=tfplan

# 5. Aplica los cambios planificados en la nube
terraform apply tfplan

# 6. Destruye toda la infraestructura creada por este código (Usar con precaución)
terraform destroy

5. The State Archive (terraform.tfstate)

The state file is the operating core of Terraform. Maintains the mapping between the HCL definitions in your code and the actual physical entities in the cloud.

  • Why is it critical? Without state, Terraform doesn't know if a code change means "creating a new resource" or "modifying an existing one."
  • Dangers of saving the state locally: If you work as a team and store terraform.tfstate on your laptop, your colleagues will not see your changes, or resources could be stepped on, causing infrastructure corruption.

6. Remote Backends & State Locking

Remote Backends are used to solve collaborative work. They store the state file securely and prevent simultaneous executions through locks (Locks).

hcl
terraform {
  backend "s3" {
    bucket         = "mc-tfstates-central-prod"
    key            = "infra/core-network/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-state-locks" # Evita que 2 personas ejecuten apply a la vez
  }
}

7. Good Infrastructure Practices as Code

  1. NEVER commit file .tfstate or secrets to Git: Add .tfstate, .tfstate.backup and .terraform/ to your .gitignore.
  1. Use descriptive variables and validations: Always define appropriate types (string, number, list) and default values.
  1. Modularize from day 1: Don't accumulate thousands of lines in a single main.tf file. Divide the infrastructure into independent modules.
  1. Automate in CI/CD: Run terraform plan automatically on every Pull Request and terraform apply only when merging to the main branch.

🚀 Continue learning in the Terraform KB Series: