Skip to content

Blog

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 Firewall vs NSG: Cuándo usar cada uno

Resumen

NSG filtra a nivel de subnet/NIC, Azure Firewall es un firewall centralizado con threat intelligence. No son excluyentes, se complementan.

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

GitHub Actions: Deploy a Azure con Workload Identity Federation

Resumen

Olv

ídate de guardar service principal secrets en GitHub. Con Workload Identity Federation, GitHub Actions se autentica a Azure sin credenciales almacenadas. Más seguro y cero rotación de secrets.

¿Qué es Workload Identity Federation?

Permite que GitHub Actions obtenga un access token de Azure usando OIDC (OpenID Connect). Azure confía en los tokens de GitHub basándose en: - Repositorio específico - Branch específico - Environment específico

Setup completo

1. Crear service principal

# Variables
APP_NAME="github-actions-federation"
RG="my-rg"
SUBSCRIPTION_ID=$(az account show --query id -o tsv)

# Crear app registration
APP_ID=$(az ad app create \
  --display-name $APP_NAME \
  --query appId -o tsv)

# Crear service principal
az ad sp create --id $APP_ID

SP_OBJECT_ID=$(az ad sp show --id $APP_ID --query id -o tsv)

# Asignar rol Contributor
az role assignment create \
  --role Contributor \
  --assignee $APP_ID \
  --scope /subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RG

2. Configurar Federated Credential

# Para branch main
az ad app federated-credential create \
  --id $APP_ID \
  --parameters '{
    "name": "github-main-branch",
    "issuer": "https://token.actions.githubusercontent.com",
    "subject": "repo:myorg/myrepo:ref:refs/heads/main",
    "description": "GitHub Actions - main branch",
    "audiences": ["api://AzureADTokenExchange"]
  }'

# Para environment production
az ad app federated-credential create \
  --id $APP_ID \
  --parameters '{
    "name": "github-prod-environment",
    "issuer": "https://token.actions.githubusercontent.com",
    "subject": "repo:myorg/myrepo:environment:production",
    "description": "GitHub Actions - production environment",
    "audiences": ["api://AzureADTokenExchange"]
  }'

# Para pull requests
az ad app federated-credential create \
  --id $APP_ID \
  --parameters '{
    "name": "github-pull-requests",
    "issuer": "https://token.actions.githubusercontent.com",
    "subject": "repo:myorg/myrepo:pull_request",
    "description": "GitHub Actions - pull requests",
    "audiences": ["api://AzureADTokenExchange"]
  }'

3. Configurar GitHub Secrets

En tu repositorio → Settings → Secrets:

AZURE_CLIENT_ID = {APP_ID}
AZURE_TENANT_ID = {TENANT_ID}
AZURE_SUBSCRIPTION_ID = {SUBSCRIPTION_ID}

4. GitHub Actions Workflow

.github/workflows/deploy.yml:

name: Deploy to Azure

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  id-token: write  # Required for OIDC
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production  # Si usas federated credential por environment

    steps:
      - uses: actions/checkout@v4

      - name: Azure Login with OIDC
        uses: azure/login@v1
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

      - name: Deploy to Azure Web App
        uses: azure/webapps-deploy@v2
        with:
          app-name: my-web-app
          package: ./dist

      - name: Azure CLI commands
        run: |
          az group list
          az webapp list --resource-group ${{ env.RG }}

Ventajas vs Service Principal Secrets

Aspecto Service Principal Secret Workload Identity
Secrets en GitHub Sí (password) No (solo IDs)
Rotación Manual cada 90 días Automática
Scope Amplio Granular (repo/branch/env)
Audit trail Limitado Completo (OIDC claims)
Expiración Hasta 2 años Token expira en minutos

Debugging

- name: Debug OIDC Token
  run: |
    curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
         "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange" \
         | jq -R 'split(".") | .[1] | @base64d | fromjson'

Claims del token:

{
  "iss": "https://token.actions.githubusercontent.com",
  "sub": "repo:myorg/myrepo:ref:refs/heads/main",
  "aud": "api://AzureADTokenExchange",
  "ref": "refs/heads/main",
  "sha": "abc123...",
  "repository": "myorg/myrepo",
  "repository_owner": "myorg",
  "run_id": "123456789",
  "workflow": "Deploy to Azure"
}

Buenas prácticas

  • Usa environments: Requiere aprobaciones manuales para producción
  • Scope mínimo: Asigna roles solo al resource group necesario
  • Multiple credentials: Diferentes para dev/staging/prod
  • Branch protection: Solo permite deploy desde branches protegidos
  • Audit logs: Revisa sign-in logs en Azure AD regularmente

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