Microsoft Azure do Zero ao Profissional: 100 Exemplos com CLI, Bicep e Python

Microsoft Azure do Zero ao Profissional: 100 Exemplos com CLI, Bicep e Python

O Microsoft Azure é uma plataforma de nuvem para rodar sites, bancos de dados, contêineres, pipelines de dados e serviços de IA sem comprar servidores. Este artigo leva você do primeiro login a uma configuração pensada para produção, em 100 exemplos. Você vai aprender a Azure CLI, grupos de recursos e tags, infraestrutura como código com Bicep, identidade com identidades gerenciadas e RBAC, máquinas virtuais, App Service, contêineres e Kubernetes, armazenamento com SAS e regras de ciclo de vida, SQL e Cosmos DB, Functions sem servidor, redes virtuais e private endpoints, Service Bus e Event Hubs, monitoramento com Log Analytics e Application Insights, Key Vault e controle de custos. Nota de transparência: os comandos de nuvem e os exemplos com o SDK não foram executados, porque exigem uma assinatura do Azure. Os exemplos marcados como executáveis foram rodados neste computador, e a saída real aparece depois do código.

O que você precisa

Uma conta do Azure com assinatura (a avaliação gratuita basta para a maioria dos exemplos), a Azure CLI, Python 3.10 ou mais recente e um editor de código como o Visual Studio Code com a extensão Bicep. Use uma assinatura de sandbox para estudar e nunca cole segredos reais em comandos ou código. Alguns recursos geram cobrança, então exclua o grupo de recursos de laboratório quando terminar.

Como usar um exemplo

Os exemplos em bash usam a Azure CLI, e os exemplos em Bicep usam a Azure CLI ou o VS Code. Os exemplos em Python que não precisam de conta do Azure rodam com python e mostram a saída real. Os exemplos que chamam o Azure precisam de uma assinatura para funcionar.

Tópico 1: Começando com o Azure

O Azure é organizado em assinaturas, grupos de recursos e recursos. Aprenda a entrar, a verificar onde seus comandos vão rodar e a usar nomes fáceis de encontrar e de cobrar.

A Azure CLI e o login

A Azure CLI é uma única ferramenta para todos os serviços do Azure. Instale, rode az login e confira com az account show. Os comandos atuam na assinatura selecionada, então confirme qual é antes de criar ou excluir qualquer coisa.

Regiões e nomes

Cada recurso vive em uma região, então escolha a mais próxima dos usuários e confirme se os serviços de que você precisa estão disponíveis nela. Os nomes de contas de armazenamento são rígidos: de 3 a 24 letras minúsculas e números, e únicos em todo o Azure.

Convenções de nomenclatura

Um padrão como rg-app-env-region-01 mantém os nomes consistentes, para que as pessoas encontrem os recursos e entendam o custo. Monte os nomes com uma função pequena e reutilize-a em todos os scripts.

Ilustrações

Como uma aplicação típica do Azure se organiza: os usuários chegam a um aplicativo web por um balanceador de carga, o aplicativo lê segredos do Key Vault e dados de um banco, e os logs e métricas fluem para o Log Analytics
Como uma aplicação típica do Azure se organiza: os usuários chegam a um aplicativo web por um balanceador de carga, o aplicativo lê segredos do Key Vault e dados de um banco, e os logs e métricas fluem para o Log Analytics

Exemplo 1: Instalar a CLI do Azure e entrar

Prepare a ferramenta de linha de comando e entre na sua conta.

winget install -e --id Microsoft.AzureCLI
az --version
az login

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 2: Verificar a assinatura ativa

Confirme em qual assinatura seus comandos vão agir.

az account show --output table
az account list --query "[].{name:name, id:id, default:isDefault}" --output table

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 3: Criar um grupo de recursos

Um contêiner para recursos relacionados em uma região.

az group create --name rg-learn-dev --location southeastasia

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 4: Listar as regiões do Azure

Encontre as regiões onde você pode implantar.

az account list-locations --query "[?metadata.regionCategory=='Recommended'].name" --output tsv

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 5: Validar o nome de uma conta de armazenamento

Os nomes têm de 3 a 24 letras minúsculas e números.

import re

def valid_storage_name(name):
    return re.fullmatch(r"[a-z0-9]{3,24}", name) is not None

for candidate in ("stlearndev01", "Store-1", "ab", "a" * 25):
    print(repr(candidate), valid_storage_name(candidate))

Saída:

'stlearndev01' True
'Store-1' False
'ab' False
'aaaaaaaaaaaaaaaaaaaaaaaaa' False

Exemplo 6: Montar um nome de recurso por convenção

Nomes consistentes facilitam encontrar recursos e cobrar custos.

def resource_name(kind, app, env, region, index=1):
    return f"{kind}-{app}-{env}-{region}-{index:02d}"

print(resource_name("rg", "shop", "dev", "sea"))
print(resource_name("app", "shop", "prod", "sea", 3))

Saída:

rg-shop-dev-sea-01
app-shop-prod-sea-03

Tópico 2: Grupos de recursos, tags e saída da CLI

Um grupo de recursos guarda os recursos de uma aplicação ou de um ambiente. As tags registram quem é o dono e quanto custa, e a CLI pode filtrar e formatar a saída para pessoas ou scripts.

Grupos de recursos e exclusão

Coloque os recursos relacionados em um grupo para gerenciá-los e excluí-los juntos. Excluir um grupo remove tudo o que há dentro, então use --no-wait só quando tiver certeza, e nunca exclua um grupo que você não criou.

Tags para responsabilidade e custo

As tags são pares de chave e valor, como owner e costcenter. Adicione-as ao criar os recursos e procure as que estiverem faltando com um script. Os relatórios de custo podem agrupar os gastos por tag.

Saída, consultas e padrões

Use --output table para pessoas e json para scripts. --query usa JMESPath para filtrar campos. Defina o grupo e a região padrão com az configure para não repeti-los.

Exemplo 7: Marcar um grupo de recursos com tags

As tags registram o dono, o centro de custo e o ambiente.

az group update --name rg-learn-dev \
  --tags owner=team-a costcenter=1001 environment=dev

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 8: Verificar as tags obrigatórias

Encontre recursos sem as tags que a equipe precisa.

REQUIRED = {"owner", "costcenter", "environment"}

def missing_tags(tags):
    return sorted(REQUIRED - set(tags))

print(missing_tags({"owner": "team-a", "environment": "dev"}))
print(missing_tags({"owner": "x", "costcenter": "1", "environment": "prod"}))

Saída:

['costcenter']
[]

Exemplo 9: Excluir um grupo de recursos sem esperar

Remova um grupo inteiro de recursos com um único comando.

az group delete --name rg-learn-test --yes --no-wait

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 10: Escolher a região mais próxima pela latência

Escolha a região que responde mais rápido aos usuários.

latency_ms = {"southeastasia": 42, "japaneast": 71, "eastus": 210, "westeurope": 185}

best = min(latency_ms, key=latency_ms.get)
print("closest region:", best, latency_ms[best], "ms")

Saída:

closest region: southeastasia 42 ms

Exemplo 11: Filtrar a saída com uma consulta JMESPath

Mostre apenas os campos e as linhas de que você precisa.

