Despliegue de IA Search en Azure con Terraform y Terragrunt

Introducción

En esta serie, exploraremos cómo desplegar diversos recursos en Azure utilizando Terraform y Terragrunt. Comenzaremos con un componente fundamental del stack de inteligencia artificial: Azure AI Search.

Azure AI Search es un servicio de búsqueda en la nube que permite a los desarrolladores integrar capacidades avanzadas de búsqueda en aplicaciones y sitios web. Este servicio ofrece herramientas potentes para indexar, buscar y explorar grandes volúmenes de datos, facilitando la creación de experiencias de búsqueda personalizadas y eficientes. Azure AI Search combina búsqueda de texto completo, búsqueda de facetas, búsqueda geolocalizada y búsqueda impulsada por inteligencia artificial para ofrecer resultados relevantes y precisos a los usuarios. Su capacidad de escalar y adaptarse a diferentes necesidades empresariales lo convierte en una solución esencial para organizaciones que buscan mejorar la accesibilidad y utilidad de sus datos.

A lo largo de esta serie, abordaremos la configuración, despliegue y gestión de Azure AI Search mediante Terraform y Terragrunt, proporcionando ejemplos prácticos y explicaciones detalladas para ayudarte a implementar soluciones de búsqueda efectivas en tu entorno de Azure.

Estructura del Proyecto

Antes de sumergirnos en el código, es importante entender la estructura del proyecto. La organización del proyecto es la siguiente:

 
├── env
│   ├── code
│   │   └── iasearch
│   │       └── 00
│   │           ├── backend.tf
│   │           ├── data.tf
│   │           ├── endpoint.tf
│   │           ├── locals.tf
│   │           ├── main.tf
│   │           ├── outputs.tf
│   │           ├── provider.tf
│   │           └── variables.tf
│   └── dev
│       ├── iasearch
│       │   └── 00
│       │       ├── terragrunt.hcl
│       │       └── vars.tfvars
│       └── varEnvironment.hcl
├── varCommon.hcl
└── varDataState.hcl

La carpeta env contiene la configuración específica del entorno, mientras que code alberga los archivos de configuración de Terraform para el despliegue de Resource Group. La carpeta dev contiene archivos de configuración específicos del entorno de desarrollo. terragrunt.hclvarCommon.hcl y varDataState.hcl son archivos de configuración para Terragrunt y variables comunes.

Configuración de Terraform

Ahora, profundicemos en los archivos de configuración de Terraform necesarios para desplegar Azure AI Search.

backend.tf

Este archivo configura el backend de Terraform para almacenar el estado remoto en Azure.

 

terraform {
  backend "azurerm" {
  }
  required_version = "~>0.14"
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "3.47.0"
    }
  }
}

Explicación:

  • Este archivo comienza con un bloque terraform, que contiene la configuración global de Terraform.
  • Dentro del bloque terraform, hay un bloque backend específico para Azure (backend "azurerm"). Sin embargo, no se proporcionan detalles específicos sobre la configuración del backend de Azure en este bloque. Es probable que la configuración detallada, como la URL del almacenamiento de estado de Azure o las credenciales de acceso, se especifiquen en otro lugar del proyecto.
  • Se especifica que se requiere una versión mínima de Terraform compatible con la sintaxis ~>0.14. Esto significa que se necesitará una versión de Terraform igual o superior a 0.14, pero menor que 0.15.
  • El bloque required_providers especifica los proveedores de Terraform necesarios para este proyecto. En este caso, solo se necesita el proveedor de Azure (azurerm). La versión específica requerida es la 3.47.0, y se indica utilizando el atributo version. La URL de origen (source) indica dónde Terraform puede encontrar este proveedor. En este caso, se espera encontrarlo en hashicorp/azurerm.

 

data.tf

El archivo data.tf contiene bloques de datos que permiten a Terraform acceder a la información de recursos existentes en Azure. Estos bloques son fundamentales para reutilizar la infraestructura existente y garantizar que los nuevos recursos se implementen de manera coherente.

data "terraform_remote_state" "rg" {
  backend = "azurerm"
  config = {
    subscription_id      = var.lz_subscription_id      
    resource_group_name  = var.lz_resource_group_name  
    storage_account_name = var.lz_storage_account_name
    container_name       = var.lz_container_name       
    key                  = "${var.ProjectName}/${var.ServiceName}/env/${var.Environment}/${var.mapProjectPathKey.rg}/terraform.tfstate"
  }
}


