Terraform – Variables y Entornos

En la anterior entrega hablamos sobre terraform, sus ventajas y sintaxis básica. Pero dejamos un tema sin cubrir, si bien hablamos de despliegue de entornos de manera rápida. ¿Qué pasa cuando queremos tener múltiples configuraciones?

En esta publicación hablaremos de las variables y como podemos mantener nuestro proyecto.

Variables

Variables, variables, variables…. Es la base de la configuración. En HCL también tenemos variables. ¿Cómo las declaramos?

Creamos un archivo variables.tf

variable "nginx_external_port" {}

Listo, con eso ya podemos utilizar variables en nuestro main.tf de la siguiente forma:

resource "docker_container" "container_nginx" {
  ...
  ports {
    ...
    external = var.nginx_external_port
    ...
  }
}

Las variables se declaran teniendo en cuenta un nombre, usamos snake_case. Ahora cuando ejecutemos el plan de terraform tendremos lo siguiente:

Nos pide un valor, excelente! ¿Podemos mejorarlo? Sí, recuerda que el código debe ser legible para otros programadores, no solo para el que lo desarrolló.

Descripciones

Podemos añadirle una descripción que permita entender el valor que espera nuestro proyecto:

variable "nginx_external_port" {
  description = "Puerto externo del nginx"
}

Ahora al verificar el plan de ejecución tendremos un mensaje como el siguiente:

Esto no te quita la responsabilidad de seguir buenas prácticas, tus variables no pueden ser variable0 asdasd!!!

Restricciones

Podemos también restringir el tipo de dato de nuestra variable, así evitamos que se pueda cometer el siguiente error:

Para esto hacemos uso de la propiedad type

variable "nginx_external_port" {
  description = "Puerto externo del nginx"
  type        = number
}

Listo, ahora solo podremos colocar valores numéricos

Ahora será un error de validación que está controlado debido a que estamos esperando un número.

Default

Simplifiquemos el ciclo de desarrollo a nuestros amigos dev, si el proyecto puede tener valores por defecto escríbelos.

variable "nginx_external_port" {
  description = "Puerto externo del nginx"
  type        = number
  default     = 3000
}

Nuestro plan de ejecución podrá ejecutarse sin tener que ingresar estas variables

¿Y que tal si quiero definir otros valores?

Ya has definido tus variables, sabes que valor debe recibir e inclusive valores por defecto que tendrá. Pero ¿Y si no quiero configurar mi despliegue con los valores por defecto? ¿De que manera puedo pasar valores o configurarlos?

Regresemos el archivo variables.tf a este estado

variable "nginx_external_port" {
  description = "Puerto externo del nginx"
  type        = number
}

Y ahora crearemos un archivo llamado terraform.tfvars donde colocaremos lo siguiente:

nginx_external_port = 3000

Si ejecutamos nuestro plan de terraform tendremos la misma salida!

Recuerda que el archivo terraform.tfvars sobreescribe los valores de variables.tf.

Entornos

Para este proyecto hemos ejecutado previamente este comando

terraform init

El cual se encargó de dos cosas: Descargó las dependencias de proveedor e inicializó el proyecto en el entorno/mesa de trabajo default

¿Cómo podemos verificarlo? Ejecuta el siguiente comando

terraform workspace show

Te mostrará una salida igual a esta:

Tenemos otra forma de ver los entornos con el comando:

terraform workspace list

Te mostrará la lista de entornos que tienes en el proyecto y pondrá un asterisco de prefijo en el entorno en el que te encuentres trabajando.

Uso de entornos

Para crear un nuevo entorno puedes utilizar el siguiente comando:

terraform workspace new NOMBRE_DEL_ENTORNO

Configuraciones por entorno

Dentro de terraform podemos utilizar el nombre del entorno a través de la siguiente propiedad:

terraform.workspace

Modifiquemos nuestro archivo terraform.tfvars. En vez de un dato numérico utilicemos un diccionario:

nginx_external_port = {
  default = 3000
  prod    = 8080
}

Para utilizar este valor en nuestro main.tf debemos realizar el siguiente cambio:

resource "docker_container" "container_nginx" {
  ...
  ports {
    ...
    external = var.nginx_external_port[terraform.workspace]
  }
}

Y como recomendación actualiza el tipo de dato en terraform.tfvars y no solo elimines esta validación. Una buena práctica es declarar el objeto que esperamos:

variable "nginx_external_port" {
  description = "Puerto externo del nginx"
  type = object({
    default = number
    prod    = number
  })
}

De esta manera si olvidamos colocar un valor tendremos una validación y no un error durante ejecución

Posibles errores

Si al ejecutar el plan de terraform tienes el siguiente error:

Es porque la variable ya no contiene un valor numérico, ahora recibe un valor de tipo diccionario. Revisa el tipo que estás declarando tu variables.tf

Si te da un error de tipo:

Es porque el entorno que tienes declarado en tu ordenador no cuenta con un valor en tu diccionario.

Conclusiones

¿Para qué sirven los entornos? Hablamos de infraestructura como código. Las cadenas de conexión, puertos o inclusive configuraciones de aplicaciones varían según el entorno, sea desarrollo, qa, producción, etc…

Haciendo uso de terraform y configuración de variables podemos facilitar el despliegue según nuestras necesidades. Además, podemos hacer seguimiento de estas configuraciones en el archivo terraform.tfvars.

Practica creando diferentes entornos y desplegando tu infraestructura con valores personalizados para cada uno. Recuerda que cada entorno tiene su propio historial de cambios!