Skip to content

Azure Services

Azure VPN Gateway Point-to-Site: Acceso remoto seguro

Resumen

P2S VPN permite que usuarios remotos se conecten a tu VNet. Soporta OpenVPN, IKEv2 y SSTP.

Introducción

[Contenido técnico detallado a desarrollar]

Configuración básica

# Comandos de ejemplo
RG="my-rg"
LOCATION="westeurope"

# Comandos Azure CLI
az group create --name $RG --location $LOCATION

Casos de uso

  • Caso 1: [Descripción]
  • Caso 2: [Descripción]
  • Caso 3: [Descripción]

Buenas prácticas

  • Práctica 1: Descripción
  • Práctica 2: Descripción
  • Práctica 3: Descripción

Monitoreo y troubleshooting

# Comandos de diagnóstico
az monitor metrics list --resource ...

Referencias

Azure Load Balancer Standard: HA para aplicaciones

Resumen

Load Balancer distribuye tráfico TCP/UDP entre VMs. aquí está el setup para alta disponibilidad.

Introducción

[Contenido técnico detallado a desarrollar]

Configuración básica

# Comandos de ejemplo
RG="my-rg"
LOCATION="westeurope"

# Comandos Azure CLI
az group create --name $RG --location $LOCATION

Casos de uso

  • Caso 1: [Descripción]
  • Caso 2: [Descripción]
  • Caso 3: [Descripción]

Buenas prácticas

  • Práctica 1: Descripción
  • Práctica 2: Descripción
  • Práctica 3: Descripción

Monitoreo y troubleshooting

# Comandos de diagnóstico
az monitor metrics list --resource ...

Referencias

Azure Service Health: Alertas proactivas de outages

Resumen

Service Health te notifica de incidents, planned maintenance y health advisories que afectan TUS recursos específicos.

Introducción

[Contenido técnico detallado a desarrollar]

Configuración básica

# Comandos de ejemplo
RG="my-rg"
LOCATION="westeurope"

# Comandos Azure CLI
az group create --name $RG --location $LOCATION

Casos de uso

  • Caso 1: [Descripción]
  • Caso 2: [Descripción]
  • Caso 3: [Descripción]

Buenas prácticas

  • Práctica 1: Descripción
  • Práctica 2: Descripción
  • Práctica 3: Descripción

Monitoreo y troubleshooting

# Comandos de diagnóstico
az monitor metrics list --resource ...

Referencias

Azure Data Factory: Pipelines de ETL para Big Data

Resumen

Data Factory orquesta movimientos de datos a escala. Aquí el setup básico para ETL desde SQL a Data Lake.

Introducción

[Contenido técnico detallado a desarrollar]

Configuración básica

# Comandos de ejemplo
RG="my-rg"
LOCATION="westeurope"

# Comandos Azure CLI
az group create --name $RG --location $LOCATION

Casos de uso

  • Caso 1: [Descripción]
  • Caso 2: [Descripción]
  • Caso 3: [Descripción]

Buenas prácticas

  • Práctica 1: Descripción
  • Práctica 2: Descripción
  • Práctica 3: Descripción

Monitoreo y troubleshooting

# Comandos de diagnóstico
az monitor metrics list --resource ...

Referencias

Azure SQL Elastic Pools: Optimiza costos con DBs compartidos

Resumen

Los Elastic Pools te permiten compartir recursos (eDTUs o vCores) entre múltiples bases de datos SQL. es la solución cuando tienes muchas DBs con picos de uso en diferentes momentos y quieres pagar por el pool en lugar de sobreaprovisionar cada DB individual.

¿Qué problema resuelven los Elastic Pools?

Escenario típico SaaS: - Tienes 100 bases de datos (una por cliente) - Cada cliente usa su DB en momentos diferentes - Picos máximos: 100 DTUs por DB - Uso promedio: 10 DTUs por DB