az vm list \
  --query "[?powerState=='VM running'].{name:name, rg:resourceGroup}" \
  --output table

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 12: Escolher o formato de saída

Tabela, JSON ou YAML, para pessoas ou para scripts.

az group list --output table
az group list --output json
az group list --output yaml

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 13: Percorrer recursos em um script

Execute um comando para cada grupo de recursos.

for rg in $(az group list --query "[].name" -o tsv); do
  echo "resource group: $rg"
done

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 14: Definir o grupo e a região padrão

Não precisa digitar as mesmas opções em todo comando.

az configure --defaults group=rg-learn-dev location=southeastasia
az configure --list-defaults

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Tópico 3: Scripts e automação

O trabalho repetitivo deve ficar em um script. Laços, novas tentativas e JSON analisado transformam comandos avulsos em automação confiável, que um pipeline consegue executar.

Laços sobre recursos

Um laço de shell executa um comando para cada recurso de uma lista. Mantenha a lista pequena e confira o resultado antes de alterar qualquer coisa.

Analisando a saída JSON

Peça à CLI a saída em JSON e analise-a com um programa, em vez de ler texto. Agrupar os recursos por tipo gera um resumo fácil de ler.

Novas tentativas e espera crescente

A API do Azure limita clientes que fazem muitas chamadas. Tente de novo com esperas cada vez maiores, para que o script se recupere sem sobrecarregar o serviço.

Exemplo 15: Analisar a saída JSON da CLI

Transforme uma lista de recursos em um resumo.

import json

sample = """[{"name": "vm-web-01", "type": "Microsoft.Compute/virtualMachines", "location": "southeastasia"},
           {"name": "stlearn01", "type": "Microsoft.Storage/storageAccounts", "location": "southeastasia"}]"""

resources = json.loads(sample)
by_type = {}
for r in resources:
    by_type.setdefault(r["type"].split("/")[-1], []).append(r["name"])
for kind, names in sorted(by_type.items()):
    print(kind, names)

Saída:

storageAccounts ['stlearn01']
virtualMachines ['vm-web-01']

Exemplo 16: Repetir uma chamada instável com recuo

Espere mais após cada solicitação limitada.

import time

def call_with_retry(fn, attempts=4, base_delay=0.05):
    for n in range(attempts):
        try:
            return fn()
        except ConnectionError as e:
            if n == attempts - 1:
                raise
            delay = base_delay * (2 ** n)
            print(f"attempt {n + 1} failed ({e}); retrying in {delay:.2f}s")
            time.sleep(delay)

state = {"calls": 0}
def flaky_list():
    state["calls"] += 1
    if state["calls"] < 3:
        raise ConnectionError("throttled")
    return ["rg-learn-dev"]

print(call_with_retry(flaky_list))

Saída:

attempt 1 failed (throttled); retrying in 0.05s
attempt 2 failed (throttled); retrying in 0.10s
['rg-learn-dev']

Exemplo 17: Verificar a versão da CLI e as extensões

Mantenha a ferramenta e suas extensões atualizadas.

az version
az extension list --output table
az extension add --name containerapp --upgrade

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 18: Criar uma entidade de serviço com segurança

Uma identidade de aplicativo para automação, com o menor escopo possível.

# Store the output securely: it contains a password. Never commit it to Git.
az ad sp create-for-rbac --name sp-learn-deploy --role Contributor \
  --scopes /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Tópico 4: Infraestrutura como código com Bicep

O Bicep descreve os recursos do Azure como código. Um modelo pode ser revisado, versionado e implantado sempre do mesmo jeito, o que é mais seguro do que clicar no portal.

Recursos, parâmetros e saídas

A declaração de um recurso informa o tipo e a versão da API e define suas propriedades. Os parâmetros tornam o modelo reutilizável, e o @secure impede que senhas apareçam nos logs. As saídas devolvem valores como o ID ao chamador.

Módulos, condições e laços

Um módulo divide um modelo grande em arquivos reutilizáveis. Uma condição cria um recurso só quando é verdadeira, como em produção. Um laço cria vários recursos a partir de uma única lista.

Implantação segura

Use az deployment group what-if para visualizar as mudanças antes de criar. Nomes montados com uniqueString evitam conflitos entre ambientes na mesma assinatura.

Exemplo 19: Uma conta de armazenamento mínima em Bicep

Descreva uma conta de armazenamento como código.

param location string = resourceGroup().location
param storageName string

resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageName
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
  properties: {
    minimumTlsVersion: 'TLS1_2'
    allowBlobPublicAccess: false
  }
}

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 20: Parâmetros, saídas e valores protegidos

Reutilize modelos e mantenha senhas fora do arquivo.

@minLength(3)
@maxLength(24)
param storageName string

@allowed([
  'dev'
  'test'
  'prod'
])
param environment string = 'dev'

@secure()
param adminPassword string

output storageId string = storage.id
resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: storageName
  location: resourceGroup().location
  sku: { name: environment == 'prod' ? 'Standard_GRS' : 'Standard_LRS' }
  kind: 'StorageV2'
}

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 21: Implantar um módulo a partir do main.bicep

Divida um modelo grande em módulos reutilizáveis.

// main.bicep
targetScope = 'resourceGroup'
module network './modules/network.bicep' = {
  name: 'networkDeploy'
  params: {
    prefix: 'shop-dev'
  }
}
output vnetId string = network.outputs.vnetId

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 22: Recursos condicionais

Crie um recurso apenas em produção.

param environment string

resource logs 'Microsoft.OperationalInsights/workspaces@2022-10-01' = if (environment == 'prod') {
  name: 'log-shop-prod'
  location: resourceGroup().location
  properties: {
    retentionInDays: 90
  }
}

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 23: Percorrer contêineres em Bicep

Crie vários contêineres de blob a partir de uma lista.

param containerNames array = [
  'uploads'
  'exports'
  'backups'
]

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

resource containers 'Microsoft.Storage/storageAccounts/blobServices/containers@2023-05-01' = [for name in containerNames: {
  name: '${storage.name}/default/${name}'
}]

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 24: Nomes únicos com uniqueString

Gere um nome que não colida com outros na assinatura.

param prefix string = 'shop'

var uniqueSuffix = uniqueString(resourceGroup().id)
var storageName = toLower('st${prefix}${uniqueSuffix}')

output generatedName string = storageName

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 25: Implantar um arquivo Bicep

Crie ou atualize recursos a partir do modelo.

az deployment group create \
  --resource-group rg-learn-dev \
  --template-file main.bicep \
  --parameters storageName=stlearndev01 environment=dev

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 26: Visualizar as mudanças com what-if

Veja antes o que a implantação vai adicionar, alterar ou excluir.

az deployment group what-if \
  --resource-group rg-learn-dev \
  --template-file main.bicep \
  --parameters storageName=stlearndev01

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Tópico 5: Identidade e controle de acesso

A segurança começa por definir quem pode fazer o quê. As identidades gerenciadas dão às aplicações credenciais sem senhas, e o controle de acesso baseado em funções concede a cada identidade apenas as permissões de que ela precisa.

Identidades gerenciadas

