En mi último post conocimos la propuesta de arquitectura con Azure API Management para integraciones. Y terminé el post con una cosa pendiente, que era cómo desplegar y configurar todos los recursos de Azure que utiliza la solución.

En el post de hoy vamos a ver cómo se crean todos los recursos, se enlazan y se configuran para tener una solución de registro de API totalmente operativo, y cómo podemos desplegar todo usando Bicep.

También te puede interesar

Buen Bicep...
Buen Bicep…

Y el truco para desplegarlo es…

¡Hacerlo a mano!

Por supuesto. ¡Esa es la forma más lógica de hacerlo! Con el teclado y ratón, dándole a los botones e introduciendo nombres, y luego buscando en Azure configuraciones, cadenas de conexión, habilitando opciones, etc.

Eso es lo que hice la primera vez que configuré esto, creé todos los recursos desde el portal de Azure a mano, cambiando la configuración de los diferentes componentes hasta que todo funcionanó bien.

Pero luego pensé que tenía que haber una forma de desplegar esto automáticamente y si, por ejemplo, tenía que desplegarlo en diferentes clientes o proyectos, poderlo reusar reduciendo la probabilidad de errores y teniendo otra tarea automatizada.

Conocía las plantillas de ARM, y también sabía que no me gustan mucho. Es entonces cuando me acordé de que había oído hablar de esta cosa nueva…

¡Utilizando Bicep!

Bicep es un lenguaje que se usa para desplegar recursos de Azure que utilizaremos para crear soluciones de infraestructura como código (IaC).

Uno de los beneficios de usar IaC es que ayuda a automatizar, y nos permite asegurarnos de que podemos desplegar los mismos recursos cada vez que se ejecuta nuestro código. Con el mismo código siempre se desplegará la misma infraestructura.

Para desplegar los recursos necesitaréis una cuenta de Azure. Recordad que podéis registraros y obtener una de forma gratuita y con un crédito de 200$ durante 30 días, y que además hay una serie de servicios que serán siempre gratuitos.

Bicep utiliza una sintaxis declarativa, lo que significa que describimos lo que queremos que haga el código, y cómo se hace es problema del compilador. Personalmente, lo encuentro mucho más fácil de leer que el JSON de las plantillas de ARM.

Y empezar a usarlo es realmente fácil, solo tienes que instalar las herramientas de Bicep, que si estás usando Visual Studio Code es tan fácil como instalar una extensión.

A continuación, imagina que quieres desplegar una nueva cuenta de almacenamiento en tu suscripción de Azure. Escribiremos el siguiente código:

resource aristeinfoStorageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = {
  name: 'aristeinfostorage'
  location: 'westeurope'
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}

Si usas la extensión de VS Code es casi tan fácil como escribir código .NET, dándole al tab sin parar 🙊 Es bromita… echemos un vistazo al código.

Todos los recursos se declaran usando la palabra clave resource, entonces aristeinfoStorageAccount sería el nombre de la variable para ese recurso, que podemos usar luego en el código para acceder a sus miembros, como si fuera un objeto en cualquier lenguaje orientado a objetos. Y lo que viene después, ‘Microsoft.Storage/storageAccounts@2021-09-01‘, es el tipo de recurso, que la extensión de VS Code nos ayuda a encontrarlo, no hace falta acordarse de como se llaman todos los recursos.

Luego en el bloque de código en el interior tenemos:

  • name, que será el nombre del recurso en Azure.
  • location, es la región donde se despliega el recurso.
  • kind, es el tipo de cuenta de almacenamiento.
  • sku, el tier del recurso.

Por supuesto, diferentes tipos de recursos tienen diferentes elementos y propiedades en su configuración.

Antes de desplegar el archivo, asegúrate de haber instalado las extensiones de Bicep y Azure Account para VS Code. Y primero, conecta a tu suscripción pulsando F1 y buscando «Azure: Sign in».

