Deploy: Cenário: Azure App Service + Github + SQL Server
Source: Dev.to
As peças do cenário que vamos montar
- Azure App Service: onde a aplicação roda
- GitHub: onde seu código vive
- GitHub Actions (opcional, mas recomendado): automação de build e deploy
- Azure SQL Database (SQL Server): onde seus dados ficam
GitHub (código)
↓
Pipeline (build / deploy)
↓
Azure App Service (API / App)
↓
Azure SQL Database (dados)
1. O que é o Azure App Service?
Como já vimos nos tipos de servidores, o Azure App Service é um serviço gerenciado. Isso significa que você:
- Não cria servidor
- Não instala Windows/Linux
- Não configura IIS, Kestrel ou Nginx manualmente
1.1 App Service
A plataforma Azure cuida de todas essas questões para você. Quando cria um App Service, define:
- Runtime (ex.: .NET 8)
- Plano de hospedagem (CPU / memória / custo)
- Região (onde o servidor fica)
Isso resulta em uma URL pública e um ambiente pronto para a execução do seu código:
https://minha-api.azurewebsites.net
Importante: neste momento não há código nenhum rodando ainda.
1.2 Como o código chega na Azure? (GitHub Actions)
Depois que o Azure App Service está configurado, precisamos subir o código de um repositório para a Azure. Nesta abordagem usaremos o GitHub Actions e entenderemos o problema que ele resolve.
1.2.1 Processo manual
Antes do GitHub Actions, o deploy normalmente era assim:
- Compila localmente
- Publica manualmente
- Sobrepõe arquivos via FTP
Esse processo gera problemas como inconsistência, erro humano, falta de histórico e deploys imprevisíveis.
1.2.2 GitHub Actions
O GitHub Actions é um robô configurável que roda dentro do GitHub sempre que algo acontece no repositório. Esse “algo” pode ser:
pushpull request- criação de tag
- horário agendado
O robô pode compilar código, rodar testes, gerar build, fazer deploy, enviar notificações, etc. Tudo isso acontece porque um workflow foi configurado.
1.3 O que é um workflow e o que ele tem a ver com tudo isso?
Um workflow é um arquivo .yml que descreve: “Quando X acontecer, execute Y passos nessa ordem”. Por exemplo:
# .github/workflows/deploy.yml
on:
push:
branches: [ main ]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Build
run: dotnet build --configuration Release
- name: Test
run: dotnet test --no-build --configuration Release
- name: Publish
run: dotnet publish -c Release -o ./publish
- name: Deploy to Azure
uses: azure/webapps-deploy@v2
with:
app-name: minha-api
publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
package: ./publish
Benefício: o arquivo de workflow é código, portanto o deploy passa a ser versionado, auditável e repetível.
2. Criando o SQL Server no Azure
Ao criar um banco de dados no Azure, você já tem backup automático, alta disponibilidade e nada para instalar. Ao final do processo você receberá:
- Nome do servidor
- Nome do banco
- Usuário e senha
Essas informações nunca devem ir ao código.
2.1 Servidor Lógico (SQL Server)
Não é uma VM, e sim um endpoint gerenciado para autenticação e conexões. O servidor:
- Pode hospedar vários bancos
- Centraliza a segurança
- Controla o firewall
No portal do Azure:
Azure SQL → Create → preencha:
- Server name →
meu-servidor.database.windows.net - Admin login
- Senha
2.2 Banco de Dados
Dentro do servidor, crie o banco nomeDoBanco e defina:
- Camada (Basic / General Purpose / Business Critical)
- DTUs ou vCores
2.3 Firewall do SQL Server
Por padrão ninguém consegue acessar o banco. Configure em Networking → Firewall rules:
- ✔️ Allow Azure services
- ✔️ Adicionar IP da sua máquina (para migrations locais)
Sem isso:
- A aplicação não conecta
- Migrations falham
- Erro de timeout
Em produção real: o ideal é usar Private Endpoint. Para início, o firewall simples já resolve.
3. Connection String – o elo entre a aplicação e o banco
Esta é uma das partes mais importantes de todo deploy. Sem a connection string, a aplicação não se comunica com a base de dados.
- Aplicação sobe: ✔️
- Banco existe: ✔️
- Mas nada se comunica: ❌
3.1 O que você já criou no Azure SQL Database
- Nome do servidor
- Nome da base de dados
- Admin login
- Senha
- Tipo de autenticação (SQL Authentication)
Essas informações são a base da sua connection string.
3.2 O que é, na prática, uma Connection String?
É um texto que informa à aplicação:
- Onde está o banco
- Qual banco acessar
- Como autenticar
- Como se comportar durante a conexão
Exemplo genérico:
Server=...
Database=...
User Id=...
Password=...
3.3 De onde vem o valor da Connection String?
No Azure SQL Database:
SQL Database → Settings → Connection strings
Normalmente você verá algo como:
Server=tcp:meuservidor.database.windows.net,1433;
Initial Catalog=MinhaBase;
PersistSecurityInfo=False;
User ID=adminuser;
Password=********;
MultipleActiveResultSets=False;
Encrypt=True;
TrustServerCertificate=False;
Connection Timeout=30;
Dica: copie a string completa e armazene-a em um Secret (por exemplo, no Azure Key Vault ou nos GitHub Secrets) para que nunca fique exposta no código.
3.4 Agora vamos ligar App → Banco
Essa configuração é feita diretamente no Azure App Service, sem precisar alterar código.
3.4.1 Caminho no Azure Portal
App Service
→ Settings
→ Configuration
→ Connection strings
Essa área funciona como um cofre de segredos da aplicação.
- ✅ Mais seguro
- ✅ Separado do código
- ✅ Ideal para ambientes (Dev / Homologação / Produção)
3.4.2 Nome da Connection String (Muito Importante)
Se você usa Entity Framework Core, o nome mais comum (e recomendado) é:
DefaultConnection
Esse nome precisa bater exatamente com o que está no seu Program.cs ou appsettings.json.
Exemplo comum no código:
builder.Services.AddDbContext(options =>
options.UseSqlServer(
builder.Configuration.GetConnectionString("DefaultConnection")));
Se o nome for diferente no Azure:
- ❌ A aplicação sobe
- ❌ Mas não encontra o banco
- ❌ Erro clássico: The ConnectionString property has not been initialized
4. Migrações
Agora vem a parte mais importante do deploy com banco. Vamos separar em três trilhas bem práticas:
- Migration Manual Local → Azure SQL
- Migration via GitHub Actions → Azure SQL (Pipeline)
- Migration por script SQL (práticas usadas por empresas)
4.1 Migration Manual (local → Azure SQL)
Pré‑requisitos
- Projeto com EF Core
- Migrations já criadas
Isso não mexe no banco ainda, apenas gera os arquivos C#.
4.2 Liberar o acesso ao banco no Azure
Por padrão, o Azure SQL bloqueia tudo e precisamos autorizar nossa máquina local; sem isso o sistema dará o erro Login failed / Timeout expired.
No Portal Azure
- Azure SQL Server
- Networking
- Firewall rules
- Add your client IPv4 address
- Save
4.3 Garantir que sua aplicação aponta para o Azure
Certifique‑se de que o arquivo appsettings.Development.json está apontando para o SQL Server no Azure:
{
"ConnectionStrings": {
"DefaultConnection": "Server=tcp:meuservidor.database.windows.net;..."
}
}
4.4 Executar a migration
dotnet ef database update
O que acontece por trás
- EF abre conexão com o Azure SQL
- Verifica se existe a tabela
__EFMigrationsHistory- Se não existir → cria
- Se existir → lê quais migrations já rodaram
- Compara:
- Migrations no código
- Migrations no banco
- Executa somente as pendentes
- Registra a versão aplicada