Ejercicio: Adición de un archivo de parámetros y de parámetros seguros

Completado

En este ejercicio, creará un archivo de parámetros que proporciona valores para el archivo de Bicep que creó anteriormente. En el mismo archivo de parámetros, también agregará referencias de Azure Key Vault para proporcionar información confidencial de forma segura.

Durante el proceso, hará estas tareas:

  • Agregar algunos parámetros seguros.
  • Crear un archivo de parámetros.
  • Probar la implementación para asegurarse de que el archivo de parámetros es válido.
  • Crear un almacén de claves y secretos.
  • Actualizar el archivo de parámetros para hacer referencia a los secretos del almacén de claves.
  • Volver a probar la implementación para asegurarse de que el archivo de parámetros sigue siendo válido.

Eliminación del valor predeterminado de la SKU del plan de App Service

Para que la plantilla funcione entre entornos, los detalles de la SKU del plan de Azure App Service se proporcionan en un archivo de parámetros en lugar de en un valor predeterminado.

En el archivo main.bicep de Visual Studio Code, actualice el parámetro appServicePlanSku para eliminar su valor predeterminado.

@description('The name and tier of the App Service plan SKU.')
param appServicePlanSku object

Adición de parámetros nuevos

Ahora, debe agregar una base de datos y un servidor SQL Server. En primer lugar, agregará parámetros para el inicio de sesión y la contraseña del administrador, y la SKU de la base de datos. Más adelante establecerá sus valores.

En el archivo main.bicep de Visual Studio Code, agregue los parámetros sqlServerAdministratorLogin, sqlServerAdministratorPassword y sqlDatabaseSku debajo de las declaraciones de parámetros actuales. Cuando haya terminado, las declaraciones de parámetros deben tener un aspecto parecido al de este ejemplo:

@description('The name of the environment. This must be dev, test, or prod.')
@allowed([
  'dev'
  'test'
  'prod'
])
param environmentName string = 'dev'

@description('The unique name of the solution. This is used to ensure that resource names are unique.')
@minLength(5)
@maxLength(30)
param solutionName string = 'toyhr${uniqueString(resourceGroup().id)}'

@description('The number of App Service plan instances.')
@minValue(1)
@maxValue(10)
param appServicePlanInstanceCount int = 1

@description('The name and tier of the App Service plan SKU.')
param appServicePlanSku object

@description('The Azure region into which the resources should be deployed.')
param location string = 'eastus'

@secure()
@description('The administrator login username for the SQL server.')
param sqlServerAdministratorLogin string

@secure()
@description('The administrator login password for the SQL server.')
param sqlServerAdministratorPassword string

@description('The name and tier of the SQL database SKU.')
param sqlDatabaseSku object

Tenga en cuenta que no va a especificar los valores predeterminados para los parámetros sqlServerAdministratorLogin y sqlServerAdministratorPassword. No es una práctica de seguridad recomendada agregar valores predeterminados para parámetros seguros. Además, no va a especificar ningún valor predeterminado para sqlDatabaseSku. Especificará un valor en un archivo de parámetros.

Adición de variables nuevas

En el archivo main.bicep de Visual Studio Code, agregue las variables sqlServerName y sqlDatabaseName debajo de las variables existentes. Cuando haya terminado, las declaraciones de variables deben tener un aspecto parecido al de este ejemplo:

var appServicePlanName = '${environmentName}-${solutionName}-plan'
var appServiceAppName = '${environmentName}-${solutionName}-app'
var sqlServerName = '${environmentName}-${solutionName}-sql'
var sqlDatabaseName = 'Employees'

Adición de recursos de base de datos y servidor de SQL Server

  1. En el archivo main.bicep en Visual Studio Code, agregue el código siguiente en la parte inferior:

    resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = {
      name: sqlServerName
      location: location
      properties: {
        administratorLogin: sqlServerAdministratorLogin
        administratorLoginPassword: sqlServerAdministratorPassword
      }
    }
    
    resource sqlDatabase 'Microsoft.Sql/servers/databases@2023-08-01-preview' = {
      parent: sqlServer
      name: sqlDatabaseName
      location: location
      sku: {
        name: sqlDatabaseSku.name
        tier: sqlDatabaseSku.tier
      }
    }
    
  2. Guarde los cambios en el archivo.