Sin Elastic Pool: - 100 DBs × 100 DTUs = 10,000 DTUs provisionadas - Costo: ~€7,000/mes - Utilización real: <20%

Con Elastic Pool: - Pool de 1,000 eDTUs compartidas - Costo: ~€1,200/mes - Utilización: 70-80% - Ahorro: 83%

Crear Elastic Pool

# Variables
RG="my-rg"
LOCATION="westeurope"
SERVER="my-sql-server"
POOL_NAME="my-elastic-pool"

# Crear SQL Server
az sql server create \
  --resource-group $RG \
  --name $SERVER \
  --location $LOCATION \
  --admin-user sqladmin \
  --admin-password 'P@ssw0rd1234!'

# Crear Elastic Pool (modelo vCore - recomendado)
az sql elastic-pool create \
  --resource-group $RG \
  --server $SERVER \
  --name $POOL_NAME \
  --edition GeneralPurpose \
  --family Gen5 \
  --capacity 4 \
  --db-min-capacity 0 \
  --db-max-capacity 2 \
  --max-size 512GB

eDTU vs vCore

  • DTU model: Más simple, bundle de CPU+RAM+IO. Ideal para workloads predecibles.
  • vCore model: Más flexible, escala CPU y memoria independientemente. Recomendado para nuevos despliegues.

Añadir bases de datos al pool

# Crear DB directamente en el pool
az sql db create \
  --resource-group $RG \
  --server $SERVER \
  --name customer-001-db \
  --elastic-pool $POOL_NAME

# Mover DB existente al pool
az sql db update \
  --resource-group $RG \
  --server $SERVER \
  --name existing-db \
  --elastic-pool $POOL_NAME

Configuración óptima de recursos

Límites por DB (evita noisy neighbor)

# Establecer mín/máx vCores por DB
az sql elastic-pool update \
  --resource-group $RG \
  --server $SERVER \
  --name $POOL_NAME \
  --db-min-capacity 0.25 \  # Mínimo garantizado
  --db-max-capacity 2        # Máximo permitido (evita monopolizar pool)

Recomendaciones: - db-min-capacity: 0 para DBs inactivas, 0.25-0.5 para DBs críticas - db-max-capacity: 50-75% del total del pool para evitar que una DB acapare todos los recursos

Escalado del pool

# Escalar verticalmente (más vCores)
az sql elastic-pool update \
  --resource-group $RG \
  --server $SERVER \
  --name $POOL_NAME \
  --capacity 8 \
  --max-size 1TB

# Escalar storage independiente
az sql elastic-pool update \
  --resource-group $RG \
  --server $SERVER \
  --name $POOL_NAME \
  --max-size 2TB

Casos de uso ideales

1. Aplicaciones SaaS multi-tenant

Cliente A: Pico 9am-12pm (50 DTUs)
Cliente B: Pico 2pm-5pm (60 DTUs)
Cliente C: Pico 8pm-11pm (40 DTUs)

Pool necesario: 60 DTUs (máximo pico)
vs
Sin pool: 150 DTUs (50+60+40)

2. Entornos dev/test

# Pool compartido para todos los devs
az sql elastic-pool create \
  --resource-group dev-rg \
  --server dev-sql-server \
  --name dev-pool \
  --edition Standard \
  --dtu 100 \
  --db-dtu-min 0 \
  --db-dtu-max 20

# Cada dev tiene su DB
for dev in alice bob charlie; do
  az sql db create \
    --resource-group dev-rg \
    --server dev-sql-server \
    --name ${dev}-dev-db \
    --elastic-pool dev-pool
done

3. Aplicaciones con variación estacional

  • E-commerce: Picos en Black Friday, navidad
  • Educación: Picos durante matrículas
  • Fiscal: Picos fin de trimestre/año

Monitoreo de recursos

