Despliegue de Servicios Cognitivos de Azure OpenAI con Terraform y Terragrunt

En el emocionante mundo de la IA, los servicios cognitivos son esenciales para impulsar aplicaciones innovadoras y transformadoras. OpenAI Azure ofrece una gama de servicios cognitivos que permiten a los desarrolladores integrar con facilidad capacidades de IA avanzadas en sus aplicaciones. No obstante, los desafíos de desplegar y gestionar estos servicios en la nube pueden ser considerables. Aquí es donde herramientas como Terraform y Terragrunt entran en juego, ofreciendo una forma eficiente y consistente de gestión de la infraestructura como código. En este blog, exploraremos cómo utilizar Terraform y Terragrunt para desplegar rápidamente servicios cognitivos de OpenAI Azure de una manera sencilla y repetible, desde la definición de la infraestructura hasta la gestión de dependencias y la configuración del entorno. Descubriremos cómo estas herramientas pueden simplificar todo el proceso de despliegue y garantizar una gestión eficiente de los recursos en la nube.

Información relevante :

Estructura del Proyecto

Antes de profundizar en el código, es importante entender la estructura del proyecto. El proyecto está organizado de la siguiente manera:

├── env
│   ├── code
│   │   └── cognitive
│   │       └── 00
│   │           ├── backend.tf
│   │           ├── data.tf
│   │           ├── endpoint.tf
│   │           ├── locals.tf
│   │           ├── main.tf
│   │           ├── outputs.tf
│   │           ├── provider.tf
│   │           └── variables.tf
│   └── dev
│       ├── cognitive
│       │   └── 00
│       │       ├── terragrunt.hcl
│       │       └── vars.tfvars
│       └── varEnvironment.hcl
├── terragrunt.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 Azure OpenAI. La carpeta dev contiene archivos de configuración específicos del entorno de desarrollo. terragrunt.hcl, varCommon.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 para desplegar Azure OpenAI:

backend.tf

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

// backend.tf

terraform {
  backend "azurerm" {
    // Configuración del backend de Azure
  }
  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

Aquí se definen los datos necesarios para la configuración, como la suscripción de Azure y los detalles del recurso.


#State rg
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"
  }
}

# State sbnInt
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.sbnVint00}/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" {}

Explicación:

  • Se definen dos recursos de datos terraform_remote_state con los alias rg y sbnInt. Estos recursos se utilizan para recuperar el estado remoto de otros proyectos de Terraform.
  • Se configura el backend de Azure para ambos recursos de datos.
  • Se especifican las configuraciones específicas del backend para cada recurso de datos, incluyendo detalles como la suscripción de Azure, el grupo de recursos, la cuenta de almacenamiento, el contenedor y la clave del estado remoto.
  • Se definen recursos de datos para obtener información sobre una zona DNS privada en Azure (azurerm_private_dns_zone), un grupo de recursos (azurerm_resource_group), una red virtual (azurerm_virtual_network), una subred (azurerm_subnet) y otra zona DNS privada (azurerm_private_dns_zone). Estos recursos se utilizan para obtener detalles sobre los recursos existentes en Azure.
  • Se define un recurso de datos azurerm_client_config para obtener la configuración del cliente de Azure. Este recurso se utiliza para obtener información sobre la configuración de autenticación y autorización utilizada por Terraform para interactuar con Azure.

endpoint.tf

Este archivo configura los puntos finales privados en Azure para el servicio de OpenAI.

