Trabajando con módulos en Terraform
En este artículo verás cómo reutilizar tu código de Terraform usando módulos para evitar tener que rescribir el mismo código una y otra vez. También aprenderás como versionar tus módulos y cómo usar versiones específicas.
¿Cómo defino un módulo?
Solo coloca todos tus archivos .tf en una carpeta, por ejemplo:
mymodule/
├── main.tf
├── outputs.tf
├── README.md
└── variables.tf
Luego cópiala dentro de una carpeta modules.
¿Cómo uso el módulo?
Usa el parámetro source para especificar la ruta de tu módulo como se muestra a continuación:
module "example" {
source = "./modules/mymodule"
var1 = "Hello World"
var2 = 1999
}
Variables del módulo
Como puedes ver este módulo recibe dos argumentos, los cuales pueden ser definidos en el archivo variables.tf de mymodule.
variable "var1" {
description = "A string var"
}
variable "var2" {
description = "A numerical var"
default = 1989
}
Salidas del módulo
Los módulos también tienen salidas que pueden ser usadas por otros módulos y recursos. Puedes definir las salidas en el archivo outputs.tf:
output "id" {
description = "This is the mymodule's id"
}
output "name" {
description = "This is the mymodule's name"
}
Sources de los módulos
Los ejemplos de arriba usan el parámetro source para obtener el módulo de la carpeta local pero también puedes usar otras fuentes como un repositorio git, mercurial, urls HTTPS, buckets S3 or el Registro de módulos de Terraform.
Por ejemplo, en vez de usar una carpeta lcoal puedes usar un repositorio git para versionar tu módulo y llamarlo de esta forma:
module "example" {
source = "git@bitbucket.org:mygitrepo/mymodule.git"
var1 = "Hello World"
var2 = 1999
}
Branch y versión del repositorio del módulo
Puedes también apuntar a un branch o versión específica en un repositorio git usando el query ?ref. Por ejemplo para especificar el branch dev:
module "example" {
source = "git@bitbucket.org:mygitrepo/mymodule.git?ref=dev"
var1 = "Hello World"
var2 = 1999
}
Para apuntar a la versión 0.0.2 usalo así:
module "example" {
source = "git@bitbucket.org:mygitrepo/mymodule.git?ref=0.0.2"
var1 = "Hello World"
var2 = 1999
}
¿Cuál es el problema con este enfoque?
Si quieres actualizar el módulo y lo has usado varias veces en un proyecto, debes editar a a mano la definición en cada lugar.
Versión del módulo
Si estás usando una versión de Terraform v0.11.0+ puedes especificar la versión del módulo. Esto ayuda a apuntar a una versión específica, por ejemplo a una estable del módulo. Esto solo funciona si estás usando un registro de módulo como el Terraform Registry
module "example" {
source = "hashicorp/mymodule"
version = "0.0.2"
var1 = "Hello World"
var2 = 1999
}
¿Cuál es el problema con este enfoque?
- El registro de Terraform es público. Para usar el registro privado (Private Registry) debes usar la versión Enterpise
- Solo disponible para las versiones v0.11.0+ de Terraform
Usando un Terrafile
Hay otro enfoque para superar los problemas de las versiones, el cual consiste en escribir un archivo para definir los módulos a usar desde un repositorio git, por branch o versión. Este archivo es conocido como Terrafile:
---
# VPC
tf_aws_vpc:
source : "git@github.com:terraform-community-modules/tf_aws_vpc.git"
version: "master"
tf_my_module:
source: "git@bitbucket.org:mygitrepo/mymodule.git"
version: "0.0.2"
Estos módulos se descargaran en la carpeta modules: y luego puedes referenciarlos en tu módulo usando esta carpeta local_:
module "example" {
source = "./modules/mymodule"
var1 = "Hello World"
var2 = 1999
}
Para obtener los módulos usa este Rakefile:
require 'yaml'
require 'fileutils'
# You may want to change this.
def modules_path
'vendor/modules'
end
# You may want to change this.
def terrafile_path
'Terrafile'
end
def read_terrafile
if File.exist? terrafile_path
YAML.load_file terrafile_path
else
fail('[*] Terrafile does not exist')
end
end
def create_modules_directory
unless Dir.exist? modules_path
puts "[*] Creating Terraform modules directory at '#{modules_path}'"
FileUtils.makedirs modules_path
end
end
def delete_cached_terraform_modules
puts "[*] Deleting cached Terraform modules at '#{modules_path}'"
FileUtils.rm_rf modules_path
end
desc 'Fetch the Terraform modules listed in the Terrafile'
task :get_modules do
terrafile = read_terrafile
create_modules_directory
delete_cached_terraform_modules
terrafile.each do |module_name, repository_details|
source = repository_details['source']
version = repository_details['version']
puts "[*] Checking out #{version} of #{source} ...".colorize(:green)
Dir.mkdir(modules_path) unless Dir.exist?(modules_path)
Dir.chdir(modules_path) do
`git clone -b #{version} #{source} #{module_name} &> /dev/null`
end
end
end
Y descárgalos usando la función get_modules:
rake get_modules
Finalmente obten los módulos en Terraform:
terraform get
Leave a Comment