# Métricas del pool
az monitor metrics list \
  --resource /subscriptions/{sub-id}/resourceGroups/$RG/providers/Microsoft.Sql/servers/$SERVER/elasticPools/$POOL_NAME \
  --metric "cpu_percent" "dtu_consumption_percent" "storage_percent" \
  --start-time 2025-02-17T00:00:00Z \
  --end-time 2025-02-17T23:59:59Z \
  --interval PT1H

# Top databases consumiendo recursos
az sql elastic-pool list-dbs \
  --resource-group $RG \
  --server $SERVER \
  --name $POOL_NAME \
  --query "[].{Name:name, MaxSize:maxSizeBytes, Status:status}"

Query en SQL para ver consumo por DB:

SELECT 
    DB_NAME(database_id) AS DatabaseName,
    AVG(avg_cpu_percent) AS AvgCPU,
    AVG(avg_data_io_percent) AS AvgDataIO,
    AVG(avg_log_write_percent) AS AvgLogWrite,
    MAX(max_worker_percent) AS MaxWorkers,
    MAX(max_session_percent) AS MaxSessions
FROM sys.dm_db_resource_stats
WHERE end_time > DATEADD(hour, -1, GETUTCDATE())
GROUP BY DB_NAME(database_id)
ORDER BY AvgCPU DESC;

Alertas automáticas

# Alerta si pool > 80% CPU
az monitor metrics alert create \
  --name elastic-pool-high-cpu \
  --resource-group $RG \
  --scopes /subscriptions/{sub-id}/resourceGroups/$RG/providers/Microsoft.Sql/servers/$SERVER/elasticPools/$POOL_NAME \
  --condition "avg cpu_percent > 80" \
  --window-size 5m \
  --evaluation-frequency 1m \
  --action /subscriptions/{sub-id}/resourceGroups/$RG/providers/Microsoft.Insights/actionGroups/dba-team

# Alerta si storage > 90%
az monitor metrics alert create \
  --name elastic-pool-storage-full \
  --resource-group $RG \
  --scopes /subscriptions/{sub-id}/resourceGroups/$RG/providers/Microsoft.Sql/servers/$SERVER/elasticPools/$POOL_NAME \
  --condition "avg storage_percent > 90" \
  --window-size 15m \
  --evaluation-frequency 5m \
  --action /subscriptions/{sub-id}/resourceGroups/$RG/providers/Microsoft.Insights/actionGroups/dba-team

Cuando NO usar Elastic Pools

Una sola DB grande: No tiene sentido pool de un solo tenant ❌ Picos simultáneos: Si todas las DBs pican a la vez, no ahorras ❌ Requisitos de aislamiento estricto: Compliance que requiere dedicación física ❌ DBs con patrones muy diferentes: OLTP + DW no mezclan bien

Estrategia de migración

Paso 1: Análisis de consumo

-- Ejecutar en cada DB durante 7 días
SELECT 
    DATEPART(hour, end_time) AS Hour,
    AVG(avg_cpu_percent) AS AvgCPU,
    MAX(avg_cpu_percent) AS MaxCPU
FROM sys.dm_db_resource_stats
WHERE end_time > DATEADD(day, -7, GETUTCDATE())
GROUP BY DATEPART(hour, end_time)
ORDER BY Hour;

Paso 2: Sizing del pool

Regla del pulgar:

Pool eDTUs = MAX(SUM(avg_dtu_per_db), MAX(concurrent_peak_dtu))

Ejemplo:
20 DBs × 10 DTU promedio = 200 DTU
Pico máximo simultáneo = 150 DTU
→ Pool de 200 eDTUs

Paso 3: Migración gradual

# Migrar en ventana de mantenimiento
for db in $(az sql db list --resource-group $RG --server $SERVER --query "[?!elasticPoolName].name" -o tsv); do
  echo "Migrando $db..."
  az sql db update \
    --resource-group $RG \
    --server $SERVER \
    --name $db \
    --elastic-pool $POOL_NAME
done