Explicación:

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

  private_service_connection {
    name                           = upper(join("-", [ var.Environment, var.BussinessUnit, var.Provider, var.ServiceName,  "openai-pren-01"]))
    private_connection_resource_id = azurerm_cognitive_account.openai.id
    is_manual_connection           = false
    subresource_names              = ["account"]
  }

  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"]
    ]
  }
}
  • Se define un recurso de Azure llamado azurerm_private_endpoint con el nombre de alias pren_01. Este recurso representa un punto de conexión privado en Azure.
  • Se especifican los atributos del recurso:
    • name: Define el nombre del punto de conexión privado. Se genera utilizando la función upper(join(...)), que concatena varias variables y las convierte a mayúsculas.
    • resource_group_name: Especifica el nombre del grupo de recursos donde se creará el punto de conexión privado. Se toma del resultado del estado remoto definido en data.terraform_remote_state.rg.outputs.name.
    • location: Especifica la ubicación geográfica donde se creará el punto de conexión privado, en este caso, «swedencentral».
    • subnet_id: Especifica la ID de la subred en la que se ubicará el punto de conexión privado. Se toma del resultado del recurso de datos data.azurerm_subnet.sbn_data.id.
  • Se define un bloque private_service_connection para configurar la conexión al servicio privado. Se especifican detalles como el nombre de la conexión, la ID del recurso del servicio privado, si la conexión es manual y los subrecursos involucrados.
  • Se define un bloque private_dns_zone_group para asociar el punto de conexión privado a un grupo de zonas DNS privadas. Se especifica el nombre del grupo y las IDs de las zonas DNS privadas asociadas.
  • Se definen etiquetas para el recurso utilizando la variable local tags.
  • Se utiliza el bloque lifecycle para ignorar cambios específicos en el ciclo de vida del recurso, en este caso, la etiqueta «CreationDate». Esto significa que Terraform ignorará cualquier cambio en la fecha de creación del recurso.

locals.tf

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

locals {
  private_endpoint_name = upper(join("-", [ var.Environment, var.BussinessUnit, var.Provider, var.ProjectName, "db-pren-01"])) #
  openai_name = lower(join("", [  var.EnvironmentLetter, "ev", var.BussinessUnit, var.Provider, var.ProjectName, var.openai_name ]))
  openai_deployment_name = lower(join("", [  var.EnvironmentLetter, "ev", var.BussinessUnit, var.Provider, var.ProjectName, var.openai_name ]))
  tags = var.tags
}

Explicación:

  • Se define un bloque locals que se utiliza para definir variables locales dentro de un módulo de Terraform. Estas variables locales se pueden utilizar en todo el módulo para simplificar la escritura y hacer que el código sea más legible.
  • Se definen tres variables locales:
    • private_endpoint_name: Define el nombre del punto de conexión privado. Se genera utilizando la función upper(join(...)), que concatena varias variables y las convierte a mayúsculas. La estructura del nombre sigue el formato definido por las variables de entorno, unidad de negocio, proveedor, nombre del proyecto y una cadena constante «db-pren-01».
    • openai_name: Define el nombre de un servicio de OpenAI. Se genera utilizando la función lower(join(...)), que concatena varias variables y las convierte a minúsculas. La estructura del nombre sigue el formato definido por la letra de entorno, «ev» como constante, unidad de negocio, proveedor, nombre del proyecto y una variable var.openai_name.
    • openai_deployment_name: Define el nombre de un despliegue de OpenAI. Es similar a openai_name y sigue la misma estructura.
    • tags: Asigna el valor de la variable var.tags a la variable local tags. Esto se hace para poder utilizar las etiquetas definidas en el archivo de configuración principal (variables.tf) en todo el módulo.

main.tf

Este archivo contiene la configuración principal para el despliegue del servicio de Azure OpenAI.



resource "azurerm_cognitive_account" "openai" {
  name                = local.openai_name
  location            = var.region
  resource_group_name = data.terraform_remote_state.rg.outputs.name
  kind                = var.oponai_kind
  sku_name            = var.openai_sku_name
  
  tags = local.tags
  lifecycle {
    ignore_changes = [
      tags["CreationDate"]
    ]
  }
  
}

resource "azurerm_cognitive_deployment" "openai_deployment-gpt-35-turbo" {
  name                 =  local.openai_deployment_name
  cognitive_account_id = azurerm_cognitive_account.openai.id
  model {
    format  = var.oponai_kind
    name    = "gpt-35-turbo"
    version = "0301"
  }

  scale {
    type = "Standard"
  }

    depends_on = [azurerm_cognitive_account.openai]

}



resource "azurerm_cognitive_deployment" "openai_deployment-gpt-4-vision" {
  name                 =  local.openai_deployment_name
  cognitive_account_id = azurerm_cognitive_account.openai.id
  model {
    format  = var.oponai_kind
    name    = "GPT-4-Vision"
    version = "1"
  }

  scale {
    type = "Standard"
  }

    depends_on = [azurerm_cognitive_account.openai]

}

