Poupe até 53% em Servidores VPS, escolha agora. Oferta limitada.

Checklist: como automatizar deploys no Linux com Ansible

17 min de leitura  ·  Guia técnico

Automatizar deploys no Linux com Ansible significa usar Playbooks YAML para orquestrar, de forma repetível e auditável, todas as etapas de publicação de uma aplicação — do pull do repositório à reinicialização do serviço — sem intervenção manual. Para montar seu checklist completo, siga estes passos:

  1. Instalar o Ansible no nó de controle e configurar acesso SSH aos servidores de destino.
  2. Criar o arquivo de inventário com os hosts de produção e staging.
  3. Escrever o Playbook principal com as tarefas de deploy (pull, build, migrate, reload).
  4. Organizar tarefas em Roles reutilizáveis para separar responsabilidades.
  5. Testar com --check --diff antes de aplicar em produção.
  6. Configurar pipeline de rollback com symlinks versionados.

Pré-requisitos para automatizar deploys com Ansible no Linux

  • Nó de controle: qualquer máquina Linux com Python 3.9+ e Ansible 2.16+ instalado (Ubuntu 24.04 LTS, Debian 12 ou Rocky Linux 9 funcionam bem).
  • Servidores de destino: Python 3 instalado (pacote python3); sem necessidade de agente Ansible.
  • Acesso SSH: chave pública do nó de controle adicionada ao ~/.ssh/authorized_keys do usuário remoto (preferencialmente um usuário dedicado, não root).
  • Permissões sudo: o usuário remoto deve ter permissão de sudo sem senha para os comandos necessários (reiniciar serviços, por exemplo).
  • Git instalado nos servidores de destino para operações de pull do repositório.
  • Conhecimento básico de YAML e familiaridade com a estrutura de diretórios do Ansible.

Como instalar e configurar o Ansible para deploys automatizados

A automação de deploys com Ansible começa pela instalação correta do nó de controle. No Ubuntu 24.04 LTS, o repositório oficial da Ansible garante a versão mais recente:

sudo apt update
sudo apt install -y software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install -y ansible
ansible --version
ansible [core 2.16.x]
  config file = /etc/ansible/ansible.cfg
  python version = 3.12.x
  jinja version = 3.1.x

No Rocky Linux 9 ou AlmaLinux 9, use o repositório EPEL:

sudo dnf install -y epel-release
sudo dnf install -y ansible
ansible --version

Após a instalação, configure o arquivo global /etc/ansible/ansible.cfg ou crie um local no diretório do projeto:

[defaults]
inventory = ./inventory/hosts.ini
remote_user = deploy
private_key_file = ~/.ssh/id_ed25519
host_key_checking = False
retry_files_enabled = False

[privilege_escalation]
become = True
become_method = sudo
become_user = root

Teste a conectividade com todos os hosts antes de qualquer deploy:

ansible all -m ping
web01 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
web02 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Se você ainda está configurando o acesso SSH ao seu VPS, consulte o guia Acessando servidores VPS Linux da AviraHost para os primeiros passos de conexão.

Estrutura do inventário e organização de ambientes

O arquivo de inventário é o mapa de infraestrutura do Ansible — ele define quais servidores recebem cada conjunto de tarefas. Para deploys profissionais, separe os ambientes em grupos distintos:

[staging]
staging01 ansible_host=192.168.1.10

[production]
web01 ansible_host=203.0.113.10
web02 ansible_host=203.0.113.11

[production:vars]
app_env=production
app_dir=/var/www/minha-app
[email protected]:empresa/minha-app.git
app_branch=main
nginx_service=nginx

[staging:vars]
app_env=staging
app_dir=/var/www/minha-app-staging
app_branch=develop

Para inventários dinâmicos (quando os IPs mudam com frequência, como em ambientes cloud), o Ansible suporta scripts Python ou plugins nativos. Para a maioria dos cenários com VPS fixos, o inventário estático acima é suficiente e mais fácil de auditar.

Organize o projeto completo seguindo a estrutura recomendada pela Ansible Galaxy:

deploy-project/
├── ansible.cfg
├── inventory/
│   └── hosts.ini
├── group_vars/
│   ├── all.yml
│   ├── production.yml
│   └── staging.yml
├── roles/
│   ├── deploy/
│   │   ├── tasks/
│   │   │   └── main.yml
│   │   ├── handlers/
│   │   │   └── main.yml
│   │   └── templates/
│   │       └── app.conf.j2
│   └── rollback/
│       └── tasks/
│           └── main.yml
└── site.yml