Uma identidade gerenciada é uma conta que o Azure mantém para a sua aplicação, então ela obtém tokens sem guardar nenhum segredo. Use identidades atribuídas pelo usuário quando vários recursos compartilham a mesma identidade.

RBAC e privilégio mínimo

Uma atribuição de função liga uma identidade a uma função em um escopo, como uma única conta de armazenamento. Prefira as funções prontas que combinam com o trabalho e crie uma função personalizada só quando nenhuma servir.

Entidades de serviço e tokens

Uma entidade de serviço é uma identidade para automação. A senha dela é um segredo, então guarde-a no cofre do pipeline. Um token é uma string assinada com data de expiração, que você pode ler no payload.

Exemplo 27: Uma identidade gerenciada atribuída pelo usuário

Uma identidade que o aplicativo usa sem guardar senha.

param location string = resourceGroup().location

resource appIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
  name: 'id-shop-dev'
  location: location
}

output principalId string = appIdentity.properties.principalId

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 28: Conceder acesso de leitura com RBAC

Dê à identidade apenas a função de que ela precisa.

PRINCIPAL_ID=$(az identity show --name id-shop-dev --resource-group rg-learn-dev --query principalId -o tsv)
az role assignment create \
  --assignee-object-id "$PRINCIPAL_ID" \
  --assignee-principal-type ServicePrincipal \
  --role "Storage Blob Data Reader" \
  --scope /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev/providers/Microsoft.Storage/storageAccounts/stlearndev01

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 29: Entrar em um pipeline com uma entidade de serviço

A automação entra com segredos do próprio pipeline.

az login --service-principal \
  --username "$AZURE_CLIENT_ID" \
  --password "$AZURE_CLIENT_SECRET" \
  --tenant "$AZURE_TENANT_ID"

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 30: Verificar atribuições de função

Veja quem pode fazer o quê em um recurso.

assignments = [
    {"principal": "id-shop-dev", "role": "Storage Blob Data Reader", "scope": "stlearndev01"},
    {"principal": "sp-learn-deploy", "role": "Contributor", "scope": "rg-learn-dev"},
    {"principal": "id-shop-dev", "role": "Key Vault Secrets User", "scope": "kv-shop-dev"},
]

def roles_for(principal):
    return sorted(a["role"] for a in assignments if a["principal"] == principal)

print(roles_for("id-shop-dev"))
print(roles_for("nobody"))

Saída:

['Key Vault Secrets User', 'Storage Blob Data Reader']
[]

Exemplo 31: Entrar em uma VM com a identidade gerenciada

A VM obtém um token sem nenhuma senha.

az login --identity
az account show --query "user.assignedIdentityInfo" -o tsv

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 32: Ler a expiração de um token JWT

Os tokens trazem o horário de expiração no payload.

import base64
import json

def jwt_payload(token):
    part = token.split(".")[1]
    part += "=" * (-len(part) % 4)
    return json.loads(base64.urlsafe_b64decode(part))

payload = {"aud": "https://management.azure.com/", "exp": 1767225600, "upn": "[email protected]"}
raw = base64.urlsafe_b64encode(json.dumps(payload).encode()).decode().rstrip("=")
token = f"header.{raw}.signature"

claims = jwt_payload(token)
print("audience:", claims["aud"])
print("expires at unix time:", claims["exp"])

Saída:

audience: https://management.azure.com/
expires at unix time: 1767225600

Exemplo 33: Uma função personalizada com privilégio mínimo

Permita uma única ação em um único escopo.

{
  "Name": "Blob Uploader",
  "IsCustom": true,
  "Description": "Can upload blobs to one storage account only.",
  "Actions": [],
  "DataActions": [
    "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write"
  ],
  "AssignableScopes": [
    "/subscriptions/<subscription-id>/resourceGroups/rg-learn-dev"
  ]
}

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 34: Criar a função personalizada

Registre a definição da função na assinatura.

az role definition create --role-definition @blob-uploader.json

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Tópico 6: Computação: máquinas virtuais e App Service

O Azure executa seu código em máquinas virtuais ou em plataformas gerenciadas. O App Service elimina a maior parte do trabalho com servidores, enquanto uma VM dá controle total sobre o sistema operacional.

Máquinas virtuais e conjuntos de dimensionamento

Uma VM tem tamanho, imagem, discos e interface de rede. Um conjunto de dimensionamento executa VMs idênticas e adiciona ou remove instâncias conforme a demanda. Desligue as máquinas de desenvolvimento à noite para economizar.

Planos do App Service e aplicativos web

O plano define as máquinas e o preço, e o aplicativo web roda sobre ele. Implante o código como arquivo zip, configure com as configurações do aplicativo e use um slot de implantação para testar antes que os usuários vejam uma mudança.

Decisões de escalonamento automático

As regras de escala comparam uma métrica, como a média de CPU, com limites, e adicionam ou removem uma instância. Um período de espera impede que o sistema fique alternando entre tamanhos.

Exemplo 35: Criar uma VM Linux

Inicie uma máquina virtual com o tamanho e a imagem escolhidos.

az vm create \
  --resource-group rg-learn-dev \
  --name vm-web-01 \
  --image Ubuntu2204 \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 36: Listar tamanhos de VM e discos

Verifique capacidade e armazenamento antes de redimensionar.

az vm list-sizes --location southeastasia --output table | head -n 10
az vm disk list --resource-group rg-learn-dev --output table

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 37: Um conjunto de dimensionamento de máquinas virtuais

Máquinas idênticas que crescem e diminuem juntas.

resource vmss 'Microsoft.Compute/virtualMachineScaleSets@2023-09-01' = {
  name: 'vmss-web'
  location: resourceGroup().location
  sku: {
    name: 'Standard_B2s'
    capacity: 2
  }
  properties: {
    upgradePolicy: { mode: 'Rolling' }
    // osProfile, networkProfile and storageProfile go here
  }
}

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 38: Desligamento automático para uma VM de desenvolvimento

Desligue a máquina de teste todas as noites para economizar.

az vm auto-shutdown --resource-group rg-learn-dev --name vm-web-01 --time 2100

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 39: Criar um plano do App Service e um aplicativo web

Hospede um aplicativo web em servidores Linux gerenciados.

az appservice plan create --name plan-shop-dev --resource-group rg-learn-dev --sku B1 --is-linux
az webapp create --name app-shop-dev-01 --resource-group rg-learn-dev \
  --plan plan-shop-dev --runtime "PYTHON:3.12"

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 40: Implantar código a partir de um arquivo zip

Envie o pacote do aplicativo para o aplicativo web.

zip -r app.zip . -x "*.git*"
az webapp deploy --resource-group rg-learn-dev --name app-shop-dev-01 \
  --src-path app.zip --type zip

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 41: Configurações do aplicativo e um slot de preparação

Teste uma nova versão antes que ela chegue aos usuários.

az webapp config appsettings set --resource-group rg-learn-dev --name app-shop-dev-01 \
  --settings ENVIRONMENT=dev LOG_LEVEL=info
az webapp deployment slot create --resource-group rg-learn-dev --name app-shop-dev-01 --slot staging

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 42: Decisões de escala pela CPU

Adicione instâncias quando estiver ocupado e remova quando estiver tranquilo.