Explicación:

  • Se definen tres recursos de Azure relacionados con servicios cognitivos de OpenAI. Estos recursos permiten crear y gestionar cuentas y despliegues de modelos de OpenAI en Azure.

Recurso azurerm_cognitive_account (openai):

  • Se define una cuenta cognitiva de Azure mediante el bloque resource.
  • Se especifican los atributos del recurso:
    • name: Define el nombre de la cuenta cognitiva. Se toma de la variable local local.openai_name.
    • location: Especifica la ubicación geográfica donde se creará la cuenta cognitiva. Se toma de la variable var.region.
    • resource_group_name: Especifica el nombre del grupo de recursos donde se creará la cuenta cognitiva. Se toma del resultado del estado remoto definido en data.terraform_remote_state.rg.outputs.name.
    • kind: Define el tipo de cuenta cognitiva, especificado por la variable var.oponai_kind.
    • sku_name: Define el nombre del SKU (Stock Keeping Unit) para la cuenta cognitiva. Se toma de la variable var.openai_sku_name.
    • tags: Asigna el valor de la variable local local.tags como etiquetas para el recurso.
    • lifecycle: Se define el bloque lifecycle para ignorar cambios específicos en el ciclo de vida del recurso, en este caso, la etiqueta «CreationDate».

Recursos azurerm_cognitive_deployment (openai_deployment-gpt-35-turbo y openai_deployment-gpt-4-vision):

  • Se definen dos recursos para despliegues de modelos cognitivos de OpenAI mediante el bloque resource.
  • Cada recurso representa un despliegue específico de un modelo de OpenAI.
  • Se especifican los atributos de cada recurso, como el nombre del despliegue (name), la ID de la cuenta cognitiva asociada (cognitive_account_id) y detalles del modelo, como el formato (format), el nombre (name) y la versión (version).
  • Ambos recursos dependen del recurso de cuenta cognitiva azurerm_cognitive_account.openai, lo que significa que el despliegue no se realizará hasta que la cuenta cognitiva esté completamente creada.

provider.tf

Aquí se configuran los proveedores de Terraform, incluido Azure.

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

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

Explicación:

  • Se definen dos bloques de proveedores de Azure con el proveedor azurerm. Estos bloques establecen la conexión y la autenticación con la API de Azure para gestionar recursos en la nube de Azure.
provider "azurerm" {
  subscription_id = var.Subscription
  tenant_id       = var.Tenant
  features {
    key_vault {
      purge_soft_delete_on_destroy = true
    }
  }
}

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

Explicación

Proveedor Principal:

  • El primer bloque de proveedor no tiene alias, lo que significa que es el proveedor principal utilizado en el archivo de configuración.
  • Se especifican los atributos del proveedor:
    • subscription_id: Define el ID de la suscripción de Azure que se utilizará para este proveedor. Se toma de la variable var.Subscription.
    • tenant_id: Define el ID del inquilino de Azure (también conocido como ID de directorio) que se utilizará para este proveedor. Se toma de la variable var.Tenant.
    • features: Este bloque se utiliza para configurar características específicas del proveedor. En este caso, se configura la característica key_vault, que afecta a los servicios de Key Vault de Azure. Se establece purge_soft_delete_on_destroy en true, lo que significa que los secretos eliminados suavemente se purgarán automáticamente cuando se elimine la instancia de Key Vault.

Proveedor con Alias:

  • El segundo bloque de proveedor tiene el alias «hub», lo que permite distinguirlo del proveedor principal y se puede utilizar para referirse a este proveedor específico en otros bloques de recursos o datos.
  • Se especifican los mismos atributos que en el primer bloque de proveedor, pero con diferentes valores:
    • subscription_id: Define el ID de la suscripción de Azure que se utilizará para este proveedor. Se toma de la variable var.subscription_hub_id.
    • tenant_id: Define el ID del inquilino de Azure (también conocido como ID de directorio) que se utilizará para este proveedor. Se toma de la variable var.Tenant.
  • No se configuran características específicas en este bloque de proveedor, por lo que el bloque features está vacío. Esto significa que se utilizarán las configuraciones predeterminadas para las características del proveedor.

variables.tf

En este archivo se definen las variables necesarias para la configuración.



######################
# 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 "EnvironmentLetter" {
  type        = string
  description = "(Required) Specifies the Environment letter 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 "EntityName" {
  type        = string
  description = "(Required) Entity."
  default     = ""
}

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

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


