Introducción
En este proyecto, se presenta una estructura organizada para el despliegue de una infraestructura en Azure utilizando Terraform y Terragrunt. La solución facilita la creación y gestión de recursos de Storage Account, optimizando la reutilización de configuraciones entre diferentes entornos, como desarrollo y producción, mediante archivos de configuración bien estructurados.
La estructura del proyecto permite una implementación modular y reutilizable, separando la configuración de los entornos específicos de los archivos de despliegue principales. Terraform y Terragrunt ofrecen un enfoque robusto para gestionar el estado y las variables comunes y específicas por entorno, facilitando así la administración y escalabilidad de la infraestructura en entornos empresariales.
Estructura del Proyecto
La organización del proyecto es la siguiente:
├── env
│ ├── code
│ │ └── storage
│ │ └── 00
│ │ ├── backend.tf
│ │ ├── data.tf
│ │ ├── endpoint.tf
│ │ ├── locals.tf
│ │ ├── main.tf
│ │ ├── outputs.tf
│ │ ├── provider.tf
│ │ └── variables.tf
│ └── dev
│ ├── storage
│ │ └── 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 deStorage Account. 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 necesarios para desplegar Storage Account.
backend.tf
terraform {
backend "azurerm" {
}
required_version = "~>0.14"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.47.0"
}
}
}
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 "azurerm_resource_group" "rg_net" {
name = var.rg_net_name
}
#State Vnet
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.sbn_data_net_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_private_dns_zone" "zone_02" {
provider = azurerm.hub
name = var.private_dns_zone_name_02
resource_group_name = data.azurerm_resource_group.hub_rg.name
}
Explicación:
1. data «terraform_remote_state» «rg»
Este bloque accede al estado remoto de Terraform para reutilizar configuraciones ya existentes en otro lugar (por ejemplo, recursos definidos en un proyecto diferente). Se utiliza comúnmente en configuraciones multi-modulares.
- backend: Define el tipo de backend (en este caso, Azure Resource Manager,
azurerm
) donde se almacena el estado de Terraform. - config: Contiene la configuración necesaria para conectarse al estado remoto:
- subscription_id: ID de la suscripción de Azure donde se encuentra el estado.
- resource_group_name: Nombre del grupo de recursos que contiene la cuenta de almacenamiento.
- storage_account_name: Nombre de la cuenta de almacenamiento que aloja el estado.
- container_name: Nombre del contenedor de blobs dentro de la cuenta de almacenamiento.
- key: Ruta específica al archivo de estado remoto, organizada utilizando variables como el proyecto, el servicio, el entorno y un mapeo de ruta (
mapProjectPathKey
).
2. data «azurerm_resource_group» «rg_net»
Este bloque recupera información sobre un grupo de recursos existente en Azure.
- name: Nombre del grupo de recursos que se desea consultar. Se define mediante la variable
var.rg_net_name
.
3. data «azurerm_virtual_network» «vnet»
Obtiene detalles sobre una red virtual específica.
- name: Nombre de la red virtual objetivo, definido mediante
var.vnet_net_name
. - resource_group_name: Nombre del grupo de recursos donde se encuentra esta red virtual. Se obtiene dinámicamente de
data.azurerm_resource_group.rg_net.name
.
4. data «azurerm_subnet» «sbn_data»
Recupera información sobre una subred dentro de una red virtual específica.
- name: Nombre de la subred, especificado mediante
var.sbn_data_net_name
. - virtual_network_name: Nombre de la red virtual asociada a la subred. Se extrae de
data.azurerm_virtual_network.vnet.name
. - resource_group_name: Grupo de recursos de la red virtual. Se obtiene de
data.azurerm_resource_group.rg_net.name
.
5. data «azurerm_resource_group» «hub_rg»
Obtiene información de un grupo de recursos que actúa como hub.
- provider: Asocia un proveedor específico para operaciones relacionadas con este grupo de recursos (
azurerm.hub
). - name: Nombre del grupo de recursos del hub, definido por
var.hub_resource_group_name
.
6. data «azurerm_private_dns_zone» «zone_01»
Obtiene información sobre una zona DNS privada para resolver nombres de dominio internos.
- provider: Usa el proveedor configurado como
azurerm.hub
para realizar operaciones en esta zona DNS. - name: Nombre de la zona DNS privada, definido por
var.private_dns_zone_name_01
. - resource_group_name: Grupo de recursos que aloja la zona DNS privada. Se obtiene del recurso
data.azurerm_resource_group.hub_rg.name
.
7. data «azurerm_private_dns_zone» «zone_02»
Otro bloque similar al anterior, pero para una segunda zona DNS privada.
- provider: Igual que el anterior, usa
azurerm.hub
. - name: Define el nombre de la zona DNS privada (por ejemplo,
privatelink.web.core.windows.net
) a través devar.private_dns_zone_name_02
. - resource_group_name: Se asocia con el grupo de recursos
data.azurerm_resource_group.hub_rg.name
.
endpoint.tf
Este archivo define el recurso de Private Endpoint
, permitiendo la conexión privada al Storage Account. Este Private Endpoint
se asocia a la subred y la zona DNS privada especificadas.
resource "azurerm_private_endpoint" "pren_01" {
name = upper(join("-", [ var.Environment, var.BussinessUnitExtended, var.Provider, var.ServiceName, var.storage_account_name, "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.BussinessUnitExtended, var.Provider, var.ServiceName, var.storage_account_name, "pren-01"]))
private_connection_resource_id = azurerm_storage_account.storage_01.id
is_manual_connection = false
subresource_names = ["blob"]
}
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:
resource «azurerm_private_endpoint» «pren_01»:
Este recurso define un Private Endpoint que permite una conexión segura y privada a una cuenta de almacenamiento en Azure.
- name:
Nombre del Private Endpoint, generado dinámicamente a partir de varias variables (Environment
,BussinessUnitExtended
,Provider
,ServiceName
,storage_account_name
). Este formato asegura consistencia con la nomenclatura corporativa. Se convierte a mayúsculas usandoupper()
. - resource_group_name:
Especifica el grupo de recursos donde se crea el Private Endpoint.
Se obtiene del estado remoto de Terraform (data.terraform_remote_state.rg.outputs.name
), que centraliza la definición del grupo de recursos. - location:
Región donde se despliega el Private Endpoint.
Se define a través de la variablevar.region
. - subnet_id:
ID de la subred donde se alojará el Private Endpoint.
Se obtiene dedata.azurerm_subnet.sbn_data.id
, que recupera los detalles de la subred correspondiente.
Bloque private_service_connection
Configura la conexión privada al recurso de destino, en este caso, una cuenta de almacenamiento.
- name:
Nombre de la conexión privada, generado de forma similar al nombre del Private Endpoint. - private_connection_resource_id:
ID del recurso de destino al que se conecta el Private Endpoint.
En este caso, corresponde a la ID de la cuenta de almacenamiento (azurerm_storage_account.storage_01.id
). - is_manual_connection:
Establecido comofalse
, lo que indica que la conexión privada se gestiona automáticamente por Azure. - subresource_names:
Especifica el subrecurso dentro del servicio al que conectarse.
En este caso, es el subrecursoblob
de la cuenta de almacenamiento.
Bloque private_dns_zone_group
Define la relación entre el Private Endpoint y una zona DNS privada para resolver nombres de dominio internos.
- name:
Nombre de la zona DNS privada, obtenido dedata.azurerm_private_dns_zone.zone_01.name
. - private_dns_zone_ids:
Lista de IDs de zonas DNS privadas asociadas al Private Endpoint.
Aquí se utiliza el ID dedata.azurerm_private_dns_zone.zone_01.id
.
tags
Aplica etiquetas definidas en local.tags
, lo que facilita la organización y el seguimiento del recurso dentro del entorno.
Bloque lifecycle
Configura el comportamiento de Terraform respecto a cambios en el recurso.
locals.tf
El archivo locals.tf
define variables locales que pueden ser reutilizadas en múltiples partes del código Terraform. Las variables locales son útiles para centralizar valores que se utilizan en varios recursos, mejorando la claridad y mantenibilidad del código.
locals {
storage_name = lower(join("", [var.Environment, var.BussinessUnitExtended, var.Provider, var.ServiceName, "st01"]))
tags = var.tags
}
Explicación:
Define un nombre dinámico para un recurso, en este caso, probablemente una cuenta de almacenamiento.
Componentes:
lower()
: Convierte el valor generado a minúsculas para cumplir con las restricciones de nombres de recursos en Azure (por ejemplo, los nombres de cuentas de almacenamiento deben estar en minúsculas).join("", [...])
: Combina los valores en una lista en una sola cadena, sin separadores.- Lista de valores usados:
var.Environment
: Variable que representa el entorno, como «dev», «prod», etc.var.BussinessUnitExtended
: Identifica la unidad de negocio.var.Provider
: Especifica el proveedor o tecnología utilizada, como «azr» para Azure.var.ServiceName
: Nombre del servicio relacionado con el recurso."st01"
: Sufijo fijo para indicar que se trata de una cuenta de almacenamiento.
main.tf
En el archivo main.tf
se definen los principales recursos de la infraestructura. En este caso, se está creando un recurso de Azure Storage Account que servirá para almacenar secretos y otros valores sensibles, asegurando así la seguridad de la información.
resource "azurerm_storage_account" "storage_01" {
name = local.storage_name
resource_group_name = data.terraform_remote_state.rg.outputs.name
location = var.region
account_tier = var.storage_account_tier
account_replication_type = var.storage_account_replication_type
access_tier = var.storage_account_access_tier
min_tls_version = var.storage_account_min_tls_version
account_kind = var.storage_account_kind
is_hns_enabled = var.storage_account_is_nhs_enabled
public_network_access_enabled = false
tags = local.tags
lifecycle {
ignore_changes = [
tags["CreationDate"]
]
}
blob_properties {
container_delete_retention_policy {
days = 7
}
delete_retention_policy {
days = 7
}
}
}
Explicación
1. Definición del recurso
resource "azurerm_storage_account" "storage_01"
: Define un recurso de tipoazurerm_storage_account
(Azure Storage Account) en Terraform.
El identificadorstorage_01
se utiliza para referenciar este recurso en otras partes del código.
2. Atributos principales
name
:
Construye el nombre de la cuenta de almacenamiento utilizando la variable locallocal.storage_name
, la cual combina dinámicamente valores como el entorno, unidad de negocio, proveedor y servicio. Esto garantiza un nombre único y estándar.
(Ejemplo:devfinanceazrbackupst01
)resource_group_name
:
Especifica el grupo de recursos donde se creará la cuenta de almacenamiento.
El nombre se obtiene del estado remoto de Terraform (terraform_remote_state.rg.outputs.name
), asegurando consistencia con otros recursos que comparten el mismo grupo.location
:
Define la región donde se ubicará la cuenta de almacenamiento, especificada por la variablevar.region
.
(Ejemplo:eastus
)account_tier
:
Define el nivel de rendimiento de la cuenta de almacenamiento.
Puede serStandard
oPremium
, según el uso previsto.
(Ejemplo:Standard
)account_replication_type
:
Especifica el tipo de replicación para garantizar la redundancia.
Valores posibles:LRS
,GRS
,ZRS
, etc.
(Ejemplo:LRS
)access_tier
:
Determina si los datos se acceden frecuentemente (Hot
) o de manera esporádica (Cool
).
(Ejemplo:Hot
)min_tls_version
:
Configura la versión mínima de TLS permitida para las conexiones. Mejora la seguridad al aceptar únicamente versiones modernas.
(Ejemplo:TLS1_2
)account_kind
:
Tipo de cuenta de almacenamiento.
(Ejemplo:StorageV2
)is_hns_enabled
:
Habilita la compatibilidad con Azure Data Lake Storage Gen2, permitiendo un modelo de acceso jerárquico para Big Data.
(Ejemplo:true
)public_network_access_enabled
:
Establecido enfalse
para restringir el acceso desde redes públicas, mejorando la seguridad al limitar el uso a redes privadas o endpoints privados.
3. Configuraciones avanzadas
tags
:
Aplica etiquetas definidas enlocal.tags
para organizar el recurso. Estas etiquetas ayudan a la clasificación y búsqueda en Azure.
(Ejemplo:{ Environment = "dev", Owner = "John Doe" }
)lifecycle
:
El bloquelifecycle
indica que Terraform debe ignorar cualquier cambio en la etiquetaCreationDate
. Esto evita que se realicen actualizaciones innecesarias en el recurso cuando solo cambia esta etiqueta.
4. Propiedades del blob
El bloque blob_properties
define políticas para la gestión del ciclo de vida de los datos:
container_delete_retention_policy
: Retiene contenedores eliminados durante 7 días, permitiendo su recuperación.delete_retention_policy
: Retiene blobs eliminados durante 7 días antes de su eliminación definitiva.
outputs.tf
El archivo outputs.tf
expone información relevante del recurso azurerm_storage_account
para facilitar su uso en otros módulos o para proporcionar datos clave a los usuarios de Terraform. Esto incluye endpoints, ubicaciones, claves de acceso, entre otros.
# IDs
output "id" {
value = azurerm_storage_account.storage_01.id
description = "The ID of the Storage Account."
}
output "primary_location" {
value = azurerm_storage_account.storage_01.primary_location
description = "The primary location of the storage account"
}
output "secondary_location" {
value = azurerm_storage_account.storage_01.secondary_location
description = "The secondary location of the storage account"
}
output "primary_blob_endpoint" {
value = azurerm_storage_account.storage_01.primary_blob_endpoint
description = "The primary blob endpoint of the storage account"
}
output "primary_blob_host" {
value = azurerm_storage_account.storage_01.primary_blob_host
description = "The primary blob host of the storage account"
}
output "secondary_blob_endpoint" {
value = azurerm_storage_account.storage_01.secondary_blob_endpoint
description = "The secondary blob endpoint of the storage account"
}
output "secondary_blob_host" {
value = azurerm_storage_account.storage_01.secondary_blob_host
description = "The secondary blob host of the storage account"
}
output "primary_access_key" {
value = azurerm_storage_account.storage_01.primary_access_key
description = "The primary access key of the storage account"
}
output "secondary_access_key" {
value = azurerm_storage_account.storage_01.secondary_access_key
description = "The secondary access key of the storage account"
}
output "primary_web_endpoint" {
value = azurerm_storage_account.storage_01.primary_web_endpoint
description = "The primary web endpoint of the storage account"
}
output "primary_web_host" {
value = azurerm_storage_account.storage_01.primary_web_host
description = "The primary web host of the storage account"
}
output "secondary_web_endpoint" {
value = azurerm_storage_account.storage_01.secondary_web_endpoint
description = "The secondary web endpoint of the storage account"
}
output "secondary_web_host" {
value = azurerm_storage_account.storage_01.secondary_web_host
description = "The secondary web host of the storage account"
}
output "primary_connection_string" {
value = azurerm_storage_account.storage_01.primary_connection_string
description = "The primary connection string of the storage account"
}
output "secondary_connection_string" {
value = azurerm_storage_account.storage_01.secondary_connection_string
description = "The secondary connection string of the storage account"
}
output "identity" {
value = azurerm_storage_account.storage_01.identity
description = "The identity of the storage account"
}
Explicación
-
output "id"
- Proporciona el ID único del recurso de Azure Storage Account.
- Útil para referencias cruzadas o integraciones con otros servicios de Azure.
(Ejemplo:/subscriptions/{subscription-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/{storage-name}
)
-
output "primary_location"
youtput "secondary_location"
- Indican la ubicación primaria y secundaria de la cuenta de almacenamiento.
- Relevante en configuraciones con replicación geográfica para identificar las regiones en uso.
(Ejemplo:eastus
,westus
)
-
output "primary_blob_endpoint"
youtput "secondary_blob_endpoint"
- Muestran los endpoints primarios y secundarios del servicio Blob.
- Estos se utilizan para acceder y gestionar blobs almacenados en la cuenta.
(Ejemplo:https://{storage-name}.blob.core.windows.net/
)
-
output "primary_blob_host"
youtput "secondary_blob_host"
- Exponen los nombres de host asociados a los endpoints Blob.
(Ejemplo:{storage-name}.blob.core.windows.net
)
- Exponen los nombres de host asociados a los endpoints Blob.
-
output "primary_access_key"
youtput "secondary_access_key"
- Devuelven las claves de acceso primarias y secundarias de la cuenta.
- Estas claves son esenciales para autenticación cuando no se utiliza identidad administrada.
(Nota: Debe manejarse con precaución y restringirse el acceso a este output en entornos sensibles).
-
output "primary_web_endpoint"
youtput "secondary_web_endpoint"
- Proporcionan los endpoints primario y secundario del servicio web asociado.
(Ejemplo:https://{storage-name}.web.core.windows.net/
)
- Proporcionan los endpoints primario y secundario del servicio web asociado.
-
output "primary_connection_string"
youtput "secondary_connection_string"
- Contienen las cadenas de conexión primarias y secundarias, utilizadas por aplicaciones para interactuar con la cuenta de almacenamiento.
(Ejemplo:DefaultEndpointsProtocol=https;AccountName={storage-name};AccountKey={key};EndpointSuffix=core.windows.net
)
- Contienen las cadenas de conexión primarias y secundarias, utilizadas por aplicaciones para interactuar con la cuenta de almacenamiento.
-
output "identity"
- Expone la identidad administrada asociada a la cuenta de almacenamiento, si está configurada.
(Ejemplo:{"principal_id": "...", "tenant_id": "...", "type": "SystemAssigned"}
)
- Expone la identidad administrada asociada a la cuenta de almacenamiento, si está configurada.
provider.tf
En el archivo provider.tf
se configuran los proveedores de infraestructura, en este caso el proveedor de Azure (azurerm
). Aquí se definen dos configuraciones para el proveedor de Azure, una por defecto y otra con un alias. Esto permite trabajar con múltiples suscripciones de Azure dentro del mismo proyecto Terraform
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:
- Primer bloque
provider "azurerm"
:subscription_id
: Esta propiedad define la ID de la suscripción de Azure que se utilizará para aprovisionar y gestionar recursos. Se obtiene de la variablevar.Subscription
, que debe estar configurada previamente.tenant_id
: El ID de tenant de Azure Active Directory al que se debe asociar el proveedor de Azure. En este caso, se toma devar.Tenant
.features {}
: Un bloque requerido por el proveedor de Azure (azurerm
) que puede contener configuraciones adicionales. Aunque en este caso está vacío, es necesario para inicializar correctamente el proveedor.
- Segundo bloque
provider "azurerm"
con aliashub
:alias
: El alias"hub"
permite crear un segundo proveedor de Azure dentro de la misma configuración de Terraform, lo cual es útil cuando se necesitan trabajar con múltiples suscripciones. Al asignar un alias, se puede referenciar este proveedor específico más adelante en los recursos o datos, de forma que se pueda diferenciar del proveedor predeterminado.subscription_id
: Similar al primer bloque, esta propiedad se define a través devar.subscription_hub_id
, que representa la ID de la suscripción de Azure para la configuración del «hub».tenant_id
: El ID de tenant sigue siendo el mismo y se toma devar.Tenant
para mantener la consistencia en el entorno.features {}
: Al igual que el primer bloque, este bloque es necesario aunque no contenga configuraciones adicionales.
variables.tf
En el archivo variables.tf
se definen todas las variables utilizadas a lo largo de la infraestructura de Terraform. Este archivo centraliza los parámetros configurables que pueden cambiar dependiendo del entorno, la suscripción, el nombre de recursos, etc. Esto permite la reutilización del código y facilita su gestió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 "BussinessUnit" {
type = string
description = "(Required) Bussiness Unit."
default = ""
}
variable "BussinessUnitExtended" {
type = string
description = "(Required) Bussiness Unit Extended."
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 "sbn_data_net_name" {
type = string
description = "Name of Subnet Data of net"
default = ""
}
variable "rg_bkp_name" {
type = string
description = "Name of resource group of bkp"
default = ""
}
variable "st_bkp_name" {
type = string
description = "Name of storage Account of bkp"
default = ""
}
variable "EntityName" {
type = string
description = "(Required) Entity Name."
default = ""
}
#############################
# VARIABLES Storage Account #
#############################
variable "storage_account_name" {
type = string
description = "Nombre del storage account"
default = ""
}
variable "storage_account_tier" {
type = string
description = "Tier of storage account"
default = ""
}
variable "storage_account_replication_type" {
type = string
description = "Replication type of storage account"
default = ""
}
variable "storage_account_access_tier" {
type = string
description = "Access tier storage account"
default = ""
}
variable "storage_account_min_tls_version" {
type = string
description = "Min tls version storage account"
default = ""
}
variable "storage_account_kind" {
type = string
description = "Storage account kind"
default = ""
}
variable "storage_account_is_nhs_enabled" {
type = bool
description = "is nhs storage account enabled"
default = true
}
######################
# 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:
1. Variables comunes
Estas variables permiten establecer configuraciones básicas para el estado remoto, la suscripción y otros parámetros clave:
-
lz_subscription_id
ylz_resource_group_name
- ID de la suscripción y nombre del grupo de recursos donde se almacenará el estado remoto.
- Facilitan la gestión del backend remoto en Terraform, generalmente almacenado en Azure Storage.
-
lz_storage_account_name
ylz_container_name
- Configuración del Storage Account y contenedor usados para almacenar el estado remoto (
tfstate
).
- Configuración del Storage Account y contenedor usados para almacenar el estado remoto (
-
Tenant
,Subscription
,Provider
- Información relacionada con el tenant de Azure, la suscripción y el proveedor en uso.
-
Environment
,BussinessUnit
,ProjectName
yServiceName
- Detallan el entorno, la unidad de negocio, el nombre del proyecto y el servicio asociado al despliegue.
- Estos valores suelen utilizarse en la definición de etiquetas (
tags
) o en nombres de recursos.
-
region
- Define la región de Azure donde se desplegarán los recursos.
- (Ejemplo:
eastus
,westeurope
)
2. Variables específicas de red (DATAS
)
Estas variables son necesarias para configurar la red del entorno:
rg_net_name
: Nombre del grupo de recursos que contiene la red virtual.vnet_net_name
: Nombre de la red virtual asociada.sbn_data_net_name
: Nombre de la subred dentro de la red virtual.rg_bkp_name
yst_bkp_name
: Recursos relacionados con backups, como grupo de recursos y Storage Account.EntityName
: Nombre identificador de la entidad asociada al despliegue.
3. Variables para el Storage Account
Estas variables permiten personalizar la configuración del almacenamiento:
-
storage_account_name
- Nombre del Storage Account. (Ejemplo:
stproject001
) - Este valor suele tener que ser único globalmente.
- Nombre del Storage Account. (Ejemplo:
-
storage_account_tier
- Determina el nivel de rendimiento, como
Standard
oPremium
.
- Determina el nivel de rendimiento, como
-
storage_account_replication_type
- Tipo de replicación:
LRS
,GRS
,ZRS
, etc. - (Ejemplo:
LRS
para replicación local,GRS
para replicación geográfica).
- Tipo de replicación:
-
storage_account_access_tier
- Acceso a datos en el almacenamiento:
Hot
oCool
.
- Acceso a datos en el almacenamiento:
-
storage_account_min_tls_version
- Versión mínima de TLS para conexiones seguras. (Ejemplo:
TLS1_2
)
- Versión mínima de TLS para conexiones seguras. (Ejemplo:
-
storage_account_kind
- Tipo de cuenta:
Storage
,StorageV2
, etc.
- Tipo de cuenta:
-
storage_account_is_nhs_enabled
- Indica si el almacenamiento está habilitado para NHS (Network Hierarchy Storage).
4. Variables de etiquetas
tags
- Mapeo opcional para asignar etiquetas a los recursos.
- Facilita la organización y el filtrado de recursos en Azure. (Ejemplo:
{"Environment" = "Dev", "Owner" = "TeamA"}
)
5. Variables específicas del proveedor HUB
Estas variables son útiles cuando el despliegue implica integración o comunicación con una suscripción secundaria de tipo HUB (red compartida, App Gateway, etc.):
-
hub_resource_group_name
- Grupo de recursos del HUB.
-
private_dns_zone_name_01
yprivate_dns_zone_name_02
- Zonas de DNS privadas utilizadas en el entorno HUB. (Ejemplo:
privatelink.blob.core.windows.net
)
- Zonas de DNS privadas utilizadas en el entorno HUB. (Ejemplo:
-
virtual_network_appgw_name
ysubnet_appgw_name
- Configuración de la red y subred para un Application Gateway.
-
subscription_hub_id
- ID de la suscripción asociada al HUB.
terragrunt.hcl
El archivo terragrunt.hcl
que proporcionas configura un entorno para gestionar infraestructura utilizando Terragrunt, que es una herramienta para gestionar configuraciones de Terraform de manera modular. Aquí está un desglose detallado de lo que hace este archivo:
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 {
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"
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}"
Subscription = "${include.varEnvironment.inputs.Subscription}"
Tenant = "${include.varCommon.inputs.Tenant}"
# ApplicationName = null
mapProjectPathKey = ${local.mapProjectPathKey}
##################################
# Valores Container Provider HUB #
##################################
hub_resource_group_name = "PRO-NWHUB-RGP-01"
private_dns_zone_name_01 = "privatelink.blob.core.windows.net"
private_dns_zone_name_02 = "privatelink.web.core.windows.net"
subscription_hub_id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
##############################
# Valores Storage Account #
##############################
rg_net_name = "${include.varEnvironment.inputs.NetworkResourceGroup}"
vnet_net_name = "${include.varEnvironment.inputs.Network}"
sbn_data_net_name = "${include.varEnvironment.inputs.SubnetworkFront}"
storage_account_name = "st01"
storage_account_tier = "Standard"
storage_account_replication_type = "LRS"
storage_account_access_tier = "Hot"
storage_account_min_tls_version = "TLS1_2"
storage_account_is_nhs_enabled = "false"
storage_account_kind = "StorageV2"
###########################
# VALORES TAGS #
###########################
tags = ${local.tags}
EOF
}
terraform {
source = "../../..//code/storage/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 Terragrunt. En este caso, no se especifican rutas de dependencias, ya que el bloquepaths
está vacío.
include
: Estos bloques incluyen archivos de variables externos (varEnvironment.hcl
,varCommon.hcl
,varDataState.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 mapamapProjectPathKey
del archivovarEnvironment.hcl
.
tags
: Codifica como JSON un conjunto de etiquetas combinando un conjunto fijo de etiquetas (Managed_By
yProvider
), las etiquetas globales definidas envarCommon.hcl
y las etiquetas específicas del entorno definidas envarEnvironment.hcl
.
generate "backend"
: Este bloque genera un archivo llamadobackend.tfvars
. Este archivo se utiliza para configurar el backend de Terraform. Contiene variables comosubscription_id
,key
,resource_group_name
,storage_account_name
, ycontainer_name
. Los valores de estas variables se obtienen de los archivos incluidos (varDataState.hcl
yvarCommon.hcl
).
generate "vars"
: Este bloque genera un archivo llamadovars.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.hcl
,varCommon.hcl
,varEnvironment.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, comoplan
yapply
. En este caso, se ejecutan dos ganchos:print_tags
ycopy_vars
.
extra_arguments
: Este bloque especifica argumentos adicionales que se pasarán a los comandos de Terraform (init
,plan
,apply
,destroy
,import
). En este caso, se especifican argumentos adicionales para la configuración del backend (backend_vars
) y para las variables (vars_vars
).
varEnvironment.hcl
locals {
region = "northeurope"
Environment = "dev"
EnvironmentLetter = "d"
Subscription = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
NetworkResourceGroup = "DEV-REDORBITA-RG-01"
Network = "DEV-REDORBITA-NET-01"
SubnetworkFront = "DEV-REDORBITA-SBN-01"
SubnetworkVint = "DEV-REDORBITA-VINT-SBN-01"
mapProjectPathKey = {
rg = "rg/00",
sbnVint00 = "networking/sbn/vint00",
storage = "storage/00"
}
}
inputs = {
region = local.region
Environment = local.Environment
EnvironmentLetter = local.EnvironmentLetter
Subscription = local.Subscription
NetworkResourceGroup = local.NetworkResourceGroup
Network = local.Network
SubnetworkFront = local.SubnetworkFront
SubnetworkVint = local.SubnetworkVint
environmentTags = {
Enviroment = "${upper(local.Environment)}"
}
mapProjectPathKey = local.mapProjectPathKey
}
}
varCommon.hcl
Este archivo contiene una definición estructurada de valores locales y entradas comunes que se utilizan para organizar y parametrizar los recursos dentro de Terraform. La combinación de locals
e inputs
permite separar las configuraciones por entorno y facilita la reutilización del código en múltiples proyectos. A continuación, se detalla cada sección:
locals {
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"
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
}
inputs = {
##############################
# VARIABLES COMMON #
##############################
EntityName = local.EntityName
ProjectName = local.ProjectName
ServiceName = local.ServiceName
BussinessUnit = local.BussinessUnit
# Subscription = local.Subscription
# Subscription_pro = local.Subscription_pro
Tenant = local.Tenant
Provider = local.Provider
required_version = local.required_version
id_project = local.id_project
globalTags = local.globalTags
}
-
Bloque
locals
En este bloque, se definen variables locales dentro del archivo que pueden ser utilizadas dentro del propio archivo o por otros módulos de Terraform:
- EntityName: Es el nombre de la entidad asociada al proyecto, en este caso, «RO». Generalmente se utiliza como identificador de un proyecto o unidad dentro de la organización.
- ProjectName: El nombre del proyecto, en este caso, «RedOrbita», que identifica el nombre de la iniciativa bajo la cual se gestionan los recursos.
- ServiceName: El nombre del servicio relacionado con el proyecto, aquí también se define como «RedOrbita». Hace referencia al servicio o solución principal que se implementará.
- BussinessUnit: Especifica la unidad de negocio asociada al proyecto, aquí representada por «XX».
- Subscription: El identificador de la suscripción de Azure asociada al proyecto. Es un valor único que se usa para gestionar los recursos dentro de la suscripción de Azure.
- Tenant: El identificador del tenant de Azure, que representa un directorio único dentro de Azure Active Directory.
- Provider: El proveedor de infraestructura que se utilizará. En este caso, «azr» hace referencia a Azure.
- required_version: Especifica la versión de Terraform requerida para ejecutar este archivo. En este caso, se requiere cualquier versión compatible con «0.14.x».
- globalTags: Define un conjunto de etiquetas globales que se aplicarán a todos los recursos. Las etiquetas incluyen detalles como el nombre de la empresa, el propietario del proyecto, el estado del proyecto, la descripción del servicio, el proveedor de infraestructura, etc.
- storage_account: El nombre de la cuenta de almacenamiento de Azure, en este caso, «protfdata».
- container_name: El nombre del contenedor dentro de la cuenta de almacenamiento de Azure, «iasearch».
- subscription_hub_id2: Un segundo ID de suscripción, posiblemente relacionado con el hub de red o recursos específicos.
- location: Especifica la región de Azure donde se desplegarán los recursos, en este caso, «northeurope».
-
Bloque
inputs
El bloque de
inputs
toma los valores definidos en el bloquelocals
y los pasa como entradas para ser utilizados en otros módulos o recursos dentro del proyecto. Las variables comunes definidas enlocals
se referencian aquí para garantizar la consistencia de los valores a través del proyecto. En este caso, se repiten las mismas entradas para las variables definidas, permitiendo su reutilización en otros módulos de Terraform.-
EntityName, ProjectName, ServiceName, BussinessUnit, Subscription, Tenant, Provider, required_version, globalTags: Estas entradas se asignan directamente a las variables locales definidas anteriormente, garantizando que los valores sean consistentes en todo el proyecto.
-
id_project: Se hace referencia a una variable llamada
id_project
, aunque esta no está definida en los locales. Esto sugiere que esta variable se puede definir en otro lugar o se utiliza para proyectos específicos.
-
varDataState.hcl
Este archivo varDataState.hcl
se utiliza para definir y organizar las variables relacionadas con el estado de los datos y la infraestructura de Terraform en el entorno de trabajo. Este archivo contiene configuraciones para el almacenamiento del estado de Terraform en Azure, lo cual es crucial para el manejo de los recursos de infraestructura y su persistencia. A continuación, se explica el propósito y uso de las configuraciones definidas en este archivo:
locals {
lz_subscription_id = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
lz_resource_group_name = "PRO-HUB-01"
lz_storage_account_name = "storage"
lz_container_name = "storage"
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
}
1. Bloque locals
El bloque locals
define las variables locales dentro de este archivo, las cuales pueden ser reutilizadas dentro del archivo o en otros módulos de Terraform. Las variables locales que se definen aquí incluyen:
- lz_subscription_id: El ID de la suscripción de Azure utilizada para gestionar los recursos en la infraestructura. Este valor es único para cada suscripción de Azure.
- lz_resource_group_name: El nombre del grupo de recursos de Azure que se utilizará para almacenar los recursos de Terraform, en este caso
PRO-HUB-01
. Los grupos de recursos son unidades lógicas que agrupan recursos relacionados en Azure. - lz_storage_account_name: El nombre de la cuenta de almacenamiento de Azure, en este caso
storage
, que se utilizará para almacenar el estado de Terraform y otros recursos persistentes. - lz_container_name: El nombre del contenedor dentro de la cuenta de almacenamiento de Azure, aquí denominado
storage
, donde se almacenarán los archivos de estado de Terraform. - path_resources_terraform_state: Un valor en formato JSON que define la ruta dentro del contenedor de almacenamiento donde se guardarán los archivos de estado de Terraform. En este caso, la ruta está definida como
rg/00
.
2. Bloque inputs
El bloque inputs
se utiliza para definir las entradas de las variables que serán pasadas a los módulos de Terraform. Estas entradas corresponden a las variables locales que se definieron previamente y que se usarán para configurar el almacenamiento del estado de Terraform en Azure. Las variables de entrada son:
- lz_subscription_id: El ID de la suscripción de Azure que se pasa como entrada a los módulos.
- lz_resource_group_name: El nombre del grupo de recursos que se pasará como entrada.
- lz_storage_account_name: El nombre de la cuenta de almacenamiento que se utilizará para gestionar el estado.
- lz_container_name: El nombre del contenedor donde se almacenará el estado.
- path_resources_terraform_state: La ruta donde se almacenará el estado de Terraform dentro del contenedor.
:wq!