def scale_decision(cpu_samples, instances, minimum=1, maximum=5):
    average = sum(cpu_samples) / len(cpu_samples)
    if average > 75 and instances < maximum:
        return instances + 1, f"scale out (avg CPU {average:.0f}%)"
    if average < 25 and instances > minimum:
        return instances - 1, f"scale in (avg CPU {average:.0f}%)"
    return instances, f"hold (avg CPU {average:.0f}%)"

print(scale_decision([82, 90, 78], 2))
print(scale_decision([10, 12, 15], 2))
print(scale_decision([40, 45, 50], 2))

Saída:

(3, 'scale out (avg CPU 83%)')
(1, 'scale in (avg CPU 12%)')
(2, 'hold (avg CPU 45%)')

Tópico 7: Contêineres: registro, Container Apps e Kubernetes

Um contêiner empacota a aplicação com tudo o que ela precisa. O Azure guarda as imagens em um registro e as executa no Container Apps ou no Kubernetes, conforme o nível de controle necessário.

Azure Container Registry

O registro é um armazenamento privado de imagens. Crie a imagem no Azure com az acr build, para que a construção não dependa do seu computador, e envie o resultado ao registro.

Container Apps e AKS

O Container Apps executa contêineres sem você gerenciar um cluster e pode escalar até zero. O AKS é um Kubernetes gerenciado para sistemas maiores. O AKS pode puxar imagens do seu registro com a identidade gerenciada, então não é preciso senha.

Tags e limpeza

Marque cada imagem com a versão, a data e o commit para poder voltar atrás. Agende uma tarefa de purga para excluir imagens antigas sem tag e manter o custo de armazenamento sob controle.

Exemplo 43: Criar um registro de contêineres

Um lugar privado para guardar imagens de contêiner.

az acr create --resource-group rg-learn-dev --name acrshopdev01 --sku Basic
az acr login --name acrshopdev01

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 44: Criar e enviar uma imagem

Crie a imagem no Azure e guarde-a no registro.

az acr build --registry acrshopdev01 --image shop-api:1.0.0 .
az acr repository show-tags --name acrshopdev01 --repository shop-api -o table

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 45: Executar um aplicativo de contêiner

Execute um contêiner sem gerenciar servidores.

az containerapp env create --name cae-shop-dev --resource-group rg-learn-dev --location southeastasia
az containerapp create --name ca-shop-api --resource-group rg-learn-dev \
  --environment cae-shop-dev \
  --image acrshopdev01.azurecr.io/shop-api:1.0.0 \
  --target-port 8080 --ingress external --min-replicas 0 --max-replicas 3

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 46: Criar um cluster AKS

Um cluster Kubernetes gerenciado que puxa imagens do seu registro.

az aks create \
  --resource-group rg-learn-dev \
  --name aks-shop-dev \
  --node-count 2 \
  --enable-managed-identity \
  --attach-acr acrshopdev01 \
  --generate-ssh-keys
az aks get-credentials --resource-group rg-learn-dev --name aks-shop-dev

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 47: Implantar no Kubernetes

Aplique o manifesto e aguarde o rollout terminar.

kubectl apply -f deployment.yaml
kubectl rollout status deployment/shop-api
kubectl get pods -l app=shop-api

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 48: Um manifesto de implantação do Kubernetes

Descreva os pods, as réplicas e os recursos.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: shop-api
  template:
    metadata:
      labels:
        app: shop-api
    spec:
      containers:
        - name: shop-api
          image: acrshopdev01.azurecr.io/shop-api:1.0.0
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: 100m
              memory: 128Mi

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 49: Gerar uma tag de imagem

Marque cada imagem com a versão, a data e o commit.

from datetime import date

def image_tag(version, commit, when):
    short = commit[:7]
    return f"{version}-{when.strftime('%Y%m%d')}-{short}"

print(image_tag("1.4.2", "9f3c1ab7e54d0a12", date(2026, 1, 15)))

Saída:

1.4.2-20260115-9f3c1ab

Exemplo 50: Limpar imagens antigas com uma tarefa

Exclua imagens sem tag em um agendamento para economizar armazenamento.

az acr task create --name purge-old-images --registry acrshopdev01 \
  --cmd "acr purge --filter 'shop-api:.*' --ago 30d --untagged" \
  --schedule "0 1 * * *" --context /dev/null

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Tópico 8: Armazenamento: blobs, filas e controle de acesso

As contas de armazenamento guardam arquivos, mensagens e tabelas. Proteja o acesso com o Entra ID, use links SAS de curta duração quando precisar compartilhar e deixe as regras de ciclo de vida mover os dados antigos para camadas mais baratas.

Blobs e nomes de caminho

Os contêineres de blobs guardam arquivos. Use caminhos com o dispositivo e a data para listar ou excluir os dados de um dia rapidamente. Mantenha o acesso público desligado, a menos que o conteúdo precise ser público.

Assinaturas de acesso compartilhado

Um link SAS dá acesso limitado por pouco tempo. Conceda apenas as permissões necessárias, como leitura, e escolha a validade mais curta que funcione.

Regras de ciclo de vida e filas

As regras de ciclo de vida movem os blobs para as camadas cool ou archive e os excluem depois de um número de dias definido. As filas guardam mensagens para os processos de segundo plano, então uma tarefa lenta não trava uma requisição web.

Exemplo 51: Criar uma conta de armazenamento

Padrões seguros: TLS 1.2 e sem acesso público a blobs.

az storage account create \
  --name stlearndev01 \
  --resource-group rg-learn-dev \
  --location southeastasia \
  --sku Standard_LRS \
  --kind StorageV2 \
  --min-tls-version TLS1_2 \
  --allow-blob-public-access false

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 52: Caminhos de blob com partições por data

Organize os envios por dispositivo e data para manter as consultas rápidas.

from datetime import datetime

def blob_path(device, when, filename):
    return f"telemetry/{device}/{when:%Y/%m/%d}/{when:%H%M%S}-{filename}"

print(blob_path("sensor-7", datetime(2026, 1, 15, 8, 30, 5), "batch.json"))

Saída:

telemetry/sensor-7/2026/01/15/083005-batch.json

Exemplo 53: Enviar um blob

Copie um arquivo para um contêiner com a CLI.

az storage container create --name uploads --account-name stlearndev01 --auth-mode login
az storage blob upload --account-name stlearndev01 --container-name uploads \
  --name reports/2026-01.csv --file ./report.csv --auth-mode login

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 54: Enviar do Python com Entra ID

Use sua identidade do Azure em vez de uma chave de conta.

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

client = BlobServiceClient(
    account_url="https://stlearndev01.blob.core.windows.net",
    credential=DefaultAzureCredential(),
)
blob = client.get_blob_client(container="uploads", blob="reports/2026-01.csv")
with open("report.csv", "rb") as data:
    blob.upload_blob(data, overwrite=True)

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 55: Criar um SAS de curta duração

Um link que expira e concede apenas leitura.

EXPIRY=$(date -u -d "+1 hour" '+%Y-%m-%dT%H:%MZ')
az storage blob generate-sas --account-name stlearndev01 --container-name uploads \
  --name reports/2026-01.csv --permissions r --expiry "$EXPIRY" --auth-mode login --as-user --output tsv

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 56: Descrever as permissões do SAS

