Adición de flexibilidad mediante parámetros y variables

Completado

Las plantillas son eficaces gracias a su reusabilidad. Puede usar Bicep para escribir plantillas que implementen varios entornos o copias de los recursos.

Su empresa de juguetes lanza nuevos productos con regularidad y debe usar las plantillas de Bicep para crear los recursos de Azure necesarios para el lanzamiento de cada producto. Debe evitar el uso de nombres de recursos fijos. Muchos tipos de recursos de Azure necesitan nombres únicos, por lo que la inserción de nombres en la plantilla significa que no podrá reutilizarla para los lanzamientos de varios productos. También tiene que implementar los recursos en diferentes ubicaciones en función de dónde se lanzarán los juguetes, lo que significa que tampoco puede insertar las ubicaciones de los recursos en la plantilla.

En esta unidad, obtendrá información sobre los parámetros y las variables, que son dos características de Bicep que pueden permitir que las plantillas sean flexibles y reutilizables. También se presentarán las expresiones.

Nota:

Los comandos de esta unidad se muestran para ilustrar conceptos. No los ejecute todavía. Pronto va a practicar lo que aprenderá aquí.

Parámetros y variables

Un parámetro le permite incorporar valores desde fuera del archivo de plantilla. Por ejemplo, si implementa manualmente la plantilla mediante la CLI de Azure o Azure PowerShell, se le pedirá que proporcione valores para cada parámetro. También puede crear un archivo de parámetros, donde se enumeran todos los parámetros y valores que desea usar para la implementación. Si la plantilla se implementa a partir de un proceso automatizado, como la canalización de una implementación, la canalización puede proporcionar los valores de parámetro.

Una variable se define y establece dentro de la plantilla. Las variables permiten almacenar información importante en un solo lugar y hacer referencia a ella en toda la plantilla, sin tener que copiarla y pegarla.

Normalmente, es una buena idea usar parámetros para cosas que cambiarán entre cada implementación, como:

  • Nombres de recursos que deben ser únicos.
  • Ubicaciones en las que implementar los recursos.
  • Configuración que afecta a los precios de los recursos, como sus SKU, planes de tarifa y recuentos de instancias.
  • Credenciales e información necesarias para acceder a otros sistemas que no están definidos en la plantilla.

Las variables suelen ser una buena opción cuando se van a usar los mismos valores para cada implementación, pero quiere hacer que un valor sea reutilizable dentro de la plantilla o cuando quiere usar expresiones para crear un valor complejo. También puede usar variables para los recursos que no necesitan nombres únicos.

Sugerencia

Es importante usar una nomenclatura correcta para los parámetros y las variables, a fin de facilitar la lectura y comprensión de las plantillas. Asegúrese de que usa nombres claros, descriptivos y coherentes.

Agregar un parámetro

En Bicep, puede definir un parámetro como el siguiente:

param appServiceAppName string

Veamos cómo funciona cada parte de esta definición:

  • param indica a Bicep que va a definir un parámetro.
  • appServiceAppName es el nombre del parámetro. Si va a implementar la plantilla manualmente, es posible que se le pida que escriba un valor, por lo que es importante que el nombre sea claro y comprensible. El nombre también sirve para hacer referencia al valor del parámetro dentro de la plantilla, al igual que con los nombres simbólicos de recursos.
  • string es el tipo del parámetro. Puede especificar varios tipos diferentes para los parámetros de Bicep, incluidos string para texto, int para números y bool para valores booleanos true o false. También puede pasar parámetros más complejos mediante los tipos array y object.

Sugerencia

Intente no generalizar en exceso las plantillas con demasiados parámetros. Debe usar el número mínimo de parámetros necesarios para su escenario empresarial. Recuerde que siempre puede cambiar las plantillas en el futuro si cambian sus requisitos.

Proporcionar valores predeterminados

Opcionalmente, puede proporcionar un valor predeterminado para un parámetro. Al especificar un valor predeterminado, el parámetro se convierte en opcional. La persona que implementa la plantilla puede especificar un valor si lo desea, pero si no lo hace, Bicep usará el valor predeterminado.

Aquí se muestra cómo puede agregar un valor predeterminado:

param appServiceAppName string = 'toy-product-launch-1'

Nota:

En este ejemplo, el nombre de aplicación de Azure App Service tiene un valor predeterminado codificado de forma rígida. Es una buena idea, ya que las aplicaciones de App Service necesitan nombres únicos. Lo corregirá en breve.

Uso de valores de parámetro en la plantilla

Una vez declarado un parámetro, puede hacer referencia a él en el resto de la plantilla. Veamos cómo puede usar el nuevo parámetro dentro de la definición de recursos:

resource appServiceApp 'Microsoft.Web/sites@2022-03-01' = {
  name: appServiceAppName
  location: 'eastus'
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
  }
}

Observe que la plantilla ahora usa el valor de parámetro para establecer el nombre del recurso de la aplicación, en lugar de un valor codificado de forma rígida.

Sugerencia

La extensión Bicep para Visual Studio Code muestra indicadores visuales para informarle de que no está siguiendo los procedimientos recomendados. Por ejemplo, le advierte si define un parámetro que no usa. El linter de Bicep ejecuta continuamente estas comprobaciones mientras trabaja.