data "terraform_remote_state" "sbnInt" {
  backend = "azurerm"
  config = {
    subscription_id      = var.lz_subscription_id     
    resource_group_name  = var.lz_resource_group_name  
    storage_account_name = var.lz_storage_account_name 
    container_name       = var.lz_container_name       
    key                  = "${var.ProjectName}/${var.ServiceName}/env/${var.Environment}/${var.mapProjectPathKey.sbn00}/terraform.tfstate"
  }
}

data "azurerm_private_dns_zone" "dns_private" {
  provider            = azurerm.hub
  name                = var.private_dns_zone_name_01
  resource_group_name = var.hub_resource_group_name
}

data "azurerm_resource_group" "rg_net" {
  name = var.vnet_resource_group
}

data "azurerm_virtual_network" "vnet" {
  name                = var.vnet_net_name
  resource_group_name = data.azurerm_resource_group.rg_net.name
}

data "azurerm_subnet" "sbn_data" {
  name                 = var.subnet_name
  virtual_network_name = data.azurerm_virtual_network.vnet.name
  resource_group_name  = data.azurerm_resource_group.rg_net.name
  
}


data "azurerm_resource_group" "hub_rg" {
  provider = azurerm.hub
  name     = var.hub_resource_group_name
}

data "azurerm_private_dns_zone" "zone_01" {
  provider            = azurerm.hub
  name                = var.private_dns_zone_name_01
  resource_group_name = data.azurerm_resource_group.hub_rg.name
}

data "azurerm_client_config" "current" {}

endpoint.tf

resource "azurerm_private_endpoint" "pren_01" {
  name                = upper(join("-", [ var.Environment, var.BussinessUnit, var.Provider, var.ServiceName,  "aisrh-pren-01"])) 
  resource_group_name = data.terraform_remote_state.rg.outputs.name
  location            = var.region
  subnet_id           = data.azurerm_subnet.sbn_data.id

  private_service_connection {
    name                           = upper(join("-", [ var.Environment, var.BussinessUnit, var.Provider, var.ServiceName,  "aisrh-pren-01"]))
    private_connection_resource_id = azurerm_search_service.mainresource_01.id
    is_manual_connection           = false
    subresource_names              = ["searchService"]
  }

  private_dns_zone_group {
    name                 = data.azurerm_private_dns_zone.zone_01.name
    private_dns_zone_ids = [data.azurerm_private_dns_zone.zone_01.id]
  }
  
  tags = local.tags

  lifecycle {
    ignore_changes = [
      tags["CreationDate"]
    ]
  }
}

Explicación:

Este código en Terraform se utiliza para acceder a información sobre recursos existentes en Azure y gestionar la infraestructura de manera efectiva. A través de varios bloques data, se obtienen datos cruciales como el estado remoto de la infraestructura (grupos de recursos, redes virtuales y zonas DNS privadas) almacenada en Azure.

  • Estado remoto: Los bloques terraform_remote_state permiten acceder a la configuración y el estado de recursos previos, esencial para reutilizar datos en múltiples configuraciones y evitar duplicaciones.

  • Zonas DNS privadas: Se configuran para facilitar la resolución de nombres dentro de la red virtual sin exponer servicios a internet, lo cual es vital para mantener la seguridad en una arquitectura de hub-and-spoke.

  • Grupos de recursos y redes: Los bloques de azurerm_resource_group, azurerm_virtual_network y azurerm_subnet se utilizan para obtener información sobre grupos de recursos y redes virtuales existentes, asegurando que los nuevos recursos se integren adecuadamente en la infraestructura.

endpoint.tf

endpoint.tf

resource "azurerm_private_endpoint" "pren_01" {
  name                = upper(join("-", [ var.Environment, var.BussinessUnit, var.Provider, var.ServiceName,  "aisrh-pren-01"])) 
  resource_group_name = data.terraform_remote_state.rg.outputs.name
  location            = var.region
  subnet_id           = data.azurerm_subnet.sbn_data.id

  private_service_connection {
    name                           = upper(join("-", [ var.Environment, var.BussinessUnit, var.Provider, var.ServiceName,  "aisrh-pren-01"]))
    private_connection_resource_id = azurerm_search_service.mainresource_01.id
    is_manual_connection           = false
    subresource_names              = ["searchService"]
  }

  private_dns_zone_group {
    name                 = data.azurerm_private_dns_zone.zone_01.name
    private_dns_zone_ids = [data.azurerm_private_dns_zone.zone_01.id]
  }
  
  tags = local.tags

  lifecycle {
    ignore_changes = [
      tags["CreationDate"]
    ]
  }
}