Ahora, para desplegarlo, solo tenemos que hacer clic con el botón derecho en la pestaña de VS Code y seleccionar la opción «Desplegar archivo Bicep…»:

Desplegando un archivo Bicep desde VS Code
Desplegando un archivo Bicep desde VS Code

Gracias a la extensión, Bicep mostrará un diálogo para seleccionar la suscripción, el grupo de recursos (o crear uno) y después también pedirá que selecciones un archivo de parámetros, dile que Ninguno.

Verás un mensaje en la ventana de output, y si vas al portal de Azure, luego al grupo de recursos en el que estás desplegando esto y seleccionas la opción Deployments verás el despliegue:

Despliegue de Bicep en el portal de Azure
Despliegue de Bicep en el portal de Azure

Y cuando termine, puedes ir a la vista general y ver tu recurso:

Cuenta de almacenamiento desplegada con Bicep
Cuenta de almacenamiento desplegada con Bicep

Es así de fácil, y si quieres aprender mucho más sobre Bicep, consulta las rutas de aprendizaje de Microsoft Learn para Bicep.

Desplegando la solución APIM

He querido que quien quiera probar esto lo tenga fácil, así que si vais a este proyecto de GitHub que he creado, encontraréis lo siguiente:

La carpeta X++ que contiene un modelo con un servicio web personalizado que creará una API de calculadora en tu entorno F&O. Hay una carpeta del modelo y un archivo axpp que puedes importar directamente en Visual Studio.

La carpeta AzureFunction contiene el código para crear una Azure Function que desplegará una API de calculadora.

Y por último, y lo que más nos interesa, la carpeta Bicep que contiene el código necesario para crear todos los recursos de Azure, para que puedas probar lo que expliqué en mi anterior post sin tener que crear todos los recursos a mano. Y tienes dos opciones.

Desplegar una función de Azure

Si quieres probar la solución utilizando una función de Azure, solo tienes que desplegar el archivo mainAzureFunction.bicep.

No necesitas crear y desplegar la Función Azure porque el archivo Bicep descargará este archivo ZIP, que es la función empaquetada para hacer tu vida más fácil, y esto más rápido para probar. Si prefieres desplegar la función en tu suscripción por razones de seguridad, tendrás que actualizar el archivo azureFunction.bicep dentro de la carpeta de módulos.

Si eliges esta opción, los diálogos en VS Code te pedirán los siguientes parámetros: Suscripción, grupo de recursos, región (que por defecto es la del grupo de recursos), prefijo que se utilizará como nombre de los recursos y, por último, correo electrónico y organización para desplegar el APIM (solo tu correo electrónico y tenant, puedes inventártelo, no se enviarán correos electrónicos).

Desplegar el código X++

Si eliges esta opción, tienes que descargar el código de la carpeta X++ y añadirlo a tu entorno. Una vez hecho esto, puedes desplegar el archivo mainDynamics.bicep.

Si prefieres utilizar este servicio web personalizado para probarlo, tendrás que proporcionar información adicional. Así que además de los mismos parámetros que pide la función de Azure tendrás que proporcionar la URL del entorno (sin la / final), la URL del entorno con la información de la API (grupo de servicios y nombre del servicio, también sin la / final), tenant, AAD App Id y secret.

Con esta forma de desplegar el código se creará una policy automáticamente en tu APIM que se encargará de la autenticación del token, por eso pide el tenant, App Id y secret.

Los archivos de Bicep

En la carpeta Bicep encontraréis estos archivos:

Carpeta Bicep
Carpeta Bicep

Los archivos mainAzureFunction.bicep y mainDynamics.bicep son los que hay que ejecutar/desplegar, dependiendo de lo que elijáis.

Echemos un vistazo al archivo mainAzureFunction.bicep:

@description('The location where the resources will be deployed')
param location string = resourceGroup().location
@description('A prefix that will be added to the resources.')
param prefix string
// Analytics
@description('Log Analytics workspace name')
var logAnalyticsWorkspaceName = '${prefix}LogAnalytics'
@description('Name for the App Insights resource')
var appInsightsName = '${prefix}AppInsights'
// Azure Function
@description('The name of the account storage used by the Azure function')
var storageName = toLower('${prefix}Storage')
@description('Azure function name')
var functionName = '${prefix}Function'
@description('App Service plan name')
var appServicePlanName = '${prefix}AppServicePlan'
// APIM
@description('Name of the APIM resource')
var apiManagementInstanceName = '${prefix}apim'
@description('APIM publisher email')
@secure()
param publisherEmail string
@description('APIM publisher name')
param publisherName string
@description('Name of the API that will be created in the APIM')
var apiName = 'calculator'
// Analytics resources
module analytics 'modules/analytics.bicep' = {
  name: logAnalyticsWorkspaceName
  params: {
    appInsightsName: appInsightsName
    location: location
    logAnalyticsWorkspaceName: logAnalyticsWorkspaceName
  }
}
// Azure Function Resources
module azureFunction 'modules/azureFunction.bicep' = {
  name: functionName
  params: {
    appInsightsId: analytics.outputs.appInsightsId
    appServicePlanName: appServicePlanName
    functionName: functionName
    location: location
    storageName: storageName
  }
}
// APIM Resources
module apiManagement 'modules/apiManagement.bicep' = {
  name: apiManagementInstanceName
  params: {
    apiManagementInstanceName: apiManagementInstanceName
    apiName: apiName
    endpointUrl: azureFunction.outputs.azureFunctionUrl
    location: location
    publisherEmail: publisherEmail
    publisherName: publisherName
    apiKey: azureFunction.outputs.azureFunctionApi    
    appInsightsId: analytics.outputs.appInsightsId
    appInsightsKey: analytics.outputs.appInsightsKey    
  }
}

He puesto los parámetros y variables al principio del archivo y los recursos después.

Cuando se utiliza un parámetro, que se declara con la palabra clave parm, es necesario informar ese parámetro cada vez que se ejecuta el archivo Bicep.

Las variables se declaran con la palabra clave var y… recordáis lo de los recursos, ¿verdad? Pero no hay recursos en este archivo, en su lugar hay…

Módulos

En Bicep, los módulos son archivos que se despliegan desde otros archivos. Pensad en ellos como si fueran clases que podemos usar en el archivo principal. Es algo así.

En los módulos se suelen agrupar recursos que necesitan ser desplegados juntos o que pueden ser reutilizados en otros archivos.

La carpeta de los módulos contiene otros archivos de Bicep que ayudan a desplegar toda la infraestructura.

Por ejemplo, echemos un vistazo al archivo azureFunction.bicep:

param functionName string
param appServicePlanName string
param appInsightsId string
param storageName string
param location string
// Storage resources
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' = {
  name: storageName
  location: location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}
resource appservice_plan 'Microsoft.Web/serverfarms@2022-03-01' = {
  name: appServicePlanName
  location: location
  properties: {}
  sku: {
    name: 'Y1'
    tier: 'Dynamic'
  }
}
resource azureFunction 'Microsoft.Web/sites@2022-03-01' = {
  name: functionName
  location: location
  kind: 'functionapp'  
  properties: {
    serverFarmId: appservice_plan.id
    siteConfig: {
      appSettings: [
        {
          name: 'AzureWebJobsStorage'
          value: 'DefaultEndpointsProtocol=https;AccountName=${storageAccount.name};AccountKey=${listKeys(storageAccount.id, storageAccount.apiVersion).keys[0].value}'
        }
        {
          name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
          value: reference(appInsightsId, '2020-02-02').InstrumentationKey
        }
        {
          name: 'FUNCTIONS_EXTENSION_VERSION'
          value: '~4'
        }
        {
          name: 'FUNCTIONS_WORKER_RUNTIME'
          value: 'dotnet'
        }
        {
          name: 'WEBSITE_RUN_FROM_PACKAGE '          
          value: 'https://static.ariste.info/wp-content/uploads/2022/08/CalculatorFunction.zip'
        }        
      ]
    }
  }  
}
output azureFunctionId string = azureFunction.id
output azureFunctionApiVersion string = azureFunction.apiVersion
output azureFunctionUrl string = azureFunction.properties.hostNames[0]

