Deploy no Azure via GitHub Actions
Configurar o GitHub Actions no Azure usando apenas a linha de comando é a forma mais direta de automatizar a publicação de uma aplicação. Neste guia, você vai criar todos os recursos com a Azure CLI e a GitHub CLI, configurar os segredos e escrever o workflow que publica uma aplicação .NET 6 a cada push.
Por que usar a linha de comando
Trabalhar pelo terminal traz diversos benefícios, e o principal deles é a integração simples e direta entre ferramentas. Em um mundo tão focado em DevOps, conhecer cada passo de uma publicação completa, seja de uma API ou de um pacote, deixou de ser opcional.
Publicar uma aplicação pelo portal do Azure, integrada ao GitHub Actions, não é uma tarefa difícil. Por outro lado, fazer o mesmo pela linha de comando exige um esforço inicial maior.
Em contrapartida, comandos podem ser automatizados com muito mais facilidade. Dessa forma, o processo deixa de depender de quem clicou no portal e pode ser repetido em qualquer ambiente.
Além disso, um script de comandos documenta a infraestrutura. Qualquer pessoa do time consegue ler, revisar e reproduzir o que foi feito, algo difícil quando tudo acontece pela interface gráfica.
Instalando a Azure CLI e a GitHub CLI
Para seguir os passos, você precisa instalar duas ferramentas: a Azure CLI e a GitHub CLI. Ambas têm instaladores para Windows, macOS e Linux.
Ao fim da instalação, os comandos az e gh ficam disponíveis no terminal. Para conferir, execute az --version e gh --version e verifique se cada um responde com a versão instalada.
Vale lembrar que a GitHub CLI não é o Git. O comando git controla versões do código, enquanto o gh conversa com a plataforma GitHub, criando repositórios, segredos e pull requests.
Preparando o GitHub Actions no Azure com a Azure CLI
Antes de escrever qualquer workflow, precisamos criar a infraestrutura que vai receber a aplicação. Todo o preparo do GitHub Actions no Azure começa pela autenticação e pela escolha da assinatura correta.
Autenticando na Azure CLI
O primeiro passo é se autenticar no Azure com o comando az login. Ele abre o navegador para que você faça um login seguro e, em seguida, devolve o controle ao terminal.
az login
Em máquinas sem navegador, como servidores remotos, a CLI oferece o login por código de dispositivo. Nesse caso, você informa um código exibido no terminal em uma página de login da Microsoft.
Listando e escolhendo a assinatura
É normal ter várias contas ou assinaturas no Azure. Para listá-las, use o comando az account list, e a flag -o table formata o retorno como tabela em vez de JSON.
az account list -o table
Para definir a assinatura que deseja usar, execute o az account set seguido do Id da subscription. Depois disso, confira os detalhes da conta ativa com o az account show.
az account set --subscription xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
az account show
Esse cuidado evita um erro comum: criar recursos na assinatura errada e só perceber quando a fatura chega.
Recursos no Azure para o GitHub Actions
Com a assinatura definida, criamos os recursos na ordem em que dependem uns dos outros. Primeiro o grupo de recursos, depois o armazenamento, o plano de serviço e, por fim, o Web App.
Resource group
O grupo de recursos funciona como um contêiner lógico que agrupa aplicações, storages, bancos de dados e outros serviços. Assim, você gerencia permissões, custos e exclusão de tudo de uma só vez.
Para criar um grupo, usamos o az group create, definindo a região com a flag --location. Neste caso, escolhemos brazilsouth, seguido pelo nome do grupo.
az group create --location brazilsouth --name blog
Para listar os grupos existentes, use o az group list. Já para excluir um grupo e todos os recursos dentro dele, use o az group delete.
az group list
az group delete --name blog
Tenha atenção com o comando de exclusão, porque ele remove tudo o que estiver no grupo, inclusive o destino do GitHub Actions no Azure.
Conta de armazenamento
Para trabalhar com storage, usamos o grupo de comandos az storage account. A flag -h mostra a ajuda de qualquer comando da CLI, o que facilita descobrir os parâmetros disponíveis.
az storage account -h
az storage account list
Em seguida, criamos a conta de armazenamento com o az storage account create. O nome precisa ser único globalmente e conter apenas letras minúsculas e números.
az storage account create --name blogstorage2812 --resource-group blog -l brazilsouth --sku Standard_LRS
O SKU define a faixa de preço e o tipo de redundância do serviço. Neste exemplo, o Standard_LRS mantém cópias locais dentro de um único datacenter, e a documentação de SKUs do Azure Storage lista as demais opções.
Para exibir a string de conexão da conta, usamos o show-connection-string. Esse valor costuma ir para as configurações da aplicação, nunca para o código.
az storage account show-connection-string --name blogstorage2812 --resource-group blog
Plano de serviço
Antes de criar a aplicação, precisamos de um plano de cobrança, que define a capacidade e o preço das máquinas usadas pelo GitHub Actions no Azure. Esse recurso fica no grupo de comandos az appservice plan.
az appservice plan -h
az appservice plan create --name blogbalta2812 --resource-group blog --sku F1 --is-linux
Novamente, o SKU define o nível de preço, e o F1 corresponde ao plano gratuito. Já a flag --is-linux indica que a aplicação vai rodar em um ambiente Linux.
Na época em que este fluxo foi montado, a CLI aceitava SKUs como B1, B2, B3, D1, F1, FREE, I1, I2, I3, P1V2, P1V3, P2V2, P2V3, P3V2, P3V3, S1, S2, S3, SHARED, WS1, WS2 e WS3. Contudo, essa lista muda com o tempo, então consulte o -h antes de escolher.
Web App
Os Web Apps ficam no grupo az webapp, e o comando abaixo lista os existentes em formato de tabela.
az webapp list -o table
Ao criar um Web App, definimos o runtime, como Java, .NET, PHP ou Node. Para saber quais runtimes estão disponíveis no seu ambiente, use o az webapp list-runtimes.
az webapp list-runtimes
Finalmente, criamos o Web App, que será o destino do GitHub Actions no Azure, apontando para o plano e o grupo que já existem. Como este exemplo publica uma aplicação .NET 6, o runtime escolhido é o DOTNETCORE:6.0.
az webapp create --name blogbalta2812webapp --plan blogbalta2812 --resource-group blog --runtime "DOTNETCORE:6.0"
Para abrir a aplicação no navegador, basta executar o az webapp browse. Nesse momento, ela ainda exibe a página padrão do App Service, já que nenhum código foi publicado.
az webapp browse -n blogbalta2812webapp --resource-group blog
Criando o repositório com a GitHub CLI
Com a infraestrutura pronta, passamos para o lado do GitHub. A GitHub CLI também precisa de autenticação, e o comando abaixo inicia um assistente interativo no terminal.
gh auth login
Depois, criamos o repositório com o gh repo create. A flag --private torna o repositório privado, o que faz sentido para projetos internos.
gh repo create balta-blog-2812 --private
Com isso, o código da aplicação pode ser enviado normalmente com git push. É justamente esse push que vai disparar o workflow do GitHub Actions no Azure mais adiante.
Credenciais do GitHub Actions no Azure
Para publicar a aplicação pelo GitHub Actions, o workflow precisa de uma identidade com permissão no Azure. Por isso, criamos um service principal, uma espécie de conta técnica, com o comando az ad sp create-for-rbac.
az ad sp create-for-rbac --name blogbalta2812deploy --role contributor --scopes /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/blog/providers/Microsoft.Web/sites/blogbalta2812webapp --sdk-auth
Repare que o escopo aponta apenas para o Web App, e não para a assinatura inteira. Na prática, essa é a forma de conceder o menor acesso possível ao pipeline.
Como resultado, o comando devolve um JSON que deve ser salvo como segredo no repositório criado anteriormente.
{
"clientId": "00000000-0000-0000-0000-000000000000",
"clientSecret": "SECRET",
"subscriptionId": "00000000-0000-0000-0000-000000000000",
"tenantId": "00000000-0000-0000-0000-000000000000",
"activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
"resourceManagerEndpointUrl": "https://management.azure.com/",
"activeDirectoryGraphResourceId": "https://graph.windows.net/",
"sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
"galleryEndpointUrl": "https://gallery.azure.com/",
"managementEndpointUrl": "https://management.core.windows.net/"
}
Em versões mais recentes da Azure CLI, a flag --sdk-auth foi substituída pela --json-auth, que gera o mesmo formato. Além disso, a Microsoft hoje recomenda o OpenID Connect, que usa tokens de curta duração em vez de um segredo fixo.
Salvando os segredos
Você pode listar e salvar os segredos pela linha de comando com o gh secret. No entanto, como este segredo é um JSON com várias linhas, salvar pelo site do GitHub costuma ser mais seguro contra erros de formatação.
gh secret list
gh secret set AZURE_DEPLOY --body "JSON"
Uma alternativa é ler o conteúdo de um arquivo, evitando problemas com aspas no terminal. De qualquer forma, apague o arquivo local logo depois, porque ele contém uma credencial.
Escrevendo o workflow do GitHub Actions no Azure
Com tudo pronto, criamos o arquivo YAML que define o workflow. Neste exemplo, ele fica em .github/workflows/main.yml.
name: Build and deploy ASP.Net Core app to Azure Web App - balta-blog-2812
on:
push:
branches:
- main
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: '6.0.x'
include-prerelease: true
- name: Build with dotnet
run: dotnet build --configuration Release
- name: dotnet publish
run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp
- name: Upload artifact for deployment job
uses: actions/upload-artifact@v2
with:
name: .net-app
path: ${{env.DOTNET_ROOT}}/myapp
- name: Azure Login
uses: azure/login@v1.1
with:
creds: ${{ secrets.AZURE_DEPLOY }}
- name: Deploy to Azure Web App
uses: azure/webapps-deploy@v2
with:
app-name: "blogbalta2812webapp"
slot-name: "production"
package: ${{env.DOTNET_ROOT}}/myapp
Entendendo cada etapa do workflow
O bloco on define os gatilhos: todo push na branch main dispara o workflow, e o workflow_dispatch permite executá-lo manualmente pela interface.
Em seguida, o job build roda em uma máquina Ubuntu hospedada pelo GitHub. Primeiro ele baixa o código com actions/checkout e depois instala o SDK do .NET 6 com actions/setup-dotnet.
Os passos de build e publish compilam a aplicação em modo Release e geram os arquivos de publicação em uma pasta. Então, o upload-artifact guarda esse pacote, o que ajuda a inspecionar o resultado de cada execução.
Por fim, o passo Azure Login usa o segredo secrets.AZURE_DEPLOY para autenticar, e o azure/webapps-deploy envia o pacote para o slot de produção do Web App.
As versões das actions mostradas aqui eram as vigentes quando o fluxo foi montado. Hoje existem versões mais novas, como azure/login@v2 e azure/webapps-deploy@v3, e vale atualizá-las em projetos novos.
Se você quiser separar build e deploy em jobs distintos ou adicionar aprovação manual, veja como criar uma etapa de aprovação no GitHub Actions.
Deploy contínuo com GitHub Actions no Azure
Agora basta informar ao Azure que o Web App recebe deploys a partir de um repositório no GitHub. Para isso, usamos o az webapp deployment source config.
az webapp deployment source config --name blogbalta2812webapp --resource-group blog --repo-url https://github.com/andrebaltieri/balta-blog-2812 --branch main
O comando também aceita a flag --github-action, que indica explicitamente o uso do GitHub Actions no Azure como mecanismo de deploy. Com isso, o portal passa a mostrar a origem do código no Deployment Center.
A partir desse ponto, cada push na main dispara o workflow. Você acompanha o progresso na aba Actions do repositório e, ao final, a nova versão já responde no endereço do Web App.
Outros recursos via CLI: SQL Server
A Azure CLI também cria bancos de dados e diversos outros recursos. Por exemplo, os comandos abaixo listam e criam um servidor SQL no mesmo grupo.
az sql server list
az sql server create -l brazilsouth --resource-group blog --name blogbalta2812sqlserver -u blogsqlserveradmusr -p YOUR_PASSWORD
Mesmo assim, recomendo criar o banco de dados pelo portal, principalmente por causa dos valores. Os preços mudam com frequência, e nem todas as opções de configuração estavam disponíveis via CLI quando este fluxo foi montado.
Se for usar o comando, nunca deixe a senha escrita em scripts versionados. Prefira variáveis de ambiente ou um cofre de segredos, como o Azure Key Vault.
Boas práticas para o GitHub Actions no Azure
Automatizar o deploy é só o começo, já que um pipeline também precisa ser seguro e fácil de manter. A seguir estão alguns cuidados que valem para qualquer projeto com GitHub Actions no Azure.
- Conceda o menor escopo possível ao service principal, como fizemos ao apontar só para o Web App.
- Prefira OpenID Connect a segredos fixos sempre que a sua organização permitir.
- Guarde todos os scripts de criação de recursos no repositório, junto do código.
- Use deployment slots para validar a versão nova antes de trocar com a produção.
- Mantenha as actions atualizadas, porque versões antigas deixam de receber correções.
Além disso, quando vários repositórios repetem os mesmos passos, vale extrair o fluxo para workflows reutilizáveis no GitHub Actions. Assim, uma correção no pipeline chega a todos os projetos de uma vez.
Para conhecer as opções oficiais de autenticação e exemplos para outras linguagens, a página Deploy to Azure App Service by using GitHub Actions é a referência mais completa.
Conclusão sobre GitHub Actions no Azure
Publicar aplicações com GitHub Actions no Azure sem abrir o portal é plenamente possível. Com a Azure CLI e a GitHub CLI, criamos o grupo, o storage, o plano, o Web App, o repositório e as credenciais, tudo por comandos.
O grande ganho está na repetibilidade, pois o mesmo script recria o ambiente em minutos e documenta cada decisão. Dessa forma, o deploy deixa de ser um ritual manual e passa a acontecer a cada push.
Se preferir ver o mesmo fluxo aplicado a uma aplicação ASP.NET passo a passo, o artigo sobre deploy com GitHub Actions e Microsoft Azure complementa este guia. Chega de sofrer com deploy!
FAQ
Preciso do portal do Azure para configurar o deploy?
Não, todos os recursos e credenciais podem ser criados com a Azure CLI e a GitHub CLI. O portal continua útil para acompanhar custos e conferir configurações.
Qual a diferença entre a GitHub CLI e o Git?
O Git controla versões do código pelo comando git. A GitHub CLI usa o comando gh para gerenciar repositórios, segredos e pull requests na plataforma GitHub.
Por que limitar o escopo do service principal ao Web App?
Assim, mesmo que a credencial vaze, ela só dá acesso a um recurso. Esse é o princípio do menor privilégio aplicado ao pipeline.
A flag sdk-auth ainda funciona?
Em versões recentes da Azure CLI, ela deu lugar à flag json-auth, que gera o mesmo JSON. A recomendação atual da Microsoft é usar OpenID Connect.
Posso executar o workflow manualmente?
Sim, o gatilho workflow_dispatch permite rodar o workflow pela aba Actions do GitHub sem precisar de um novo push.