Cómo desplegar y monitorear aplicaciones web en Azure con Terraform: Guía paso a paso
Daniel J. Saldaña
Posted on May 19, 2024
En este post, quiero compartir cómo desarrollé un módulo de Terraform para desplegar varios recursos en Azure que son esenciales para monitorear una aplicación web. Este módulo permite implementar de manera eficiente y repetible servicios como Log Analytics, Application Insights, grupos de acción y pruebas web estándar de Application Insights.
Recursos de Azure utilizados
El módulo desplegará los siguientes recursos de Azure:
- Grupos de Recursos (Resource Groups): Contenedores que mantienen los recursos relacionados de Azure juntos.
- Log Analytics Workspace : Servicio que proporciona una solución unificada de gestión de logs y análisis de datos.
- Application Insights : Servicio que ayuda a monitorear el rendimiento y uso de aplicaciones web.
- Monitor Action Groups : Grupos de acción que pueden ejecutar respuestas automáticas a las alertas.
- Key Vault : Servicio para gestionar y mantener de manera segura secretos, claves y certificados.
- Application Insights Standard Web Test : Pruebas web que monitorean la disponibilidad y el rendimiento de aplicaciones web.
Este módulo es ideal para usuarios de servicios de aplicaciones web estáticas que desean monitorear sus aplicaciones, ver logs y obtener métricas detalladas sobre el rendimiento de sus aplicaciones web.
Contenido de main.tf
Configuración del Proveedor de Azure
Primero, inicializamos el proveedor de Azure. Esto es esencial para gestionar cualquier recurso en Azure con Terraform.
provider "azurerm" {
features {}
}
Creación del Grupo de Recursos
Definimos la creación de un grupo de recursos de manera condicional, basado en una variable. Esto permite mayor flexibilidad y reutilización del módulo, ya que podemos decidir dinámicamente si queremos crear un grupo de recursos.
resource "azurerm_resource_group" "resource_group" {
count = var.create_resource ? 1 : 0
name = "log-analytics-workspace"
location = "West Europe"
}
Log Analytics Workspace
Creamos un espacio de trabajo de Log Analytics, que será utilizado para centralizar los datos de monitoreo y diagnóstico.
resource "azurerm_log_analytics_workspace" "analytics_workspace" {
count = var.create_resource ? 1 : 0
name = "shared-workspace"
location = "westeurope"
resource_group_name = azurerm_resource_group.resource_group[0].name
sku = "PerGB2018"
retention_in_days = 30
tags = var.tags
}
Application Insights
Deployamos instancias de Application Insights. Este recurso es fundamental para monitorear el rendimiento de las aplicaciones y detectar problemas potenciales.
resource "azurerm_application_insights" "application_insights" {
for_each = var.create_resource ? var.resources : {}
name = each.value.app_insights_name
location = var.location
resource_group_name = var.resource_group_name
workspace_id = azurerm_log_analytics_workspace.analytics_workspace[0].id
application_type = each.value.application_type
tags = each.value.tags
}
Monitor Action Group
Creamos un grupo de acción para la detección inteligente de Application Insights. Estos grupos son esenciales para definir respuestas automáticas a alertas específicas, mejorando la capacidad de respuesta ante incidentes.
resource "azurerm_monitor_action_group" "application_insights_smart_detection" {
count = var.create_resource ? 1 : 0
name = "Application Insights Smart Detection"
resource_group_name = var.resource_group_name
short_name = "SmartDetect"
location = "Global"
arm_role_receiver {
name = "Monitoring Contributor"
role_id = "749f88d5-cbae-40b8-bcfc-e573ddc772fa"
use_common_alert_schema = true
}
arm_role_receiver {
name = "Monitoring Reader"
role_id = "43d0d8ad-25c7-4714-9337-8ba259a9fe05"
use_common_alert_schema = true
}
}
Key Vault
Configuramos el almacenamiento de secretos en Azure Key Vault. Esto asegura que los secretos y claves de las aplicaciones estén protegidos y gestionados de manera segura.
resource "azurerm_key_vault_secret" "app_insights_secrets_app_insights_connection_string" {
depends_on = [azurerm_application_insights.application_insights]
for_each = var.create_resource ? { for k, v in var.resources : k => v } : {}
name = format("%s-insights-key", each.value.app_insights_name)
value = azurerm_application_insights.application_insights[each.key].connection_string
key_vault_id = data.azurerm_key_vault.vault.id
}
Application Insights Standard Web Test
Configuramos pruebas web estándar para monitorear la disponibilidad y el rendimiento de nuestras aplicaciones web desde varias ubicaciones geográficas.
resource "azurerm_application_insights_standard_web_test" "web_test" {
for_each = { for k, v in var.resources : k => v if var.create_resource && v.domain != "" }
name = each.value.app_insights_name
resource_group_name = var.resource_group_name
location = var.location
application_insights_id = azurerm_application_insights.application_insights[each.key].id
geo_locations = [
"emea-fr-pra-edge",
"emea-nl-ams-azr",
"apac-jp-kaw-edge",
"latam-br-gru-edge"
]
description = "Web test for ${each.value.app_insights_name}"
enabled = true
frequency = 300
retry_enabled = true
tags = var.tags
timeout = 30
request {
url = format("http://%s", each.value.domain)
}
}
Output de Cadenas de Conexión e IDs de aplicaciones
Finalmente, definimos los outputs que incluyen las cadenas de conexión y los IDs de las aplicaciones para facilitar la integración con otros módulos o scripts.
output "connection_string" {
value = {
for k, v in var.resources :
k => var.create_resource ? try(azurerm_application_insights.application_insights[k].connection_string, null) : null
}
sensitive = true
}
output "app_ids" {
value = {
for k, v in var.resources :
k => var.create_resource ? try(azurerm_application_insights.application_insights[k].app_id, null) : null
}
}
Contenido de variables.tf
Definimos las variables necesarias en el archivo variables.tf
. Las variables permiten una configuración flexible y reutilizable del módulo, adaptándolo a diferentes entornos y necesidades específicas.
variable "create_resource" {
type = bool
default = true
validation {
condition = var.create_resource == true || var.create_resource == false
error_message = "El valor de create_resource debe ser verdadero o falso."
}
}
variable "resource_group_name" {
description = "The name of the resource group"
type = string
validation {
condition = length(var.resource_group_name) > 0
error_message = "The resource group name must be provided."
}
}
variable "location" {
description = "The location for all resources"
type = string
validation {
condition = length(var.location) > 0
error_message = "The location must be provided."
}
}
variable "resources" {
description = "Map of resource configurations"
type = map(object({
app_insights_name = string
application_type = string
static_web_apps = list(string)
domain = optional(string)
tags = optional(map(string))
}))
validation {
condition = length(var.resources) > 0
error_message = "At least one resource must be provided."
}
}
variable "vault_name" {
description = "The name of the Vault to store the keys"
type = string
validation {
condition = length(var.vault_name) > 0
error_message = "The Vault name must be provided."
}
}
variable "tags" {
description = "Un mapa de etiquetas"
type = map(string)
validation {
condition = length(var.tags) > 0
error_message = "Se debe proporcionar al menos una etiqueta."
}
}
Contenido de data.tf
En el archivo data.tf
, obtenemos datos de Key Vault necesarios para configurar los secretos de las aplicaciones.
data "azurerm_key_vault" "vault" {
name = var.vault_name
resource_group_name = var.resource_group_name
}
Contenido de outputs.tf
Definimos outputs en el archivo outputs.tf
para las cadenas de conexión y los IDs de las aplicaciones. Esto facilita la integración y el uso de estos datos en otros módulos o scripts.
output "connection_string" {
value = {
for k, v in var.resources :
k => var.create_resource ? try(azurerm_application_insights.application_insights[k].connection_string, null) : null
}
sensitive = true
}
output "app_ids" {
value = {
for k, v in var.resources :
k => var.create_resource ? try(azurerm_application_insights.application_insights[k].app_id, null) : null
}
}
Ejemplo de Configuración
Aquí tienes un ejemplo de configuración para utilizar este módulo:
create_resource = true
resource_group_name = "ejemplo-grupo-recursos"
location = "westeurope"
resources = {
"resource1" = {
app_insights_name = "appinsights-frontend"
application_type = "web"
static_web_apps = ["frontend-test"]
domain = "frontend.com"
},
"resource2" = {
app_insights_name = "appinsights-backend"
application_type = "web"
static_web_apps = ["backend-test"]
domain = ""
}
}
tags = {
Project = "Proyecto Ejemplo"
Tier = "Gratis"
Environment = "Producción"
}
vault_name = "vault-ejemplo"
Conclusión
Este módulo de Terraform facilita la gestión de recursos en Azure, asegurando una configuración coherente y repetible. Al utilizar variables y condicionales, podemos adaptarlo a diferentes entornos y necesidades específicas. Este módulo es especialmente útil para aquellos que utilizan servicios de aplicaciones web estáticas en Azure y desean monitorear sus aplicaciones, ver logs y obtener métricas detalladas. ¡Espero que este post te haya proporcionado una visión clara de cómo desarrollar un módulo de Terraform para Azure! ¡Gracias por leer!
Posted on May 19, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.