Explique o que uma assinatura de acesso compartilhado permite e por quanto tempo.

from datetime import datetime, timedelta, timezone

def describe_sas(permissions, expiry):
    names = {"r": "read", "w": "write", "d": "delete", "c": "create"}
    allowed = ", ".join(names[p] for p in permissions)
    left = expiry - datetime(2026, 1, 15, 8, 0, tzinfo=timezone.utc)
    return f"allows {allowed} for {int(left.total_seconds() // 60)} minutes"

print(describe_sas("rw", datetime(2026, 1, 15, 9, 0, tzinfo=timezone.utc)))

Saída:

allows read, write for 60 minutes

Exemplo 57: Regras de ciclo de vida para blobs

Mova dados antigos para um armazenamento mais barato e depois exclua.

{
  "rules": [
    {
      "enabled": true,
      "name": "archive-telemetry",
      "type": "Lifecycle",
      "definition": {
        "filters": { "blobTypes": ["blockBlob"], "prefixMatch": ["telemetry/"] },
        "actions": {
          "baseBlob": {
            "tierToCool": { "daysAfterModificationGreaterThan": 30 },
            "delete": { "daysAfterModificationGreaterThan": 365 }
          }
        }
      }
    }
  ]
}

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 58: Armazenamento de fila para trabalho em segundo plano

Coloque tarefas em uma fila e deixe os workers processarem depois.

az storage queue create --name jobs --account-name stlearndev01 --auth-mode login
az storage message put --queue-name jobs --content "resize:photo-42" \
  --account-name stlearndev01 --auth-mode login

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Tópico 9: Bancos de dados: Azure SQL e Cosmos DB

O Azure oferece um banco relacional gerenciado e um banco NoSQL distribuído globalmente. Conecte-se com identidade em vez de senha e use sempre parâmetros nas consultas.

Azure SQL

O Azure SQL é um banco SQL Server gerenciado. Ative a autenticação com o Microsoft Entra ID e os private endpoints, e o banco não terá senha guardada nem endereço público.

Consultas parametrizadas

Envie a entrada do usuário como parâmetro, nunca concatenando texto ao SQL. O banco trata a entrada como dado, o que impede a injeção de SQL.

Cosmos DB e chaves de partição

O Cosmos DB guarda documentos JSON em contêineres. A chave de partição define como os dados se espalham pelas máquinas. Uma chave com muitos valores diferentes, como o ID do cliente, mantém a carga equilibrada.

Exemplo 59: Servidor e banco de dados Azure SQL

Um banco relacional gerenciado com rede privada.

az sql server create --name sql-shop-dev-01 --resource-group rg-learn-dev \
  --location southeastasia --enable-public-network false --enable-ad-only-auth \
  --external-admin-principal-type User --external-admin-name [email protected]
az sql db create --resource-group rg-learn-dev --server sql-shop-dev-01 \
  --name shopdb --service-objective S0

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 60: Conectar ao Azure SQL sem senha

Autenticação com Entra ID em vez de uma senha guardada.

import pyodbc

conn = pyodbc.connect(
    "Driver={ODBC Driver 18 for SQL Server};"
    "Server=tcp:sql-shop-dev-01.database.windows.net,1433;"
    "Database=shopdb;Encrypt=yes;"
    "Authentication=ActiveDirectoryDefault;"
)
cursor = conn.cursor()
cursor.execute("SELECT TOP 5 name FROM sys.tables")
print([row.name for row in cursor.fetchall()])

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 61: Consultas parametrizadas

Passe os valores como parâmetros para que a entrada não altere a consulta.

import sqlite3

conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE orders (id INTEGER, customer TEXT, total REAL)")
conn.executemany("INSERT INTO orders VALUES (?, ?, ?)",
                 [(1, "ana", 120.0), (2, "ben", 75.5)])

customer = "ana' OR '1'='1"          # hostile input stays a plain value
rows = conn.execute("SELECT id, total FROM orders WHERE customer = ?", (customer,)).fetchall()
print("matches:", rows)
conn.close()

Saída:

matches: []

Exemplo 62: Criar um contêiner Cosmos DB

Um banco distribuído globalmente com chave de partição.

az cosmosdb create --name cosmos-shop-dev-01 --resource-group rg-learn-dev \
  --locations regionName=southeastasia failoverPriority=0
az cosmosdb sql database create --account-name cosmos-shop-dev-01 --resource-group rg-learn-dev \
  --name shop
az cosmosdb sql container create --account-name cosmos-shop-dev-01 --resource-group rg-learn-dev \
  --database-name shop --name orders --partition-key-path "/customerId"

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 63: Gravar um item no Cosmos DB

Guarde um documento JSON em um contêiner.

from azure.cosmos import CosmosClient
from azure.identity import DefaultAzureCredential

client = CosmosClient("https://cosmos-shop-dev-01.documents.azure.com:443/", DefaultAzureCredential())
container = client.get_database_client("shop").get_container_client("orders")
container.upsert_item({"id": "o-1001", "customerId": "ana", "total": 120.0})

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 64: Espalhar itens com um hash da chave de partição

Uma boa chave distribui os dados igualmente entre as partições.

import hashlib

def partition_for(key, partitions=4):
    digest = hashlib.sha256(key.encode("utf-8")).hexdigest()
    return int(digest, 16) % partitions

counts = [0, 0, 0, 0]
for customer in ["ana", "ben", "chai", "dao", "eve", "fon", "gus", "hana"]:
    counts[partition_for(customer)] += 1
print("items per partition:", counts)

Saída:

items per partition: [4, 1, 1, 2]

Tópico 10: Sem servidor com Azure Functions

O Azure Functions executa pequenos trechos de código quando algo acontece: uma requisição HTTP, um temporizador ou uma mensagem em uma fila. Você paga pelas execuções e não gerencia servidores.

Gatilhos e ligações

Um gatilho inicia a função, como uma requisição HTTP ou um temporizador. As ligações (bindings) conectam a função a outros serviços, como gravar em uma fila, então é necessário menos código de conexão.

Temporizadores e agendas cron

O gatilho de temporizador usa uma expressão NCRONTAB de seis campos, com os segundos no começo. A expressão 0 */5 * * * * roda a cada cinco minutos.

Processamento idempotente

Uma fila pode entregar a mesma mensagem mais de uma vez. Registre os IDs já processados e ignore as duplicatas, para que rodar um job duas vezes não cobre o cliente duas vezes.

Exemplo 65: Criar um aplicativo de funções

Código sem servidor no plano de consumo.

az storage account create --name stfuncshopdev01 --resource-group rg-learn-dev --sku Standard_LRS
az functionapp create --name func-shop-dev-01 --resource-group rg-learn-dev \
  --storage-account stfuncshopdev01 --consumption-plan-location southeastasia \
  --runtime python --runtime-version 3.12 --functions-version 4 --os-type Linux

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 66: Uma função acionada por HTTP

Execute código quando chegar uma requisição web.

import azure.functions as func

app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)

@app.route(route="hello", methods=["GET"])
def hello(req: func.HttpRequest) -> func.HttpResponse:
    name = req.params.get("name", "world")
    return func.HttpResponse(f"Hello, {name}!", status_code=200)

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 67: Uma função de temporizador com agenda cron

