Adicionar flexibilidade usando parâmetros e variáveis

Concluído

Os modelos são poderosos devido à sua reutilização. Você pode usar o Bicep para criar modelos que implantam vários ambientes ou cópias de seus recursos.

Sua empresa de brinquedos lança novos produtos regularmente, e você precisa usar os modelos Bicep a fim de criar os recursos do Azure necessários para cada lançamento de produto. Você precisa evitar o uso de nomes de recursos fixos. Muitos tipos de recursos do Azure precisam de nomes exclusivos, portanto, a inserção de nomes em um modelo impede a reutilização desse modelo para lançar vários produtos. Você também deve implantar os recursos em locais diferentes, dependendo de onde os brinquedos serão lançados, o que significa que você também não pode inserir os locais dos recursos em seu modelo.

Nesta unidade, você aprenderá sobre parâmetros e variáveis, que são dois recursos do Bicep que podem tornar seus modelos flexíveis e reutilizáveis. Você também conhecerá as expressões.

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.

Parâmetros e variáveis

Um parâmetro permite trazer valores de fora do arquivo do modelo. Por exemplo, se você estiver implantando manualmente o modelo usando a CLI do Azure ou o Azure PowerShell, você será solicitado a fornecer valores para cada parâmetro. Você também pode criar um arquivo de parâmetro, que lista todos os parâmetros e valores que você deseja usar para a implantação. Se o modelo for implantado por meio de um processo automatizado, como um pipeline de implantação, o pipeline poderá fornecer os valores dos parâmetros.

Uma variável é definida e configurada no modelo. As variáveis permitem armazenar as informações importantes em apenas um local e referenciá-las em todo o modelo sem precisar copiar e colar.

Geralmente, é uma boa ideia usar parâmetros para itens que mudam entre cada implantação, como:

  • Nomes de recursos que precisam ser exclusivos.
  • Locais nos quais implantar os recursos.
  • Configurações que afetam o preço dos recursos, como SKUs, tipos de preço e contagens de instâncias.
  • Credenciais e informações necessárias para acessar outros sistemas que não estão definidos no modelo.

As variáveis geralmente são uma boa opção quando você usa os mesmos valores para cada implantação, mas deseja tornar um valor reutilizável no modelo ou quando você quer usar expressões para criar um valor complexo. Você também pode usar variáveis de recursos que não precisam de nomes exclusivos.

Dica

É importante usar uma boa nomenclatura para parâmetros e variáveis, de modo que seus modelos sejam fáceis de ler e entender. Use nomes claros, descritivos e consistentes.

Adicionar um parâmetro

No Bicep, você pode definir um parâmetro da seguinte forma:

param appServiceAppName string

Vejamos como cada parte dessa definição funciona:

  • param diz ao Bicep que você está definindo um parâmetro.
  • appServiceAppName é o nome do parâmetro. Se você estiver implantando o modelo manualmente, poderá ser solicitado a inserir um valor, portanto, é importante que o nome seja claro e compreensível. O nome também é como você se refere ao valor do parâmetro dentro do modelo, assim como os nomes simbólicos de recursos.
  • string é o tipo do parâmetro. Você pode especificar vários tipos diferentes de parâmetros Bicep, incluindo string para texto, int para números e bool para valores boolianos true ou false. Você também pode passar parâmetros mais complexos usando os tipos array e object.

Dica

Tente não generalizar demais os modelos usando muitos parâmetros. Você deve usar o número mínimo de parâmetros necessários para o seu cenário de negócios. Lembre-se de que você sempre pode alterar os modelos se as suas necessidades mudam.

Fornecer valores padrão

Você tem a opção de fornecer um valor padrão para um parâmetro. Quando você especifica um valor padrão, o parâmetro se torna opcional. A pessoa que está implantando o modelo poderá especificar um valor se quiser, porém, se ela não quiser, o Bicep usará o valor padrão.

Confira como você pode adicionar um valor padrão:

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

Observação

Nesse exemplo, o nome do aplicativo do Serviço de Aplicativo do Azure tem um valor padrão embutido em código. Essa não é uma boa ideia, pois os aplicativos do Serviço de Aplicativo precisam de nomes exclusivos. Você corrigirá isso em breve.

Usar valores de parâmetro no modelo

Depois de declarar um parâmetro, você pode consultá-lo em todo o restante do modelo. Vejamos como você pode usar seu novo parâmetro na definição do recurso:

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

Observe que o modelo agora usa o valor do parâmetro para definir o nome do recurso do aplicativo em vez um valor embutido em código.

Dica

A extensão Bicep para Visual Studio Code mostra indicadores visuais que informam quando você não está seguindo as práticas recomendadas. Por exemplo, ele avisa se você definir um parâmetro que não usa. O Linter do Bicep executa continuamente essas verificações enquanto você trabalha.

