Dos tiendas, una receta
Una empresa tiene una tienda en la esquina y otra en la colina. Las dos necesitan la misma instalación. Copiar los archivos funciona hasta el día en que hay que arreglar algo: entonces se arregla dos veces.
Un módulo es la receta escrita una sola vez. Cada tienda la llama con sus propios valores.
Al final de esta lección
Nota
Puedo llamar a un módulo dos veces y leer lo que devuelve cada copia.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Módulo | una carpeta de archivos que se puede reutilizar | |
| Llamada a un módulo | un bloque que usa un módulo y le da valores | module "hill" |
| Salida | un valor que un módulo devuelve | output |
| Validación | una regla que rechaza una entrada mala | |
| Dirección de módulo | la ruta de un recurso, que empieza por module | module.hill.terraform_data.sign |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un módulo es una carpeta que llamas
Un módulo es una carpeta de archivos de OpenTofu. El proyecto que lo usa es la raíz. La raíz escribe una llamada a un módulo, nombra la carpeta en source y da un valor a cada entrada.
Dos llamadas hacen dos copias separadas de todo lo que hay en la carpeta. Aquí la fuente es una ruta local, así que no se descarga nada.
Crea las carpetas y entra
mkdir -p ~/iac-demo/mods/modules/shop && cd ~/iac-demo/modsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el módulo
printf '%s\n' 'variable "name" {' ' type = string' ' validation {' ' condition = length(var.name) >= 3 && length(var.name) <= 10' ' error_message = "El nombre debe tener de 3 a 10 caracteres."' ' }' '}' '' 'resource "terraform_data" "sign" {' ' input = format("%s: abierto", var.name)' '}' '' 'output "sign" {' ' value = terraform_data.sign.output' '}' > modules/shop/main.tfSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la raíz: dos llamadas y una salida
printf '%s\n' 'module "corner" {' ' source = "./modules/shop"' ' name = "Corner"' '}' '' 'module "hill" {' ' source = "./modules/shop"' ' name = "Hill"' '}' '' 'output "signs" {' ' value = [module.corner.sign, module.hill.sign]' '}' > main.tfSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Prepara la carpeta
tofu init -no-color | grep -E "Initializing modules|corner|hill|successfully"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Planifica y mira las direcciones
tofu plan -no-color | grep -E "will be created|^Plan"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un módulo devuelve salidas
Un recurso dentro de un módulo tiene una dirección más larga, como module.hill.terraform_data.sign. La raíz no puede leerlo directamente.
Solo una salida atraviesa el muro. La raíz la lee como module.hill.sign: el nombre de la llamada y luego el de la salida.
Aplica: el estado guarda las dos copias
tofu apply -auto-approve -no-color | grep "Apply complete"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Lista las direcciones del estado
tofu state listSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Lee la salida que hizo la raíz
tofu output signsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un error frecuente
Advertencia
Mucha gente cree que la raíz puede leer cualquier recurso de un módulo. No puede. Un módulo solo comparte lo que nombran sus salidas: un valor que se quiere fuera necesita un bloque output.
Lee un recurso sin salida
printf '%s\n' 'output "bad" {' ' value = module.corner.terraform_data.sign' '}' > bad.tf; tofu validate -no-color 2>&1 | grep -E "Error|Unsupported"; rm bad.tfSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Una validación rechaza una entrada mala
Un bloque validation tiene una condition y un error_message. Cuando la condición es falsa, OpenTofu se detiene antes de planificar nada y muestra el mensaje.
El módulo acepta un nombre de 3 a 10 caracteres. Prueba con uno demasiado corto.
Da a la colina un nombre corto
sed -i 's/"Hill"/"Hi"/' main.tf; tofu validate -no-color 2>&1 | grep -E "Error|debe tener"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Vuelve a poner el nombre y comprueba
sed -i 's/"Hi"/"Hill"/' main.tf; tofu validate -no-colorSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Dos llamadas calculadas en Python
# Calcula las direcciones que crea la llamada a un módulo.
resources = ["sign", "door"]
calls = {"corner": None, "hill": None}
for call in calls:
copies = calls[call]
if copies is None:
prefixes = ["module." + call]
else:
prefixes = []
for key in copies:
prefixes.append("module." + call + '["' + key + '"]')
for prefix in prefixes:
for name in resources:
print(prefix + ".terraform_data." + name)
# Cambia "hill": None por "hill": ["a", "b"] y mira otra vez.
Ahora, en el lab
Los Run construyeron un módulo en una carpeta de práctica. El lab también tiene una carpeta para esto, ~/tofu-lab/shop, y la parte 7 de su README (en inglés) dice qué construir. No es el mismo módulo: tienes que cambiar lo que viste, no copiarlo.
Cómo se califica
Tu profesor lo califica ejecutando una comprobación en tu lab guardado. La comprobación aplica tu proyecto y después vuelve a llamar a tu módulo con nombres y un estado que nunca has visto. Un módulo con las respuestas escritas a mano no puede seguirlos, ni uno sin regla de validación.
Para ir más lejos: una llamada con count
Añade count = 2 a la llamada hill y cambia module.hill.sign en la salida por module.hill[0].sign. Ejecuta tofu plan -no-color | grep -E "will be|^Plan".
¿Qué direcciones muestra ahora el plan y por qué tuvo que cambiar la línea de la salida?