Comprobación del archivo de Bicep

Una vez completados todos los cambios anteriores, el archivo de Bicep debe tener un aspecto parecido al de este ejemplo:

@description('The name of the environment. This must be dev, test, or prod.')
@allowed([
  'dev'
  'test'
  'prod'
])
param environmentName string = 'dev'

@description('The unique name of the solution. This is used to ensure that resource names are unique.')
@minLength(5)
@maxLength(30)
param solutionName string = 'toyhr${uniqueString(resourceGroup().id)}'

@description('The number of App Service plan instances.')
@minValue(1)
@maxValue(10)
param appServicePlanInstanceCount int = 1

@description('The name and tier of the App Service plan SKU.')
param appServicePlanSku object

@description('The Azure region into which the resources should be deployed.')
param location string = 'eastus'

@secure()
@description('The administrator login username for the SQL server.')
param sqlServerAdministratorLogin string

@secure()
@description('The administrator login password for the SQL server.')
param sqlServerAdministratorPassword string

@description('The name and tier of the SQL database SKU.')
param sqlDatabaseSku object

var appServicePlanName = '${environmentName}-${solutionName}-plan'
var appServiceAppName = '${environmentName}-${solutionName}-app'
var sqlServerName = '${environmentName}-${solutionName}-sql'
var sqlDatabaseName = 'Employees'

resource appServicePlan 'Microsoft.Web/serverfarms@2023-12-01' = {
  name: appServicePlanName
  location: location
  sku: {
    name: appServicePlanSku.name
    tier: appServicePlanSku.tier
    capacity: appServicePlanInstanceCount
  }
}

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

resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = {
  name: sqlServerName
  location: location
  properties: {
    administratorLogin: sqlServerAdministratorLogin
    administratorLoginPassword: sqlServerAdministratorPassword
  }
}

resource sqlDatabase 'Microsoft.Sql/servers/databases@2023-08-01-preview' = {
  parent: sqlServer
  name: sqlDatabaseName
  location: location
  sku: {
    name: sqlDatabaseSku.name
    tier: sqlDatabaseSku.tier
  }
}

Si no es así, copie el ejemplo o ajuste la plantilla para que coincida con él.

Creación de un archivo de parámetros

  1. Abra Visual Studio Code y abra la carpeta donde se encuentra el archivo main.bicep. En la misma carpeta, cree un archivo denominado main.parameters.dev.json.

  2. En el archivo main.parameters.dev.json, agregue el código siguiente:

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "appServicePlanSku": {
          "value": {
            "name": "F1",
            "tier": "Free"
          }
        },
        "sqlDatabaseSku": {
          "value": {
            "name": "Standard",
            "tier": "Standard"
          }
        }
      }
    }
    
  3. Guarde los cambios en el archivo.

Implementación de la plantilla de Bicep con el archivo de parámetros

Ejecute el siguiente comando de la CLI de Azure en el terminal. Tenga en cuenta que va a proporcionar un archivo de parámetros para la implementación.

az deployment group create \
  --template-file main.bicep \
  --parameters main.parameters.dev.json

Ejecute el siguiente comando de Azure PowerShell en el terminal. Tenga en cuenta que va a proporcionar un archivo de parámetros para la implementación.

New-AzResourceGroupDeployment `
  -TemplateFile main.bicep `
  -TemplateParameterFile main.parameters.dev.json

Al ejecutar la implementación, se le pedirá que escriba los valores de los parámetros sqlServerAdministratorLogin y sqlServerAdministratorPassword. No es necesario especificar solutionName porque tiene un valor predeterminado especificado en la plantilla. No es necesario especificar los otros valores de parámetros porque sus valores están especificados en el archivo de parámetros.

Sugerencia

Cuando especifique los parámetros seguros, los valores que elija deben seguir algunas reglas:

  • sqlServerAdministratorLogin no debe ser un nombre de inicio de sesión fácil de adivinar, como admin o root. Solo puede contener caracteres alfanuméricos y debe comenzar con una letra.
  • sqlServerAdministratorPassword debe tener al menos ocho caracteres e incluir letras minúsculas, letras mayúsculas, números y símbolos. Para más información sobre la complejidad de la contraseña, consulte la directiva de contraseñas de SQL Azure.

