¿Qué es el Terraform Registry?
El Terraform Registry (registry.terraform.io) es el repositorio central y oficial del ecosistema Terraform. Funciona como un hub de distribución donde desarrolladores, empresas y la propia HashiCorp publican módulos de Terraform listos para usar.
Puedes pensar en él como el equivalente de npm para Node.js o PyPI para Python, pero especializado en infraestructura como código. En el registry encontrarás:
- Providers: los plugins que permiten a Terraform interactuar con APIs (AWS, Azure, GCP, Kubernetes, etc.)
- Módulos: conjuntos de recursos preconfigurados y reutilizables
Cuando visitas el registry, lo primero que notas es que los módulos están organizados por el proveedor de nube con el que trabajan. Esto facilita enormemente la búsqueda cuando sabes qué plataforma estás usando.
Acceso al registry
# El registry es accesible públicamente sin autenticación para módulos públicos
# URL principal:
# https://registry.terraform.io
# Buscar módulos via CLI (necesita Terraform instalado)
# No hay comando CLI directo para buscar, pero sí puedes ver info de un módulo:
terraform providers
# O usar la API del registry:
curl https://registry.terraform.io/v1/modules/terraform-aws-modules/vpc/awsMódulos oficiales vs módulos de la comunidad
Existe una distinción importante entre los tipos de módulos disponibles:
Módulos verificados por HashiCorp (Verified)
Son módulos creados y mantenidos por socios tecnológicos de HashiCorp (AWS, Google, Microsoft, etc.) o por la propia HashiCorp. Se identifican con un escudo azul de verificación en el registry.
Características:
- Mantenidos activamente por organizaciones de confianza
- Siguen las mejores prácticas de Terraform
- Tienen documentación completa
- Son revisados por HashiCorp antes de recibir el badge
- Ejemplo:
terraform-aws-modules/vpc/aws(mantenido por Anton Babenko, socio verificado)
Módulos de la comunidad (Community)
Creados y mantenidos por la comunidad open source. No tienen el escudo de verificación pero pueden ser igual de útiles y fiables.
Características:
- Calidad variable (depende del mantenedor)
- Pueden no estar actualizados con versiones recientes de Terraform o providers
- Algunos tienen una comunidad muy activa y muchas estrellas en GitHub
- Requieren más evaluación por parte del usuario
| Criterio | Módulos verificados | Módulos de la comunidad |
|---|---|---|
| Mantenedor | Partner de HashiCorp | Cualquier desarrollador |
| Badge en registry | Escudo azul | No |
| Confiabilidad | Alta | Variable |
| Actualizaciones | Frecuentes | Depende del autor |
| Soporte | Documentado | Issues en GitHub |
| Cantidad disponible | Limitada (alta calidad) | Muy amplia |
| Recomendado para producción | Si, como punto de partida | Con evaluación previa |
Cómo buscar y evaluar módulos en registry.terraform.io
Búsqueda en el registry
El registry ofrece búsqueda por texto libre y filtros:
- Ve a registry.terraform.io/browse/modules
- Usa la barra de búsqueda con términos como "vpc", "s3", "kubernetes"
- Filtra por provider (aws, google, azurerm, kubernetes...)
- Filtra por verified para ver solo módulos verificados
Información disponible en cada módulo
Al acceder a la página de un módulo verás:
- Readme: documentación principal del módulo
- Inputs: todas las variables de entrada con tipos y descripciones
- Outputs: todos los valores que el módulo expone
- Dependencies: providers y versiones requeridas
- Resources: lista de recursos que el módulo gestiona (muy útil para entender qué crea)
- Submodules: módulos adicionales dentro del mismo repositorio
- Examples: ejemplos de uso
Criterios para elegir un módulo
Antes de usar un módulo externo en producción, evalúa estos factores:
- Actividad de mantenimiento
# Comprueba en GitHub:
# - Último commit: ¿fue hace menos de 6 meses?
# - Issues abiertos: ¿hay muchos sin respuesta?
# - Pull requests: ¿se revisan y fusionan con regularidad?
# - Releases: ¿hay versiones recientes?
- Número de descargas y popularidad
En el registry, los módulos más populares tienen más ojos encima y los bugs se detectan antes. Un módulo con millones de descargas es señal de confianza.
- Versiones publicadas y semver
Un módulo que sigue el versionado semántico correctamente indica madurez. Desconfía de módulos que solo tienen versión 0.x.x o que nunca han publicado releases.
- Documentación
¿Tiene README? ¿Están documentadas todas las variables? ¿Hay ejemplos? La calidad de la documentación refleja la calidad del módulo.
- Compatibilidad con tu versión de Terraform
# Verifica el bloque terraform en el módulo:
terraform {
required_version = ">= 1.3" # ¿Es compatible con tu versión?
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0" # ¿Es compatible con tu versión del provider?
}
}
}
- Licencia
La mayoría de módulos usan MIT o Apache 2.0, que permiten uso comercial. Verifica que la licencia es compatible con tu uso.
Checklist de evaluación
| Criterio | Cómo verificar | Señal positiva |
|---|---|---|
| Ultimo commit | GitHub → commits | Menos de 6 meses |
| Issues sin respuesta | GitHub → Issues | Menos del 20% sin respuesta |
| Estrellas en GitHub | GitHub → Stars | Más de 100 para módulos relevantes |
| Versiones publicadas | Registry → Versions | Versión >= 1.0.0 con historial |
| Badge verificado | Registry → Verified | Presente |
| Documentación completa | Registry → Readme | Readme + Inputs + Outputs documentados |
| Tests automatizados | GitHub → .github/workflows | CI/CD configurado |
| Ejemplos | Registry → Examples | Al menos 1 ejemplo funcional |
| Licencia permisiva | GitHub → LICENSE | MIT, Apache 2.0, MPL 2.0 |
Módulos verificados de HashiCorp
Los módulos verificados son la primera opción a considerar. Aquí tienes los más usados:
| Módulo | Proveedor | Fuente en registry |
|---|---|---|
| VPC (Virtual Private Cloud) | AWS | terraform-aws-modules/vpc/aws |
| EC2 Instance | AWS | terraform-aws-modules/ec2-instance/aws |
| RDS (Base de datos) | AWS | terraform-aws-modules/rds/aws |
| EKS (Kubernetes) | AWS | terraform-aws-modules/eks/aws |
| S3 Bucket | AWS | terraform-aws-modules/s3-bucket/aws |
| Lambda Function | AWS | terraform-aws-modules/lambda/aws |
| Virtual Network | Azure | Azure/vnet/azurerm |
| AKS (Kubernetes) | Azure | Azure/aks/azurerm |
| VPC Network | GCP | terraform-google-modules/network/google |
| GKE (Kubernetes) | GCP | terraform-google-modules/kubernetes-engine/google |
Requisitos para publicar un módulo en el registry
Para publicar un módulo en el Terraform Registry público, debes cumplir estos requisitos:
Requisitos técnicos
-
Repositorio en GitHub: el código debe estar en un repositorio público de GitHub.
-
Nombre del repositorio: debe seguir el formato
terraform-<provider>-<nombre>:terraform-aws-vpc terraform-google-network terraform-azurerm-compute -
Estructura de archivos mínima:
terraform-aws-mi-modulo/ ├── main.tf # Obligatorio ├── variables.tf # Obligatorio ├── outputs.tf # Obligatorio └── README.md # Obligatorio (con descripción y uso) -
Releases con tags de GitHub: las versiones se detectan automáticamente a partir de los tags de GitHub que sigan el formato semver (con
vopcional):git tag v1.0.0 git push origin v1.0.0 -
Provider declarado: el
main.tfdebe incluir el bloqueterraformconrequired_providers.
Proceso de publicación
El proceso es automático una vez conectas tu cuenta de GitHub al registry:
# Pasos para publicar:
# 1. Crea el repositorio con el nombre correcto
# terraform-aws-mi-servidor (ejemplo)
# 2. Desarrolla el módulo con la estructura correcta
# 3. Crea una cuenta en registry.terraform.io y conecta GitHub
# 4. El registry detecta automáticamente el repositorio por el nombre
# 5. Publica el módulo desde la interfaz del registry
# 6. Crea tags para las versiones:
git tag v1.0.0
git push origin v1.0.0
# El registry detecta el tag y publica la versión automáticamente
# Para versiones posteriores:
git tag v1.1.0
git push origin v1.1.0Estructura de nomenclatura: terraform-provider-nombre
La convención de nombres terraform-<provider>-<nombre> no es solo un requisito del registry; comunica información importante sobre el módulo:
terraform-aws-vpc │ │ │ │ │ └── Función/componente: qué hace el módulo │ └────── Provider: con qué cloud/tecnología trabaja └─────────────── Prefijo: siempre "terraform" para módulos publicables
Ejemplos de buenos nombres
terraform-aws-vpc # VPC en Amazon Web Services terraform-google-gke # Google Kubernetes Engine en GCP terraform-azurerm-aks # Azure Kubernetes Service en Azure terraform-kubernetes-nginx # NGINX en Kubernetes terraform-github-repository # Repositorios en GitHub
Nombres para módulos internos (no publicados)
Para módulos internos de empresa que no se publicarán en el registry, la convención es más flexible:
modules/ ├── networking/ # Kebab-case o snake_case ├── compute-web/ ├── database_rds/ └── security-groups/
Publicar tu propio módulo: proceso paso a paso
Vamos a ver el proceso completo para publicar un módulo real:
Paso 1: Preparar el repositorio
# Crear el repositorio con el nombre correcto
# En GitHub: New repository → nombre: terraform-local-proyecto
# Clonar el repositorio
git clone https://github.com/tu-usuario/terraform-local-proyecto.git
cd terraform-local-proyectoPaso 2: Crear la estructura del módulo
# Crear los archivos necesarios
touch main.tf variables.tf outputs.tf README.md
mkdir -p examples/basico
touch examples/basico/main.tf examples/basico/README.mdPaso 3: Implementar el módulo
# main.tf
terraform {
required_version = ">= 1.0"
required_providers {
local = {
source = "hashicorp/local"
version = "~> 2.0"
}
}
}
resource "local_file" "proyecto" {
filename = "${var.directorio}/${var.nombre}.conf"
content = var.contenido
file_permission = var.permisos
}# variables.tf
variable "nombre" {
description = "Nombre del archivo de configuración del proyecto."
type = string
}
variable "directorio" {
description = "Directorio destino donde se creará el archivo."
type = string
}
variable "contenido" {
description = "Contenido del archivo de configuración."
type = string
default = "# Configuración generada por Terraform"
}
variable "permisos" {
description = "Permisos del archivo en formato octal."
type = string
default = "0644"
}# outputs.tf
output "ruta_archivo" {
description = "Ruta completa del archivo de configuración creado."
value = local_file.proyecto.filename
}
output "contenido_guardado" {
description = "Contenido guardado en el archivo."
value = local_file.proyecto.content
}# examples/basico/main.tf
module "mi_proyecto" {
source = "../.." # Apunta al módulo raíz del repositorio
nombre = "mi-aplicacion"
directorio = "/tmp/configs"
contenido = "servidor=localhost\npuerto=8080"
}
output "config_creada" {
value = module.mi_proyecto.ruta_archivo
}Paso 4: Documentar con README.md
# terraform-local-proyecto
Módulo de Terraform para gestionar archivos de configuración de proyectos.
## Uso
module "config" { source = "tu-usuario/proyecto/local" version = "~> 1.0"
nombre = "mi-app" directorio = "/etc/mi-app" contenido = "puerto=8080\ndebug=false" }
## Variables de entrada | Variable | Tipo | Obligatoria | Default | Descripción | |---|---|---|---|---| | nombre | string | Sí | - | Nombre del archivo | | directorio | string | Sí | - | Directorio destino | | contenido | string | No | Comentario | Contenido del archivo | | permisos | string | No | "0644" | Permisos del archivo | ## Outputs | Output | Descripción | |---|---| | ruta_archivo | Ruta completa del archivo creado | | contenido_guardado | Contenido guardado |
Paso 5: Publicar la primera versión
# Commitear todos los cambios
git add .
git commit -m "feat: implementación inicial del módulo"
git push origin main
# Crear el primer tag de versión
git tag v1.0.0
git push origin v1.0.0
# Ahora en registry.terraform.io:
# 1. Sign in with GitHub
# 2. Publish → Module
# 3. Seleccionar el repositorio "terraform-local-proyecto"
# 4. ¡El registry lo detecta automáticamente!Paso 6: Publicar actualizaciones
# Desarrollar el cambio
# ... modificar archivos ...
# Commitear con mensaje descriptivo siguiendo convenciones
git add .
git commit -m "feat: añadir soporte para permisos de directorio"
git push origin main
# Crear nuevo tag (versión MENOR porque es nueva funcionalidad)
git tag v1.1.0
git push origin v1.1.0
# El registry detecta el tag y publica la nueva versión automáticamenteMódulos privados en Terraform Cloud/Enterprise
Si tu organización necesita módulos privados (que no sean públicos), Terraform Cloud y Terraform Enterprise ofrecen un Private Registry:
Características del Private Registry
- Los módulos solo son accesibles para miembros de tu organización en Terraform Cloud
- Mismo flujo de publicación que el registry público pero con autenticación
- Integración con VCS privados (GitHub Enterprise, GitLab, Bitbucket Server)
- Control de acceso por equipo (RBAC)
Configurar acceso al Private Registry
# Para usar módulos del registry privado, configura las credenciales
# en el CLI de Terraform:
# 1. Obtener un token de API de Terraform Cloud
# app.terraform.io → User Settings → Tokens
# 2. Configurar el token localmente
terraform login app.terraform.io
# Abre el navegador para autenticación
# 3. Usar el módulo privado en tu configuración
module "mi_modulo_privado" {
source = "app.terraform.io/mi-organizacion/nombre-modulo/provider"
version = "~> 1.0"
# Variables del módulo
variable_1 = "valor"
}Flujo de trabajo con módulos privados
# Los módulos privados se publican desde VCS (GitHub Enterprise, GitLab, etc.)
# Proceso en Terraform Cloud:
# 1. Navega a: app.terraform.io → Registry → Publish Module
# 2. Conecta tu VCS provider
# 3. Selecciona el repositorio del módulo
# 4. El naming sigue la misma convención: terraform-<provider>-<nombre>
# 5. Los tags de git crean versiones automáticamente
# Para equipos que no pueden usar git tags directamente,
# Terraform Cloud Enterprise permite publicar via API:
curl \
--header "Authorization: Bearer $TOKEN" \
--header "Content-Type: application/vnd.api+json" \
--request POST \
--data @module.json \
"https://app.terraform.io/api/v2/organizations/mi-org/registry-modules"Tabla de módulos populares por proveedor
Amazon Web Services (AWS)
| Módulo | Descripción | Fuente |
|---|---|---|
| VPC | Red privada virtual completa | terraform-aws-modules/vpc/aws |
| EC2 Instance | Instancias de servidor | terraform-aws-modules/ec2-instance/aws |
| RDS | Bases de datos relacionales | terraform-aws-modules/rds/aws |
| S3 Bucket | Almacenamiento de objetos | terraform-aws-modules/s3-bucket/aws |
| EKS | Kubernetes gestionado | terraform-aws-modules/eks/aws |
| Lambda | Funciones serverless | terraform-aws-modules/lambda/aws |
| ALB | Load balancer de aplicación | terraform-aws-modules/alb/aws |
| IAM | Gestión de identidad | terraform-aws-modules/iam/aws |
| CloudFront | CDN y distribución de contenido | terraform-aws-modules/cloudfront/aws |
Microsoft Azure
| Módulo | Descripción | Fuente |
|---|---|---|
| Virtual Network | Red virtual de Azure | Azure/vnet/azurerm |
| AKS | Kubernetes gestionado | Azure/aks/azurerm |
| Compute | Máquinas virtuales | Azure/compute/azurerm |
| Storage Account | Almacenamiento | Azure/storage/azurerm |
Google Cloud Platform (GCP)
| Módulo | Descripción | Fuente |
|---|---|---|
| Network | VPC y subredes | terraform-google-modules/network/google |
| GKE | Kubernetes gestionado | terraform-google-modules/kubernetes-engine/google |
| Cloud SQL | Bases de datos | GoogleCloudPlatform/sql-db/google |
| IAM | Permisos y roles | terraform-google-modules/iam/google |
Kubernetes y contenedores
| Módulo | Descripción | Fuente |
|---|---|---|
| Helm Release | Deployar charts de Helm | registry.terraform.io/modules/... |
| Kubernetes Manifests | Aplicar manifiestos | Múltiples autores |
Ejemplo: usar el módulo terraform-aws-modules/vpc/aws
Este es el módulo de VPC más utilizado en el ecosistema Terraform para AWS. Vamos a ver un ejemplo completo y explicado:
# main.tf
terraform {
required_version = ">= 1.3"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Configuración del provider AWS
provider "aws" {
region = "eu-west-1" # Irlanda
# En producción, las credenciales se gestionan via:
# - Variables de entorno: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
# - IAM Role (en EC2 o ECS)
# - AWS SSO / Identity Center
# NUNCA las hardcodees en el código
}
# ============================================================
# Datos de contexto: obtenemos información de la cuenta AWS
# ============================================================
# data sources obtienen información existente (no crean recursos)
data "aws_availability_zones" "disponibles" {
# Filtra por estado: solo zonas "available" (activas)
state = "available"
}
# ============================================================
# Módulo VPC: crea la red completa
# ============================================================
module "vpc_produccion" {
# source: identificador único del módulo en el registry
# Formato: <namespace>/<nombre>/<provider>
source = "terraform-aws-modules/vpc/aws"
# version: SIEMPRE especificar. ~> 5.0 acepta 5.x.x pero no 6.x.x
version = "~> 5.0"
# --- Configuración básica ---
# Nombre de la VPC (se usa para nombrar todos los recursos internos)
name = "vpc-produccion"
# Bloque CIDR de la VPC: rango de IPs de toda la red
cidr = "10.0.0.0/16" # 65,536 IPs disponibles
# --- Zonas de disponibilidad y subredes ---
# Usamos las 3 primeras AZs disponibles en la región
# slice() toma los primeros N elementos de una lista
azs = slice(data.aws_availability_zones.disponibles.names, 0, 3)
# Subredes privadas: recursos internos (bases de datos, workers)
# No tienen acceso directo desde internet
# Una subred por AZ = alta disponibilidad
private_subnets = [
"10.0.1.0/24", # 256 IPs en AZ-a
"10.0.2.0/24", # 256 IPs en AZ-b
"10.0.3.0/24", # 256 IPs en AZ-c
]
# Subredes públicas: recursos accesibles desde internet (load balancers, bastiones)
public_subnets = [
"10.0.101.0/24", # 256 IPs en AZ-a
"10.0.102.0/24", # 256 IPs en AZ-b
"10.0.103.0/24", # 256 IPs en AZ-c
]
# Subredes de base de datos: aisladas, sin acceso a internet
# (Buena práctica de seguridad: bases de datos en su propia subred)
database_subnets = [
"10.0.201.0/24",
"10.0.202.0/24",
"10.0.203.0/24",
]
# --- Conectividad a internet ---
# Internet Gateway: permite a las subredes PÚBLICAS acceder a internet
# Se crea automáticamente cuando hay public_subnets
# (No es necesario configurarlo explícitamente)
# NAT Gateway: permite a las subredes PRIVADAS acceder a internet (salida)
# pero el tráfico entrante desde internet no puede llegar a ellas
enable_nat_gateway = true
# single_nat_gateway = true: UN SOLO NAT para todas las AZs
# Ventaja: más económico (~$32/mes vs ~$96/mes por 3 NATs)
# Desventaja: punto único de fallo (si esa AZ falla, las privadas pierden internet)
# En PRODUCCIÓN real: usa one_nat_gateway_per_az = true
single_nat_gateway = true
# --- DNS ---
# Habilitar resolución DNS en la VPC (necesario para muchos servicios AWS)
enable_dns_hostnames = true
enable_dns_support = true
# --- Configuración de base de datos ---
# Crea un "DB subnet group": agrupación de subredes para RDS
# Necesario si vas a usar el módulo RDS posteriormente
create_database_subnet_group = true
# --- Etiquetas ---
# Tags aplicados a TODOS los recursos que crea el módulo
tags = {
Entorno = "produccion"
Proyecto = "tienda-online"
GestionPor = "terraform"
Equipo = "infraestructura"
}
# Tags adicionales solo para las subredes públicas
public_subnet_tags = {
"kubernetes.io/role/elb" = "1" # Necesario para AWS Load Balancer Controller en EKS
}
# Tags adicionales solo para las subredes privadas
private_subnet_tags = {
"kubernetes.io/role/internal-elb" = "1" # Para load balancers internos en EKS
}
}
# ============================================================
# Outputs: exponemos información de la VPC para otros módulos
# ============================================================
output "vpc_id" {
description = "ID de la VPC creada"
value = module.vpc_produccion.vpc_id
}
output "subredes_privadas" {
description = "IDs de las subredes privadas"
value = module.vpc_produccion.private_subnets
}
output "subredes_publicas" {
description = "IDs de las subredes públicas"
value = module.vpc_produccion.public_subnets
}
output "subredes_base_datos" {
description = "IDs de las subredes de base de datos"
value = module.vpc_produccion.database_subnets
}
output "cidr_vpc" {
description = "Bloque CIDR de la VPC"
value = module.vpc_produccion.vpc_cidr_block
}Verificar qué recursos crea este módulo:
# Inicializar
terraform init
# Ver el plan (sin aplicar)
terraform plan
# El módulo vpc crea aproximadamente:
# - 1 VPC
# - 9 subredes (3 privadas + 3 públicas + 3 de BD)
# - 1 Internet Gateway
# - 1 NAT Gateway + 1 Elastic IP
# - 3 Route tables (1 pública, 1 privada, 1 de BD)
# - 1 DB Subnet Group
# - Varias asociaciones de route tables
# Total: ~25-30 recursos con una sola llamada al móduloEjercicio: Encontrar, evaluar y usar un módulo del registry
Objetivo: Aplicar los criterios de evaluación aprendidos para seleccionar un módulo del registry.
Contexto: Tu equipo necesita gestionar múltiples repositorios de GitHub usando Terraform. Debes:
- Buscar en registry.terraform.io módulos para gestionar repositorios de GitHub.
- Evaluar los resultados según los criterios vistos.
- Usar el módulo seleccionado para crear una configuración que gestione 2 repositorios.
Criterios de evaluación que debes documentar:
- ¿Tiene badge verificado?
- ¿Cuándo fue el último commit?
- ¿Cuántas versiones tiene publicadas?
- ¿La documentación es completa?
- ¿Tiene ejemplos?
Solución y criterios de evaluación
Evaluación del módulo
Buscando "github repository" en el registry, encontramos el provider oficial de GitHub que incluye recursos directos (sin módulo de terceros necesario). Para repositorios GitHub, lo habitual es usar el provider integrations/github directamente:
# Buscar en el registry:
# 1. Ve a registry.terraform.io
# 2. Busca "github"
# 3. Selecciona el provider "integrations/github"Para este ejercicio, crearemos un módulo local que encapsula la creación de repositorios GitHub:
Configuración con el provider de GitHub
# main.tf
terraform {
required_version = ">= 1.0"
required_providers {
# Provider oficial de GitHub (mantenido por Integrations, socio de HashiCorp)
github = {
source = "integrations/github"
version = "~> 6.0"
}
}
}
# Configuración del provider de GitHub
provider "github" {
# El token se pasa via variable de entorno: GITHUB_TOKEN
# Nunca lo pongas aquí en el código
# export GITHUB_TOKEN="ghp_tu_token_aqui"
owner = "tu-organizacion" # o tu usuario de GitHub
}
# ============================================================
# Crear repositorios usando el provider directamente
# (sin módulo del registry porque no hay uno verificado ampliamente)
# ============================================================
locals {
# Definir los repositorios como mapa para usar for_each
repositorios = {
"api-backend" = {
descripcion = "API REST del backend de la aplicación"
privado = true
auto_init = true
topics = ["api", "backend", "rest"]
}
"frontend-web" = {
descripcion = "Aplicación web del frontend"
privado = false
auto_init = true
topics = ["frontend", "web", "react"]
}
}
}
# Crear los repositorios con for_each
resource "github_repository" "repos" {
for_each = local.repositorios
# Nombre del repositorio
name = each.key
# Descripción visible en GitHub
description = each.value.descripcion
# Visibilidad del repositorio
visibility = each.value.privado ? "private" : "public"
# Inicializar con README.md automáticamente
auto_init = each.value.auto_init
# Topics (etiquetas) del repositorio
topics = each.value.topics
# Configuración de branches
has_issues = true
has_wiki = false
has_projects = false
# Configuración de merge: solo squash y merge commits, no merge commits directos
allow_squash_merge = true
allow_merge_commit = false
allow_rebase_merge = true
delete_branch_on_merge = true # eliminar rama al hacer merge de PR
}
# Proteger la rama main en todos los repositorios
resource "github_branch_protection" "main" {
for_each = local.repositorios
repository_id = github_repository.repos[each.key].node_id
pattern = "main"
# Requerir pull requests antes de hacer merge
required_pull_request_reviews {
dismiss_stale_reviews = true
required_approving_review_count = 1
}
# Requerir que los checks de CI pasen
required_status_checks {
strict = true # los checks deben ejecutarse sobre la versión más reciente
}
# No permitir forzar push a main
force_push_bypassers = []
}
# Outputs
output "urls_repositorios" {
description = "URLs de los repositorios creados en GitHub"
value = {
for k, v in github_repository.repos : k => v.html_url
}
}
output "ssh_clone_urls" {
description = "URLs SSH para clonar los repositorios"
value = {
for k, v in github_repository.repos : k => v.ssh_clone_url
}
}Criterios de evaluación aplicados (guía de puntuación)
| Criterio | Puntuación máxima | Descripción |
|---|---|---|
| Mantenimiento activo | 25 pts | Commits en los últimos 3 meses: 25pts; 6 meses: 15pts; más: 5pts |
| Versiones publicadas | 20 pts | v1.0+ con historial: 20pts; solo v0.x: 10pts; sin releases: 0pts |
| Documentación | 20 pts | README + inputs + outputs documentados: 20pts; parcial: 10pts |
| Badge verificado | 15 pts | Verificado: 15pts; no verificado: 0pts |
| Ejemplos funcionales | 10 pts | Al menos 1 ejemplo: 10pts; ninguno: 0pts |
| Tests automatizados | 10 pts | CI/CD visible: 10pts; ninguno: 0pts |
Un módulo con más de 70/100 puntos es una opción razonable para producción.
Errores comunes al trabajar con el registry
Error 1: No bloquear la versión del módulo
# PELIGROSO: sin versión
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
# Si sale una versión 6.0 con breaking changes, terraform init la usará
}
# CORRECTO: versión bloqueada
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0"
}Error 2: Confiar ciegamente en módulos no verificados
Siempre verifica el código fuente de un módulo antes de usarlo en producción. Los módulos pueden crear recursos costosos o con configuraciones inseguras. Usa el enlace "Source Code" en el registry para ver el repositorio GitHub.
Error 3: Usar la misma versión de módulo en todos los entornos
En algunos casos puede ser útil probar una nueva versión en staging antes de actualizarla en producción:
# staging/main.tf
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.1" # Probando nueva versión menor
}
# produccion/main.tf
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0" # Versión probada y estable
}Error 4: No leer el CHANGELOG antes de actualizar
Antes de ejecutar terraform get -update, revisa el CHANGELOG del módulo en GitHub para identificar breaking changes o cambios de comportamiento importantes.
Error 5: Publicar módulos con información sensible
Si publicas un módulo en el registry público, asegúrate de que no contiene:
- Credenciales hardcodeadas
- IDs de recursos específicos de tu cuenta
- Configuraciones internas de tu empresa
- Variables con valores por defecto que sean secretos
Resumen del módulo 4
Has completado el módulo 4 del curso, que cubre todo el ciclo de vida de los módulos de Terraform. Hagamos un repaso de lo aprendido:
Tema 4-01: Introducción a los módulos
- Un módulo es un directorio de archivos
.tfque encapsula infraestructura reutilizable. - El módulo raíz vs módulos secundarios y cómo se relacionan.
- Los tipos de fuentes de módulos: local, registry, Git, S3.
- La regla de los 3 para decidir cuándo extraer código en un módulo.
Tema 4-02: Creando módulos
- La estructura estándar:
main.tf,variables.tf,outputs.tf,versions.tf,README.md. - Cómo declarar variables con tipos, descripciones, validaciones y valores sensitive.
- Cómo definir outputs y agruparlos en objetos.
- Principios de diseño: responsabilidad única, interfaz mínima.
- Versionado semántico para módulos.
Tema 4-03: Usando módulos
- La sintaxis del bloque
moduley sus argumentos especiales. - Todos los formatos del argumento
source. - Cómo pasar variables y acceder a outputs.
- Uso de
countyfor_eachcon módulos. - Los operadores de versión:
~>,>=,!=, etc. - Diferencia entre
terraform inityterraform get.
Tema 4-04: El Terraform Registry
- Qué es el registry y la diferencia entre módulos verificados y de comunidad.
- Criterios para evaluar módulos externos antes de usarlos en producción.
- Los módulos más populares por proveedor de cloud.
- Requisitos y proceso para publicar un módulo propio.
- Módulos privados en Terraform Cloud/Enterprise.
Próximos pasos
Con el conocimiento de módulos bien consolidado, estás listo para abordar el Módulo 5: Provisionamiento de Infraestructura, donde aprenderás a crear recursos reales en AWS, Azure y GCP, y cómo combinar todos los conceptos vistos (variables, state, módulos) en proyectos de infraestructura completos y listos para producción.
Los módulos son el corazón de Terraform a escala. A medida que tu experiencia crezca, desarrollar una biblioteca de módulos internos de alta calidad se convertirá en una de tus tareas más valiosas como ingeniero de infraestructura.
Curso de Terraform
Módulo 1: Introducción a Terraform
- ¿Qué es Terraform?
- Instalando Terraform
- Conceptos Básicos de Terraform
- Primera Configuración de Terraform
Módulo 2: Lenguaje de Configuración de Terraform
Módulo 3: Gestión del Estado
Módulo 4: Módulos de Terraform
Módulo 5: Aprovisionamiento de Recursos
- Conceptos Básicos de Aprovisionamiento
- Aprovisionamiento de Recursos AWS
- Aprovisionamiento de Recursos Azure
- Aprovisionamiento de Recursos GCP
Módulo 6: Funcionalidades Avanzadas de Terraform
Módulo 7: Mejores Prácticas de Terraform
- Organización del Código
- Control de Versiones
- Pruebas del Código de Terraform
- Mejores Prácticas de Seguridad
Módulo 8: Terraform en CI/CD
- Integración de Terraform con CI/CD
- Automatización de Terraform con Jenkins
- Uso de Terraform con GitHub Actions
- Terraform Cloud y Enterprise