Explicación:

Este bloque de código de Terraform define un azurerm_private_endpoint llamado pren_01, que permite conectarse a un servicio privado dentro de Azure de manera segura y privada, sin exposición a Internet. Aquí se detallan los componentes clave:

  • Nombre del recurso: Se utiliza la función join("-", [...]) para crear un nombre en mayúsculas que combina varios parámetros como el entorno, la unidad de negocio, el proveedor, y el nombre del servicio, junto con un sufijo fijo ("aisrh-pren-01"). Esto asegura que el nombre del recurso sea descriptivo y uniforme.

  • Grupo de recursos y ubicación: Se especifica el grupo de recursos donde se implementará el endpoint utilizando el estado remoto y se establece la ubicación a partir de la variable var.region.

  • Conexión del servicio privado: Dentro de private_service_connection, se configura la conexión al recurso privado especificando el ID del recurso de conexión y se determina que la conexión no es manual. También se define el subrecurso como searchService, lo que indica que se conectará a un servicio de búsqueda de Azure.

  • Grupo de zonas DNS privadas: En private_dns_zone_group, se asigna el nombre y el ID de la zona DNS privada para asegurar que el endpoint esté correctamente registrado en el DNS, facilitando así el acceso a través de nombres en lugar de direcciones IP.

  • Etiquetas y ciclo de vida: Se asignan etiquetas al endpoint utilizando local.tags para la gestión de recursos y se define un ciclo de vida que ignora los cambios en la etiqueta CreationDate, evitando que Terraform considere estas modificaciones como un cambio en el recurso.

locals.tf

Aquí se definen las variables locales utilizadas en el proyecto.

 

locals {
  resource_name = lower(join("", [ var.Environment, var.BussinessUnit, var.Provider, var.ProjectName, "aisrh"]))
  tags = var.tags
}

Explicación:

En este fragmento de código de Terraform, se utilizan locales para definir valores reutilizables dentro de la configuración.

  • resource_name: Se crea una variable local llamada resource_name, que combina varios valores (var.Environment, var.BussinessUnit, var.Provider, var.ProjectName) y le agrega el sufijo "aisrh". La función join("", [...]) concatena estos elementos en una única cadena sin espacios, y lower(...) convierte el resultado a minúsculas. Este enfoque es útil para generar nombres de recursos que sigan un formato estándar y sean fáciles de identificar.

  • tags: La segunda variable local, tags, se asigna directamente al valor de var.tags. Esto permite agrupar y organizar recursos en Azure mediante etiquetas, facilitando la gestión y el seguimiento de costos y recursos.

main.tf

Este archivo define un recurso en Terraform para desplegar un servicio de Azure Cognitive Search (azurerm_search_service). Este servicio se utiliza para crear potentes capacidades de búsqueda en aplicaciones personalizadas en la nube. Vamos a desglosar cada parte del código para entender su propósito.

resource "azurerm_search_service" "mainresource_01" {
  name                = local.resource_name
  resource_group_name = data.terraform_remote_state.rg.outputs.name
  location            = local.locat

  sku = var.account_sku_name

  tags = local.tags

  lifecycle {
    ignore_changes = [
      tags["CreationDate"]
    ]
  }

}

Explicación:

Este bloque de código de Terraform define un azurerm_search_service llamado mainresource_01, que crea un servicio de búsqueda en Azure. A continuación se explican sus componentes principales:

  • Nombre del recurso: Se asigna el nombre del servicio de búsqueda utilizando local.resource_name, que se construye previamente en el archivo con base en diferentes variables del entorno y del proyecto, asegurando que el nombre sea único y representativo.

  • Grupo de recursos y ubicación: Se especifica el grupo de recursos donde se implementará el servicio de búsqueda, recuperando el nombre desde el estado remoto de Terraform. La ubicación del servicio se establece utilizando local.locat, que probablemente se define en la sección de variables locales del proyecto.

  • SKU del servicio: Se establece el SKU (Stock Keeping Unit) del servicio a partir de la variable var.account_sku_name, lo que determina la capacidad y características del servicio de búsqueda (por ejemplo, capacidad de almacenamiento, rendimiento, etc.).

  • Etiquetas: Se asignan etiquetas al recurso utilizando local.tags para facilitar la gestión, categorización y seguimiento del recurso dentro de Azure.

  • Ciclo de vida: En la sección lifecycle, se indica que se deben ignorar los cambios en la etiqueta CreationDate. Esto significa que si esta etiqueta se modifica, Terraform no considerará este cambio como una razón para recrear o actualizar el recurso.

