Terraform Associate
Deep Dive
Terraform soporta múltiples tipos de fuentes para módulos: locales, el registry público, GitHub, S3, y más. Conocer el formato exacto de cada fuente y cuándo pinear versiones es un tema frecuente en el examen.
Contenido
| Tipo | Prefijo / Formato | ¿Requiere version? | Cuándo usarlo |
|---|---|---|---|
| Local | "./modules/vpc" | ❌ No | Módulos del mismo repositorio |
| Registry público | "hashicorp/consul/aws" | ✅ Sí | Módulos públicos verificados |
| Registry HCP | "app.terraform.io/org/vpc/aws" | ✅ Sí | Módulos corporativos privados |
| GitHub HTTPS | "github.com/org/repo" | ❌ No* | Módulos en repos GitHub públicos o privados |
| GitHub SSH | "git@github.com:org/repo" | ❌ No* | Repos GitHub via SSH (sin token) |
| Git genérico | "git::https://..." | ❌ No* | Cualquier servidor Git |
| S3 | "s3::https://bucket/module.zip" | ❌ No | Módulos empaquetados en S3 |
| GCS | "gcs::https://bucket/module.zip" | ❌ No | Módulos empaquetados en GCS |
* Para fuentes Git, se usa el argumento ref en la URL (ej: ?ref=v2.0.0) en lugar de version.
Las fuentes locales referencian un directorio en el mismo sistema de archivos. Usan rutas relativas (comenzando con ./ o ../).
# Módulo en subdirectorio del mismo repositorio
module "vpc" {
source = "./modules/vpc" # relativo al módulo que llama
}
# Módulo en directorio padre
module "shared" {
source = "../shared/modules/tags"
}
# No se puede usar versión con fuentes locales:
# version = "~> 1.0" ← ERROR con fuentes locales
# terraform get / terraform init —ambos copian el módulo
# a .terraform/modules/ del directorio de trabajo💡 Rutas relativas vs absolutas
Siempre usa rutas relativas (./ o ../) para módulos locales. Las rutas absolutas (/home/user/modules) funcionan en tu máquina pero rompen en CI/CD u otras máquinas. La ruta es relativa al archivo que hace la llamada, no al directorio donde ejecutas Terraform.
# Registry PÚBLICO: namespace/nombre/provider
# (Terraform asume registry.terraform.io como host)
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
version = "~> 5.0" # OBLIGATORIO para registry
}
module "iam_role" {
source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks"
version = "~> 5.30"
# Las // dobles permiten referenciar un submódulo dentro del repositorio
}
# Registry PRIVADO HCP Terraform: app.terraform.io/org/nombre/provider
module "vpc" {
source = "app.terraform.io/mi-empresa/vpc/aws"
version = "~> 2.0"
}
# También funciona con el host de tu Terraform Enterprise:
module "vpc" {
source = "terraform.mi-empresa.com/org/vpc/aws"
version = "~> 1.0"
}🎯 Submódulos con //
La doble barra // en el source separa el repositorio del subdirectorio dentro de él. Por ejemplo: terraform-aws-modules/iam/aws//modules/iam-role referencia el subdirectorio modules/iam-role dentro del módulo terraform-aws-modules/iam/aws.
# GitHub HTTPS (para repos públicos o con token HTTPS)
module "vpc" {
source = "github.com/mi-org/terraform-vpc-module"
}
# GitHub HTTPS con ref (tag, branch o commit)
module "vpc" {
source = "github.com/mi-org/terraform-vpc-module?ref=v2.0.0"
}
# GitHub SSH (autenticación via SSH key)
module "vpc" {
source = "git@github.com:mi-org/terraform-vpc-module.git"
}
# Git genérico (cualquier servidor Git)
module "vpc" {
source = "git::https://gitlab.mi-empresa.com/infra/vpc.git?ref=v1.5"
}
# Submódulo dentro del repo (con //)
module "vpc" {
source = "github.com/mi-org/terraform-modules//modules/vpc?ref=v3.0"
}| Fuente Git | Autenticación | ref para pinear versión |
|---|---|---|
| github.com/org/repo | Token HTTPS en variable de entorno o ~/.netrc | ?ref=v2.0.0 o ?ref=main |
| git@github.com:org/repo | SSH key en ~/.ssh/ | ?ref=v2.0.0 |
| git::https://gitlab.com/... | Token en URL o ~/.netrc | ?ref=tag-o-commit |
| bitbucket.org/org/repo | Token HTTPS | ?ref=v1.0 |
# Amazon S3 (módulo empaquetado como .zip o .tar.gz)
module "vpc" {
source = "s3::https://s3-eu-west-1.amazonaws.com/mi-bucket/vpc-module.zip"
}
# Google Cloud Storage
module "vpc" {
source = "gcs::https://www.googleapis.com/storage/v1/mi-bucket/vpc-module.zip"
}
# HTTP/HTTPS genérico (cualquier URL que devuelva un archivo)
module "vpc" {
source = "https://mi-servidor.com/modules/vpc-1.0.0.zip"
}
# Nota: estas fuentes no soportan el argumento version
# La versión se gestiona en el nombre del archivo o la URL| Tipo de fuente | ¿Pinear versión? | Cómo |
|---|---|---|
| Registry público/privado | ✅ SIEMPRE — obligatorio para registry | Argumento version = "~> X.Y" |
| Fuente local | ❌ No aplica | No tiene versiones, es el código local |
| Git con tag | ✅ Recomendado — usa tag semántico | ?ref=v2.0.0 en la URL |
| Git con branch | ⚠️ No recomendado en prod | ?ref=main — puede cambiar en cualquier momento |
| S3/GCS/HTTP | ✅ Recomendado — en el nombre del archivo | URL incluye la versión: module-v2.0.0.zip |
⚠️ Sin versión en registry = riesgo de rotura
Si no especificas version en un módulo del registry, Terraform instalará la última versión disponible en cada terraform init. Una nueva versión major del módulo puede introducir cambios incompatibles que rompan tu configuración sin previo aviso.
¿Entendiste este tema?
Pon a prueba lo que acabas de aprender
Un equipo quiere usar un módulo de Terraform almacenado en un repositorio GitHub privado de su empresa. Necesitan que siempre se use exactamente la versión etiquetada como 'v3.2.1'. ¿Cuál es la forma correcta de configurar el source?