Buenas prácticas

  • Homogeneidad: Agrupa DBs con workloads similares (OLTP con OLTP, no con DW)
  • Naming convention: pool-{env}-{tier} (ej: pool-prod-gp, pool-dev-std)
  • Límites por DB: Siempre configura db-max-capacity para evitar noisy neighbors
  • Monitoring: Habilita diagnostic logs a Log Analytics
  • Escalado proactivo: Escala antes de llegar al 80% de utilización
  • Backups: Los backups se gestionan por DB, no por pool

Costos (West Europe, Feb 2025)

vCore model: - General Purpose, 4 vCores: ~€550/mes - Business Critical, 4 vCores: ~€1,700/mes

DTU model: - Standard 100 eDTUs: ~€120/mes - Premium 125 eDTUs: ~€450/mes

Storage adicional: €0.115/GB/mes

Ahorro con Reserved Capacity

Reserva 1 o 3 años → hasta 65% descuento en vCores.

Referencias

Azure API Management: Políticas esenciales de seguridad

Resumen

API Management no es solo un proxy. Las políticas (policies) te dan control total: rate limiting, auth, transformaciones, caching, circuit breakers. Aquí las más importantes.

Arquitectura de políticas

Las políticas se aplican en 4 fases:

<policies>
  <inbound>   <!-- Antes de enviar a backend -->
  </inbound>
  <backend>   <!-- Modificar llamada a backend -->
  </backend>
  <outbound>  <!-- Modificar respuesta -->
  </outbound>
  <on-error>  <!-- Manejo de errores -->
  </on-error>
</policies>

Política 1: Rate limiting

<policies>
  <inbound>
    <rate-limit calls="100" renewal-period="60" />
    <!-- 100 llamadas por minuto -->

    <!-- Rate limit por suscripción -->
    <rate-limit-by-key calls="1000"
                        renewal-period="3600"
                        counter-key="@(context.Subscription.Id)" />

    <!-- Quota mensual -->
    <quota calls="1000000" renewal-period="2592000" />
  </inbound>
</policies>

Política 2: Validar JWT

<policies>
  <inbound>
    <validate-jwt header-name="Authorization" failed-validation-httpcode="401">
      <openid-config url="https://login.microsoftonline.com/{tenant}/.well-known/openid-configuration" />
      <audiences>
        <audience>api://my-api</audience>
      </audiences>
      <issuers>
        <issuer>https://sts.windows.net/{tenant}/</issuer>
      </issuers>
      <required-claims>
        <claim name="roles" match="any">
          <value>Admin</value>
          <value>User</value>
        </claim>
      </required-claims>
    </validate-jwt>
  </inbound>
</policies>

Política 3: Caching

<policies>
  <inbound>
    <cache-lookup vary-by-developer="false"
                  vary-by-developer-groups="false"
                  allow-private-response-caching="false">
      <vary-by-header>Accept</vary-by-header>
      <vary-by-query-parameter>category</vary-by-query-parameter>
    </cache-lookup>
  </inbound>
  <outbound>
    <cache-store duration="3600" />
    <!-- Cache por 1 hora -->
  </outbound>
</policies>

Política 4: Transformar request/response

<policies>
  <inbound>
    <!-- Añadir header de autenticación al backend -->
    <set-header name="X-API-Key" exists-action="override">
      <value>{{backend-api-key}}</value>
    </set-header>

    <!-- Reescribir URL -->
    <rewrite-uri template="/v2/api/{path}" />

    <!-- Transformar body -->
    <set-body template="liquid">
    {
      "requestId": "{{context.RequestId}}",
      "timestamp": "{{DateTime.UtcNow}}",
      "data": {{body}}
    }
    </set-body>
  </inbound>

  <outbound>
    <!-- Eliminar headers internos -->
    <set-header name="X-Internal-Server" exists-action="delete" />

    <!-- Transformar respuesta JSON -->
    <find-and-replace from="&quot;oldField&quot;" to="&quot;newField&quot;" />
  </outbound>