variable "principal_name" {
  type        = string
  description = "(Required) Principal name"
  default     = ""
}


variable "principal_type" {
  type        = string
  description = "(Required) Principal type"
  default     = ""
}

variable "object_id" {
  type        = string
  description = "(Required) Object id"
  default     = ""
}

variable "private_endpoint_name" {
  type = string
  description = "Private endpoint name"
  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 "azuread_group" {
#   type    = string
#   default = ""
#   description = "Nombre del de grupo de AD para acceso a SQL Server"
# }

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 "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"
}

################
#  OpenAI  #
################

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

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

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

variable "openai_name" {
  type        = string
  description = "(Required) Database Name"
  default     = ""
}


variable "openai_sku_name" {
  type        = string
  description = "(Required) Database sku tier"
  default     = ""
}

variable "oponai_kind" {
  type        = string
  description = "(Required) Database kind tier"
  default     = ""
}

variable "openai_type_name" {
  type        = string
  description = "(Required) opoenAI type "
  default     = ""
}

variable "openai_version" {
  type        = string
  description = "(Required) opoenAI version"
  default     = ""
}


Explicación


VARIABLES COMUNES:

  • lz_subscription_id: Representa el ID de la suscripción para los tfstate.
  • lz_resource_group_name: Indica el nombre del grupo de recursos para los tfstate.
  • lz_storage_account_name: Define el nombre de la cuenta de almacenamiento para los tfstate.
  • lz_container_name: Especifica el nombre del contenedor para los tfstate.
  • Tenant: Se refiere al nombre del inquilino.
  • Subscription: Representa el nombre de la suscripción.
  • Provider: Define el nombre del proveedor de la nube.
  • Environment: Especifica el entorno donde deben existir los recursos.
  • EnvironmentLetter: Especifica la letra de entorno donde deben existir los recursos.
  • BussinessUnit: Representa la unidad de negocio.
  • ProjectName: Indica el nombre del proyecto.
  • ServiceName: Se refiere al nombre del servicio.
  • EntityName: Representa la entidad.
  • mapProjectPathKey: Es un mapa de rutas de los elementos.
  • region: Es el nombre de la región.
  • principal_name: Indica el nombre del principal.
  • principal_type: Representa el tipo de principal.
  • object_id: Es el ID del objeto.
  • private_endpoint_name: Es el nombre del punto de conexión privado.

VARIABLE TAGS:

  • tags: Es un mapeo de etiquetas que se asignarán al grupo de recursos.

Variables Provider HUB:

  • hub_resource_group_name: Representa el nombre del grupo de recursos de HUB.
  • private_dns_zone_name_01: Indica el nombre de la zona DNS privada de HUB.
  • virtual_network_appgw_name: Es el nombre de la red virtual de Application Gateway de HUB.
  • subnet_appgw_name: Se refiere al nombre de la subred de Application Gateway de HUB.
  • subscription_hub_id: Es el ID de la suscripción de HUB.

OpenAI:

  • vnet_resource_group: Representa el nombre del grupo de recursos de la red.
  • vnet_net_name: Es el nombre de la red virtual de la red.
  • subnet_name: Se refiere al nombre de la subred de la red.
  • openai_name: Indica el nombre de la base de datos.
  • openai_sku_name: Es el nivel de SKU de la base de datos.
  • oponai_kind: Representa el nivel de tipo de base de datos.
  • openai_type_name: Especifica el tipo de OpenAI.
  • openai_version: Es la versión.

output.tf

Aquí se definen las salidas del despliegue para obtener información útil después del despliegue.

output "id" {
    value = azurerm_cognitive_account.openai.id
    description = "The ID of the OpenAI."
}

Explicación

  • output "id": Esto define el nombre de la salida. En este caso, la salida se llama «id».
  • value = azurerm_cognitive_account.openai.id: Esta línea establece el valor de la salida. Utiliza la interpolación para acceder al ID del recurso azurerm_cognitive_account llamado openai.
  • description = "The ID of the OpenAI.": Proporciona una descripción para la salida. En este caso, describe lo que representa el valor de la salida, que es el ID de la instancia de OpenAI.

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/",
    "../../networking/sbn/vint00"
  ]
}

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 OpenAI             #
###############################