Execute código a cada cinco minutos sem servidor.

import logging
import azure.functions as func

app = func.FunctionApp()

@app.timer_trigger(schedule="0 */5 * * * *", arg_name="timer", run_on_startup=False)
def every_five_minutes(timer: func.TimerRequest) -> None:
    logging.info("checking sensors")

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 68: Próxima execução de uma expressão cron

Calcule quando a agenda vai disparar de novo.

def next_minutes(expression, current_minute):
    field = expression.split()[1]           # minute field, for example */5
    step = int(field.removeprefix("*/"))
    return step - (current_minute % step) if current_minute % step else step

for minute in (0, 3, 12, 14):
    print(f"at minute {minute:2d}: next run in {next_minutes('0 */5 * * * *', minute)} min")

Saída:

at minute  0: next run in 5 min
at minute  3: next run in 2 min
at minute 12: next run in 3 min
at minute 14: next run in 1 min

Exemplo 69: Publicar um aplicativo de funções

Implante o código Python no Azure Functions.

func azure functionapp publish func-shop-dev-01 --python

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 70: Uma função acionada por fila

Processe cada mensagem e grave o resultado em outra fila.

import azure.functions as func

app = func.FunctionApp()

@app.queue_trigger(arg_name="msg", queue_name="jobs", connection="AzureWebJobsStorage")
@app.queue_output(arg_name="out", queue_name="done", connection="AzureWebJobsStorage")
def process(msg: func.QueueMessage, out: func.Out[str]) -> None:
    out.set(f"processed:{msg.get_body().decode('utf-8')}")

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 71: Tratamento de mensagens idempotente

Processe uma mensagem uma vez, mesmo que ela chegue duas vezes.

processed_ids = set()

def handle(message):
    if message["id"] in processed_ids:
        return "skipped duplicate"
    processed_ids.add(message["id"])
    return f"processed {message['id']}"

events = [{"id": "e1"}, {"id": "e2"}, {"id": "e1"}]
for event in events:
    print(handle(event))

Saída:

processed e1
processed e2
skipped duplicate

Exemplo 72: Referências ao Key Vault nas configurações do aplicativo

Carregue um segredo no aplicativo sem copiá-lo.

az functionapp config appsettings set --name func-shop-dev-01 --resource-group rg-learn-dev \
  --settings "[email protected](VaultName=kv-shop-dev;SecretName=db-password)"

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Tópico 11: Redes: redes virtuais, NSGs e private endpoints

Uma rede virtual é a sua rede privada dentro do Azure. As sub-redes separam as camadas, as regras de segurança limitam o tráfego e os private endpoints mantêm os serviços fora da internet pública.

Redes virtuais e sub-redes

Escolha um intervalo de endereços como 10.10.0.0/16 e divida-o em sub-redes para web e dados. O Azure reserva cinco endereços em cada sub-rede, então uma /24 oferece 251 endereços utilizáveis.

Grupos de segurança de rede

Um NSG é uma lista de regras de permissão e de bloqueio com prioridade. Libere só as portas de que você precisa, como a 443 para HTTPS, e bloqueie o resto por padrão.

Private endpoints e DNS

Um private endpoint dá ao serviço um endereço IP privado dentro da sua rede. Uma zona DNS privada faz o nome do serviço resolver para esse endereço, então as aplicações não precisam mudar o código.

Exemplo 73: Rede virtual e sub-redes

Uma rede privada com sub-redes separadas para web e dados.

az network vnet create --name vnet-shop-dev --resource-group rg-learn-dev \
  --address-prefix 10.10.0.0/16 --subnet-name snet-web --subnet-prefix 10.10.1.0/24
az network vnet subnet create --vnet-name vnet-shop-dev --resource-group rg-learn-dev \
  --name snet-data --address-prefixes 10.10.2.0/24

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 74: Regra de grupo de segurança de rede

Permita apenas HTTPS vindo da internet.

az network nsg create --name nsg-web --resource-group rg-learn-dev
az network nsg rule create --nsg-name nsg-web --resource-group rg-learn-dev \
  --name allow-https --priority 100 --direction Inbound --access Allow \
  --protocol Tcp --destination-port-ranges 443 --source-address-prefixes Internet

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 75: Ponto de extremidade privado para armazenamento

Acesse a conta de armazenamento apenas de dentro da sua rede.

az network private-endpoint create --name pe-storage --resource-group rg-learn-dev \
  --vnet-name vnet-shop-dev --subnet snet-data \
  --private-connection-resource-id $(az storage account show -n stlearndev01 -g rg-learn-dev --query id -o tsv) \
  --group-id blob --connection-name conn-storage

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 76: Zona DNS privada

Resolva os nomes dos pontos de extremidade privados dentro da rede virtual.

az network private-dns zone create --resource-group rg-learn-dev \
  --name privatelink.blob.core.windows.net
az network private-dns link vnet create --resource-group rg-learn-dev \
  --zone-name privatelink.blob.core.windows.net --name link-shop \
  --virtual-network vnet-shop-dev --registration-enabled false

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 77: Balanceador de carga público

Distribua o tráfego de entrada entre várias máquinas virtuais.

az network public-ip create --name pip-lb --resource-group rg-learn-dev --sku Standard
az network lb create --name lb-shop --resource-group rg-learn-dev --sku Standard \
  --public-ip-address pip-lb --backend-pool-name be-web
az network lb probe create --lb-name lb-shop --resource-group rg-learn-dev \
  --name probe-https --protocol Tcp --port 443

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 78: Calculadora de tamanho de sub-rede

Conte os endereços utilizáveis em um bloco CIDR.

import ipaddress

def usable_hosts(cidr):
    net = ipaddress.ip_network(cidr)
    return net.num_addresses - 5          # Azure reserves 5 addresses in every subnet

for block in ("10.10.1.0/24", "10.10.2.0/27", "10.10.0.0/16"):
    print(block, usable_hosts(block))

Saída:

10.10.1.0/24 251
10.10.2.0/27 27
10.10.0.0/16 65531

Tópico 12: Mensagens e streaming: Service Bus e Event Hubs

Os serviços conversam por meio de mensagens. O Service Bus serve para mensagens de negócio confiáveis, e o Event Hubs serve para fluxos de grande volume, como telemetria.

Filas do Service Bus

Uma fila guarda as mensagens até que o receptor as conclua. Conclua a mensagem só depois de processá-la, para que uma falha leve a uma nova tentativa, e não a um pedido perdido. Mensagens que falham muitas vezes vão para uma fila de mensagens mortas.

Event Hubs e partições

Um event hub divide o fluxo em partições que muitos leitores podem consumir em paralelo. Envie os eventos em lotes e mantenha cada lote abaixo do limite de tamanho.

Como escolher entre os dois

Use o Service Bus quando cada mensagem importa e precisa ser processada exatamente como planejado. Use o Event Hubs quando você coleta grandes volumes de eventos e pode processá-los em ordem dentro de cada partição.

Exemplo 79: Fila do Service Bus

Mensagens confiáveis entre aplicativos, com filas de mensagens mortas.