</policies>

Política 5: Circuit breaker

<policies>
  <inbound>
    <base />
  </inbound>
  <backend>
    <retry condition="@(context.Response.StatusCode >= 500)"
           count="3"
           interval="1"
           delta="1"
           first-fast-retry="true">
      <forward-request timeout="10" />
    </retry>
  </backend>
  <on-error>
    <return-response>
      <set-status code="503" reason="Service Unavailable" />
      <set-body>Backend service is temporarily unavailable</set-body>
    </return-response>
  </on-error>
</policies>

Política 6: IP whitelist

<policies>
  <inbound>
    <ip-filter action="allow">
      <address>192.168.1.1</address>
      <address-range from="10.0.0.1" to="10.0.0.255" />
    </ip-filter>
  </inbound>
</policies>

Named Values para secretos

# Crear named value (variable global)
az apim nv create \
  --resource-group $RG \
  --service-name my-apim \
  --named-value-id backend-api-key \
  --display-name "Backend API Key" \
  --value "secret-key-12345" \
  --secret true

# Usar en política: {{backend-api-key}}

Buenas prácticas

  • Rate limiting: Siempre por subscription/IP
  • Caching: Solo para GET requests idempotentes
  • Secrets: Usa Named Values con KeyVault integration
  • Error handling: Customiza mensajes de error, no expongas internals
  • Logging: Habilita Application Insights para todas las APIs

Referencias

Azure Logic Apps: Automatización sin código para integraciones

Resumen

Logic Apps te permite crear workflows de integración sin escribir código. Ideal para automatizar procesos que involucran múltiples servicios: recibir email → guardar adjunto en Blob → procesar con Function → enviar notificación.

¿Cuándo usar Logic Apps?

  • Integraciones entre SaaS (Office 365, Salesforce, Dynamics)
  • Procesos de negocio automatizados
  • Event-driven workflows
  • B2B con EDI/AS2/X12

No uses Logic Apps si: - Necesitas lógica compleja (usa Functions) - Performance crítico <100ms (usa Functions) - Procesamiento en batch grande (usa Data Factory)

Crear Logic App

# Variables
RG="my-rg"
LOGIC_APP="email-processor"
LOCATION="westeurope"

# Crear Logic App (Consumption plan)
az logic workflow create \
  --resource-group $RG \
  --location $LOCATION \
  --name $LOGIC_APP

Ejemplo: Procesar emails con adjuntos

Workflow: 1. Trigger: Cuando llega email a Outlook 2. Acción: Si tiene adjunto PDF 3. Acción: Guardar en Blob Storage 4. Acción: Llamar Function para OCR 5. Acción: Guardar metadatos en Cosmos DB 6. Acción: Enviar notificación a Teams

{
  "definition": {
    "$schema": "https://schema.management.azure.com/schemas/2016-06-01/Microsoft.Logic.json",
    "triggers": {
      "When_a_new_email_arrives": {
        "type": "ApiConnection",
        "inputs": {
          "host": {"connection": {"name": "@parameters('$connections')['office365']['connectionId']"}},
          "method": "get",
          "path": "/Mail/OnNewEmail"
        }
      }
    },
    "actions": {
      "Condition_has_PDF": {
        "type": "If",
        "expression": {
          "@contains(triggerBody()?['Attachments'], '.pdf')"
        },
        "actions": {
          "Upload_to_Blob": {
            "type": "ApiConnection",
            "inputs": {
              "host": {"connection": {"name": "@parameters('$connections')['azureblob']['connectionId']"}},
              "method": "post",
              "path": "/datasets/default/files",
              "queries": {
                "folderPath": "/invoices",
                "name": "@triggerBody()?['Attachments'][0]['Name']"
              },
              "body": "@base64ToBinary(triggerBody()?['Attachments'][0]['ContentBytes'])"
            }
          }
        }
      }
    }
  }
}