oponai_kind = "OpenAI"
openai_sku_name = "S0"



vnet_resource_group = "${include.varEnvironment.inputs.NetworkResourceGroup}"
vnet_net_name = "${include.varEnvironment.inputs.Network}"
subnet_name = "${include.varEnvironment.inputs.SubnetworkData}"

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

hub_resource_group_name = "PRO-HUB-01"
private_dns_zone_name_01 = "privatelink.openai.azure.com"
subscription_hub_id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

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

tags = ${local.tags}

EOF
}

terraform {
  source = "../../..//code/cognitive/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"
    ]
  }
}

Explicación

  • dependencies: Este bloque define las dependencias del módulo, indicando las rutas donde se encuentran otros módulos en los que este módulo depende.
  • include «varEnvironment»: Incluye el archivo varEnvironment.hcl, que contiene variables específicas del entorno.
  • path = find_in_parent_folders(«varEnvironment.hcl»): Especifica la ruta donde se encuentra el archivo varEnvironment.hcl.
  • expose = true: Permite exponer las variables definidas en el archivo incluido para que puedan ser utilizadas por otros módulos.
  • include «varCommon»: Incluye el archivo varCommon.hcl, que contiene variables comunes.
  • path = find_in_parent_folders(«varCommon.hcl»): Especifica la ruta donde se encuentra el archivo varCommon.hcl.
  • expose = true: Permite exponer las variables definidas en el archivo incluido para que puedan ser utilizadas por otros módulos.
  • include «varDataState»: Incluye el archivo varDataState.hcl, que contiene variables relacionadas con el estado de los datos.
  • path = find_in_parent_folders(«varDataState.hcl»): Especifica la ruta donde se encuentra el archivo varDataState.hcl.
  • expose = true: Permite exponer las variables definidas en el archivo incluido para que puedan ser utilizadas por otros módulos.
  • locals: Este bloque define variables locales que pueden ser utilizadas en este módulo.
  • mapProjectPathKey = jsonencode(include.varEnvironment.inputs.mapProjectPathKey): Codifica como JSON el mapa de rutas de los elementos definidos en el archivo varEnvironment.hcl.
  • tags = jsonencode(merge({…})): Codifica como JSON un conjunto de etiquetas combinando etiquetas específicas del entorno y etiquetas globales definidas en los archivos incluidos.
  • generate «backend»: Este bloque genera un archivo llamado backend.tfvars con la configuración para el backend de Terraform.
  • path = «backend.tfvars»: Indica el nombre y la ubicación del archivo generado.
  • contents: Define el contenido del archivo generado utilizando interpolación para incluir las variables de otros archivos incluidos.
  • generate «vars»: Este bloque genera un archivo llamado vars.tfvars con las variables necesarias para la configuración del entorno.
  • path = «vars.tfvars»: Indica el nombre y la ubicación del archivo generado.
  • contents: Define el contenido del archivo generado utilizando interpolación para incluir las variables de otros archivos incluidos.
  • terraform: Este bloque define la configuración de Terraform:
    • source: Este atributo especifica la ubicación del código fuente del directorio Terraform que se utilizará. En este caso, el código fuente se encuentra en la ruta ../../..//code/cognitive/00/.
    • before_hook: Este bloque define hooks que se ejecutarán antes de ciertos comandos de Terraform, como plan y apply. En este caso, hay dos hooks definidos:
      • El primero (print_tags) ejecuta un comando que imprime las etiquetas (tags) y las redirige a un archivo llamado vars.tfvars.
      • El segundo (copy_vars) copia el archivo vars.tfvars a otro directorio utilizando el comando cp.
    • extra_arguments: Este bloque permite definir argumentos adicionales que se pasarán a ciertos comandos de Terraform. En este caso, se definen dos conjuntos de argumentos adicionales:
      • backend_vars: Argumentos adicionales que se pasarán al comando init. Aquí se especifica la configuración del backend de Terraform utilizando el archivo backend.tfvars.
      • vars_vars: Argumentos adicionales que se pasarán a los comandos plan, apply, destroy, e import. Aquí se especifica que se utilizará el archivo vars.tfvars como archivo de variables (-var-file) durante la ejecución de estos comandos.