output.tf

# IDs
output "id" {
    value = azurerm_search_service.mainresource_01.id
    description = "The ID of the Cognitive Service Account."
}

output "endpoint" {
    value = azurerm_search_service.mainresource_01.name
    description = "The endpoint used to connect to the Cognitive Service Account."
}

output "identity" {
    value = azurerm_search_service.mainresource_01.identity
    description = "An identity block as defined below."
}

Explicación:

Este bloque de código de Terraform define varias salidas (output) que permiten a los usuarios y otros módulos acceder a información clave sobre el servicio de búsqueda creado. A continuación se explican sus componentes principales:

  • Salida id: Esta salida devuelve el identificador único del servicio de búsqueda, azurerm_search_service.mainresource_01.id. Esto es útil para referenciar el recurso en otras configuraciones o módulos, proporcionando una forma sencilla de obtener su ID en el contexto de Azure.

  • Salida endpoint: Esta salida proporciona el nombre del servicio de búsqueda, azurerm_search_service.mainresource_01.name, que puede ser utilizado como el punto de conexión para interactuar con el servicio. Es esencial para las aplicaciones que necesitan comunicarse con el servicio de búsqueda, ya que define la URL que se utilizará para las solicitudes.

  • Salida identity: Esta salida devuelve el bloque de identidad del servicio de búsqueda, azurerm_search_service.mainresource_01.identity. Este bloque puede contener información relacionada con la identidad administrada del servicio, que es importante para la autenticación y autorización de acceso a otros recursos de Azure.

 

provider.tf

provider "azurerm" {
  subscription_id = var.Subscription
  tenant_id       = var.Tenant
  features {}
}

provider "azurerm" {
  alias           = "hub"
  subscription_id = var.subscription_hub_id
  tenant_id       = var.Tenant
  features {}
}

Explicación:

Este bloque de código de Terraform define dos proveedores de Azure Resource Manager (azurerm), que permiten gestionar recursos de Azure dentro de la configuración de Terraform.

  • Primer proveedor azurerm:

    • Se configura el proveedor principal para la gestión de recursos de Azure.
    • subscription_id: Hace referencia a la variable var.Subscription, que debe contener el ID de la suscripción de Azure donde se crearán los recursos.
    • tenant_id: Utiliza var.Tenant, que se refiere al ID del inquilino de Azure Active Directory correspondiente a la suscripción.
    • features {}: Se incluye un bloque vacío para especificar características adicionales del proveedor, aunque en este caso no se están configurando opciones específicas.
  • Segundo proveedor azurerm con alias:

    • Este proveedor se define con un alias hub, lo que permite utilizar múltiples instancias del mismo proveedor con configuraciones diferentes dentro de la misma configuración de Terraform.
    • subscription_id: Aquí se utiliza var.subscription_hub_id para apuntar a una suscripción diferente, facilitando la gestión de recursos en otra cuenta o contexto de Azure.
    • tenant_id: También utiliza la misma variable var.Tenant, asegurando que ambos proveedores estén conectados al mismo inquilino de Azure Active Directory.
    • features {}: Similar al primer proveedor, se incluye un bloque vacío para posibles configuraciones futuras.

variables.tf


######################
# VARIABLES COMUNES  #
######################

variable "lz_subscription_id" {
  type        = string
  description = "ID de la susbcriptcion de los tfstate"
  default     = ""
}

variable "lz_resource_group_name" {
  type        = string
  description = "Nombre del resoruce group de los tfstate"
  default     = ""
} 

variable "lz_storage_account_name" {
  type        = string
  description = "Nombre del storage account de los tfstate"
  default     = ""
}    

variable "lz_container_name" {
  type        = string
  description = "Nombre del container name de los tfstate"
  default     = ""
}

variable "Tenant" {
  type        = string
  description = "Nombre del tenant"
  default     = ""
}

