Desplegar Azure Event Grid donde quieras con Azure Arc

Si estás desarrollando aplicaciones basadas en eventos y ya venías usando Azure Event Grid como concentrador de los mismos ahora en preview tienes la posibilidad de desplegar este servicio donde quieras gracias a Kubernetes y Azure Arc, como ya vimos con App Service, Functions, Logic Apps y el gateway de API Management. En este artículo te cuento cómo probarlo.

Crear un cluster de Kubernetes

Para este ejemplo, por simplificar, creo un clúster en AKS pero, como ya te mostré en este otro artículo con EKS, puedes tenerlo donde quieras:

# Variables
RESOURCE_GROUP="k8s-for-event-grid"
LOCATION="westeurope"
AKS_NAME="aks-event-grid"
RESOURCE_GROUP_ARC="arc-resources"
# Create resource group
az group create --name $RESOURCE_GROUP --location $LOCATION
# Create a AKS cluster
az aks create \
--resource-group $RESOURCE_GROUP \
--name $AKS_NAME \
--generate-ssh-keys \
--location $LOCATION 
# Get AKS credentials
az aks get-credentials --resource-group $RESOURCE_GROUP --name $AKS_NAME

Conectar el clúster con Azure Arc

El siguiente paso es conectarlo con Azure Arc, para poder desde este instalar lo necesario, en este caso para Azure Event Grid:

# Connect the cluster to Azure Arc
az connectedk8s connect \
--resource-group $RESOURCE_GROUP_ARC \
--name $AKS_NAME \
--location $LOCATION
# Validate connection
az connectedk8s show --resource-group $RESOURCE_GROUP_ARC --name $AKS_NAME --query "provisioningState"
CONNECTED_CLUSTER_ID=$(az connectedk8s show -n $AKS_NAME -g $RESOURCE_GROUP_ARC --query id -o tsv)

Instalar extensión Event Grid en el clúster de Kubernetes

Al igual que con la extensión de App Service o la del gateway de API Management, para Azure Event Grid también es necesario instalar una extensión que desplegará diferentes recursos en el clúster:


# Install event grid extension
EVENT_GRID_EXT="eventgrid-extension"
NAMESPACE="event-grid-resources"
az k8s-extension create \
--cluster-type connectedClusters \
--cluster-name $AKS_NAME \
--resource-group $RESOURCE_GROUP_ARC \
--name $EVENT_GRID_EXT \
--extension-type Microsoft.EventGrid \
--scope cluster \
--auto-upgrade-minor-version true \
--release-train Stable \
--release-namespace $NAMESPACE \
--configuration-settings-file settings-extension.json
EXTENSION_ID=$(az k8s-extension show \
    --cluster-type connectedClusters \
    --cluster-name $AKS_NAME \
    --resource-group $RESOURCE_GROUP_ARC \
    --name $EVENT_GRID_EXT \
    --query id \
    --output tsv)
kubectl get all -n $NAMESPACE

En este caso es necesario, además, adjuntar un archivo, en mi ejemplo llamado settings-extension.json que tiene la siguiente pinta:

{
    "Microsoft.CustomLocation.ServiceAccount": "eventgrid-operator",
    "eventgridbroker.service.serviceType": "ClusterIP",
    "eventgridbroker.service.supportedProtocols[0]": "http",
    "eventgridbroker.dataStorage.storageClassName": "default",
    "eventgridbroker.diagnostics.metrics.reporterType": "prometheus"
}

Por simplificar la prueba, estoy utilizando como protocolo HTTP, para no tener que adjuntar el certificado correspondiente para HTTPs y hacer la configuración más fácil, pero también es posible y puedes ver el cómo aquí.

Crear una custom location

Por último necesitas una custom location, que será la que asocies a tu nuevo recursos de Azure Event Grid, para indicarle dónde va a estar alojado, en este caso en tu Kubernetes. Intenta que el nombre sea lo más descriptivo posible:

# Create a custom location
CUSTOM_LOCATION_NAME="k8s-location"
az customlocation create \
-n $CUSTOM_LOCATION_NAME \
-g $RESOURCE_GROUP_ARC \
--namespace $NAMESPACE \
--host-resource-id $CONNECTED_CLUSTER_ID \
--cluster-extension-ids $EXTENSION_ID \
--location $LOCATION
CUSTOM_LOCATION_ID=$(az customlocation show -n $CUSTOM_LOCATION_NAME -g $RESOURCE_GROUP_ARC --query id -o tsv)