Adicionar uma variável

Você pode definir uma variável da seguinte forma:

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

As variáveis são definidas de forma semelhante aos parâmetros, mas há algumas diferenças:

  • Use a palavra-chave var para informar ao Bicep que você está declarando uma variável.
  • Você precisa fornecer um valor para uma variável.
  • As variáveis não precisam de tipos. O Bicep poderá determinar o tipo com base no valor que você definir.

Expressões

Ao criar modelos, geralmente não convém embutir valores no código nem solicitar que sejam especificados em um parâmetro. Em vez disso, descubra os valores quando o modelo for executado. Por exemplo, você pode querer implantar todos os recursos de um modelo em apenas uma região do Azure: aquela em que criou o grupo de recursos. Ou talvez você deseje criar automaticamente um nome exclusivo para um recurso com base na estratégia de nomenclatura específica da sua empresa.

As expressões no Bicep são um recurso poderoso que ajuda você a lidar com todos os tipos de cenários interessantes. Vamos dar uma olhada em alguns lugares onde você pode usar expressões em um modelo Bicep.

Locais de recursos

Quando você está escrevendo e implantando um modelo, geralmente não deseja ter que especificar o local de cada recurso individualmente. Em vez disso, você pode ter uma regra de negócios simples que determine, por padrão, implantar todos os recursos no mesmo local em que o grupo de recursos foi criado.

No Bicep, você pode criar um parâmetro chamado location e usar uma expressão para definir o valor dele:

param location string = resourceGroup().location

Confira o valor padrão desse parâmetro. Ele usa uma função chamada resourceGroup(), que oferece acesso a informações sobre o grupo de recursos em que o modelo está sendo implantado. Nesse exemplo, o modelo usa a propriedade location. É comum usar essa abordagem para implantar os recursos na mesma região do Azure que o grupo de recursos.

Se alguém estiver implantando esse modelo, poderá optar por substituir o valor padrão aqui e usar um local diferente.

Observação

Alguns recursos do Azure só podem ser implantados em determinados locais. Você pode precisar de parâmetros separados para definir os locais desses recursos.

Agora você pode usar o parâmetro local do recurso dentro do modelo, desta forma:

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

Nomes de recurso

Muitos recursos do Azure precisam de nomes exclusivos. Em seu cenário, você tem dois recursos que precisam de nomes exclusivos: a conta de armazenamento e o aplicativo do Serviço de Aplicativo. Pedir que esses valores sejam configurados como parâmetros pode dificultar as coisas para quem usa o modelo, pois é preciso encontrar um nome que ninguém mais usou.

O Bicep tem outra função chamada uniqueString() que é útil quando você está criando nomes de recursos. Ao usar essa função, você precisa fornecer um valor de semente, que deve ser diferente em implantações distintas, mas consistente em todas as implantações dos mesmos recursos.

Se você escolher um bom valor de semente, poderá obter o mesmo nome sempre que implantar o mesmo conjunto de recursos, mas obterá um nome diferente sempre que implantar um conjunto diferente de recursos usando o mesmo modelo. Vamos conferir como você pode usar a função uniqueString():

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

O valor padrão desse parâmetro usa a função resourceGroup() novamente, como você fez ao definir o local do recurso. Desta vez, no entanto, você está obtendo a ID de um grupo de recursos. Esta é a aparência de uma ID de grupo de recursos:

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

A ID do grupo de recursos inclui a ID da assinatura do Azure (3e57e557-826f-460b-8f1c-4ce38fd53b32) e o nome do grupo de recursos (MyResourceGroup). A ID do grupo de recursos costuma ser uma boa candidata para valor de semente em nomes de recursos, porque:

  • Toda vez que você implantar os mesmos recursos, eles irão para o mesmo grupo de recursos. A função uniqueString() retornará o mesmo valor todas as vezes.
  • Se você implantar em dois grupos de recursos distintos da mesma assinatura do Azure, o valor de resourceGroup().id será diferente, pois os nomes dos grupos de recursos serão diferentes. A função uniqueString() resultará em valores diferentes para cada conjunto de recursos.
  • Se você implantar em duas assinaturas distintas do Azure, mesmo se usar um nome de grupo de recursos igual, o valor de resourceGroup().id será diferente, pois a ID de assinatura do Azure também será. A função uniqueString() resultará novamente em valores diferentes para cada conjunto de recursos.

Dica

Geralmente, é uma boa ideia usar expressões de modelo para criar nomes de recursos. Muitos tipos de recursos do Azure têm regras sobre os caracteres permitidos e o comprimento de seus nomes. Incorporar a criação de nomes de recursos no modelo significa que quem usa o modelo não precisa se lembrar de seguir essas regras por conta própria.