variable "Subscription" {
  type        = string
  description = "Nombre de la subscripcion"
  default     = ""
}

variable "Provider" {
  type        = string
  description = "Nombre del Provider cloud"
  default     = ""
}

variable "Environment" {
  type        = string
  description = "(Required) Specifies the Environment where the Resources should exist."
  default     = ""
}

variable "BussinessUnit" {
  type        = string
  description = "(Required) Bussiness Unit."
  default     = ""
}

variable "ProjectName" {
  type        = string
  description = "(Required) ProjectName."
  default     = ""
}

variable "ServiceName" {
  type        = string
  description = "(Required) ServiceName."
  default     = ""
}

variable "mapProjectPathKey" {
  type        = map(string)
  default     = {}
  description = "Mapa de rutas de los elementos"
}

variable "region" {
  type        = string
  description = "(Required) Region Name"
  default     = ""
}

#############################
#   VARIABLES DATAS         #
#############################


variable "rg_net_name" {
  type        = string
  description = "Name rg of net"
  default = ""
}

variable "vnet_net_name" {
  type        = string
  description = "Name of vnet of net"
  default = ""
}

variable "vnet_resource_group" {
  type        = string
  description = "Name of rg of net"
  default = ""
}

variable "sbn_data_net_name" {
  type        = string
  description = "Name of Subnet Data of net"
  default = ""
}

variable "sbn_net_name" {
  type        = string
  description = "Name of Subnet Data of net"
  default = ""
}

variable "subnet_name" {
  type        = string
  description = "Name of subnet of net"
  default = ""
}

variable "EntityName" {
  type        = string
  description = "(Required) Entity."
  default     = ""
}

#####################
# VARIABLES RECURSO #
#####################

variable "resource_name" {
  type        = string
  description = "Name of resource"
  default = ""
}

variable "account_sku_name" {
  type        = string
  description = "Cognitive Account SKU"
  default = ""
}

variable "account_kind" {
  type        = string
  description = "Cognitive Account Kind"
  default = ""
}

######################
#   VARIABLE TAGS    #
######################

variable "tags" {
  type        = map(string)
  default     = {}
  description = "(Optional) A mapping of tags which should be assigned to the Resource Group."
}

##########################
# Variables Provider HUB #
##########################

variable "hub_resource_group_name" {
  type    = string
  default = ""
  description = "Nombre del resource group de HUB"
}

variable "private_dns_zone_name_01" {
  type    = string
  default = ""
  description = "Nombre del private dns zone name de HUB"
}

variable "private_dns_zone_name_02" {
  type    = string
  default = ""
  description = "Nombre del private dns zone name de HUB"
}

variable "virtual_network_appgw_name" {
  type    = string
  default = ""
  description = "Nombre del network appgw de HUB"
}

variable "subnet_appgw_name" {
  type    = string
  default = ""
  description = "Nombre del subnet appgw de HUB"
}

variable "subscription_hub_id" {
  type    = string
  default = ""
  description = "Nombre de la subscripcion de HUB"
}

Explicación:

El bloque de código anterior define una serie de variables en Terraform, organizadas en varias secciones para facilitar su gestión y comprensión. A continuación, se resumen las secciones y el propósito de cada variable:

  • Variables Comunes: Estas variables establecen configuraciones generales que son utilizadas en varios recursos y módulos de Terraform, como el ID de suscripción (lz_subscription_id), el nombre del grupo de recursos (lz_resource_group_name), y el nombre de la cuenta de almacenamiento (lz_storage_account_name), entre otras. La mayoría de ellas tienen un valor por defecto vacío.
  • Variables de Datos: Aquí se definen variables relacionadas con redes, como el nombre del grupo de recursos de la red (rg_net_name), el nombre de la red virtual (vnet_net_name), y el nombre de la subred (subnet_name). Estas variables son esenciales para configurar la infraestructura de red.
  • Variables de Recursos: Incluyen variables específicas para recursos que se van a crear, como el nombre del recurso (resource_name) y el SKU de la cuenta cognitiva (account_sku_name).
  • Variables de Etiquetas: Esta sección permite definir un mapa de etiquetas (tags), que se pueden asignar a recursos para facilitar su gestión y clasificación en Azure.
  • Variables para el Proveedor HUB: Estas variables son específicas para la configuración de un proveedor que gestiona recursos en un entorno de hub. Incluyen el nombre del grupo de recursos de HUB y el nombre de las zonas DNS privadas.