Escrevendo o Playbook de deploy com Ansible

O Playbook de deploy é o coração da automação — ele orquestra cada etapa da publicação de forma idempotente, garantindo que rodar duas vezes produza o mesmo resultado que rodar uma vez. Crie o arquivo site.yml:

---
- name: Deploy da aplicação em produção
  hosts: production
  serial: 1
  gather_facts: true

  roles:
    - deploy

Agora crie o arquivo de tarefas principal em roles/deploy/tasks/main.yml:

---
- name: Garantir que o diretório de releases existe
  file:
    path: "{{ app_dir }}/releases"
    state: directory
    owner: "{{ remote_user }}"
    mode: "0755"

- name: Registrar timestamp do release
  command: date +%Y%m%d%H%M%S
  register: release_timestamp
  changed_when: false

- name: Definir caminho do release atual
  set_fact:
    release_path: "{{ app_dir }}/releases/{{ release_timestamp.stdout }}"

- name: Clonar repositório na versão correta
  git:
    repo: "{{ app_repo }}"
    dest: "{{ release_path }}"
    version: "{{ app_branch }}"
    depth: 1
    accept_hostkey: true

- name: Instalar dependências (exemplo: Node.js)
  command: npm ci --production
  args:
    chdir: "{{ release_path }}"
  environment:
    NODE_ENV: "{{ app_env }}"

- name: Copiar arquivo de configuração de ambiente
  template:
    src: app.conf.j2
    dest: "{{ release_path }}/.env"
    mode: "0640"

- name: Executar migrações de banco de dados
  command: ./bin/migrate.sh
  args:
    chdir: "{{ release_path }}"
  when: app_env == "production"

- name: Atualizar symlink current para o novo release
  file:
    src: "{{ release_path }}"
    dest: "{{ app_dir }}/current"
    state: link