Si los valores de los parámetros no cumplen los requisitos, Azure SQL no implementará el servidor.

Además, asegúrese de anotar el inicio de sesión y la contraseña que escriba. Los usará en la siguiente sección.

La implementación puede tardar un par de minutos en finalizar.

Creación de un almacén de claves y secretos

La empresa de juguetes ya tiene un almacén de claves con los secretos que necesita para sus implementaciones. Para simular este escenario, creará un nuevo almacén de claves y agregará algunos secretos para usarlos.

En el terminal, ejecute los siguientes comandos para crear el almacén de claves y los secretos. Actualice los valores de variables antes de ejecutar estos comandos. Los nombres del almacén de claves deben ser una cadena única global de 3 a 24 caracteres que solo pueden contener letras mayúsculas y minúsculas, guiones (-) y números. Por ejemplo, demo-kv-1234567abcdefg.

Precaución

Asegúrese de usar el mismo inicio de sesión y contraseña que usó en el paso anterior. Si no lo hace, la siguiente implementación no se completará correctamente.

Para keyVaultName, reemplace YOUR-KEY-VAULT-NAME por un nombre para el almacén de claves. Los comandos read de las variables login y password le pedirán valores. A medida que se va escribiendo, los valores no se muestran en el terminal y no se guardan en el historial de comandos.

Tenga en cuenta los siguientes elementos a la hora de proteger los valores de variable en una sesión de terminal de Bash:

  • Los valores de variable no se almacenan como una cadena segura, y se pueden mostrar escribiendo un comando como $yourVariableName en la línea de comandos o con el comando echo. En este ejercicio, una vez creados los secretos del almacén, puede quitar el valor existente de cada variable ejecutando los comandos read, sin tener que introducir un valor.
  • az keyvault secret set usa el parámetro --value para crear el valor de un secreto. La salida del comando muestra una propiedad denominada value que contiene el valor del secreto. Puede suprimir la salida completa del comando con el parámetro --output none, como se muestra en el ejemplo.

Para crear las variables keyVaultName, login y password, ejecute cada comando por separado. A continuación, puede ejecutar el bloque de comandos para crear el almacén de claves y los secretos.

keyVaultName='YOUR-KEY-VAULT-NAME'
read -s -p "Enter the login name: " login
read -s -p "Enter the password: " password

az keyvault create --name $keyVaultName --location eastus --enabled-for-template-deployment true
az keyvault secret set --vault-name $keyVaultName --name "sqlServerAdministratorLogin" --value $login --output none
az keyvault secret set --vault-name $keyVaultName --name "sqlServerAdministratorPassword" --value $password --output none

Nota:

Configure la opción --enabled-for-template-deployment en el almacén, para que Azure pueda usar los secretos del almacén durante las implementaciones. Si no establece esta configuración, de forma predeterminada, las implementaciones no podrán acceder a los secretos del almacén.

Además, quien ejecute la implementación también debe tener permiso para acceder al almacén. Dado que ha creado el almacén de claves, es el propietario, por lo que no tendrá que conceder explícitamente el permiso en este ejercicio. En sus propios almacenes, debe conceder acceso a los secretos.

Para keyVaultName, reemplace YOUR-KEY-VAULT-NAME por un nombre para el almacén de claves. Los comandos Read-Host de las variables login y password le pedirán valores. A medida que se va escribiendo, los valores no se muestran en el terminal y no se guardan en el historial de comandos. Los valores se almacenan como una cadena segura.

Para crear las variables keyVaultName, login y password, ejecute cada comando por separado. A continuación, puede ejecutar el bloque de comandos para crear el almacén de claves y los secretos.

$keyVaultName = 'YOUR-KEY-VAULT-NAME'
$login = Read-Host "Enter the login name" -AsSecureString
$password = Read-Host "Enter the password" -AsSecureString

New-AzKeyVault -VaultName $keyVaultName -Location eastus -EnabledForTemplateDeployment
Set-AzKeyVaultSecret -VaultName $keyVaultName -Name 'sqlServerAdministratorLogin' -SecretValue $login
Set-AzKeyVaultSecret -VaultName $keyVaultName -Name 'sqlServerAdministratorPassword' -SecretValue $password

