Definir recursos filho

Concluído

Faz sentido implantar alguns recursos apenas dentro do contexto de seu pai. Esses recursos são chamados de recursos filho. Há muitos tipos de recursos filho no Azure. Veja alguns exemplos:

Nome Tipo de recurso
Sub-redes da rede virtual Microsoft.Network/virtualNetworks/subnets
Configuração do Serviço de Aplicativo Microsoft.Web/sites/config
Bancos de dados SQL Microsoft.Sql/servers/databases
Extensões de máquina virtual Microsoft.Compute/virtualMachines/extensions
Contêineres de blobs de armazenamento Microsoft.Storage/storageAccounts/blobServices/containers
Contêineres do Azure Cosmos DB Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers

Por exemplo, vamos considerar um contêiner de blobs de armazenamento. Um contêiner de blobs deve ser implantado em uma conta de armazenamento, e não faz sentido que um contêiner exista fora de uma conta de armazenamento.

Os tipos de recursos filho têm nomes mais longos com várias partes. Um contêiner de blob de armazenamento tem o seguinte nome de tipo totalmente qualificado: Microsoft.Storage/storageAccounts/blobServices/containers. A ID de recurso de um contêiner de blob inclui o nome da conta de armazenamento que contém o contêiner e o nome deste.

Observação

Alguns recursos filho podem ter o mesmo nome que outros tipos de recursos filho de diferentes pais. Por exemplo, containers é um tipo filho de ambas as contas de armazenamento e bancos de dados do Azure Cosmos DB. Os nomes são os mesmos, mas representam recursos diferentes e seus nomes de tipo totalmente qualificados são distintos.

Como os recursos filho são definidos?

Com o Bicep, você pode declarar recursos filho de várias maneiras diferentes. Cada maneira tem suas próprias vantagens, e cada uma é adequada para algumas situações e não para outras. Vamos examinar cada abordagem.

Dica

Todas as abordagens a seguir resultam nas mesmas atividades de implantação no Azure. Você pode escolher a abordagem que melhor atenda às suas necessidades sem precisar se preocupar em interromper algo. E pode atualizar seu modelo e alterar a abordagem que está usando.

Recursos aninhados

Uma abordagem de definição de um recurso filho é aninhá-lo dentro do pai. Confira um exemplo de modelo Bicep que implanta uma máquina virtual e uma extensão de máquina virtual. Uma extensão de máquina virtual é um recurso filho que fornece comportamento extra para uma máquina virtual. Nesse caso, a extensão executa um script personalizado na máquina virtual após a implantação.

resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = {
  name: vmName
  location: location
  properties: {
    // ...
  }

  resource installCustomScriptExtension 'extensions' = {
    name: 'InstallCustomScript'
    location: location
    properties: {
      // ...
    }
  }
}

Observe que o recurso aninhado tem um tipo mais simples que o normal. Embora o nome do tipo totalmente qualificado seja Microsoft.Compute/virtualMachines/extensions, o recurso aninhado herda automaticamente o tipo de recurso do pai, portanto, você precisa especificar apenas o tipo de recurso filho, extensions.

Observe também que não há nenhuma versão de API especificada para o recurso aninhado. O Bicep pressupõe que você deseja usar a mesma versão de API que o recurso pai, embora você possa substituir a versão da API caso queira.

Você pode fazer referência a um recurso aninhado usando o operador ::. Por exemplo, você pode criar uma saída que retorna a ID de recurso completa da extensão:

output childResourceId string = vm::installCustomScriptExtension.id

O aninhamento de recursos é uma maneira simples de declarar um recurso filho. Esse aninhamento também torna a relação pai-filho óbvia para qualquer pessoa que leia o modelo. No entanto, se você tiver muitos recursos aninhados ou várias camadas de aninhamento, os modelos poderão ficar mais difíceis de ler. O aninhamento de recursos também só pode ter até cinco camadas de profundidade.

Propriedade pai

Uma segunda abordagem é declarar o recurso filho sem nenhum aninhamento. Em seguida, use a propriedade parent para informar o Bicep sobre a relação pai-filho:

resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = {
  name: vmName
  location: location
  properties: {
    // ...
  }
}

resource installCustomScriptExtension 'Microsoft.Compute/virtualMachines/extensions@2024-07-01' = {
  parent: vm
  name: 'InstallCustomScript'
  location: location
  properties: {
    // ...
  }
}

Observe que o recurso filho usa a propriedade parent para se referir ao nome simbólico de seu pai.

Essa abordagem para referenciar o pai é outra maneira fácil de declarar um recurso filho. O Bicep compreende a relação entre os recursos pai e filho. Portanto, você não precisa especificar o nome totalmente qualificado do recurso nem configurar uma dependência entre recursos. Essa abordagem também evita muitos aninhamentos, que podem dificultar sua leitura. No entanto, você precisa especificar explicitamente o tipo de recurso completo e a versão da API cada vez que definir um recurso filho usando a propriedade parent.

Para se referir a um recurso filho declarado com a propriedade parent, use o seu nome simbólico como faria com um recurso pai normal:

