Motor de Plantillas Terragrunt: Generación Dinámica de Configuraciones de Infraestructura

Conceptos Fundamentales del Motor de Plantillas en Terragrunt

Terragrunt, como herramienta de infraestructura como código (IaC) basada en Terraform, incluye un motor de plantillas que permite crear configuraciones de infraestructura dinámicas y reutilizables. Esta guía técnica describe cómo emplear las características de templating de Terragrunt para optimizar el despliegue de infraestructura en entornos múltiples.

Características Principales

  • Reutilización de Configuraciones: Mediante el bloque include para heredar y extender configuraciones base.
  • Generación Automática: Uso del bloque generate para crear archivos de Terraform de forma dinámica.
  • Administración de Dependencias: El bloque dependency permite establecer relaciones entre módulos y resolver el orden de ejecución.
  • Segregación por Entornos: Combinación de locals y variables de entrada para adaptar configuraciones a distintos ambientes.

Configuración Inicial y Estructura Básica

Para empezar, instala Terragrunt y crea una estructura de directorios base. Un archivo de configuración típico (terragrunt.hcl) se compone de varios bloques esenciales.

# Configuración del estado remoto en un bucket de almacenamiento
remote_state {
  backend = "gcs"
  config = {
    bucket = "estado-infraestructura-empresa"
    prefix = "${path_relative_to_include()}/terraform.tfstate"
    region = "us-central1"
  }
}

# Herencia de configuración desde un archivo raíz
include "global" {
  path = find_in_parent_folders("global.hcl")
}

# Variables locales para valores específicos del entorno
locals {
  ambiente = "staging"
  rango_red = "172.16.0.0/20"
}

# Entradas que se pasan a los módulos de Terraform
inputs = {
  ambiente = local.ambiente
  rango_red = local.rango_red
}

Técnicas de Generación Dinámica de Archivos

Uso del Bloque generate para Creación Automatizada

El bloque generate facilita la creación de archivos de configuración de Terraform, como proveedores o backends, garantizando consistencia en todos los módulos.

generate "proveedor_cloud" {
  path      = "proveedor_cloud.tf"
  if_exists = "overwrite"
  contents  = <<eof ambiente="${local.ambiente}" eof="" equipo="${local.equipo}" etiquetas="{" etiquetas_predeterminadas="" project="${local.proyecto}" proveedor="" region="${local.region}"></eof>

Este snippet genera automáticamente un archivo proveedor_cloud.tf con configuraciones uniformes para Google Cloud.

Herancia de Configuraciones con include

El bloque include permite compartir configuraciones comunes y sobrescribirlas según las necesidades del entorno.

# global.hcl - Configuración base compartida
remote_state {
  backend = "s3"
  config = {
    bucket         = "estado-central-terraform"
    encrypt        = true
    dynamodb_table = "bloqueos-despliegue"
  }
}

# staging/terragrunt.hcl - Herencia y personalización
include "global" {
  path = find_in_parent_folders("global.hcl")
}

locals {
  ambiente = "staging"
}

remote_state {
  config = {
    key    = "staging/${path_relative_to_include()}/terraform.tfstate"
    region = "us-west-2"
  }
}

Gestión de Dependencias y Secuencia de Despliegue

Definición de Relaciones entre Módulos

Terragrunt resuelve automáticamente las dependencias, asegurando que los módulos se desplieguen en el orden correcto.

dependency "red_virtual" {
  config_path = "../red_virtual"
  
  # Valores simulados para entornos no desplegados
  mock_outputs = {
    id_red         = "red-xyz789"
    cidr_subredes  = ["10.0.1.0/24", "10.0.2.0/24"]
  }
}

inputs = {
  id_red        = dependency.red_virtual.outputs.id_red
  cidr_subredes = dependency.red_virtual.outputs.cidr_subredes
}

Ejecución Paralela con Dependencias Explícitas

Utiliza el bloque dependencies para establecer el orden de despliegue de módulos interconectados.

dependencies {
  paths = ["../red_virtual", "../reglas_firewall"]
}

Al ejecutar terragrunt run-all apply, Terragrunt desplegará primero las dependencias antes de aplicar el módulo actual.

Administración de Configuraciones Multi-Ambiente

La estructura de directorios organizada por entornos simplifica la gestión de configuraciones para desarrollo, preproducción y producción.

Estructura de Directorios Recomendada

infraestructura/
  ├── global.hcl                    # Configuración global
  ├── desarrollo/
  │   ├── red_virtual/terragrunt.hcl
  │   └── servicio_web/terragrunt.hcl
  ├── preproduccion/
  │   ├── red_virtual/terragrunt.hcl
  │   └── servicio_web/terragrunt.hcl
  └── produccion/
      ├── red_virtual/terragrunt.hcl
      └── servicio_web/terragrunt.hcl

Configuración Específica por Entorno

# desarrollo/servicio_web/terragrunt.hcl
include "global" {
  path = find_in_parent_folders("global.hcl")
}

locals {
  ambiente = "desarrollo"
  replicas = 1
  tamano_instancia = "e2-standard-2"
}

inputs = merge(
  include.global.inputs,
  {
    ambiente         = local.ambiente
    replicas         = local.replicas
    tamano_instancia = local.tamano_instancia
  }
)

Prácticas Avanzadas y Optimización

Uso de Locals para Lógica Condicional

locals {
  # Obtención de secretos desde variables de entorno
  credencial_acceso = get_env("GOOGLE_CREDENTIALS")
  
  # Lógica basada en el entorno
  tamano_instancia = local.ambiente == "produccion" ? "n2-highmem-4" : "e2-medium"
  
  # Generación dinámica de etiquetas
  etiquetas_comunes = merge(
    {
      Ambiente = local.ambiente
      MantenidoPor = "terragrunt"
    },
    local.etiquetas_personalizadas
  )
}

Funciones Integradas para Manipulación de Configuraciones

Terragrunt ofrece funciones para trabajar con archivos, rutas y comandos externos.

locals {
  # Lectura de un archivo YAML
  configuracion = yamldecode(file("${get_terragrunt_dir()}/settings.yaml"))
  
  # Cálculo de rutas relativas
  ruta_relativa = path_relative_to_include()
  
  # Ejecución de comandos para obtener metadatos
  revision_actual = run_cmd("git", "log", "--oneline", "-1")
}

Mecanismos de Reintentos y Manejo de Errores

errors {
  retry "errores_temporales" {
    retryable_errors = [".*timeout.*", ".*transient.*"]
    max_attempts = 5
    sleep_interval_sec = 20
  }
  
  ignore "avisos_no_criticos" {
    ignorable_errors = [".*deprecation warning.*"]
    message = "Ignorando avisos de deprecación no bloqueantes"
  }
}

Etiquetas: Terragrunt Terraform Infrastructure as Code HCL Template Engine

Publicado el 5-31 23:56