Nota:

Configure la opción -EnabledForTemplateDeployment en el almacén, para que Azure pueda usar los secretos del almacén durante las implementaciones. Si no establece esta configuración, de forma predeterminada, las implementaciones no podrán acceder a los secretos del almacén.

Además, quien ejecute la implementación también debe tener permiso para acceder al almacén. Dado que ha creado el almacén de claves, es el propietario, por lo que no tendrá que conceder explícitamente el permiso en este ejercicio. En sus propios almacenes, debe conceder acceso a los secretos.

Obtención del identificador de recurso del almacén de claves

Para usar los secretos del almacén de claves en la implementación, necesita el identificador de recurso del almacén. Ejecute el siguiente comando para recuperar el identificador de recurso del almacén de claves:

az keyvault show --name $keyVaultName --query id --output tsv
(Get-AzKeyVault -Name $keyVaultName).ResourceId

El identificador de recurso tendrá un aspecto similar al siguiente ejemplo:

/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/PlatformResources/providers/Microsoft.KeyVault/vaults/toysecrets

Copie el identificador de recurso. La usará en el paso siguiente.

Adición de una referencia de almacén de claves a un archivo de parámetros

  1. En el archivo main.parameters.dev.json, anexe el código siguiente después de la llave de cierre del parámetro sqlDatabaseSku. Asegúrese de reemplazar YOUR-KEY-VAULT-RESOURCE-ID por el valor del identificador de recurso del almacén de claves que copió en el paso anterior. Cuando haya terminado, el archivo de parámetros debe tener un aspecto parecido al de este ejemplo:

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "appServicePlanSku": {
          "value": {
            "name": "F1",
            "tier": "Free"
          }
        },
        "sqlDatabaseSku": {
          "value": {
            "name": "Standard",
            "tier": "Standard"
          }
        },
        "sqlServerAdministratorLogin": {
          "reference": {
            "keyVault": {
              "id": "YOUR-KEY-VAULT-RESOURCE-ID"
            },
            "secretName": "sqlServerAdministratorLogin"
          }
        },
        "sqlServerAdministratorPassword": {
          "reference": {
            "keyVault": {
              "id": "YOUR-KEY-VAULT-RESOURCE-ID"
            },
            "secretName": "sqlServerAdministratorPassword"
          }
        }
      }
    }
    
  2. Guarde los cambios en el archivo.

Implementación de la plantilla de Bicep con el archivo de parámetros y las referencias de Azure Key Vault

Ejecute el siguiente comando de la CLI de Azure en el terminal. Va a proporcionar un archivo de parámetros junto con un archivo de Bicep.

az deployment group create \
  --template-file main.bicep \
  --parameters main.parameters.dev.json

Ejecute el siguiente comando de Azure PowerShell en el terminal. Va a proporcionar un archivo de parámetros junto con un archivo de Bicep.

New-AzResourceGroupDeployment `
  -TemplateFile main.bicep `
  -TemplateParameterFile main.parameters.dev.json

Al ejecutar la implementación esta vez, no se le pedirá que escriba los valores de los parámetros sqlServerAdministratorLogin y sqlServerAdministratorPassword. En su lugar, Azure recupera los valores del almacén de claves.

La implementación se completa más rápidamente esta vez porque los recursos de Azure ya existen.

Comprobación de la implementación

  1. En el explorador, vuelva a Azure Portal. Vaya a su grupo de recursos. Seguirá viendo una implementación correcta, ya que esta habrá usado el mismo nombre que la primera.

  2. Seleccione el vínculo 1 Succeeded (1 correcta).

  3. Seleccione la implementación denominada main.

  4. En el menú de la izquierda, seleccione Entradas.

  5. Observe que los valores de parámetros appServicePlanSku y sqlDatabaseSku se han establecido en los valores del archivo de parámetros. Además, tenga en cuenta que los valores de parámetros sqlServerAdministratorLogin y sqlServerAdministratorPassword no se muestran, porque les aplicó el decorador @secure().

    Captura de pantalla de la interfaz de Azure Portal de la implementación específica, donde se muestran los valores de parámetros.