Bloques de configuración dinámicos en Terraform
Una de las cosas que tenía pendiente por resolver era el hecho de que en Terraform hay bloques de configuración que dependiendo de las opciones puede que tengan parámetros distintos o que incluso no acepte los mismos parámetros.
Para eso, y guiándome de un código de un módulo de la comunidad, logré sortear este problema usando locals values de Terraform
Tomando un ejemplo de esto tenemos el bloque artifacts
del recurso aws_codebuild_project de Terraform, el cual puede tener parámetros algunos parámetros si el tipo es S3
, CODEPIPELINE
o NO_ARTIFACTS
. Por ejemplo, si definimos un bloque de la siguiente manera no será fácil la parametrización del mismo:
resource "aws_codebuild_project" "codebuild" {
[...]
artifacts{
type = "${var.codebuild_artifacts_type}"
location = "${var.codebuild_artifacts_location}"
name = "${var.codebuild_artifacts_name}"
namespace_type = "${var.codebuild_artifacts_namespace_type}"
packaging = "${var.codebuild_artifacts_packaging}"
path = "${var.codebuild_artifacts_path}"
}
}
Si por ejemplo intentamos colocar el NO_ARTIFACTS
fallará porque aunque se coloquen valores “vacíos” para el resto de los parámetros, estos argumentos no están soportados. Para resolver esto hay que crear una definición del bloque con locals
según el tipo proporcionado por type
y usar esto como un índice:
resource "aws_codebuild_project" "codebuild" {
[...]
artifacts = ["${local.codebuild_artifacts}"]
}
locals {
codebuild_artifacts_def = {
"S3" = [{
type = "${var.codebuild_artifacts_type}"
location = "${var.codebuild_artifacts_location}"
name = "${var.codebuild_artifacts_name}"
namespace_type = "${var.codebuild_artifacts_namespace_type}"
packaging = "${var.codebuild_artifacts_packaging}"
path = "${var.codebuild_artifacts_path}"
}]
"CODEPIPELINE" = [{
type = "${var.codebuild_artifacts_type}"
location = "${var.codebuild_artifacts_location}"
name = "${var.codebuild_artifacts_name}"
namespace_type = "${var.codebuild_artifacts_namespace_type}"
packaging = "${var.codebuild_artifacts_packaging}"
path = "${var.codebuild_artifacts_path}"
}]
"NO_ARTIFACTS" = [{
type = "${var.codebuild_artifacts_type}"
}]
}
# Retuned map
codebuild_artifacts = "${local.codebuild_artifacts_def[var.codebuild_artifacts_type]}"
}
Esto crea un bloque diferente dependiendo del tipo definido en la variable codebuild_artifacts_type
.
Leave a Comment