En primer lugar, vemos también los parámetros. Estos parámetros serán necesarios cuando se utilice el módulo en otro archivo.

Y luego vemos los recursos. Puedes ver que estoy desplegando una cuenta de almacenamiento, un app service plan y la función. Van este módulo porque son cosas necesarias cuando se despliega una función.

Y al final vemos las variables de salida, a las que se puede acceder desde el archivo que utiliza el módulo, como si fuera un return en un método.

Despliegue

Para esto voy a usar la función de Azure, así que abrimos el fichero mainAzureFunction.bicep y hacemos clic derecho en el tab y seleccionamos «Deploy Bicep file…»:

Deploy Bicep file
Deploy Bicep file

Veremos una lista de las suscripciones a las que el usuario con el que nos hemos autenticado tiene acceso:

Suscripciones Azure
Suscripciones Azure

Ahora nos preguntará en qué grupo de recursos lo queremos desplegar, o si queremos crear uno nuevo:

Crear nuevo grupo de recursos
Crear nuevo grupo de recursos

Vamos a crear un nuevo grupo de recursos. Cuando hagamos esto nos pedirá en otro diálogo en qué región lo queremos crear.

Después nos pide si queremos usar un archivo de parámetros, pero no lo usaremos, así que le damos a «None«.

Y ahora tenemos que seleccionar la región en la que desplegar todo. Como en el código estamos usando el valor de resourceGroup().location vemos esta opción en el diálogo, pero podríamos usar otra.

Selección de región
Selección de región

Ahora meteremos el prefijo, teniendo en cuenta que sea un nombre único:

Prefijo
Prefijo

Y al final ponemos el correo y vuestro nombre, dominio o lo que queráis.

Y para acabar, un diálogo nos preguntará si queremos crear un archivo de parámetros, le decimos que «No»:

Fichero de parámetros
Fichero de parámetros

Después de todo esto veremos el mensaje en la ventana output, y si queremos ver el estado de la operación podemos ir al grupo de recursos y a la opción «Deployments»:

Deployments en el grupo de recursos
Deployments en el grupo de recursos

Va a tardar unos minutos en desplegar todo, y cuando esté todo listo podemos ir a la vista general y ver todos los recursos ahí:

Recursos de la arquitectura APIM
Recursos de la arquitectura APIM

¡Y así de fácil tenemos todo listo para probar!

Un último truco

Igual ya os habéis dado cuenta mientras probabais la solución de Bicep, pero cuando hacéis clic con el botón derecho en la pestaña del fichero main, podéis seleccionar estas opciones:

Bicep Visualizer
Bicep Visualizer

El visualizador de Bicep abrirá una pestaña nueva que mostrará un diagrama con los recursos, con sus iconos, y con flechas mostrando la relación entre recursos.

Diagrama Bicep
Diagrama Bicep

Igual no es lo más importante de todo, ¡pero me gusta!

Insisto: si queréis aprender más sobre Bicep, id a las rutas de aprendizaje de Microsoft Learn para Bicep, ni siquiera hace falta tener una suscripción a Azure porque los módulos de Learn despliegan una cuenta sandbox gratuita para hacer los ejercicios.

Y eso es todo, espero que esto os ayude un poco como introducción a Bicep, y también a desplegar la arquitectura APIM que he propuesto y probarla, y ver si puede ser útil para vuestros proyectos.

¡Suscríbete!

Recibe un correo cuando se publique un nuevo post
Author

Microsoft Dynamics 365 Finance & Operations technical architect and developer. Business Applications MVP since 2020.

Write A Comment

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

ariste.info