Trabajo con recursos existentes

Completado

Los archivos de Bicep a menudo necesitan hacer referencia a recursos que se han creado en otra parte. Estos recursos podrían haberse creado manualmente, quizás por un compañero que usa Azure Portal. O bien, podrían crearse en otro archivo de Bicep. Hay muchas razones por las que debe hacer referencia a estos recursos, como las siguientes:

  • Va a agregar una base de datos SQL en una instancia de servidor lógico de Azure SQL que alguien ya ha creado.
  • Está configurando los ajustes de diagnóstico para los recursos que están definidos en otro módulo de Bicep.
  • Tiene que acceder de forma segura a las claves de una cuenta de almacenamiento que se ha implementado manualmente en su suscripción.

Bicep proporciona la palabra clave existing para que la use en estas situaciones.

Nota:

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

Referencia a recursos existentes

Dentro de un archivo de Bicep, puede definir un recurso que ya existe. La declaración es similar a una definición de recursos normal, pero hay algunas diferencias clave. En el ejemplo siguiente de una definición de recurso existente, la definición hace referencia a una cuenta de almacenamiento denominada toydesigndocs. La cuenta de almacenamiento se encuentra en el mismo grupo de recursos en el que la plantilla de Bicep está implementando recursos.

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' existing = {
  name: 'toydesigndocs'
}

Echemos un vistazo a los elementos que componen esta definición:

  • Como lo haría con un recurso normal, incluya la palabra clave resource, un nombre simbólico y el tipo de recurso y la versión de API.

    Nota:

    Recuerde que el nombre simbólico solo se usa dentro de este archivo de Bicep. Si crea este recurso mediante un archivo de Bicep y hace referencia a él mediante el uso del recurso existing en otro archivo de Bicep, los nombres simbólicos no tienen que coincidir.

  • La palabra clave existing indica a Bicep que esta definición de recurso es una referencia a un recurso ya creado y que Bicep no debe intentar implementarlo.

  • La propiedad name es el nombre del recurso de Azure de la cuenta de almacenamiento que se implementó anteriormente.

  • No es necesario especificar location, sku o properties, porque la plantilla no implementa el recurso. Simplemente hace referencia a un recurso existente. Considérelo un recurso de marcador de posición.

Referencia a los recursos secundarios

También puede hacer referencia a un recurso secundario existente. Use el mismo tipo de sintaxis que empleó al implementar un recurso secundario. En el ejemplo siguiente se muestra cómo puede hacer referencia a una subred existente, que es un recurso secundario de una red virtual. En el ejemplo se usa un recurso secundario anidado, como se muestra aquí:

resource vnet 'Microsoft.Network/virtualNetworks@2024-01-01' existing = {
  name: 'toy-design-vnet'

  resource managementSubnet 'subnets' existing = {
    name: 'management'
  }
}

Observe que tanto el recurso primario como el secundario tienen aplicada la palabra clave existing.

A continuación, puede hacer referencia a la subred mediante el mismo operador :: que usa para otros recursos secundarios anidados:

output managementSubnetResourceId string = vnet::managementSubnet.id

Referencia a recursos fuera del grupo de recursos

A menudo, tendrá que hacer referencia a los recursos de un grupo de recursos diferente. Por ejemplo, si tiene una red virtual en un grupo de recursos centralizado, es posible que quiera implementar una máquina virtual en esa red virtual en su propio grupo de recursos. Puede usar la palabra clave scope para hacer referencia a recursos existentes en un grupo de recursos diferente. En el ejemplo siguiente se muestra cómo puede hacer referencia a una red virtual denominada toy-design-vnet dentro del grupo de recursos networking-rg:

resource vnet 'Microsoft.Network/virtualNetworks@2024-01-01' existing = {
  scope: resourceGroup('networking-rg')
  name: 'toy-design-vnet'
}

Observe que scope usa la palabra clave resourceGroup() para hacer referencia al grupo de recursos que contiene la red virtual.

Puede incluso hacer referencia a los recursos de una suscripción de Azure diferente, siempre que la suscripción esté dentro de su inquilino de Microsoft Entra. Si el equipo de redes aprovisiona la red virtual en una suscripción diferente, la plantilla podría hacer referencia a ella como en este ejemplo:

resource vnet 'Microsoft.Network/virtualNetworks@2024-01-01' existing = {
  scope: resourceGroup('A123b4567c-1234-1a2b-2b1a-1234abc12345', 'networking-rg')
  name: 'toy-design-vnet'
}

Observe que scope usa la palabra clave resourceGroup() para hacer referencia al identificador de suscripción de Azure (A123b4567c-1234-1a2b-2b1a-1234abc12345) y al nombre del grupo de recursos que contiene la red virtual.