Conectores más útiles

Azure: - Service Bus, Event Grid, Storage, Cosmos DB, Key Vault, Functions

Microsoft 365: - Outlook, Teams, SharePoint, OneDrive, Planner

Terceros: - Salesforce, SAP, Twitter, Slack, Twilio, SendGrid

On-premises: - SQL Server, File System, Oracle (requiere Data Gateway)

Standard vs Consumption

Feature Consumption Standard
Pricing Por ejecución Por vCPU/hora
Networking Public VNET integration
Stateful/Stateless Stateful Ambos
Local dev No Sí (VS Code)
CI/CD Difícil Fácil

Buenas prácticas

  • Idempotencia: Usa ClientTrackingId para deduplicación
  • Error handling: Configura retry policy y run after
  • Monitoreo: Habilita diagnostic logs
  • Variables: Usa variables para valores reutilizables
  • Funciones inline: Usa expressions para transformaciones simples

Referencias

Test the proxy configuration in an AKS cluster

Variables

export RESOURCE_GROUP=<your-resource-group>
export AKS_CLUSTER_NAME=<your-aks-cluster-name>
export MC_RESOURCE_GROUP_NAME=<your-mc-resource-group-name>
export VMSS_NAME=<your-vmss-name>
export HTTP_PROXYCONFIGURED="http://<your-http-proxy>:8080/"
export HTTPS_PROXYCONFIGURED="https://<your-https-proxy>:8080/"

Get the VMSS instance IDs

# To get the instance IDs of all the instances in the VMSS, use the following command:
az vmss list-instances --resource-group $MC_RESOURCE_GROUP_NAME --name $VMSS_NAME --output table --query "[].instanceId"

# For one instance, you can use the following command to get the instance ID:
VMSS_INSTANCE_IDS=$(az vmss list-instances --resource-group $MC_RESOURCE_GROUP_NAME --name $VMSS_NAME --output table --query "[].instanceId" | tail -1)

Use an instance ID to test connectivity from the HTTP proxy server to HTTPS

az vmss run-command invoke --resource-group $MC_RESOURCE_GROUP_NAME \
    --name $VMSS_NAME \
    --command-id RunShellScript \
    --instance-id $VMSS_INSTANCE_IDS \
    --output json \
    --scripts "curl --proxy $HTTP_PROXYCONFIGURED --head https://mcr.microsoft.com"

Use an instance ID to test connectivity from the HTTPS proxy server to HTTPS

az vmss run-command invoke --resource-group $MC_RESOURCE_GROUP_NAME \
    --name $VMSS_NAME \
    --command-id RunShellScript \
    --instance-id $VMSS_INSTANCE_IDS \
    --output json \
    --scripts "curl --proxy $HTTPS_PROXYCONFIGURED --head https://mcr.microsoft.com"

Use an instance ID to test DNS functionality

az vmss run-command invoke --resource-group $MC_RESOURCE_GROUP_NAME \
    --name $VMSS_NAME \
    --command-id RunShellScript \
    --instance-id $VMSS_INSTANCE_IDS \
    --output json \
    --scripts "dig mcr.microsoft.com 443"

Test wagent logs

az vmss run-command invoke --resource-group $MC_RESOURCE_GROUP_NAME \
    --name $VMSS_NAME \
    --command-id RunShellScript \
    --instance-id $VMSS_INSTANCE_IDS \
    --output json \
    --scripts "cat /var/log/waagent.log"

Test wagent status

az vmss run-command invoke --resource-group $MC_RESOURCE_GROUP_NAME \
    --name $VMSS_NAME \
    --command-id RunShellScript \
    --instance-id $VMSS_INSTANCE_IDS \
    --output json \
    --scripts "systemctl status waagent"

Update the proxy configuration