- name: Manter apenas os 5 releases mais recentes
  shell: |
    ls -dt {{ app_dir }}/releases/*/ | tail -n +6 | xargs rm -rf
  changed_when: false

- name: Reiniciar o serviço da aplicação
  notify: restart app service

Crie o handler em roles/deploy/handlers/main.yml:

---
- name: restart app service
  systemd:
    name: minha-app
    state: restarted
    daemon_reload: true

Atenção: a tarefa de migração de banco de dados é potencialmente destrutiva. Sempre faça backup antes de executar o Playbook em produção. Consulte as Dicas de Otimização de Servidores Linux para boas práticas de manutenção antes de deploys críticos.

Configurando o Playbook de rollback com symlinks versionados

A estratégia de rollback com Ansible usa a estrutura de releases versionados criada no deploy — basta redirecionar o symlink current para a versão anterior sem necessidade de novo upload. Crie roles/rollback/tasks/main.yml:

---
- name: Listar releases disponíveis
  find:
    paths: "{{ app_dir }}/releases"
    file_type: directory
  register: available_releases

- name: Ordenar releases por data de modificação
  set_fact:
    sorted_releases: "{{ available_releases.files | sort(attribute='mtime', reverse=True) | map(attribute='path') | list }}"

- name: Verificar se existe release anterior
  fail:
    msg: "Não há release anterior disponível para rollback."
  when: sorted_releases | length < 2

- name: Definir release anterior
  set_fact:
    previous_release: "{{ sorted_releases[1] }}"

- name: Redirecionar symlink para release anterior
  file:
    src: "{{ previous_release }}"
    dest: "{{ app_dir }}/current"
    state: link

- name: Reiniciar serviço após rollback
  systemd:
    name: minha-app
    state: restarted

Para executar o rollback em emergência:

ansible-playbook -i inventory/hosts.ini rollback.yml --limit production
PLAY [Rollback da aplicação] ***********************************

TASK [rollback : Redirecionar symlink para release anterior] ***
changed: [web01]
changed: [web02]

PLAY RECAP *****************************************************
web01 : ok=5  changed=2  unreachable=0  failed=0
web02 : ok=5  changed=2  unreachable=0  failed=0

Testando Playbooks com dry-run antes de aplicar em produção

O modo de verificação do Ansible permite simular toda a execução sem alterar nenhum arquivo ou serviço no servidor remoto — essencial antes de qualquer deploy em produção. Use sempre as flags --check e --diff juntas:

ansible-playbook -i inventory/hosts.ini site.yml --check --diff --limit staging
TASK [deploy : Atualizar symlink current para o novo release] ***
--- before
+++ after
@@ -1,4 +1,4 @@
 {
-    "path": "/var/www/minha-app/current -> /var/www/minha-app/releases/20240315120000"
+    "path": "/var/www/minha-app/current -> /var/www/minha-app/releases/20240316093045"
 }

PLAY RECAP *****************************************************
staging01 : ok=8  changed=3  unreachable=0  failed=0  skipped=0

Algumas tarefas que dependem de resultados anteriores (como o timestamp do release) podem reportar skipped no modo --check — isso é comportamento esperado. Valide sempre em staging antes de promover para produção.

Para verificar a sintaxe do Playbook sem executar nada:

ansible-playbook site.yml --syntax-check
playbook: site.yml

Para listar todas as tarefas que seriam executadas, sem rodar nenhuma:

ansible-playbook site.yml --list-tasks

Automatizando deploys em múltiplos VPS com controle de paralelismo

O Ansible executa tarefas em paralelo por padrão em todos os hosts do inventário — o que pode causar downtime total se todos os servidores reiniciarem ao mesmo tempo. A diretiva serial no Playbook controla o deploy gradual (rolling deploy):

---
- name: Deploy gradual em produção
  hosts: production
  serial: 1
  max_fail_percentage: 0

  roles:
    - deploy

Com serial: 1, o Ansible processa um servidor por vez. Com serial: "50%", processa metade dos hosts simultaneamente. A diretiva max_fail_percentage: 0 interrompe o deploy imediatamente se qualquer host falhar, evitando que o problema se propague.

Para deploys com health check entre cada servidor:

- name: Verificar saúde da aplicação após deploy
  uri:
    url: "http://{{ ansible_host }}/health"
    status_code: 200
    timeout: 30
  retries: 5
  delay: 10
  register: health_check
  until: health_check.status == 200

Esse padrão garante que o próximo servidor só receba o deploy após o anterior estar respondendo corretamente — fundamental para ambientes de alta disponibilidade.

Problemas comuns e como resolver

Sintoma: erro "Python not found" ao executar o Playbook

Causa: o servidor de destino não tem Python 3 instalado ou o Ansible está procurando no caminho errado. Em distribuições minimalistas como Debian 12 slim, o Python pode não estar presente por padrão.
Solução: adicione a variável ansible_python_interpreter no inventário ou instale o Python manualmente antes do primeiro Playbook. No inventário: web01 ansible_host=x.x.x.x ansible_python_interpreter=/usr/bin/python3. Para instalar: ansible all -m raw -a "apt-get install -y python3" (o módulo raw não requer Python).

Sintoma: tarefa "git clone" falha com "Host key verification failed"

Causa: o servidor de destino nunca se conectou ao host Git (GitHub, GitLab) e a chave do host não está no known_hosts do usuário remoto.
Solução: adicione accept_hostkey: true no módulo git do Playbook (já incluído no exemplo acima) ou pré-popule o known_hosts com uma tarefa dedicada: ansible all -m known_hosts -a "name=github.com key={{ lookup('pipe', 'ssh-keyscan github.com') }}".

Sintoma: handler "restart app service" não é executado

Causa: handlers só são disparados ao final do Play, e apenas se a tarefa que os notifica reportar changed: true. Se a tarefa anterior não alterou nada (idempotência), o handler não é chamado.
Solução: force a notificação explícita com changed_when: true na tarefa de atualização do symlink, ou use meta: flush_handlers para executar handlers imediatamente após um ponto específico do Playbook.

Sintoma: deploy falha com "sudo: no tty present and no askpass program specified"

Causa: o usuário remoto requer senha para sudo, mas o Ansible não tem como fornecê-la de forma interativa.
Solução: configure o sudoers no servidor de destino para permitir sudo sem senha para o usuário de deploy: adicione a linha deploy ALL=(ALL) NOPASSWD: ALL no arquivo /etc/sudoers.d/deploy. Use visudo para editar com validação de sintaxe.

Sintoma: Playbook demora muito em ambientes com muitos hosts

Causa: o fator de fork padrão do Ansible é 5, o que limita o paralelismo em inventários grandes.
Solução: aumente o valor de forks no ansible.cfg: forks = 20. Ative também o pipelining para reduzir o número de conexões SSH por tarefa: pipelining = True na seção [ssh_connection].

Perguntas frequentes sobre Ansible para deploys no Linux

O Ansible precisa de agente instalado nos servidores remotos?

Não. O Ansible opera sem agente (agentless), usando apenas SSH e Python no servidor remoto. Basta que o servidor de destino tenha Python 3 instalado e que a chave SSH do nó de controle esteja autorizada no arquivo authorized_keys do usuário remoto. Essa arquitetura simplifica enormemente a gestão de infraestrutura, pois não há processos adicionais rodando nos servidores de destino.

Qual a diferença entre um Playbook e um Role no Ansible?

Um Playbook é um arquivo YAML que descreve uma sequência de tarefas a executar em hosts específicos — é o ponto de entrada da automação. Um Role é uma estrutura de diretórios que organiza tarefas, variáveis, templates e handlers reutilizáveis, permitindo compartilhar e versionar configurações entre projetos diferentes. Pense no Playbook como o roteiro e no Role como um módulo reutilizável que o roteiro chama.

Como testar um Playbook Ansible sem aplicar mudanças reais no servidor?

Use o modo dry-run com a flag --check ao executar o comando ansible-playbook. Combine com --diff para visualizar exatamente quais linhas de arquivos seriam alteradas. Nenhuma mudança é aplicada ao servidor durante essa execução — é a forma mais segura de validar um Playbook antes de promovê-lo para produção.

É possível usar Ansible para fazer rollback de um deploy?

Sim. A prática mais comum é manter versões anteriores em diretórios numerados no servidor e usar um symlink apontando para a versão ativa. O Playbook de rollback simplesmente redireciona o symlink para a versão anterior e reinicia o serviço, sem necessidade de novo upload de arquivos. Essa abordagem torna o rollback quase instantâneo, independentemente do tamanho da aplicação.

Ansible funciona bem para gerenciar múltiplos VPS simultaneamente?

Sim. O Ansible executa tarefas em paralelo em múltiplos hosts definidos no arquivo de inventário. É possível controlar o grau de paralelismo com a diretiva serial no Playbook, útil para deploys graduais que evitam downtime total em ambientes com vários servidores. Aumentar o valor de forks no ansible.cfg também melhora a performance em inventários grandes.

Conclusão

  • Comece pelo inventário e conectividade SSH: valide com ansible all -m ping antes de escrever qualquer Playbook — problemas de acesso são a causa número um de falhas em deploys automatizados.
  • Adote a estrutura de Roles desde o início: mesmo para projetos pequenos, separar tarefas em Roles facilita a manutenção, o reuso e a colaboração em equipe à medida que a infraestrutura cresce.
  • Nunca pule o dry-run em produção: execute sempre --check --diff em staging antes de aplicar em produção, e mantenha pelo menos 5 releases versionados para garantir rollback rápido em caso de falha.

Leia também

Precisa de ajuda com automação de deploys no seu servidor?

Ter uma infraestrutura Linux estável e bem configurada é o primeiro passo para que o Ansible funcione de forma confiável. Os planos de VPS da AviraHost oferecem acesso root completo, suporte a chaves SSH e Python 3 pré-instalado, prontos para receber seus Playbooks.

Conheça os planos de VPS da AviraHost

  • 0 Os usuários acharam isso útil
  • Ansible, automação, deploy, Linux, AviraHost, DevOps, AlmaLinux
Esta resposta foi útil?

Artigos Relacionados

Guia Completo: Como escolher o melhor plano de hospedagem para o seu site

Escolher o plano de hospedagem ideal para o seu site é fundamental para garantir seu bom...

Lista Prática: 5 Vantagens de ter SSL gratuito no seu site

Ter um certificado SSL no seu site não é apenas uma questão de segurança, mas também uma...

Comparativo: Hospedagem de sites vs. VPS: qual é a melhor opção?

Quando se trata de escolher entre hospedagem compartilhada ou VPS, as opções variam de acordo...

Dicas de Otimização de Servidores Linux

Dicas de Otimização de Servidores Linux Servidores Linux são amplamente utilizados por sua...

Como Implementar Soluções Eficientes para Melhorar a Gestão de Serviços Online

Como Implementar Soluções Eficientes para Melhorar a Gestão de Serviços Online...