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 :
- https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models
- https://msandbu.org/deploy-azure-openai-using-terraform-with-private-endpoint/
- https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cognitive_deployment
- https://learn.microsoft.com/es-es/azure/ai-services/openai/quotas-limits
- https://customervoice.microsoft.com/Pages/ResponsePage.aspx?id=v4j5cvGGr0GRqy180BHbR7en2Ais5pxKtso_Pz4b1_xUNTZBNzRKNlVQSFhZMU9aV09EVzYxWFdORCQlQCN0PWcu
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 bloquebackend
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 atributoversion
. La URL de origen (source
) indica dónde Terraform puede encontrar este proveedor. En este caso, se espera encontrarlo enhashicorp/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 aliasrg
ysbnInt
. 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 aliaspren_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ónupper(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 endata.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 datosdata.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ónupper(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ónlower(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 variablevar.openai_name
.openai_deployment_name
: Define el nombre de un despliegue de OpenAI. Es similar aopenai_name
y sigue la misma estructura.tags
: Asigna el valor de la variablevar.tags
a la variable localtags
. 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 locallocal.openai_name
.location
: Especifica la ubicación geográfica donde se creará la cuenta cognitiva. Se toma de la variablevar.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 endata.terraform_remote_state.rg.outputs.name
.kind
: Define el tipo de cuenta cognitiva, especificado por la variablevar.oponai_kind
.sku_name
: Define el nombre del SKU (Stock Keeping Unit) para la cuenta cognitiva. Se toma de la variablevar.openai_sku_name
.tags
: Asigna el valor de la variable locallocal.tags
como etiquetas para el recurso.lifecycle
: Se define el bloquelifecycle
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 variablevar.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 variablevar.Tenant
.features
: Este bloque se utiliza para configurar características específicas del proveedor. En este caso, se configura la característicakey_vault
, que afecta a los servicios de Key Vault de Azure. Se establecepurge_soft_delete_on_destroy
entrue
, 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 variablevar.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 variablevar.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 recursoazurerm_cognitive_account
llamadoopenai
.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
yapply
. 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 llamadovars.tfvars
. - El segundo (
copy_vars
) copia el archivovars.tfvars
a otro directorio utilizando el comandocp
.
- El primero (
- 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 comandoinit
. Aquí se especifica la configuración del backend de Terraform utilizando el archivobackend.tfvars
.vars_vars
: Argumentos adicionales que se pasarán a los comandosplan
,apply
,destroy
, eimport
. Aquí se especifica que se utilizará el archivovars.tfvars
como archivo de variables (-var-file
) durante la ejecución de estos comandos.
- 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
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:
- 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.
- 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”