output childResourceId string = installCustomScriptExtension.id

Construir o nome do recurso

Há algumas circunstâncias em que você não pode usar recursos aninhados ou a palavra-chave parent. Um exemplo disso é quando você declara recursos filho dentro de um loop for ou quando precisa usar expressões complexas para selecionar dinamicamente um recurso pai para um filho. Nessas situações, você pode implantar um recurso filho construindo manualmente o nome dele para que inclua o nome de seu recurso pai, como mostrado aqui:

resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = {
  name: vmName
  location: location
  properties: {
    // ...
  }
}

resource installCustomScriptExtension 'Microsoft.Compute/virtualMachines/extensions@2024-07-01' = {
  name: '${vm.name}/InstallCustomScript'
  location: location
  properties: {
    // ...
  }
}

Observe que esse exemplo usa a interpolação de cadeia de caracteres para acrescentar a propriedade name de recurso de máquina virtual ao nome do recurso filho. O Bicep entende que há uma dependência entre seus recursos filho e pai. Alternativamente, você pode declarar o nome do recurso filho usando a variável vmName. No entanto, se você fizer isso, sua implantação poderá falhar porque o Bicep pode não entender que o recurso pai precisa ser implantado antes do recurso filho:

Para resolver essa situação, você pode informar manualmente ao Bicep sobre a dependência usando a palavra-chave dependsOn, conforme mostrado aqui:

resource vm 'Microsoft.Compute/virtualMachines@2024-07-01' = {
  name: vmName
  location: location
  properties: {
    // ...
  }
}

resource installCustomScriptExtension 'Microsoft.Compute/virtualMachines/extensions@2024-07-01' = {
  name: '${vmName}/InstallCustomScript'
  dependsOn: [
    vm
  ]
  //...
}

Dica

De maneira geral, é melhor evitar a construção de nomes de recursos, pois perde-se muitos dos benefícios que o Bicep pode fornecer quando entende as relações entre seus recursos. Use essa opção somente quando não for possível usar uma das outras abordagens para declarar recursos filho.

IDs de recurso filho

Você começa a criar uma ID de recurso filho, incluindo a ID de seu pai, anexando o tipo e o nome do recurso. Por exemplo, vamos considerar uma conta do Azure Cosmos DB chamada toyrnd. O provedor de recursos do Azure Cosmos DB expõe um tipo chamado databaseAccounts, que é o recurso pai que você implanta:

/subscriptions/A123b4567c-1234-1a2b-2b1a-1234abc12345/resourceGroups/ToyDevelopment/providers/Microsoft.DocumentDB/databaseAccounts/toyrnd

Confira uma representação visual da mesma ID de recurso:

ID do recurso de uma conta do Azure Cosmos DB dividida com o par chave-valor em uma linha separada.

Se adicionarmos um banco de dados a essa conta, poderemos usar o tipo de recurso filho sqlDatabases. Vamos adicionar um banco de dados chamado FlightTests à nossa conta do Azure Cosmos DB e observar a ID do recurso filho:

/subscriptions/A123b4567c-1234-1a2b-2b1a-1234abc12345/resourceGroups/ToyDevelopment/providers/Microsoft.DocumentDB/databaseAccounts/toyrnd/sqlDatabases/FlightTests

Confira uma representação visual:

ID do recurso filho de um banco de dados do Azure Cosmos DB dividida com o par chave-valor em uma linha separada.

Você pode ter vários níveis de recursos filho. Confira um exemplo de ID de recurso que mostra uma conta de armazenamento com dois níveis de filhos:

/subscriptions/A123b4567c-1234-1a2b-2b1a-1234abc12345/resourceGroups/ToyDevelopment/providers/Microsoft.Storage/storageAccounts/secrettoys/blobServices/default/containers/glitterspecs

Confira uma representação visual da mesma ID de recurso:

ID do recurso filho de uma conta de armazenamento com contêiner de blobs, dividida com o par chave-valor em uma linha separada.

Essa ID de recurso tem vários componentes:

  • Tudo até secrettoys é a ID do recurso pai.

  • blobServices indica que o recurso está dentro de um tipo de recurso filho chamado blobServices.

    Observação

    Você não precisa criar recursos blobServices por conta própria. O provedor de recursos Microsoft.Storage o cria automaticamente quando você cria uma conta de armazenamento. Às vezes, esse tipo de recurso é chamado de implícito. Eles são bastante incomuns, mas você os encontrará em todo o Azure.

  • default é o nome do recurso filho blobServices.

    Observação

    Às vezes, apenas uma única instância de um recurso filho é permitida. Esse tipo de instância é chamado de singleton e geralmente recebe o nome de default.

  • containers indica que o recurso está dentro de um tipo de recurso filho chamado containers.

  • glitterspecs é o nome do contêiner de blobs.

Quando você trabalha com recursos filhos, as IDs podem parecer longas e complicadas. No entanto, se você dividir uma ID de recurso em suas partes componentes, será mais fácil entender como o recurso é estruturado. Uma ID de recurso também pode fornecer dicas importantes sobre como o recurso se comporta.