<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <docs>https://blogs.law.harvard.edu/tech/rss</docs>
    <title>Backup on FXShell - DevOps &amp; Sec</title>
    <link>https://fxshelll.github.io/tags/backup/</link>
    <description>Recent content in Backup on FXShell - DevOps &amp; Sec</description>
    <ttl>1440</ttl>
    <generator>Hugo 0.152.2</generator>
    <language>pt-br</language>
    <lastBuildDate>Wed, 22 Apr 2026 04:21:39 UT</lastBuildDate>
    <atom:link href="https://fxshelll.github.io/tags/backup/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Automatizando Backups de SQL Server no Azure com Ansible</title>
      <link>https://fxshelll.github.io/posts/ansible-mssql-backup-azure/</link>
      <pubDate>Tue, 21 Apr 2026 00:00:00 UT</pubDate>
      <dc:creator>Felipe da Matta</dc:creator>
      <guid>https://fxshelll.github.io/posts/ansible-mssql-backup-azure/</guid>
      <description>Manter backups consistentes de múltiplos SQL Servers e armazená-los em nuvem é uma tarefa crítica que, quando feita manualmente, vira fonte de erros, esquecimentos e surpresas na hora de um restore. Este lab mostra como resolver isso com Ansible rodando em uma máquina Linux, alcançando servidores Windows via WinRM e enviando os arquivos .bak diretamente para o Azure Blob Storage.