az aks update -n $AKS_CLUSTER_NAME -g $RESOURCE_GROUP --http-proxy-config aks-proxy-config.json
az aks update --resource-group $RESOURCE_GROUP --name $AKS_CLUSTER_NAME --http-proxy-config aks-proxy-config.json

AKS: Autoscaling con KEDA para event-driven workloads

Resumen

KEDA (Kubernetes Event-Driven Autoscaling) escala tus pods basado en eventos externos: colas de Service Bus, métricas de Prometheus, HTTP requests, etc. Mucho más flexible que HPA estándar.

¿Qué es KEDA?

KEDA extiende Kubernetes con scalers específicos para: - Azure Service Bus queues/topics - Azure Storage queues - Kafka topics - Redis lists - Prometheus metrics - HTTP traffic - Cron schedules

Instalación en AKS

# Habilitar KEDA addon (managed)
az aks update \
  --resource-group $RG \
  --name my-aks \
  --enable-keda

# Ver pods de KEDA
kubectl get pods -n kube-system | grep keda

Ejemplo 1: Escalar con Azure Service Bus

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: servicebus-scaler
spec:
  scaleTargetRef:
    name: message-processor  # Deployment a escalar
  minReplicaCount: 0  # Scale to zero cuando no hay mensajes
  maxReplicaCount: 10
  triggers:
  - type: azure-servicebus
    metadata:
      queueName: myqueue
      namespace: myservicebus
      messageCount: "5"  # 1 pod por cada 5 mensajes
    authenticationRef:
      name: servicebus-auth
---
apiVersion: v1
kind: Secret
metadata:
  name: servicebus-connection
stringData:
  connection: "Endpoint=sb://myservicebus.servicebus.windows.net/;..."
---
apiVersion: keda.sh/v1alpha1
kind: TriggerAuthentication
metadata:
  name: servicebus-auth
spec:
  secretTargetRef:
  - parameter: connection
    name: servicebus-connection
    key: connection

Ejemplo 2: Escalar con métricas Prometheus

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: prometheus-scaler
spec:
  scaleTargetRef:
    name: api-server
  minReplicaCount: 2
  maxReplicaCount: 20
  triggers:
  - type: prometheus
    metadata:
      serverAddress: http://prometheus:9090
      metricName: http_requests_per_second
      threshold: '100'
      query: sum(rate(http_requests_total[2m]))

Ejemplo 3: Escalar con HTTP traffic

# Instalar HTTP Add-on
az aks addon enable \
  --resource-group $RG \
  --name my-aks \
  --addon http_application_routing
apiVersion: keda.sh/v1alpha1
kind: HTTPScaledObject
metadata:
  name: http-scaler
spec:
  scaleTargetRef:
    name: web-app
    kind: Deployment
  minReplicaCount: 1
  maxReplicaCount: 50
  targetPendingRequests: 100  # Escalar cuando hay >100 requests pendientes

Ejemplo 4: Cron-based scaling

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: cron-scaler
spec:
  scaleTargetRef:
    name: batch-processor
  minReplicaCount: 0
  maxReplicaCount: 10
  triggers:
  - type: cron
    metadata:
      timezone: Europe/Madrid
      start: 0 8 * * 1-5  # Lunes a viernes a las 8:00
      end: 0 18 * * 1-5   # Lunes a viernes a las 18:00
      desiredReplicas: "5"

Monitore de KEDA

# Ver scaled objects
kubectl get scaledobjects

# Ver estado detallado
kubectl describe scaledobject servicebus-scaler

# Logs de KEDA operator
kubectl logs -n kube-system deployment/keda-operator

Buenas prácticas

  • Scale to zero: Solo para workloads que toleran cold start
  • Min replicas: Al menos 2 para alta disponibilidad
  • Cooldown period: Evita flapping con cooldownPeriod: 300
  • Managed Identity: Usa workload identity para autenticación
  • Monitoring: Integra con Prometheus para métricas de scaling

Referencias