Ahora que sabe cómo hacer referencia a los recursos existentes, echemos un vistazo a cómo puede usar esta funcionalidad en las plantillas.

Adición de recursos secundarios y de extensión a un recurso existente

Puede agregar un recurso secundario a un recurso primario ya creado mediante una combinación de la palabra clave existing y la palabra clave parent. En la plantilla de ejemplo siguiente se crea una base de datos de Azure SQL en un servidor que ya existe:

resource server 'Microsoft.Sql/servers@2023-08-01-preview' existing = {
  name: serverName
}

resource database 'Microsoft.Sql/servers/databases@2023-08-01-preview' = {
  parent: server
  name: databaseName
  location: location
  sku: {
    name: 'Standard'
    tier: 'Standard'
  }
}

Si necesita implementar un recurso de extensión en un recurso existente, puede usar la palabra clave scope. Esta es una plantilla que usa la palabra clave existing y la palabra clave scope para agregar un bloqueo de recursos a una cuenta de almacenamiento que ya existe:

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' existing = {
  name: 'toydesigndocs'
}

resource lockResource 'Microsoft.Authorization/locks@2020-05-01' = {
  scope: storageAccount
  name: 'DontDelete'
  properties: {
    level: 'CanNotDelete'
    notes: 'Prevents deletion of the toy design documents storage account.'
  }
}

Referencia a las propiedades de un recurso existente

Los recursos a menudo necesitan hacer referencia a las propiedades de otros recursos. Por ejemplo, si implementa una aplicación, es posible que tenga que conocer las claves o la información de conexión de otro recurso. Con la palabra clave existing, se obtiene acceso a las propiedades del recurso al que se hace referencia.

Sugerencia

Es un procedimiento recomendado buscar claves de otros recursos de esta manera en lugar de pasarlas por las salidas. Siempre se obtienen los datos más actualizados. Además, lo importante es que las salidas no están diseñadas para administrar datos seguros, como claves.

La forma de acceder a la información sobre un recurso depende del tipo de información que se obtenga. Si se trata de una propiedad que no es segura, normalmente solo usa el elemento properties del recurso. En la siguiente plantilla de ejemplo se implementa una aplicación de Azure Functions, y se utilizan los detalles de acceso (clave de instrumentación) para una instancia de Application Insights que ya se creó:

resource applicationInsights 'Microsoft.Insights/components@2020-02-02' existing = {
  name: applicationInsightsName
}

resource functionApp 'Microsoft.Web/sites@2023-12-01' = {
  name: functionAppName
  location: location
  kind: 'functionapp'
  properties: {
    siteConfig: {
      appSettings: [
        // ...
        {
          name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
          value: applicationInsights.properties.InstrumentationKey
        }
      ]
    }
  }
}

En este ejemplo, dado que la clave de instrumentación no se considera información confidencial, está disponible en el elemento properties del recurso. Cuando necesite acceder a datos seguros, como las credenciales que se usarán para acceder a un recurso, use la función listKeys(), como se muestra en el código siguiente:

resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' existing = {
  name: storageAccountName
}

resource functionApp 'Microsoft.Web/sites@2023-12-01' = {
  name: functionAppName
  location: location
  kind: 'functionapp'
  properties: {
    siteConfig: {
      appSettings: [
        // ...
        {
          name: 'StorageAccountKey'
          value: storageAccount.listKeys().keys[0].value
        }
      ]
    }
  }
}

Observe que la función listKeys devuelve una matriz keys. El código Bicep recupera la propiedad value del primer elemento de la matriz keys. Cada tipo de recurso tiene información diferente disponible de la función listKeys(). La extensión de Bicep para Visual Studio Code proporciona sugerencias que lo ayudan a saber los datos que devuelve la función listKeys() de cada recurso. En la siguiente captura de pantalla, se muestra la salida de la función listKeys() para una cuenta de almacenamiento:

Captura de pantalla de la extensión de Bicep para Visual Studio Code. IntelliSense muestra alguna de la información devuelta por la función listKeys para una cuenta de almacenamiento.

Algunos recursos admiten otras funciones también. La característica IntelliSense de Visual Studio Code enumera las funciones disponibles para cada recurso. En la siguiente captura de pantalla, puede ver que las cuentas de almacenamiento proporcionan las funciones denominadas listAccountSas() y listServiceSas(), además de listKeys():

Captura de pantalla de la extensión Bicep para Visual Studio Code. IntelliSense muestra varias funciones disponibles para la cuenta de almacenamiento.

Importante

La función listKeys() proporciona acceso a datos confidenciales sobre el recurso. Esto significa que el usuario o la entidad de servicio que ejecuta la implementación debe tener el nivel de permiso adecuado en el recurso. Suele ser el rol integrado Colaborador o un rol personalizado que asigne el permiso adecuado.