Agrupar recursos relacionados usando módulos

Concluído

Você começou a usar modelos Bicep para alguns lançamentos recentes de produtos, e eles têm tido sucesso. Como você declarou seus recursos em um arquivo de modelo, poderá implantá-los com rapidez em novos lançamentos de brinquedos sem a necessidade de configurar manualmente os recursos no portal do Azure.

O gerente de TI percebe que o seu código Bicep está se ficando cada vez mais complexo e tem um número crescente de recursos definidos, então ele pergunta se você pode tornar o código mais modularizado. Você pode criar arquivos Bicep individuais, chamados de módulos, para diferentes partes de sua implantação. O modelo principal do Bicep pode fazer referência a esses módulos. Nos bastidores, os módulos são transcompilados em um único modelo JSON para implantação.

Os módulos também são uma forma de tornar o código Bicep ainda mais reutilizável. Você pode ter um único módulo Bicep que muitos modelos Bicep usam.

Geralmente, você também precisará emitir saídas dos modelos e módulos do Bicep. As saídas são uma forma do seu código Bicep enviar dados de volta para quem iniciou a implantação. Vamos examinar as saídas primeiro.

Observação

Os comandos nesta unidade são mostrados para ilustrar conceitos. Não execute os comandos ainda. Você praticará o que aprendeu aqui em breve.

Saídas

Os modelos Bicep podem ser implantados manualmente por um humano, ou isso pode ser feito por algum tipo de processo de liberação automatizado. De qualquer forma, é comum ter alguns dados do modelo que precisam ser enviados de volta a quem (ou o que) está executando a implantação dele.

Aqui estão alguns cenários de exemplo em que talvez seja necessário obter informações da implantação do modelo:

  • Você cria um modelo do Bicep que implanta uma máquina virtual e precisa obter o endereço IP público para que possa usar SSH no computador.
  • Você cria um modelo Bicep que aceita um conjunto de parâmetros, como um nome de ambiente e um nome de aplicativo. O modelo usa uma expressão para criar o nome de um aplicativo do Serviço de Aplicativo do Azure que ele implanta. É preciso gerar o nome do aplicativo que o modelo implantou como saída para que possa ser usado em um pipeline de implantação a fim de publicar os binários do aplicativo.

Você pode usar saídas para esses cenários. Para definir uma saída em um modelo Bicep, use a palavra-chave output da seguinte forma:

output appServiceAppName string = appServiceAppName

A definição da saída inclui algumas partes principais:

  • A palavra-chave output informa ao Bicep que você está definindo uma saída.
  • appServiceAppName é o nome da saída. Quando alguém implantar o modelo com sucesso, os valores de saída incluirão o nome que você especificou para que seja possível acessar os valores esperados.
  • string é o tipo de saída. As saídas do Bicep dão suporte os mesmos tipos de parâmetros.
  • Um valor precisa ser especificado para cada saída. Ao contrário dos parâmetros, as saídas sempre precisam ter valores. Os valores de saída podem ser expressões, referências a parâmetros ou variáveis ou propriedades de recursos implantados dentro do arquivo.

Dica

As saídas podem usar os mesmos nomes que variáveis e parâmetros. Essa convenção poderá ser útil se você construir uma expressão complexa dentro de uma variável para usar nos recursos do seu modelo e também precisar expor o valor da variável como saída.

Aqui está outro exemplo de saída. Esta terá seu valor definido como o FQDN (nome de domínio totalmente qualificado) de um recurso de endereço IP público.

output ipFqdn string = publicIPAddress.properties.dnsSettings.fqdn

Dica

Tente usar propriedades de recursos como saídas, em vez de fazer suposições sobre como os recursos se comportarão. Por exemplo, se você precisar ter uma saída da URL para um aplicativo de Serviço de Aplicativo, use a propriedade defaultHostName do aplicativo em vez de criar uma cadeia de caracteres para a URL. Às vezes, essas suposições não são válidas em ambientes diferentes, ou a maneira como o recurso funciona muda, portanto, é mais seguro que o recurso informe as próprias propriedades dele.

Cuidado

Não crie saídas para valores secretos, como cadeias de conexão ou chaves. Qualquer pessoa com acesso ao seu grupo de recursos pode ler saídas de modelos. Há outras abordagens que você pode usar para obter acesso às propriedades de recurso secretas, que abordaremos em um módulo posterior.

