🏗️ Infraestructura Terraform como código
Terraform de HashiCorp es la herramienta de infraestructura como código (IaC) estándar de la industria. Le permite definir la infraestructura de la nube en un lenguaje de configuración declarativo (HCL), planificar cambios antes de aplicarlos y mantener el estado para realizar un seguimiento de lo que se ha aprovisionado.
Conceptos básicos
- Proveedores: complementos que interactúan con API (AWS, GCP, Azure, Kubernetes, GitHub, etc.).
- Recursos — La unidad fundamental. Cada recurso se asigna a un objeto de infraestructura real (por ejemplo,
aws_instance).
- Fuentes de datos: consulta la infraestructura existente administrada fuera de Terraform.
- Estado: un archivo JSON (local o remoto) que asigna su configuración a recursos del mundo real.
- Módulos: colecciones de recursos reutilizables y parametrizadas.
- Espacios de trabajo: entornos de estado aislado para la misma configuración (dev/staging/prod).
Sintaxis HCL
HashiCorp Configuration Language (HCL) es la sintaxis declarativa de Terraform. Está diseñado para ser legible por humanos y escribible por máquinas.
variable "environment" {
description = "Deployment environment (dev, staging, prod)"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging, or prod."
}
}
variable "instance_count" {
description = "Number of EC2 instances"
type = number
default = 2
}
variable "allowed_cidrs" {
description = "CIDR blocks allowed to reach the load balancer"
type = list(string)
default = ["0.0.0.0/0"]
}
# locals.tf
locals {
common_tags = {
Project = "mc-platform"
Environment = var.environment
ManagedBy = "terraform"
Owner = "platform-team"
}
name_prefix = "mc-${var.environment}"
}Proveedores y configuración de backend
terraform {
required_version = ">= 1.7.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.25"
}
}
# Remote state in S3 with DynamoDB locking
backend "s3" {
bucket = "mc-terraform-state-prod"
key = "platform/terraform.tfstate"
region = "us-east-1"
encrypt = true
dynamodb_table = "mc-terraform-locks"
kms_key_id = "alias/terraform-state"
}
}
provider "aws" {
region = "us-east-1"
default_tags {
tags = local.common_tags
}
}
provider "aws" {
alias = "us-west-2"
region = "us-west-2"
}Gestión del Estado
Nunca confirme archivos de estado Utilice siempre un backend remoto (S3, Terraform Cloud, GCS) con bloqueo de estado. Los archivos de estado locales pueden provocar una deriva irreversible de la infraestructura cuando se comparten en equipos.
terraform state list # list all managed resources
terraform state show aws_instance.web_server # inspect a specific resource
terraform state mv aws_instance.old aws_instance.new # rename resource
terraform state rm aws_instance.imported # stop managing (does NOT destroy)
# Import existing infrastructure
terraform import aws_s3_bucket.assets mc-assets-prod
# Refresh state to match real-world (use carefully)
terraform apply -refresh-onlyMódulos
Los módulos encapsulan patrones de infraestructura reutilizables. Maxi's Computers mantiene un registro de módulos interno para componentes comunes.
module "vpc" {
source = "git::https://github.com/maxiscomputers/terraform-modules.git//vpc?ref=v3.2.0"
name = "${local.name_prefix}-vpc"
cidr_block = "10.0.0.0/16"
azs = ["us-east-1a", "us-east-1b", "us-east-1c"]
private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
public_subnets = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]
enable_nat_gateway = true
single_nat_gateway = var.environment != "prod"
tags = local.common_tags
}
module "eks" {
source = "git::https://github.com/maxiscomputers/terraform-modules.git//eks?ref=v2.1.0"
cluster_name = "${local.name_prefix}-eks"
cluster_version = "1.29"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnet_ids
node_groups = {
general = {
instance_types = ["m6i.xlarge"]
min_size = 2
max_size = 10
desired_size = 3
}
}
}
# outputs.tf
output "vpc_id" { value = module.vpc.vpc_id }
output "eks_endpoint" { value = module.eks.cluster_endpoint }
output "eks_ca_data" { value = module.eks.cluster_ca_certificate }Espacios de trabajo
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod
terraform workspace list
terraform workspace select prod
# Use workspace name in configuration
resource "aws_s3_bucket" "app_data" {
bucket = "mc-app-${terraform.workspace}-data"
# ...
}Flujo de trabajo CLI estándar
terraform init -upgrade
# 2. Format and validate
terraform fmt -recursive
terraform validate
# 3. Plan — preview changes (always review before applying!)
terraform plan -var-file="environments/prod.tfvars" -out=tfplan
# 4. Apply — execute the plan
terraform apply tfplan
# 5. Targeted apply (use sparingly)
terraform apply -target=module.eks -var-file="environments/prod.tfvars"
# 6. Destroy (DANGER — requires explicit approval)
terraform destroy -var-file="environments/prod.tfvars"Mejores prácticas en MC
- Versiones del proveedor de pines con restricciones
~>para evitar cambios importantes inesperados.
- Utilice
terraform planen CI: publique el resultado del plan como un comentario de solicitud de extracción antes de fusionarlo.
- Almacenar
.tfvarsde forma segura: nunca confirme valores confidenciales; utilice secretos de CI o integración con Vault.
- Etiquete cada recurso con
local.common_tagspara asignación de costos y cumplimiento.
- Ejecute
terraform fmtcomo gancho de confirmación previa para aplicar un formato coherente.
- Utilice el indicador
-outpara que el plan aplicado sea exactamente el que se revisó.
- Estado separado por entorno: nunca comparta un solo archivo de estado entre prod/staging/dev.