az servicebus namespace create --name sb-shop-dev --resource-group rg-learn-dev --location southeastasia --sku Standard
az servicebus queue create --namespace-name sb-shop-dev --resource-group rg-learn-dev \
  --name orders --max-delivery-count 5 --dead-lettering-on-message-expiration true

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 80: Enviar uma mensagem ao Service Bus

Coloque um pedido na fila a partir do Python.

from azure.identity import DefaultAzureCredential
from azure.servicebus import ServiceBusClient, ServiceBusMessage

with ServiceBusClient("sb-shop-dev.servicebus.windows.net", DefaultAzureCredential()) as client:
    with client.get_queue_sender("orders") as sender:
        sender.send_messages(ServiceBusMessage('{"orderId": "o-1001"}'))

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 81: Receber e concluir uma mensagem

Remova a mensagem somente depois de processá-la.

from azure.identity import DefaultAzureCredential
from azure.servicebus import ServiceBusClient

with ServiceBusClient("sb-shop-dev.servicebus.windows.net", DefaultAzureCredential()) as client:
    with client.get_queue_receiver("orders", max_wait_time=5) as receiver:
        for msg in receiver:
            print(str(msg))
            receiver.complete_message(msg)     # removes it only after processing succeeded

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 82: Event Hubs para telemetria

Um fluxo que recebe milhões de eventos por segundo.

az eventhubs namespace create --name evhns-shop-dev --resource-group rg-learn-dev --location southeastasia --sku Standard
az eventhubs eventhub create --name telemetry --namespace-name evhns-shop-dev --resource-group rg-learn-dev \
  --partition-count 4 --message-retention 1

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 83: Enviar lotes ao Event Hubs

Agrupe eventos em lotes para ganhar eficiência.

import json
from azure.eventhub import EventData, EventHubProducerClient
from azure.identity import DefaultAzureCredential

producer = EventHubProducerClient(
    fully_qualified_namespace="evhns-shop-dev.servicebus.windows.net",
    eventhub_name="telemetry",
    credential=DefaultAzureCredential(),
)
with producer:
    batch = producer.create_batch()
    batch.add(EventData(json.dumps({"device": "sensor-7", "temp_c": 21.5})))
    producer.send_batch(batch)

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 84: Dividir mensagens pelo limite de tamanho

Mantenha cada lote abaixo do tamanho máximo.

def make_batches(messages, limit_bytes=60):
    batches, current, size = [], [], 0
    for msg in messages:
        n = len(msg.encode("utf-8"))
        if current and size + n > limit_bytes:
            batches.append(current)
            current, size = [], 0
        current.append(msg)
        size += n
    if current:
        batches.append(current)
    return batches

events = [f'{{"id": {i}, "temp": 21.{i}}}' for i in range(6)]
for number, batch in enumerate(make_batches(events), start=1):
    print("batch", number, len(batch), "messages")

Saída:

batch 1 2 messages
batch 2 2 messages
batch 3 2 messages

Tópico 13: Monitoramento: Log Analytics, Application Insights e alertas

Não dá para corrigir o que não se vê. O Azure Monitor coleta logs e métricas, o Log Analytics permite consultá-los com KQL, e os alertas avisam a equipe quando algo está errado.

Log Analytics e KQL

Um workspace do Log Analytics guarda logs de muitos recursos. A linguagem Kusto filtra, resume e gera gráficos desses dados, como contar as falhas por hora.

Application Insights

O Application Insights rastreia requisições, dependências e eventos personalizados do seu código. Use-o para descobrir qual chamada está lenta, e não apenas saber que a aplicação está lenta.

Alertas sem falsos alarmes

Um alerta de métrica dispara quando uma medida ultrapassa um limite. Exija que a condição se mantenha em várias amostras seguidas, para que um pico isolado não acorde o engenheiro de plantão.

Exemplo 85: Workspace do Log Analytics

Um lugar central para consultar os logs de todos os recursos.

az monitor log-analytics workspace create --resource-group rg-learn-dev \
  --workspace-name log-shop-dev --location southeastasia --retention-time 30

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 86: Consulta KQL para falhas

Conte as requisições com falha por hora na linguagem Kusto.

AppRequests
| where TimeGenerated > ago(24h)
| where Success == false
| summarize failures = count() by bin(TimeGenerated, 1h), ResultCode
| order by TimeGenerated desc

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 87: Configurações de diagnóstico

Envie logs e métricas da plataforma para o workspace.

az monitor diagnostic-settings create \
  --name diag-storage \
  --resource /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev/providers/Microsoft.Storage/storageAccounts/stlearndev01 \
  --workspace log-shop-dev \
  --logs '[{"category":"StorageRead","enabled":true}]' \
  --metrics '[{"category":"Transaction","enabled":true}]'

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 88: Telemetria do Application Insights

Rastreie requisições e eventos personalizados no código Python.

from opentelemetry import trace
from azure.monitor.opentelemetry import configure_azure_monitor

configure_azure_monitor(connection_string="InstrumentationKey=<key>;IngestionEndpoint=https://southeastasia-1.in.applicationinsights.azure.com/")
tracer = trace.get_tracer("shop")
with tracer.start_as_current_span("checkout") as span:
    span.set_attribute("order.total", 120.0)

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 89: Alerta de métrica quando a resposta fica lenta

Avise a equipe de plantão quando a API ficar lenta.

az monitor metrics alert create --name alert-slow-api --resource-group rg-learn-dev \
  --scopes /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev/providers/Microsoft.Web/sites/app-shop-dev-01 \
  --condition "avg HttpResponseTime > 2" --window-size 5m --evaluation-frequency 1m \
  --action /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev/providers/microsoft.insights/actionGroups/ag-oncall

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 90: Alerta depois de várias amostras ruins

Evite falsos alarmes exigindo uma sequência de leituras ruins.

def should_alert(samples, threshold=2.0, required=3):
    streak = 0
    for value in samples:
        streak = streak + 1 if value > threshold else 0
        if streak >= required:
            return True
    return False

print(should_alert([1.0, 2.5, 2.7, 2.9, 1.1]))
print(should_alert([2.5, 1.0, 2.5, 2.5, 1.0]))

Saída:

True
False

Tópico 14: Segurança: Key Vault, segredos e proteção contra ameaças

Os segredos pertencem a um cofre, não ao código nem aos logs. O Key Vault os guarda com controle de acesso, e o Defender for Cloud vigia os seus recursos em busca de ameaças.

Key Vault e acesso

O Key Vault guarda segredos, chaves e certificados. Use acesso baseado em funções, dê a cada aplicação leitura apenas dos segredos de que ela precisa e registre todos os acessos.

Lendo segredos com segurança

O DefaultAzureCredential usa a identidade gerenciada no Azure e o seu próprio login no computador, então o mesmo código funciona nos dois lugares. Nunca imprima um segredo e nunca o escreva em um log.

Defender for Cloud

O Defender for Cloud avalia a sua postura de segurança e ativa a proteção contra ameaças para máquinas virtuais, armazenamento e cofres. Revise as recomendações com regularidade.

Exemplo 91: Key Vault e um segredo

Guarde uma senha em um cofre com controle de acesso.

az keyvault create --name kv-shop-dev --resource-group rg-learn-dev --location southeastasia \
  --enable-rbac-authorization true