Objetivo do Lab Construir uma automação completa que, a partir de uma máquina Linux, conecta em múltiplos SQL Servers Windows, executa os três tipos de backup que o SQL Server suporta (Full, Differential e Transaction Log) e faz o upload para o Azure Blob Storage com verificação de integridade. O projeto inclui também um playbook de restore com suporte a ponto no tempo (point-in-time recovery).
</description>
      <content:encoded><![CDATA[Manter backups consistentes de múltiplos SQL Servers e armazená-los em nuvem é uma tarefa crítica que, quando feita manualmente, vira fonte de erros, esquecimentos e surpresas na hora de um restore. Este lab mostra como resolver isso com Ansible rodando em uma máquina Linux, alcançando servidores Windows via WinRM e enviando os arquivos .bak diretamente para o Azure Blob Storage.
Objetivo do Lab Construir uma automação completa que, a partir de uma máquina Linux, conecta em múltiplos SQL Servers Windows, executa os três tipos de backup que o SQL Server suporta (Full, Differential e Transaction Log) e faz o upload para o Azure Blob Storage com verificação de integridade. O projeto inclui também um playbook de restore com suporte a ponto no tempo (point-in-time recovery).
Tecnologias Utilizadas Ansible é a ferramenta de automação de infraestrutura que orquestra todo o fluxo. Ela executa tarefas em hosts remotos sem precisar instalar agentes — usa SSH para Linux e WinRM para Windows. No mercado é amplamente usada por times DevOps e SRE para padronizar operações repetitivas.
WinRM (Windows Remote Management) é o protocolo da Microsoft equivalente ao SSH para Windows. O Ansible usa ele, com autenticação NTLM, para executar comandos em servidores Windows sem precisar de nenhum agente instalado.
sqlcmd é a ferramenta de linha de comando do SQL Server para executar scripts T-SQL. O Ansible gera o script .sql via template Jinja2 e chama o sqlcmd remotamente para executá-lo.
T-SQL é a linguagem de consulta e administração do SQL Server. Os scripts de backup e restore são escritos em T-SQL e gerados dinamicamente pelo Ansible conforme os parâmetros de cada banco.
azcopy é a ferramenta CLI da Microsoft para transferir dados de e para o Azure Blob Storage. É instalada na máquina ops (Linux) e utiliza um SAS Token para autenticação sem expor credenciais de conta.
ansible-vault é o mecanismo de criptografia do Ansible para proteger variáveis sensíveis — senhas, tokens, chaves — dentro dos arquivos de inventário e variáveis do projeto.
Arquitetura ┌─────────────────────────────────────────────────────────────────────┐ │ BACKUP FLOW │ │ │ │ ┌──────────────┐ WinRM/NTLM ┌──────────┐ ┌──────────┐ │ │ │ ops-linux │ ─────────────► │ sql01 │ │ sql02 │ │ │ │ (Ansible) │ ◄──────────── │ sql03 │ │ ... │ │ │ └──────┬───────┘ fetch .bak └──────────┘ └──────────┘ │ │ │ azcopy │ │ ▼ │ │ ┌──────────────────────────────────────────┐ │ │ │ Azure Blob Storage │ │ │ │ 📦 sql-backup-full │ │ │ │ 📦 sql-backup-diff │ │ │ │ 📦 sql-backup-log │ │ │ └──────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────┐ │ RESTORE FLOW │ │ │ │ ┌──────────────────────────────────────────┐ │ │ │ Azure Blob Storage │ │ │ │ 📦 containers (full/diff/log) │ │ │ └──────────────────┬───────────────────────┘ │ │ │ azcopy download │ │ ▼ │ │ ┌──────────────┐ win_copy + sqlcmd ┌────────────────┐ │ │ │ ops-linux │ ──────────────────► │ sql-target │ │ │ └──────────────┘ │ (RESTORE) │ │ │ └────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘ Componente Função ops-linux Máquina Ansible Controller — orquestra tudo, roda o azcopy sql01..03 SQL Servers Windows — onde os backups são gerados sqlcmd Executa os scripts T-SQL de backup/restore azcopy Transfere os .bak entre a máquina ops e o Azure Azure Blob Storage Destino final dos backups, separados por containers Estrutura do Projeto ansible-mssql-backup-azure/ ├── ansible.cfg ├── inventory/ │ └── hosts.ini ├── group_vars/ │ ├── all.yml # Azure storage + azcopy │ └── sqlservers.yml # credenciais SQL + lista de bancos ├── playbook-backup.yml ├── playbook-restore.yml └── roles/ ├── mssql_backup/ │ ├── tasks/ │ │ ├── main.yml │ │ ├── full.yml │ │ ├── diff.yml │ │ └── log.yml │ └── templates/ │ ├── backup_full.sql.j2 │ ├── backup_diff.sql.j2 │ └── backup_log.sql.j2 └── mssql_restore/ ├── tasks/ │ ├── main.yml │ └── restore.yml └── templates/ └── restore.sql.j2 Inventário e Variáveis O inventário separa claramente os dois tipos de host: a máquina ops (conexão local) e os SQL Servers (WinRM):
[ops] ops01 ansible_host=192.168.1.10 ansible_connection=local [sqlservers] sql01 ansible_host=192.168.1.20 sql02 ansible_host=192.168.1.21 sql03 ansible_host=192.168.1.22 [sqlservers:vars] ansible_user=ansible_svc ansible_password=&#34;{{ vault_winrm_password }}&#34; ansible_connection=winrm ansible_winrm_transport=ntlm ansible_winrm_server_cert_validation=ignore ansible_port=5985 Em group_vars/sqlservers.yml, cada banco é declarado com seu modelo de recuperação, o que determina se backup de log é possível:
databases: - name: &#34;AppDB&#34; recovery_model: &#34;FULL&#34; - name: &#34;LegacyDB&#34; recovery_model: &#34;SIMPLE&#34; # só aceita full e diff backup_compression: true verify_backup: true Em group_vars/all.yml, as credenciais do Azure ficam protegidas com vault:
azure_storage_account: &#34;minhaconta&#34; azure_container_full: &#34;sql-backup-full&#34; azure_container_diff: &#34;sql-backup-diff&#34; azure_container_log: &#34;sql-backup-log&#34; vault_azure_sas_token: !vault | $ANSIBLE_VAULT;1.1;AES256 &lt;criptografado&gt; Para criar o vault:
ansible-vault encrypt_string &#39;seu-sas-token&#39; --name &#39;vault_azure_sas_token&#39; Os Três Tipos de Backup Full — Backup Completo O backup Full captura o banco inteiro. É sempre o ponto de partida para qualquer cadeia de restore.
ansible-playbook playbook-backup.yml -e backup_type=full --ask-vault-pass O script T-SQL gerado pelo template:
BACKUP DATABASE [AppDB] TO DISK = N&#39;C:\SQLBackups\Staging\sql01_AppDB_FULL_20240715_030000.bak&#39; WITH FORMAT, INIT, NAME = N&#39;AppDB - Full Backup 2024-07-15 03:00:00&#39;, COMPRESSION, STATS = 10, CHECKSUM; Após o backup, o Ansible executa RESTORE VERIFYONLY para confirmar que o arquivo não está corrompido antes de enviá-lo ao Azure.
Differential — Backup Diferencial Captura apenas os dados que mudaram desde o último Full. Muito mais rápido e menor em tamanho, ideal para execuções diárias quando o Full é semanal.
ansible-playbook playbook-backup.yml -e backup_type=diff --ask-vault-pass BACKUP DATABASE [AppDB] TO DISK = N&#39;C:\SQLBackups\Staging\sql01_AppDB_DIFF_20240715_120000.bak&#39; WITH DIFFERENTIAL, COMPRESSION, STATS = 10, CHECKSUM; Transaction Log — Backup de Log de Transações Captura todas as transações registradas no log desde o último backup de log. Permite restaurar o banco para qualquer ponto no tempo (point-in-time recovery). Requer que o banco use o modelo de recuperação FULL ou BULK_LOGGED — o script verifica isso antes de executar.
ansible-playbook playbook-backup.yml -e backup_type=log --ask-vault-pass -- Verifica modelo de recuperação antes de prosseguir IF (SELECT recovery_model_desc FROM sys.databases WHERE name = &#39;AppDB&#39;) = &#39;SIMPLE&#39; BEGIN RAISERROR(&#39;Banco AppDB usa modelo SIMPLE — backup de log não suportado.&#39;, 16, 1); RETURN; END BACKUP LOG [AppDB] TO DISK = N&#39;C:\SQLBackups\Staging\sql01_AppDB_LOG_20240715_150000.bak&#39; WITH COMPRESSION, STATS = 10, CHECKSUM; Fluxo Interno de Cada Backup Para cada banco, a role mssql_backup executa na sequência:
Define o nome do arquivo com hostname + banco + tipo + timestamp Gera o script .sql via win_template (Jinja2) Executa o backup com sqlcmd via win_shell Verifica a integridade com RESTORE VERIFYONLY (quando verify_backup: true) Faz o fetch do .bak para a máquina ops (/tmp/mssql-backups/) Executa o azcopy copy via delegate_to: localhost para enviar ao Azure Remove o arquivo da máquina ops e do SQL Server (staging limpo) O delegate_to: localhost é um detalhe importante: embora a task seja definida dentro do play dos sqlservers, o azcopy precisa rodar na máquina ops, que é quem tem acesso ao Azure. Isso instrui o Ansible a executar aquela task específica na máquina de controle.
Playbook de Restore O restore suporta quatro modos:
Modo O que aplica full Somente backup Full full_diff Full + Differential mais recente full_diff_log Full + Diff + todos os Logs em sequência point_in_time Full + Diff + Logs até um STOPAT específico # Restore simples ansible-playbook playbook-restore.yml \ -e restore_db=AppDB \ -e restore_mode=full \ --ask-vault-pass # Point-in-time recovery ansible-playbook playbook-restore.yml \ -e restore_db=AppDB \ -e restore_mode=point_in_time \ -e restore_stopat=&#34;2024-07-15 14:30:00&#34; \ --ask-vault-pass # Restaurar com nome diferente (não sobrescreve o banco original) ansible-playbook playbook-restore.yml \ -e restore_db=AppDB \ -e restore_new_name=AppDB_RestoreTest \ -e restore_mode=full_diff \ --ask-vault-pass O script T-SQL de restore gerencia o estado do banco durante a sequência:
-- Força desconexão de sessões ativas ALTER DATABASE [AppDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; -- FULL com NORECOVERY (banco fica em &#34;restaurando&#34; para aceitar diff/log) RESTORE DATABASE [AppDB] FROM DISK = N&#39;C:\SQLBackups\Restore\sql01_AppDB_FULL_20240715_030000.bak&#39; WITH NORECOVERY, REPLACE, STATS = 10; -- DIFF com NORECOVERY RESTORE DATABASE [AppDB] FROM DISK = N&#39;C:\SQLBackups\Restore\sql01_AppDB_DIFF_20240715_120000.bak&#39; WITH NORECOVERY, STATS = 10; -- LOG final com RECOVERY (encerra a sequência) e STOPAT opcional RESTORE LOG [AppDB] FROM DISK = N&#39;C:\SQLBackups\Restore\sql01_AppDB_LOG_20240715_150000.bak&#39; WITH STOPAT = &#39;2024-07-15 14:30:00&#39;, RECOVERY; -- Volta para multi-user ALTER DATABASE [AppDB] SET MULTI_USER; O uso de NORECOVERY em todos os passos exceto o último é obrigatório — ele mantém o banco em modo de restauração para aceitar os próximos arquivos. Apenas o último comando usa RECOVERY, que finaliza a sequência e coloca o banco online.
Segurança Todos os segredos ficam no vault — nunca em texto plano:
# Criptografar SAS token do Azure ansible-vault encrypt_string &#39;sv=2022-11-02&amp;ss=b...&#39; --name &#39;vault_azure_sas_token&#39; # Criptografar senha WinRM ansible-vault encrypt_string &#39;SenhaDoServico123!&#39; --name &#39;vault_winrm_password&#39; # Criptografar senha SQL ansible-vault encrypt_string &#39;SenhaSql123!&#39; --name &#39;mssql_password&#39; O SAS Token é passado via variável de ambiente para o azcopy, evitando que apareça no histórico do shell:
AZCOPY_SAS_TOKEN=&#34;{{ vault_azure_sas_token }}&#34; azcopy copy ... O usuário SQL usado (backup_svc) precisa apenas das permissões mínimas:
-- No SQL Server, criar usuário com privilégios mínimos CREATE LOGIN backup_svc WITH PASSWORD = &#39;SenhaSql123!&#39;; GRANT CONNECT SQL TO backup_svc; -- Em cada banco: EXEC sp_addrolemember &#39;db_backupoperator&#39;, &#39;backup_svc&#39;; GRANT VIEW DATABASE STATE TO backup_svc; Executando # Testar conectividade antes de tudo ansible sqlservers -m win_ping --ask-vault-pass # Backup Full de todos os bancos ansible-playbook playbook-backup.yml -e backup_type=full --ask-vault-pass # Backup Full de um banco específico ansible-playbook playbook-backup.yml -e backup_type=full -e target_db=AppDB --ask-vault-pass # Backup Differential ansible-playbook playbook-backup.yml -e backup_type=diff --ask-vault-pass # Backup de Log ansible-playbook playbook-backup.yml -e backup_type=log --ask-vault-pass # Restore full + diff + log ansible-playbook playbook-restore.yml \ -e restore_db=AppDB \ -e restore_mode=full_diff_log \ --ask-vault-pass Para Que Serve no Mercado Times de DBA e SRE que gerenciam ambientes com SQL Server Windows enfrentam o desafio de manter backups consistentes sem depender de jobs do SQL Server Agent configurados manualmente em cada instância. Com Ansible, a política de backup fica no código, versionada no Git, aplicável a qualquer número de servidores com um único comando.
O modelo de ter a máquina ops como intermediária (Linux orquestrando Windows) é um padrão real em empresas que já adotaram Ansible para outros fins e querem unificar a automação. O Azure Blob Storage como destino elimina a necessidade de gerenciar servidores de backup e oferece retenção configurável, geo-redundância e custos baixos para armazenamento frio.
O suporte a point-in-time recovery é o que diferencia um backup operacional de um backup de compliance — em caso de corrupção de dados, ransomware ou erro humano, a capacidade de restaurar para um momento específico pode ser a diferença entre minutos e horas de downtime.
Conclusão Automatizar backups não é apenas uma questão de conveniência — é uma prática de resiliência. Quando o restore precisa acontecer, não é hora de descobrir que o backup estava corrompido, desatualizado ou mal documentado. Este projeto aplica verificação de integridade antes do upload, cadeia de restore estruturada no código e segredos protegidos por vault, tornando o processo auditável e reproduzível da mesma forma em desenvolvimento e produção.
Referências Documentação do Ansible para Windows Documentação do azcopy T-SQL BACKUP DATABASE T-SQL RESTORE DATABASE ansible-vault ]]></content:encoded>
    </item>
  </channel>
</rss>