Adición de una variable

Puede definir una variable como esta:

var appServicePlanName = 'toy-product-launch-plan'

Las variables se definen de forma similar a los parámetros, pero hay algunas diferencias:

  • Use la palabra clave var para indicar a Bicep que va a declarar una variable.
  • Debe proporcionar un valor para una variable.
  • Las variables no necesitan tipos. Bicep puede determinar el tipo en función del valor establecido.

Expresiones

Al escribir plantillas, en general no es conveniente codificar de forma rígida los valores ni siquiera pedir que se especifiquen en un parámetro. En su lugar, quiere detectar valores cuando se ejecuta la plantilla. Por ejemplo, es probable que quiera implementar todos los recursos de una plantilla en una sola región de Azure: la región en la que ha creado el grupo de recursos. O bien, puede que quiera crear automáticamente un nombre único para un recurso en función de una estrategia de nomenclatura determinada que use su empresa.

Las expresiones de Bicep son una característica eficaz que le ayuda a controlar todo tipo de escenarios interesantes. Echemos un vistazo a algunos lugares donde puede usar expresiones en una plantilla de Bicep.

Ubicaciones de recursos

Al escribir e implementar una plantilla, a menudo no es conveniente que tenga que especificar la ubicación de cada recurso individualmente. En su lugar, puede tener una regla de negocio simple que diga: De manera predeterminada, implemente todos los recursos en la misma ubicación en la que se ha creado el grupo de recursos.

En Bicep puede crear un parámetro denominado location y, a continuación, usar una expresión para establecer su valor:

param location string = resourceGroup().location

Observe el valor predeterminado de ese parámetro. Usa una función denominada resourceGroup() que proporciona acceso a la información sobre el grupo de recursos en el que se implementa la plantilla. En este ejemplo, la plantilla usa la propiedad location. Es habitual usar este enfoque para implementar los recursos en la misma región de Azure que el grupo de recursos.

Si alguien implementa esta plantilla, existe la opción de invalidar el valor predeterminado aquí y usar una ubicación diferente.

Nota:

Algunos recursos de Azure solo se pueden implementar en determinadas ubicaciones. Puede que necesite parámetros independientes para establecer las ubicaciones de estos recursos.

Ahora puede usar el parámetro de ubicación del recurso dentro de la plantilla, de la siguiente forma:

resource appServiceApp 'Microsoft.Web/sites@2022-03-01' = {
  name: appServiceAppName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
  }
}

Nombres de recurso

Muchos recursos de Azure necesitan nombres únicos. En su escenario, tiene dos recursos que necesitan nombres únicos: la cuenta de almacenamiento y la aplicación de App Service. Solicitar que estos valores se establezcan como parámetros puede dificultar el uso de la plantilla, ya que es necesario encontrar un nombre que nadie más haya usado.

Bicep tiene otra función llamada uniqueString() que resulta útil al crear nombres de recursos. Al usar esta función, debe proporcionar un valor de inicialización que debe ser diferente en distintas implementaciones, pero coherente en todas las implementaciones de los mismos recursos.

Si elige un buen valor de inicialización, puede obtener el mismo nombre cada vez que implemente el mismo conjunto de recursos, pero obtendrá un nombre diferente cada vez que implemente un conjunto diferente de recursos mediante la misma plantilla. Echemos un vistazo a cómo podría usar la función uniqueString():

param storageAccountName string = uniqueString(resourceGroup().id)

El valor predeterminado de este parámetro vuelve a usar la función resourceGroup(), como hizo al establecer la ubicación del recurso. Sin embargo, esta vez se obtiene el identificador de un grupo de recursos. Este es el aspecto del identificador de un grupo de recursos:

/subscriptions/3e57e557-826f-460b-8f1c-4ce38fd53b32/resourceGroups/MyResourceGroup

El identificador del grupo de recursos incluye el identificador de suscripción de Azure (3e57e557-826f-460b-8f1c-4ce38fd53b32) y el nombre del grupo de recursos (MyResourceGroup). El identificador del grupo de recursos suele ser un buen candidato como valor de inicialización para los nombres de recursos por los siguientes motivos:

  • Cada vez que implemente los mismos recursos, irán a parar al mismo grupo de recursos. La función uniqueString() devolverá el mismo valor cada vez.
  • Si realiza la implementación en dos grupos de recursos diferentes en la suscripción de Azure, el valor de resourceGroup().id será distinto porque los nombres de los grupos de recursos también lo serán. La función uniqueString() dará valores diferentes para cada conjunto de recursos.
  • Si realiza la implementación en dos suscripciones de Azure diferentes, incluso si usa el mismo nombre de grupo de recursos, el valor de resourceGroup().id será diferente porque el identificador de la suscripción de Azure también lo será. La función uniqueString() volverá a dar valores diferentes para cada conjunto de recursos.

Sugerencia

A menudo, es una buena idea usar expresiones de plantilla para crear nombres de recursos. Muchos tipos de recursos de Azure tienen reglas sobre los caracteres permitidos y la longitud de sus nombres. Incorporar la creación de nombres de recursos en la plantilla significa que cualquier persona que use la plantilla no tiene que acordarse de seguir estas reglas.