Ahora ya tienes todo lo necesario para trabajar con el servicio como venías haciendo. Para terminar, vamos a crear un topic y una suscripción de prueba para que puedas verlo en funcionamiento.

Crear un topic en Azure Event Grid

La forma de crear un topic para este Azure Event Grid es la misma que podías seguir con Azure CLI con el servicio en Azure, solo que en este caso utilizamos nuestra custom location:

# Create a topic
TOPIC_NAME="returngis"
az eventgrid topic create \
-g $RESOURCE_GROUP_ARC \
--name $TOPIC_NAME \
--kind azurearc \
--extended-location-name $CUSTOM_LOCATION_ID \
--extended-location-type customlocation \
--input-schema CloudEventSchemaV1_0 \
--location $LOCATION
# Create a subscription
TOPIC_ID=$(az eventgrid topic show --name $TOPIC_NAME \
--resource-group $RESOURCE_GROUP_ARC --query id -o tsv)

Desplegar aplicación ver para visualizar los eventos de Event Grid

Para poder visualizar los eventos que llegan del servicio, el equipo de producto ha puesto a nuestra disposición una aplicación web sencilla que puedes desplegar desde aquí. Una vez finalizado el proceso deberías de ver un sitio como este:

Aplicación web - Azure Event Grid Viewer
Aplicación web – Azure Event Grid Viewer

Crear una suscripción

Ahora que ya tenemos un topic, ya podemos generar una suscripción a este. El endpoint que va a recepcionar los eventos que se generen es el sitio previamente desplegado /api/updates:

# Create a subscription
EVENT_SUBSCRIPTION_NAME="returngis-subscription"
az eventgrid event-subscription create \
--name $EVENT_SUBSCRIPTION_NAME \
--source-resource-id $TOPIC_ID \
--endpoint https://event-viewer-for-returngis.azurewebsites.net/api/updates

Generar eventos de prueba

Para comprobar que todo funciona como se espera, el último paso es generar un pod dentro del clúster, instalar cURL y ejecutar una petición POST con un evento ficticio. Para poder lanzar esta llamada necesitas la clave y el endpoint. Estos puedes recuperarlos, antes de entrar en el pod, con los siguientes comandos:

# Get key
az eventgrid topic key list --name $TOPIC_NAME -g $RESOURCE_GROUP_ARC --query "key1" --output tsv
# Get endpoint
az eventgrid topic show --name $TOPIC_NAME -g $RESOURCE_GROUP_ARC --query "endpoint" --output tsv

y ya con ellos ejecutar lo siguiente, cambiando los valores de YOUR_KEY y YOUR_ENDPOINT_URL:

# Run a pod with curl
kubectl run returngis --tty --stdin=true --image=ubuntu --restart=Never --rm -n $NAMESPACE
apt update && apt upgrade -y
apt install curl -y

# Send event
curl  -k -X POST -H "Content-Type: application/cloudevents-batch+json" -H "aeg-sas-key: <YOUR_KEY>" -g "<YOUR_ENDPOINT_URL>" \
-d  '[{ 
      "specversion": "1.0",
      "type" : "orderCreated",
      "source": "myCompanyName/us/webCommerceChannel/myOnlineCommerceSiteBrandName",
      "id" : "eventId-n",
      "time" : "2020-12-25T20:54:07+00:00",
      "subject" : "account/acct-123224/order/o-123456",
      "dataSchema" : "1.0",
      "data" : {
         "orderId" : "123",
         "orderType" : "PO",
         "reference" : "https://www.myCompanyName.com/orders/123"
      }
}]'

Si accedes a la web de nuevo, comprobarás que los mensajes están llegando, enrutados por tu Azure Event Grid en Kubernetes, gracias a Azure Arc.

Eventos de Azure Event Grid en Kubernetes en Azure Event Grid Viewer
Eventos de Azure Event Grid en Kubernetes en Azure Event Grid Viewer

¡Saludos!