varCommon.hcl y varDataState.hcl

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

varCommon.hcl



###############################
#    VALORES DATA DataState     #
###############################
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              = "openai" 

###############################
#     VALORES GENERALES       #
###############################
region  = "swedencentral"
Environment = "PRO"
BussinessUnit = "IT"
ProjectName = "chatgpt"
ServiceName = "chatgpt"
EntityName = "RO"
Subscription = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
Tenant = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
# ApplicationName = null
mapProjectPathKey = {"rg":"rg/00","sbnVint00":"networking/sbn/vint00","sbnVint01":"networking/sbn/vint01","sbnVint02":"networking/sbn/vint02"}

###############################
# Valores OpenAI             #
###############################

oponai_kind = "OpenAI"
openai_sku_name = "S"



vnet_resource_group = "DEV-REDORBITA-NET"
vnet_net_name = "DEV-REDORBITA-VNET"
subnet_name = "DEV-REDORBITA-SNET"

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

hub_resource_group_name = "PRO-HUB-01"
private_dns_zone_name_01 = "privatelink.openai.azure.com"
subscription_hub_id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"

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

tags = {"Enviroment":"PRO","Environment Tech":"IT","Managed_By":"Terraform","ProjectAlias":"chatgpt","Provider":"Azure","Service Description":"CHATGPT","ServiceAlias":"V1","Status":"Implementation","Temporal":"NO"}

Explicación

  • VALORES DATA DataState:
    • lz_subscription_id: ID de suscripción para los recursos de datos.
    • lz_resource_group_name: Nombre del grupo de recursos para los recursos de datos.
    • lz_storage_account_name: Nombre de la cuenta de almacenamiento para los recursos de datos.
    • lz_container_name: Nombre del contenedor para los recursos de datos.
  • VALORES GENERALES:
    • region: Región donde se despliegan los recursos.
    • Environment: Ambiente en el que se despliegan los recursos.
    • BussinessUnit: Unidad de negocio relacionada con los recursos.
    • ProjectName: Nombre del proyecto.
    • ServiceName: Nombre del servicio.
    • EntityName: Entidad relacionada con los recursos.
    • Subscription: ID de suscripción para los recursos generales.
    • Tenant: ID del inquilino asociado.
    • mapProjectPathKey: Mapeo de rutas de proyectos.
  • Valores OpenAI:
    • oponai_kind: Tipo de OpenAI.
    • openai_sku_name: SKU de OpenAI.
  • Valores para la red virtual (VNET):
    • vnet_resource_group: Grupo de recursos de la red virtual.
    • vnet_net_name: Nombre de la red virtual.
    • subnet_name: Nombre de la subred.
  • Valores para el proveedor de contenedores HUB:
    • hub_resource_group_name: Nombre del grupo de recursos del proveedor de contenedores HUB.
    • private_dns_zone_name_01: Nombre de la zona DNS privada.
    • subscription_hub_id: ID de suscripción para el proveedor de contenedores HUB.
  • VALORES TAGS:
    • tags: Diccionario de etiquetas para los recursos, incluyendo información como el entorno, el proveedor, el alias del proyecto, la descripción del servicio, entre otros.

varDataState.hcl

Este código define variables locales y entradas para un módulo de Terraform que gestiona el estado de los datos:

locals {
  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       = "openai"
  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
}

Explicación:

  1. Locales: Se definen variables locales que contienen valores estáticos o calculados para su posterior uso.
    • lz_subscription_id: ID de la suscripción.
    • lz_resource_group_name: Nombre del grupo de recursos.
    • lz_storage_account_name: Nombre de la cuenta de almacenamiento.
    • lz_container_name: Nombre del contenedor.
    • path_resources_terraform_state: Codifica en formato JSON la ruta de recursos para el estado de Terraform.
  2. Inputs: Se define un mapa de entradas que se utilizarán en otros archivos de configuración.
    • lz_subscription_id, lz_resource_group_name, lz_storage_account_name, lz_container_name, path_resources_terraform_state: Se asignan los valores locales respectivos a cada entrada. Estos valores son los que se utilizarán en otros módulos o configuraciones de Terraform.

:wq!

Una respuesta a “Despliegue de Servicios Cognitivos de Azure OpenAI con Terraform y Terragrunt”

Deja una respuesta

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