Cadenas combinadas

Si solo usa la función uniqueString() para establecer nombres de recursos, probablemente obtenga nombres únicos, pero no serán significativos. Un buen nombre de recurso también debe ser descriptivo para que esté claro cuál es su propósito. A menudo, querrá crear un nombre combinando una palabra o cadena significativas con un valor único. De este modo, tendrá recursos con nombres significativos y únicos.

Bicep cuenta con una característica llamada interpolación de cadenas que permite combinar cadenas. Veamos cómo funciona:

param storageAccountName string = 'toylaunch${uniqueString(resourceGroup().id)}'

El valor predeterminado del parámetro storageAccountName ahora tiene dos partes:

  • toylaunch es una cadena codificada de forma rígida que ayuda a cualquiera que examine el recurso implementado en Azure a comprender el propósito de la cuenta de almacenamiento.
  • ${uniqueString(resourceGroup().id)} es una manera de decir a Bicep que evalúe la salida de la función uniqueString(resourceGroup().id) y que, a continuación, la concatene en la cadena.

Sugerencia

En ocasiones, la función uniqueString() creará cadenas que comienzan con un número. Algunos recursos de Azure, como las cuentas de almacenamiento, no permiten que sus nombres comiencen por números. Esto significa que es una buena idea usar la interpolación de cadenas para crear nombres de recursos, como en el ejemplo anterior.

Selección de las SKU para los recursos

Los demás miembros del equipo se han quedado impresionados con el código de Bicep que ha creado hasta ahora. Han decidido juntos que usará su plantilla para implementar los recursos que permitan los lanzamientos de todos los juguetes nuevos.

Uno de los compañeros ha sugerido que cree entornos que no sean de producción para cada lanzamiento de producto y así ayudar al equipo de marketing a probar los sitios antes de que estén disponibles para los clientes. Sin embargo, quiere asegurarse de que no gasta demasiado dinero en los entornos que no son de producción, por lo que deciden algunas directivas juntos:

  • En entornos de producción, las cuentas de almacenamiento se implementarán con la SKU Standard_GRS (almacenamiento con redundancia geográfica) para mejorar la resistencia. Los planes de App Service se implementarán con la SKU P2v3 para mejorar el rendimiento.
  • En entornos que no son de producción, las cuentas de almacenamiento se implementarán con la SKU Standard_LRS (almacenamiento con redundancia local). Los planes de App Service se implementarán con la SKU gratuita F1.

Una manera de implementar estos requisitos empresariales es usar parámetros para especificar cada SKU. Sin embargo, la especificación de cada SKU como parámetro puede volverse difícil de administrar, especialmente cuando se tienen plantillas más grandes. Otra opción es insertar las reglas de negocio en la plantilla mediante una combinación de parámetros, variables y expresiones.

En primer lugar, puede especificar un parámetro que indique si la implementación es para un entorno de producción o que no sea de producción:

@allowed([
  'nonprod'
  'prod'
])
param environmentType string

Tenga en cuenta que este código usa sintaxis nueva para especificar una lista de valores permitidos para el parámetro environmentType. Bicep no permitirá que nadie implemente la plantilla a menos que se proporcione uno de estos valores.

A continuación, puede crear variables que determinen las SKU que se usarán para la cuenta de almacenamiento y el plan de App Service según el entorno:

var storageAccountSkuName = (environmentType == 'prod') ? 'Standard_GRS' : 'Standard_LRS'
var appServicePlanSkuName = (environmentType == 'prod') ? 'P2V3' : 'F1'

Observe una nueva sintaxis también aquí. Vamos a desglosarla:

  • (environmentType == 'prod') se evalúa como un valor booleano (true o false), en función del valor permitido que se utiliza para el parámetro environmentType.
  • ? se denomina un operador ternario y evalúa una instrucción if/then. El valor después del operador ? se usa si la expresión es verdadera. Si la expresión se evalúa como falsa, se usa el valor después de los dos puntos (:).

Podemos traducir estas reglas a:

  • Para la variable storageAccountSkuName, si el parámetro environmentType está establecido en prod, use la SKU Standard_GRS. De lo contrario, use la SKU Standard_LRS.
  • Para la variable appServicePlanSkuName, si el parámetro environmentType está establecido en prod, use la SKU P2V3 y el nivel PremiumV3. De lo contrario, use la SKU F1.

Sugerencia

Al crear expresiones de varias partes como esta, es mejor usar variables en lugar de insertar las expresiones directamente en las propiedades del recurso. De esta forma, las plantillas son más fáciles de leer y comprender, ya que se evita que las definiciones de recursos se abarroten con la lógica.

Cuando usa parámetros, variables y expresiones en la plantilla, puede volver a utilizar la plantilla e implementar rápidamente un conjunto nuevo de recursos. Por ejemplo, cada vez que el departamento de marketing le pide que implemente un sitio web nuevo para el lanzamiento del próximo juguete, proporcione valores de parámetro nuevos para cada entorno que implemente. ¡Y listo!