Configuración de Terragrunt

Por último, echemos un vistazo a la configuración de Terragrunt para manejar la infraestructura de manera eficiente.

terragrunt.hcl

Este archivo especifica las dependencias y configura la ejecución de Terraform.

 


dependencies {
  paths = [
    "../../rg/00/",
     ]
}

include "varEnvironment" {
  path = find_in_parent_folders("varEnvironment.hcl")
  expose = true
}

include "varCommon" {
  path = find_in_parent_folders("varCommon.hcl")
  expose = true
}

include "varDataState" {
  path = find_in_parent_folders("varDataState.hcl")
  expose = true
}

locals {
  #acm = yamldecode(file(find_in_parent_folders("config.yaml"))).dataAcm
  mapProjectPathKey = jsonencode(include.varEnvironment.inputs.mapProjectPathKey)
  tags = jsonencode(merge({
    Managed_By = "Terraform"
    Provider = "AZR"
  },
  include.varCommon.inputs.globalTags,
  include.varEnvironment.inputs.environmentTags
  ))
}

generate "backend"{
  path      = "backend.tfvars"
  if_exists = "overwrite" # "overwrite" "skip" "overwrite_terragrunt" 
  contents = <<EOF
subscription_id = "${include.varDataState.inputs.lz_subscription_id}"
key = "${include.varCommon.inputs.ProjectName}/${include.varCommon.inputs.ServiceName}/${get_path_from_repo_root()}/terraform.tfstate"
resource_group_name = "${include.varDataState.inputs.lz_resource_group_name}"
storage_account_name =  "${include.varDataState.inputs.lz_storage_account_name}"
container_name = "${include.varDataState.inputs.lz_container_name}"
EOF
}

generate "vars"{
  path      = "vars.tfvars"
  if_exists = "overwrite" #"skip" #"overwrite_terragrunt"
  contents = <<EOF
###############################
#    VALORES DATA DataState     #
###############################
lz_subscription_id             = "${include.varDataState.inputs.lz_subscription_id}"
lz_resource_group_name         = "${include.varDataState.inputs.lz_resource_group_name}" 
lz_storage_account_name        = "${include.varDataState.inputs.lz_storage_account_name}" 
lz_container_name              = "${include.varDataState.inputs.lz_container_name}" 

###############################
#     VALORES GENERALES       #
###############################
region  = "${include.varEnvironment.inputs.region}"
Environment = "${include.varEnvironment.inputs.Environment}"
BussinessUnit = "${include.varCommon.inputs.BussinessUnit}"
ProjectName = "${include.varCommon.inputs.ProjectName}"
ServiceName = "${include.varCommon.inputs.ServiceName}"
EntityName = "${include.varCommon.inputs.EntityName}"
Subscription = "${include.varEnvironment.inputs.Subscription}"
Tenant = "${include.varCommon.inputs.Tenant}"
# ApplicationName = null
mapProjectPathKey = ${local.mapProjectPathKey}

##################################
# Valores Container Provider HUB #
##################################

hub_resource_group_name = "PRO-HUB-01"
private_dns_zone_name_01 = "privatelink.search.windows.net"
subscription_hub_id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

###################
# Valores Recurso #
###################

resource_name = "aisrh01"
location = "swedencentral"

vnet_resource_group = "${include.varEnvironment.inputs.rg_net_name}"
vnet_net_name = "${include.varEnvironment.inputs.vnet_net_name}"
subnet_name = "${include.varEnvironment.inputs.sbn_front_net_name}"

account_sku_name = "standard"

###########################
#       VALORES TAGS      #
###########################

tags = ${local.tags}

EOF
}

