Como usar Bicep para provisionar um ambiente no Azure e suas vantagens

Question151

Tagsazure, bicep, iac, infrastructure-as-code, devops, arm, provisioning, cloud

Introdução

Bicep é uma linguagem de domínio específico (DSL) desenvolvida pela Microsoft como uma abstração sobre templates ARM (Azure Resource Manager). Ela oferece uma sintaxe mais limpa e legível para definir infraestrutura como código no Azure, simplificando significativamente o processo de provisionamento de recursos.

Conceito-chave

O Bicep funciona como uma linguagem transpilada que converte código Bicep em templates ARM JSON. Isso permite aproveitar toda a funcionalidade do ARM enquanto oferece uma experiência de desenvolvimento muito superior, com sintaxe declarativa mais intuitiva e ferramentas avançadas de desenvolvimento.

Tópicos Relevantes

Estrutura básica de um arquivo Bicep

// Parâmetros de entrada
param location string = resourceGroup().location
param appServicePlanName string
param webAppName string

// Variáveis computadas
var appServicePlanSku = 'F1'

// Recursos
resource appServicePlan 'Microsoft.Web/serverfarms@2021-02-01' = {
  name: appServicePlanName
  location: location
  sku: {
    name: appServicePlanSku
    tier: 'Free'
  }
}

resource webApp 'Microsoft.Web/sites@2021-02-01' = {
  name: webAppName
  location: location
  properties: {
    serverFarmId: appServicePlan.id
  }
}

Módulos e reutilização

// Módulo para storage account
module storageAccount 'modules/storage.bicep' = {
  name: 'storageDeployment'
  params: {
    storageAccountName: 'mystorageaccount'
    location: location
  }
}

Loops e condicionais

// Loop para criar múltiplos recursos
resource storageAccounts 'Microsoft.Storage/storageAccounts@2021-04-01' = [for i in range(0, 3): {
  name: 'storage${i}'
  location: location
  kind: 'StorageV2'
  sku: {
    name: 'Standard_LRS'
  }
}]

// Condicional
resource publicIP 'Microsoft.Network/publicIPAddresses@2021-02-01' = if (createPublicIP) {
  name: publicIPName
  location: location
}

Exemplo Prático

Provisionamento de um ambiente completo com Web App, SQL Database e Application Insights:

// main.bicep
targetScope = 'resourceGroup'

@description('Nome do ambiente (dev, staging, prod)')
param environmentName string = 'dev'

@description('Nome da aplicação')
param applicationName string

param location string = resourceGroup().location

// Variáveis
var resourcePrefix = '${applicationName}-${environmentName}'
var tags = {
  Environment: environmentName
  Application: applicationName
  ManagedBy: 'Bicep'
}

// App Service Plan
resource appServicePlan 'Microsoft.Web/serverfarms@2021-02-01' = {
  name: '${resourcePrefix}-asp'
  location: location
  tags: tags
  sku: {
    name: environmentName == 'prod' ? 'P1v2' : 'F1'
    tier: environmentName == 'prod' ? 'PremiumV2' : 'Free'
  }
}

// Web App
resource webApp 'Microsoft.Web/sites@2021-02-01' = {
  name: '${resourcePrefix}-webapp'
  location: location
  tags: tags
  properties: {
    serverFarmId: appServicePlan.id
    httpsOnly: true
    siteConfig: {
      minTlsVersion: '1.2'
      ftpsState: 'Disabled'
      connectionStrings: [
        {
          name: 'DefaultConnection'
          connectionString: 'Server=${sqlServer.properties.fullyQualifiedDomainName};Database=${sqlDatabase.name};Trusted_Connection=False;Encrypt=True;'
          type: 'SQLAzure'
        }
      ]
    }
  }
  identity: {
    type: 'SystemAssigned'
  }
}

// SQL Server
resource sqlServer 'Microsoft.Sql/servers@2021-02-01' = {
  name: '${resourcePrefix}-sql'
  location: location
  tags: tags
  properties: {
    administratorLogin: 'sqladmin'
    administratorLoginPassword: 'P@ssw0rd123!'
  }
}

// SQL Database
resource sqlDatabase 'Microsoft.Sql/servers/databases@2021-02-01' = {
  parent: sqlServer
  name: '${applicationName}DB'
  location: location
  tags: tags
  sku: {
    name: environmentName == 'prod' ? 'S2' : 'Basic'
    tier: environmentName == 'prod' ? 'Standard' : 'Basic'
  }
}

// Application Insights
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
  name: '${resourcePrefix}-ai'
  location: location
  tags: tags
  kind: 'web'
  properties: {
    Application_Type: 'web'
  }
}

// Key Vault para secrets
resource keyVault 'Microsoft.KeyVault/vaults@2021-04-01-preview' = {
  name: '${resourcePrefix}-kv'
  location: location
  tags: tags
  properties: {
    sku: {
      family: 'A'
      name: 'standard'
    }
    tenantId: tenant().tenantId
    accessPolicies: [
      {
        tenantId: tenant().tenantId
        objectId: webApp.identity.principalId
        permissions: {
          secrets: ['get', 'list']
        }
      }
    ]
  }
}

// Outputs
output webAppUrl string = 'https://${webApp.properties.defaultHostName}'
output sqlServerName string = sqlServer.name
output keyVaultName string = keyVault.name

Deployment com Azure CLI

# Criar resource group
az group create --name myapp-dev-rg --location eastus

# Deploy do Bicep
az deployment group create \
  --resource-group myapp-dev-rg \
  --template-file main.bicep \
  --parameters environmentName=dev applicationName=myapp

Benefícios

1. Sintaxe mais limpa e legível

  • Redução significativa de código comparado ao ARM JSON
  • Sintaxe mais próxima de linguagens de programação modernas
  • Melhor legibilidade e manutenibilidade

2. Tooling superior

  • IntelliSense avançado no VS Code
  • Validação em tempo real
  • Debugging e error reporting melhorados
  • Extension oficial da Microsoft

3. Modularidade e reutilização

  • Sistema de módulos nativo
  • Facilita a criação de bibliotecas de componentes
  • Promove boas práticas de arquitetura

4. Segurança aprimorada

  • Validação de tipos em tempo de compilação
  • Prevenção de configurações inseguras
  • Integração com Azure Policy

5. Compatibilidade total com ARM

  • Compila para ARM templates padrão
  • Aproveita toda funcionalidade existente
  • Facilita migração de templates ARM existentes

6. Versionamento e governança

  • Integração natural com controle de versão
  • Facilita code reviews
  • Suporte a GitOps workflows

7. Performance de deployment

  • Deployments incrementais inteligentes
  • Detecção automática de mudanças
  • Otimização de dependências entre recursos