Cadeias de caracteres combinadas

Se usar apenas a função uniqueString() para definir nomes de recursos, você provavelmente obterá nomes exclusivos, mas eles não serão significativos. Um bom nome de recurso também deve ser descritivo para que fique claro do que se trata o recurso. Geralmente, convém criar um nome combinando uma palavra ou cadeia de caracteres significativa com um valor exclusivo. Dessa forma, você terá recursos com nomes significativos e únicos.

O Bicep tem um recurso chamado interpolação de cadeia de caracteres que permite combinar cadeias. Vejamos como isso funciona:

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

O valor padrão do parâmetro storageAccountName agora tem duas partes:

  • toylaunch é uma cadeia de caracteres embutida em código que ajuda quem estiver analisando o recurso implantado no Azure a entender a finalidade da conta de armazenamento.
  • ${uniqueString(resourceGroup().id)} é uma forma de dizer ao Bicep para avaliar a saída da função uniqueString(resourceGroup().id), depois concatená-la à cadeia de caracteres.

Dica

Às vezes, a função uniqueString() criará cadeias de caracteres que começam com um número. Alguns recursos do Azure, como contas de armazenamento, não permitem que seus nomes comecem com números. Isso significa que é uma boa ideia usar a interpolação de cadeia de caracteres para criar nomes de recursos, como no exemplo anterior.

Selecionar SKUs para recursos

Os outros membros de sua equipe ficaram impressionados com o código Bicep que você criou até agora. Vocês decidiram juntos que usarão seu modelo para implantar os recursos a fim de dar suporte aos lançamentos de todos os novos brinquedos.

Um de seus colegas sugeriu que você crie ambientes que não sejam de produção para cada lançamento de produto a fim de ajudar a equipe de marketing a testar os sites antes de disponibilizá-los aos clientes. No entanto, você deseja garantir que não gaste muito dinheiro em seus ambientes de não produção, portanto, você decide em algumas políticas em conjunto, portanto, você decide usar algumas políticas em conjunto:

  • Em ambientes de produção, as contas de armazenamento serão implantadas no SKU Standard_GRS (armazenamento com redundância geográfica) para alta resiliência. Os Planos do Serviço de Aplicativo serão implantados no SKU P2v3 para alto desempenho.
  • Em ambientes de não produção, as contas de armazenamento serão implantadas no SKU Standard_LRS (armazenamento com redundância local). Os Planos do Serviço de Aplicativo serão implantados no SKU F1 gratuito.

Uma maneira de implementar esses requisitos de negócios é usar parâmetros para especificar cada SKU. No entanto, a especificação de cada SKU como um parâmetro pode se tornar difícil de gerenciar, especialmente quando você tem modelos maiores. Outra opção é inserir as regras de negócio no modelo usando uma combinação de parâmetros, variáveis e expressões.

Primeiro, você pode especificar um parâmetro que indica se a implantação é para um ambiente de produção ou não produção:

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

Observe que esse código usa uma nova sintaxe para especificar uma lista de valores permitidos para o parâmetro environmentType. O Bicep não permitirá que ninguém implante o modelo a menos que forneça um desses valores.

Em seguida, você pode criar variáveis que determinam os SKUs a serem usados para a conta de armazenamento e o Plano do Serviço de Aplicativo com base no ambiente:

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

Observe novas sintaxes aqui também. Vamos por partes:

  • (environmentType == 'prod') é avaliado como um valor booliano (verdadeiro ou falso) dependendo de qual valor permitido é usado para o parâmetro environmentType.
  • ? é chamado de operador ternário e avalia uma instrução if/then. O valor após o operador ? será usado se a expressão for true. Se a expressão for avaliada como false, o valor após os dois-pontos (:) será usado.

Podemos traduzir essas regras para:

  • Para a variável storageAccountSkuName, se o parâmetro environmentType for definido como prod, use o SKU Standard_GRS. Caso contrário, use o SKU Standard_LRS.
  • Para a variável appServicePlanSkuName, se o parâmetro environmentType for definido como prod, use o SKU P2V3 e a camada PremiumV3. Caso contrário, use o SKU F1.

Dica

Ao criar expressões com várias partes como essa, é melhor usar variáveis em vez de inserir as expressões diretamente nas propriedades do recurso. Isso torna seus modelos mais fáceis de ler e entender, pois evita confundir suas definições de recursos com lógica.

Quando você usa parâmetros, variáveis e expressões em sue modelo, pode reutilizar o modelo e implantar rapidamente um novo conjunto de recursos. Por exemplo, sempre que seu departamento de marketing solicitar que você implante um novo site para o próximo lançamento de brinquedos, você fornecerá novos valores de parâmetro para cada ambiente implantado e pronto!