terraform {
  source = "../../..//code/iasearch/00/"

  before_hook "print_tags" {
    commands = ["plan", "apply"] #["${get_terraform_commands_that_need_vars()}"]
    execute  = ["echo", "tags", "=", "${local.tags}", ">", "vars.tfvars"]
  }

  before_hook "copy_vars" {
    commands = ["plan", "apply"] #["${get_terraform_commands_that_need_vars()}"]
    execute  = ["cp", "-f", "vars.tfvars", "${get_original_terragrunt_dir()}/vars.tfvars"]
  }

  extra_arguments "backend_vars" {
    commands = ["init"]
    arguments = [
      "-backend-config=backend.tfvars"
    ]
  }
  extra_arguments "vars_vars" {
    commands = ["plan", "apply", "destroy", "import"]

    arguments = [
      "-var-file=vars.tfvars"
    ]
  }
}
  • dependencies: Este bloque define las dependencias del Terragrunt. En este caso, no se especifican rutas de dependencias, ya que el bloque paths está vacío.
  • include: Estos bloques incluyen archivos de variables externos (varEnvironment.hclvarCommon.hclvarDataState.hcl) en el Terragrunt. Los archivos incluidos pueden exponer sus variables para ser utilizadas en este archivo Terragrunt.
  • locals: Este bloque define variables locales que se utilizan dentro de este archivo Terragrunt.
  • mapProjectPathKey: Codifica como JSON el mapa mapProjectPathKey del archivo varEnvironment.hcl.
  • tags: Codifica como JSON un conjunto de etiquetas combinando un conjunto fijo de etiquetas (Managed_By y Provider), las etiquetas globales definidas en varCommon.hcl y las etiquetas específicas del entorno definidas en varEnvironment.hcl.
  • generate "backend": Este bloque genera un archivo llamado backend.tfvars. Este archivo se utiliza para configurar el backend de Terraform. Contiene variables como subscription_idkeyresource_group_namestorage_account_name, y container_name. Los valores de estas variables se obtienen de los archivos incluidos (varDataState.hcl y varCommon.hcl).
  • generate "vars": Este bloque genera un archivo llamado vars.tfvars. Este archivo se utiliza para proporcionar valores de variables a Terraform. Contiene valores para las variables específicas definidas en los archivos incluidos (varDataState.hclvarCommon.hclvarEnvironment.hcl). Los valores se interpolan a partir de las variables incluidas.
  • terraform: Este bloque proporciona configuraciones adicionales para Terraform.
  • source: Especifica la ruta de origen del módulo de Terraform. En este caso, el origen se establece en un directorio relativo ../../..//code/rg/00/.
  • before_hook: Este bloque define ganchos de ejecución que se ejecutarán antes de ciertos comandos de Terraform, como plan y apply. En este caso, se ejecutan dos ganchos: print_tags y copy_vars.
  • extra_arguments: Este bloque especifica argumentos adicionales que se pasarán a los comandos de Terraform (initplanapplydestroyimport). En este caso, se especifican argumentos adicionales para la configuración del backend (backend_vars) y para las variables (vars_vars).

varEnvironment.hcl

locals {
  subscription_hub_id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
  hub_resource_group_name = "PRO-NWHUB-RGP-01"
  region = "northeurope"
  Subscription = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
  Environment = "dev"
  MoebiusMetal = "BRONCE"
  rg_net_name = "DEV-REDORBITA-RG-01"
  vnet_net_name = "DEV-REDORBITA-NET-01"
  subnet_name  = "DEV-REDORBITA-SBN-01"
  mapProjectPathKey = {
    rg = "rg/00"
    sbn00 = "networking/sbn/sbn00"
  }
}

inputs = {
    ##############################
    #   VARIABLES Environment    #
    ##############################
    subscription_hub_id = local.subscription_hub_id
    hub_resource_group_name = local.hub_resource_group_name
    vnet_net_name = local.vnet_net_name
    subnet_name = local.subnet_name
    rg_net_name = local.rg_net_name
    Subscription = local.Subscription
    region = local.region
    #profile = local.profile
    Environment = local.Environment
    environmentTags = {
        Enviroment         = "${upper(local.Environment)}"
        MoebiusMetal        = local.MoebiusMetal
    }
    mapProjectPathKey = local.mapProjectPathKey
}

Variables Locales (locals):

  • Se definen variables que pueden ser utilizadas en todo el archivo. Esto incluye identificadores de suscripción, nombres de grupos de recursos, configuraciones de red y más.
  • Identificadores de Suscripción: subscription_hub_id y Subscription son críticos para la autenticación y la gestión de recursos en Azure.
  • Nombres de Recursos: Los nombres de grupos de recursos, redes virtuales y subredes se establecen para facilitar la gestión y referencia en el código.
  • Mapas de Proyecto: mapProjectPathKey permite definir rutas de acceso a diferentes componentes de la infraestructura, lo que puede facilitar la reutilización de código y la navegación en el proyecto.