Definir um módulo

Os módulos do Bicep permitem que você organize e reutilize o código do Bicep criando unidades menores que podem ser compostas em um modelo. Qualquer modelo Bicep pode ser usado como um módulo por outro modelo. Ao longo deste módulo de aprendizagem, você criou modelos Bicep. Isso significa que você já criou arquivos que podem ser usados como módulos Bicep.

Imagine que você tenha um modelo do Bicep que implanta recursos de aplicativo, banco de dados e rede para a solução A. Você pode dividir esse modelo em três módulos, cada qual focado em um conjunto de recursos próprio. Como bônus, agora você pode reutilizar os módulos em outros modelos para outras soluções também; portanto, ao desenvolver um modelo para a solução B, que tem requisitos de rede semelhantes à solução A, você pode reutilizar o módulo de rede.

Diagram that shows a template for solution A referencing three modules: application, database, and networking. The networking module is then reused in another template for solution B.

Quando quiser que o modelo inclua uma referência a um arquivo de módulo, use a palavra-chave module. Uma definição de módulo é semelhante a uma declaração de recurso, porém, em vez de incluir um tipo de recurso e uma versão da API, você usará o nome de arquivo do módulo:

module myModule 'modules/mymodule.bicep' = {
  name: 'MyModule'
  params: {
    location: location
  }
}

Vamos examinar mais detalhadamente algumas partes principais dessa definição de módulo:

  • A palavra-chave module informa ao Bicep que você está prestes a usar outro arquivo do Bicep como módulo.
  • Assim como ocorre com os recursos, os módulos precisam de um nome simbólico, como myModule. Você usa o nome simbólico quando se refere às saídas do módulo em outras partes do modelo.
  • modules/mymodule.bicep é o caminho para o arquivo do módulo, relativo ao arquivo de modelo. Lembre-se de que um arquivo de módulo é apenas um arquivo Bicep normal.
  • Assim como ocorre com os recursos, a propriedade name é obrigatória. O Azure usa o nome do módulo porque cria uma implantação separada para cada módulo no arquivo de modelo. Essas implantações têm nomes que você pode usar para identificá-las.
  • É possível especificar qualquer parâmetro do módulo usando a palavra-chave params. Ao definir os valores de cada parâmetro no modelo, você pode usar expressões, parâmetros de modelo, variáveis, propriedades de recursos implantados no modelo e saídas de outros módulos. O Bicep entenderá automaticamente as dependências entre os recursos.

Módulos e saídas

Assim como os modelos, os módulos Bicep podem definir saídas. É comum encadear módulos em um modelo. Nesse caso, a saída de um módulo pode ser um parâmetro de outro módulo. Usando módulos e saídas juntos, você pode criar arquivos Bicep avançados e reutilizáveis.

Criar seus módulos

Um bom módulo Bicep segue alguns princípios importantes:

  • Um módulo deve ter uma finalidade clara. Você pode usar módulos para definir todos os recursos relacionados a uma parte específica da sua solução. Por exemplo, você pode criar um módulo que contenha todos os recursos que são usados para monitorar seu aplicativo. Você também pode usar um módulo para definir um conjunto de recursos que estão associados, como todos os seus bancos de dados e servidores de banco de dados.

  • Não coloque cada recurso em seu próprio módulo. Você não deve criar um módulo separado para cada recurso que implantar. Se você tiver um recurso que tenha muitas propriedades complexas, talvez faça sentido colocar esse recurso em seu próprio módulo, mas, em geral, é melhor que os módulos combinem vários recursos.

  • Um módulo deve ter parâmetros e saídas claros que façam sentido. Considere a finalidade do módulo. Reflita se o módulo deve manipular valores de parâmetro ou se o modelo pai deve lidar com isso e passar um único valor para o módulo. Da mesma forma, pense nas saídas que o módulo deve retornar e verifique se elas são úteis para os modelos que usarão o módulo.

  • Um módulo deve ser o mais autossuficiente possível. Se um módulo precisar usar uma variável para definir uma parte dele, a variável geralmente deverá ser incluída no arquivo do módulo, e não no modelo pai.

  • Um módulo não deve gerar segredos. Assim como nos modelos, não crie saídas de módulo para valores secretos, como cadeias de conexão ou chaves.