Bloques de configuración dinámicos en Terraform

1 minute read

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.

Referencias:

Leave a Comment