az keyvault secret set --vault-name kv-shop-dev --name db-password --value "$DB_PASSWORD"

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 92: Ler um segredo no Python

Use o DefaultAzureCredential para buscar um segredo.

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

client = SecretClient(vault_url="https://kv-shop-dev.vault.azure.net/", credential=DefaultAzureCredential())
password = client.get_secret("db-password").value
# use the value, never print it

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 93: Ocultar segredos dos logs

Esconda senhas e chaves antes de qualquer gravação.

import re

def redact(text):
    text = re.sub(r"(password|secret|token)=\S+", r"\1=***", text, flags=re.IGNORECASE)
    text = re.sub(r"(AccountKey=)[^;\s]+", r"\1***", text)
    return text

print(redact("connecting with password=hunter2 to host"))
print(redact("AccountKey=abc123==;EndpointSuffix=core.windows.net"))

Saída:

connecting with password=*** to host
AccountKey=***;EndpointSuffix=core.windows.net

Exemplo 94: Planos do Defender for Cloud

Ative a proteção contra ameaças para VMs, armazenamento e cofres de chaves.

az security pricing create --name VirtualMachines --tier Standard
az security pricing create --name StorageAccounts --tier Standard
az security pricing create --name KeyVaults --tier Standard

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Tópico 15: DevOps, custo e governança

Sistemas em produção precisam de um pipeline repetível, de um limite de gastos e de regras que todo recurso novo deve seguir. Essas práticas mantêm o Azure confiável e acessível conforme a equipe cresce.

Pipelines e reversão

Um pipeline testa cada mudança e faz a implantação a partir da branch main. Acompanhe a taxa de erros e a latência depois de uma versão, e reverta quando ultrapassarem os seus limites.

Orçamentos e estimativas de custo

Um orçamento define um limite mensal e envia alertas antes que você o atinja. Estime o custo a partir das horas e do armazenamento, compare com a conta real e exporte relatórios diários.

Azure Policy

Uma política verifica os recursos contra uma regra, como exigir a tag de proprietário. O efeito deny impede a criação de recursos fora do padrão, o que faz valer os padrões que a equipe combinou.

Exemplo 95: Pipeline do Azure DevOps

Teste a cada envio e implante o aplicativo web a partir da main.

trigger:
  branches:
    include: [main]

pool:
  vmImage: ubuntu-latest

steps:
  - task: UsePythonVersion@0
    inputs:
      versionSpec: '3.12'
  - script: pip install -r requirements.txt && pytest
    displayName: Test
  - task: AzureWebApp@1
    inputs:
      azureSubscription: sc-shop-dev
      appName: app-shop-dev-01
      package: '$(System.DefaultWorkingDirectory)'

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 96: Orçamento mensal

Defina um limite de gastos e avise antes de atingi-lo.

az consumption budget create --budget-name budget-dev --amount 200 \
  --category Cost --time-grain Monthly \
  --start-date 2026-01-01 --end-date 2026-12-31 \
  --resource-group rg-learn-dev

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 97: Estimar a conta mensal

Transforme horas de uso e armazenamento em um custo aproximado.

def monthly_cost(hours_per_day, hourly_rate, storage_gb, storage_rate, days=30):
    compute = hours_per_day * days * hourly_rate
    storage = storage_gb * storage_rate
    return round(compute + storage, 2)

print(monthly_cost(10, 0.05, 120, 0.02))
print(monthly_cost(24, 0.05, 120, 0.02))

Saída:

17.4
38.4

Exemplo 98: Exportar dados de custo

Envie relatórios de custo diários para uma conta de armazenamento.

az costmanagement export create --name daily-costs \
  --scope "/subscriptions/<subscription-id>/resourceGroups/rg-learn-dev" \
  --storage-account-id /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev/providers/Microsoft.Storage/storageAccounts/stlearndev01 \
  --storage-container exports --timeframe MonthToDate --recurrence Daily \
  --recurrence-period from=2026-01-01T00:00:00Z to=2026-12-31T00:00:00Z

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Exemplo 99: Decidir um rollback

Use a taxa de erro e a latência para decidir se volta a versão anterior.

def should_roll_back(error_rate, previous_error_rate, latency_ms, latency_limit=800):
    if error_rate > 0.05:
        return True, "error rate above 5 percent"
    if error_rate > previous_error_rate * 2 and error_rate > 0.01:
        return True, "error rate doubled since the last release"
    if latency_ms > latency_limit:
        return True, "latency above limit"
    return False, "healthy"

print(should_roll_back(0.02, 0.01, 300))
print(should_roll_back(0.07, 0.01, 300))

Saída:

(False, 'healthy')
(True, 'error rate above 5 percent')

Exemplo 100: Exigir tags com o Azure Policy

Negue novos recursos que não tenham a tag de proprietário.

az policy definition create --name require-owner-tag --display-name "Require owner tag" \
  --rules '{"if":{"field":"tags[owner]","exists":"false"},"then":{"effect":"deny"}}' --mode Indexed
az policy assignment create --name require-owner --policy require-owner-tag \
  --scope /subscriptions/<subscription-id>/resourceGroups/rg-learn-dev

*Este exemplo não foi executado aqui, porque precisa de uma assinatura do Azure ou das ferramentas do Azure.*

Projeto Prático: um Aplicativo Web Seguro com Armazenamento e Monitoramento

Monte uma configuração pequena e segura que use ideias de várias seções. Escreva o Bicep e os scripts por conta própria primeiro, depois compare com os exemplos. Exclua o grupo de recursos quando terminar para evitar cobranças.

1. Crie um grupo de recursos com as tags owner e environment e verifique as tags que faltam com um script.

2. Escreva um modelo Bicep para uma conta de armazenamento com TLS 1.2 e sem acesso público a blobs, e visualize-o com what-if antes de implantar.

3. Crie uma identidade gerenciada atribuída pelo usuário e dê a ela a função Storage Blob Data Reader somente na conta de armazenamento.

4. Implante um aplicativo web que lê blobs com a identidade gerenciada e adicione um alerta quando o tempo médio de resposta ficar acima de dois segundos.

5. Crie um orçamento em 80% do seu limite mensal, depois exclua o grupo de recursos e confirme a exclusão no portal.

Próximos passos

Depois, estude as orientações de arquitetura do Azure, faça uma certificação baseada em funções como a AZ-900 ou a AZ-104 e pratique pipelines de infraestrutura com o GitHub Actions ou o Azure DevOps. Execute todos os comandos primeiro em uma assinatura de sandbox e leia a documentação do serviço para a versão que você for implantar.

Resumo

O Azure se torna uma plataforma profissional quando você o descreve como código, protege com identidades em vez de senhas, monitora e controla o custo. Ao longo de 100 exemplos, este artigo cobriu a Azure CLI, grupos de recursos e tags, scripts, Bicep, identidade e RBAC, máquinas virtuais e App Service, contêineres e Kubernetes, armazenamento, bancos de dados, Functions sem servidor, redes, mensagens, monitoramento, Key Vault e segurança, além de DevOps com governança de custos. Construa o aplicativo web seguro no projeto prático e mude uma configuração de cada vez para entender como cada parte se comporta.