Entradas (inputs):

  • Se define un mapa de entradas que se utilizarán en los módulos de Terraform. Cada entrada corresponde a una variable local, lo que permite que los módulos reciban valores configurados de manera centralizada.
  • Etiquetas del Entorno: environmentTags se utiliza para definir etiquetas que se aplicarán a los recursos. Las etiquetas son útiles para la clasificación, gestión y facturación de recursos en Azure.

varCommon.hcl y varDataState.hcl
Estos archivos contienen variables comunes y específicas del estado de los datos para Terragrunt.

varDataState.hcl


locals {
  #common_vars = yamldecode(file(find_in_parent_folders("config.yaml")))
  lz_subscription_id      = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
  lz_resource_group_name  = "PRO-TF-DATA-RG-01"
  lz_storage_account_name = "protfdata"
  lz_container_name       = "iasearch"
  path_resources_terraform_state = jsonencode({
    rg = "rg/00"

})
}

inputs = {
##############################
#  VARIABLES FOR DATA STATES #
##############################
lz_subscription_id      = local.lz_subscription_id
lz_resource_group_name  = local.lz_resource_group_name
lz_storage_account_name = local.lz_storage_account_name
lz_container_name       = local.lz_container_name
path_resources_terraform_state = local.path_resources_terraform_state
}

varCommon.hcl


locals {
  #common_vars = yamldecode(file(find_in_parent_folders("config.yaml")))
  EntityName              = "RO"
  ProjectName             = "RedOrbita"
  ServiceName             = "RedOrbita"
  BussinessUnit           = "XX"
  Subscription            = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
  Tenant                  = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
  Provider                = "azr"
  required_version = "~>0.14"
  globalTags = {
      Company             = "Red-Orbita"
      Owner               = "xxxx@redorbita.com"
      MoebiusURGestion    = "False"
      ProjectName         = "XXXX"
      "Service Description" = "XXXX"
      Status              = "Implementacion"
      Provider            = "Azure"
      Cluster             = "N/A"
      "Operating System"  = "N/A"
      Temporal            = "NO"
      "App ID"              = "N/A"
    }
  storage_account          = "protfdata"
  container_name           = "iasearch" 
  subscription_hub_id2     = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
  location                 = "northeurope"
}



inputs = {
  ##############################
  #  VARIABLES COMMON          #
  ##############################

  EntityName              = local.EntityName
  ProjectName             = local.ProjectName
  ServiceName             = local.ServiceName
  BussinessUnit           = local.BussinessUnit
  Subscription            = local.Subscription
  Tenant                  = local.Tenant
  Provider                = local.Provider
  required_version        = local.required_version
  globalTags              = local.globalTags
}

Valores Locales:

  • EntityName: Nombre de la entidad configurada como «RedOrbita».
  • ProjectName: Nombre del proyecto configurado como «OpenAI».
  • ServiceName: Nombre del servicio configurado como «OpenAI».
  • BussinessUnit: Unidad de negocio configurada como «chatgpt».
  • BussinessUnitExtended: Unidad de negocio extendida configurada como «infra».
  • Tenant: Identificación del inquilino configurada como «XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX».
  • Provider: Proveedor configurado como «azr».
  • required_version: Versión de Terraform requerida configurada como «~>0.14».
  • id_project: Identificación del proyecto configurada como «XXXXXXXX».
  • globalTags: Conjunto de etiquetas globales que incluyen metadatos sobre el proyecto, como el nombre del proyecto, la empresa, la descripción del servicio, la identificación SSR-NSSR, la conformidad, la confidencialidad, la integridad, la disponibilidad, la criticidad y el alias del servicio.

Entradas:

  • EntityName: Nombre de la entidad obtenido del valor local EntityName.
  • ProjectName: Nombre del proyecto obtenido del valor local ProjectName.
  • ServiceName: Nombre del servicio obtenido del valor local ServiceName.
  • BussinessUnit: Unidad de negocio obtenida del valor local BussinessUnit.
  • BussinessUnitExtended: Unidad de negocio extendida obtenida del valor local BussinessUnitExtended.
  • Tenant: Identificación del inquilino obtenida del valor local Tenant.
  • Provider: Proveedor obtenido del valor local Provider.
  • required_version: Versión de Terraform requerida obtenida del valor local required_version.
  • id_project: Identificación del proyecto obtenida del valor local id_project.
  • globalTags: Conjunto de etiquetas globales obtenido del valor local globalTags.

:wq!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *