ANSIBLE — AUTOMATIZACAO SEM AGENTE VIA SSH No de Controle Playbooks Inventario Roles ansible-playbook SSH Servidores Web nginx, deploy app Servidores BD mysql, backups Balanceadores haproxy, certs Fluxo de Execucao do Playbook 1. Coletar Facts (modulo setup) 2. Executar Tarefas (apt, copy, service) 3. Notificar Handlers (reiniciar servicos) 4. Reportar Resultados (ok/changed/failed) Idempotente — seguro para executar multiplas vezes Automatizacao push: sem agentes necessarios nos hosts gerenciados

Fazer login em dezenas de servidores um por um para instalar pacotes, editar arquivos de configuracao e reiniciar servicos e tedioso e propenso a erros. Um passo esquecido em um servidor gera desvio de configuracao, e de repente seus servidores “identicos” se comportam de maneira diferente. Ansible resolve isso permitindo que voce defina toda a configuracao do seu servidor em arquivos YAML simples e aplique-a consistentemente em centenas de maquinas com um unico comando. Como Ansible nao requer agente e se comunica via SSH, nao ha nada para instalar nos seus servidores gerenciados — se voce pode se conectar por SSH a um host, o Ansible pode gerencia-lo.

O Que E Ansible?

Ansible e uma ferramenta de automatizacao de codigo aberto criada pela Red Hat que gerencia configuracao de servidores, implantacao de aplicacoes e orquestracao. Diferente de ferramentas que requerem um agente dedicado rodando em cada servidor gerenciado, Ansible usa SSH para se conectar a hosts remotos e executar tarefas.

Caracteristicas principais:

  • Sem agente — Nenhum software para instalar ou manter nos nos gerenciados. Ansible usa conexoes SSH existentes
  • Baseado em push — O no de controle envia configuracoes aos hosts gerenciados sob demanda, em vez dos hosts consultarem um servidor central
  • Idempotente — Executar um playbook multiplas vezes produz o mesmo resultado. Ansible verifica o estado atual antes de fazer mudancas
  • Baseado em YAML — Playbooks sao escritos em YAML legivel por humanos, tornando-os acessiveis a qualquer pessoa que possa ler um arquivo de configuracao
  • Extensivel — Milhares de modulos integrados para gerenciar pacotes, arquivos, servicos, recursos cloud e mais

Como o Ansible Funciona

Ansible segue um modelo de execucao direto:

  1. Voce escreve um playbook (arquivo YAML) descrevendo o estado desejado dos seus servidores
  2. Voce define um inventario listando quais hosts gerenciar
  3. Voce executa ansible-playbook, e o Ansible se conecta a cada host via SSH
  4. Ansible transfere pequenos programas chamados modulos para o host remoto
  5. Os modulos executam, aplicam o estado desejado e reportam resultados
  6. Ansible remove os modulos e exibe um resumo

Nenhum daemon roda nos hosts gerenciados. Nenhum banco de dados rastreia estado. Cada execucao de playbook e autocontida.

Pre-requisitos

Antes de comecar, certifique-se de ter:

  • Uma maquina Ubuntu 22.04 ou 24.04 como no de controle (onde o Ansible executa)
  • Um ou mais servidores de destino acessiveis via SSH
  • Autenticacao SSH baseada em chaves configurada entre o no de controle e os hosts gerenciados
  • Python 3 instalado em todos os nos gerenciados (pre-instalado na maioria das distribuicoes Linux)
  • Uma conta de usuario com privilegios sudo nos hosts gerenciados

Dica: Se voce ainda nao configurou a autenticacao SSH por chaves, siga nosso guia de hardening SSH para configurar acesso seguro baseado em chaves antes de prosseguir.

Instalar Ansible no Ubuntu

Usando o gerenciador de pacotes do sistema

sudo apt update
sudo apt install ansible -y

Usando pip (recomendado para a versao mais recente)

sudo apt install python3-pip python3-venv -y
python3 -m venv ~/ansible-venv
source ~/ansible-venv/bin/activate
pip install ansible

Verificar a instalacao

ansible --version

Voce devera ver uma saida mostrando a versao do Ansible, o caminho do arquivo de configuracao e a versao do Python:

ansible [core 2.16.x]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules']
  python version = 3.12.x

Arquivos de Inventario

O inventario informa ao Ansible quais hosts gerenciar. Voce pode escrever inventarios em formato INI ou YAML.

Formato INI (simples)

# inventory.ini
[webservers]
web1.example.com
web2.example.com
192.168.1.50

[dbservers]
db1.example.com ansible_port=2222
db2.example.com

[loadbalancers]
lb1.example.com

[production:children]
webservers
dbservers
loadbalancers

[all:vars]
ansible_user=deployer
ansible_ssh_private_key_file=~/.ssh/id_ed25519

Formato YAML

# inventory.yml
all:
  vars:
    ansible_user: deployer
    ansible_ssh_private_key_file: ~/.ssh/id_ed25519
  children:
    webservers:
      hosts:
        web1.example.com:
        web2.example.com:
        192.168.1.50:
    dbservers:
      hosts:
        db1.example.com:
          ansible_port: 2222
        db2.example.com:
    loadbalancers:
      hosts:
        lb1.example.com:
    production:
      children:
        webservers:
        dbservers:
        loadbalancers:

Testar conectividade

Verifique que o Ansible consegue alcancar todos os hosts:

ansible all -m ping -i inventory.ini

Saida esperada para uma conexao bem-sucedida:

web1.example.com | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Seu Primeiro Playbook

Um playbook e um arquivo YAML contendo um ou mais “plays.” Cada play direciona um grupo de hosts e define tarefas para executar.

Instalar e configurar nginx

# site.yml
---
- name: Configurar servidores web
  hosts: webservers
  become: true

  tasks:
    - name: Atualizar cache do apt
      apt:
        update_cache: true
        cache_valid_time: 3600

    - name: Instalar nginx
      apt:
        name: nginx
        state: present

    - name: Copiar configuracao do nginx
      copy:
        src: files/nginx.conf
        dest: /etc/nginx/sites-available/default
        owner: root
        group: root
        mode: "0644"
      notify: Reiniciar nginx

    - name: Habilitar site nginx
      file:
        src: /etc/nginx/sites-available/default
        dest: /etc/nginx/sites-enabled/default
        state: link
      notify: Reiniciar nginx

    - name: Garantir que nginx esta rodando e habilitado
      service:
        name: nginx
        state: started
        enabled: true

  handlers:
    - name: Reiniciar nginx
      service:
        name: nginx
        state: restarted

Executar o playbook:

ansible-playbook -i inventory.ini site.yml

Executar com saida detalhada para depuracao:

ansible-playbook -i inventory.ini site.yml -v

Realizar uma execucao a seco para ver o que mudaria sem aplicar:

ansible-playbook -i inventory.ini site.yml --check --diff

Modulos do Ansible

Modulos sao as unidades de trabalho no Ansible. Cada modulo lida com uma tarefa especifica. Aqui estao os modulos mais utilizados:

Gerenciamento de pacotes (apt)

- name: Instalar multiplos pacotes
  apt:
    name:
      - nginx
      - curl
      - ufw
      - fail2ban
    state: present
    update_cache: true

- name: Remover um pacote
  apt:
    name: apache2
    state: absent
    purge: true

Gerenciamento de servicos (service)

- name: Iniciar e habilitar um servico
  service:
    name: nginx
    state: started
    enabled: true

- name: Reiniciar um servico
  service:
    name: mysql
    state: restarted

Gerenciamento de arquivos (copy, template, file)

- name: Copiar um arquivo para o host remoto
  copy:
    src: files/app.conf
    dest: /etc/app/app.conf
    owner: www-data
    group: www-data
    mode: "0644"

- name: Implantar um template com variaveis
  template:
    src: templates/vhost.conf.j2
    dest: /etc/nginx/sites-available/myapp.conf
    owner: root
    group: root
    mode: "0644"

- name: Criar um diretorio
  file:
    path: /var/www/myapp
    state: directory
    owner: www-data
    group: www-data
    mode: "0755"

Execucao de comandos (command, shell)

- name: Executar um comando
  command: /usr/bin/myapp --init
  args:
    creates: /var/lib/myapp/initialized

- name: Executar um comando shell com pipes
  shell: cat /var/log/syslog | grep error | wc -l
  register: error_count
  changed_when: false

Gerenciamento de usuarios (user)

- name: Criar um usuario de deploy
  user:
    name: deployer
    groups: sudo,www-data
    shell: /bin/bash
    create_home: true
    state: present

- name: Adicionar chave SSH autorizada
  authorized_key:
    user: deployer
    key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"
    state: present

Variaveis e Facts

Variaveis tornam seus playbooks flexiveis e reutilizaveis. Ansible suporta varias fontes de variaveis.

Definindo variaveis em playbooks

---
- name: Implantar aplicacao
  hosts: webservers
  become: true
  vars:
    app_name: myapp
    app_port: 8080
    app_user: www-data
    packages:
      - nginx
      - python3
      - python3-pip

  tasks:
    - name: Instalar pacotes necessarios
      apt:
        name: "{{ packages }}"
        state: present

    - name: Criar diretorio da aplicacao
      file:
        path: "/var/www/{{ app_name }}"
        state: directory
        owner: "{{ app_user }}"
        mode: "0755"

Variaveis de grupo e de host

Crie diretorios para variaveis especificas por grupo e por host:

project/
  inventory.ini
  group_vars/
    all.yml
    webservers.yml
    dbservers.yml
  host_vars/
    web1.example.com.yml
    db1.example.com.yml
  playbook.yml
# group_vars/webservers.yml
http_port: 80
https_port: 443
document_root: /var/www/html
max_workers: 4
# host_vars/web1.example.com.yml
server_name: web1.example.com
ssl_certificate: /etc/ssl/certs/web1.pem

Coletando facts

Ansible coleta automaticamente facts do sistema (SO, enderecos IP, memoria, disco) dos hosts gerenciados. Use-os em templates e condicionais:

- name: Exibir informacoes do sistema
  debug:
    msg: >
      Hostname: {{ ansible_hostname }},
      SO: {{ ansible_distribution }} {{ ansible_distribution_version }},
      IP: {{ ansible_default_ipv4.address }},
      RAM: {{ ansible_memtotal_mb }} MB

- name: Instalar pacotes baseado no SO
  apt:
    name: nginx
    state: present
  when: ansible_os_family == "Debian"

- name: Instalar pacotes no Red Hat
  yum:
    name: nginx
    state: present
  when: ansible_os_family == "RedHat"

Handlers e Notificacoes

Handlers sao tarefas especiais que executam somente quando notificados por outra tarefa. Sao acionados no final de um play, depois que todas as tarefas regulares foram completadas. Isso previne reinicializacoes desnecessarias de servicos.

---
- name: Configurar servidor web
  hosts: webservers
  become: true

  tasks:
    - name: Instalar nginx
      apt:
        name: nginx
        state: present

    - name: Implantar configuracao principal do nginx
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify:
        - Validar configuracao do nginx
        - Reiniciar nginx

    - name: Implantar virtual host
      template:
        src: templates/vhost.conf.j2
        dest: /etc/nginx/sites-available/{{ domain }}.conf
      notify:
        - Validar configuracao do nginx
        - Reiniciar nginx

    - name: Habilitar virtual host
      file:
        src: /etc/nginx/sites-available/{{ domain }}.conf
        dest: /etc/nginx/sites-enabled/{{ domain }}.conf
        state: link
      notify:
        - Validar configuracao do nginx
        - Reiniciar nginx

  handlers:
    - name: Validar configuracao do nginx
      command: nginx -t
      listen: "Validar configuracao do nginx"

    - name: Reiniciar nginx
      service:
        name: nginx
        state: restarted
      listen: "Reiniciar nginx"

Mesmo que tres tarefas notifiquem os handlers, Reiniciar nginx executa apenas uma vez no final do play.

Roles e Estrutura de Diretorios

Roles organizam seus playbooks em componentes reutilizaveis e compartilhaveis. Cada role encapsula tarefas, handlers, variaveis, templates e arquivos para uma funcao especifica.

Criar uma role

ansible-galaxy init roles/webserver

Isso gera a seguinte estrutura:

roles/
  webserver/
    tasks/
      main.yml
    handlers/
      main.yml
    templates/
    files/
    vars/
      main.yml
    defaults/
      main.yml
    meta/
      main.yml

Tarefas da role

# roles/webserver/tasks/main.yml
---
- name: Instalar nginx
  apt:
    name: nginx
    state: present
    update_cache: true

- name: Implantar configuracao do nginx
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: Reiniciar nginx

- name: Implantar virtual host
  template:
    src: vhost.conf.j2
    dest: "/etc/nginx/sites-available/{{ domain }}.conf"
  notify: Reiniciar nginx

- name: Habilitar virtual host
  file:
    src: "/etc/nginx/sites-available/{{ domain }}.conf"
    dest: "/etc/nginx/sites-enabled/{{ domain }}.conf"
    state: link
  notify: Reiniciar nginx

- name: Remover virtual host padrao
  file:
    path: /etc/nginx/sites-enabled/default
    state: absent
  notify: Reiniciar nginx

- name: Garantir que nginx esta rodando
  service:
    name: nginx
    state: started
    enabled: true

Handlers da role

# roles/webserver/handlers/main.yml
---
- name: Reiniciar nginx
  service:
    name: nginx
    state: restarted

Valores padrao da role

# roles/webserver/defaults/main.yml
---
domain: example.com
http_port: 80
https_port: 443
document_root: /var/www/html
worker_processes: auto
worker_connections: 1024

Usar roles em um playbook

# site.yml
---
- name: Configurar infraestrutura
  hosts: webservers
  become: true
  roles:
    - role: webserver
      vars:
        domain: knowledgexchange.xyz
    - role: security
    - role: monitoring

Exemplos Praticos

Implantacao de stack LAMP

# lamp.yml
---
- name: Implantar stack LAMP
  hosts: webservers
  become: true
  vars:
    mysql_root_password: "{{ vault_mysql_root_password }}"
    php_version: "8.3"

  tasks:
    - name: Instalar Apache e PHP
      apt:
        name:
          - apache2
          - libapache2-mod-php{{ php_version }}
          - php{{ php_version }}
          - php{{ php_version }}-mysql
          - php{{ php_version }}-curl
          - php{{ php_version }}-xml
          - php{{ php_version }}-mbstring
        state: present
        update_cache: true

    - name: Instalar servidor MySQL
      apt:
        name: mysql-server
        state: present

    - name: Iniciar e habilitar MySQL
      service:
        name: mysql
        state: started
        enabled: true

    - name: Iniciar e habilitar Apache
      service:
        name: apache2
        state: started
        enabled: true

    - name: Implantar pagina PHP info para testes
      copy:
        content: "<?php phpinfo(); ?>"
        dest: /var/www/html/info.php
        owner: www-data
        group: www-data
        mode: "0644"

Gerenciamento de usuarios em todos os servidores

# users.yml
---
- name: Gerenciar contas de usuario
  hosts: all
  become: true
  vars:
    admin_users:
      - name: jcarlos
        key: "ssh-ed25519 AAAAC3Nza... jcarlos@workstation"
        groups: sudo,adm
      - name: deployer
        key: "ssh-ed25519 AAAAC3Nza... deployer@ci"
        groups: www-data
    removed_users:
      - oldadmin
      - tempuser

  tasks:
    - name: Criar usuarios administradores
      user:
        name: "{{ item.name }}"
        groups: "{{ item.groups }}"
        shell: /bin/bash
        create_home: true
        state: present
      loop: "{{ admin_users }}"

    - name: Adicionar chaves SSH para usuarios administradores
      authorized_key:
        user: "{{ item.name }}"
        key: "{{ item.key }}"
        exclusive: true
      loop: "{{ admin_users }}"

    - name: Remover usuarios antigos
      user:
        name: "{{ item }}"
        state: absent
        remove: true
      loop: "{{ removed_users }}"

Hardening de seguranca

# harden.yml
---
- name: Hardening de seguranca
  hosts: all
  become: true

  tasks:
    - name: Instalar pacotes de seguranca
      apt:
        name:
          - ufw
          - fail2ban
          - unattended-upgrades
        state: present
        update_cache: true

    - name: Configurar padroes do UFW
      ufw:
        direction: incoming
        policy: deny

    - name: Permitir SSH atraves do UFW
      ufw:
        rule: allow
        port: "2222"
        proto: tcp

    - name: Permitir HTTP e HTTPS
      ufw:
        rule: allow
        port: "{{ item }}"
        proto: tcp
      loop:
        - "80"
        - "443"

    - name: Habilitar UFW
      ufw:
        state: enabled

    - name: Implantar configuracao do fail2ban
      copy:
        src: files/jail.local
        dest: /etc/fail2ban/jail.local
      notify: Reiniciar fail2ban

    - name: Habilitar atualizacoes de seguranca automaticas
      copy:
        content: |
          APT::Periodic::Update-Package-Lists "1";
          APT::Periodic::Unattended-Upgrade "1";
          APT::Periodic::AutocleanInterval "7";
        dest: /etc/apt/apt.conf.d/20auto-upgrades

    - name: Desabilitar login SSH como root
      lineinfile:
        path: /etc/ssh/sshd_config
        regexp: "^PermitRootLogin"
        line: "PermitRootLogin no"
      notify: Reiniciar sshd

  handlers:
    - name: Reiniciar fail2ban
      service:
        name: fail2ban
        state: restarted

    - name: Reiniciar sshd
      service:
        name: sshd
        state: restarted

Ansible Vault para Segredos

Nunca armazene senhas ou chaves de API em texto puro. Ansible Vault criptografa dados sensiveis:

# Criar um arquivo de variaveis criptografado
ansible-vault create group_vars/all/vault.yml

# Editar um arquivo criptografado
ansible-vault edit group_vars/all/vault.yml

# Criptografar um arquivo existente
ansible-vault encrypt secrets.yml

# Executar um playbook com vault
ansible-playbook site.yml --ask-vault-pass

# Usar um arquivo de senha em vez disso
ansible-playbook site.yml --vault-password-file ~/.vault_pass

Dentro do arquivo vault, prefixe variaveis sensiveis com vault_:

# group_vars/all/vault.yml (criptografado)
vault_mysql_root_password: "s3cur3P@ssw0rd"
vault_api_key: "abc123def456"
vault_ssl_private_key: |
  -----BEGIN PRIVATE KEY-----
  ...
  -----END PRIVATE KEY-----

Referencie variaveis vault no seu arquivo de variaveis regular:

# group_vars/all/vars.yml
mysql_root_password: "{{ vault_mysql_root_password }}"
api_key: "{{ vault_api_key }}"

Solucao de Problemas

Falhas de conexao SSH

# Testar conectividade SSH manualmente
ssh -i ~/.ssh/id_ed25519 deployer@web1.example.com

# Executar com modo detalhado para ver detalhes SSH
ansible all -m ping -i inventory.ini -vvvv

# Verificar se Python esta disponivel no host remoto
ansible all -m raw -a "python3 --version" -i inventory.ini

Erros de permissao negada

# Garantir que become (sudo) esta configurado
ansible-playbook site.yml -i inventory.ini --become --ask-become-pass

# Verificar configuracao do sudo no host remoto
ssh deployer@web1.example.com "sudo -l"

Erros de modulo nao encontrado

# Listar todos os modulos disponiveis
ansible-doc -l | grep apt

# Ver documentacao de um modulo especifico
ansible-doc apt

# Verificar versao do Ansible para compatibilidade de modulos
ansible --version

Erros de sintaxe em playbooks

# Validar sintaxe do playbook sem executar
ansible-playbook site.yml --syntax-check

# Lint do playbook para melhores praticas
pip install ansible-lint
ansible-lint site.yml

Depurar saida de tarefas

- name: Executar comando e capturar saida
  command: systemctl status nginx
  register: nginx_status
  ignore_errors: true

- name: Exibir a saida
  debug:
    var: nginx_status.stdout_lines

Referencia de Comandos Essenciais

ComandoDescricao
ansible --versionExibir versao e configuracao do Ansible
ansible all -m ping -i inventory.iniTestar conectividade a todos os hosts
ansible all -m setup -i inventory.iniColetar e exibir facts dos hosts
ansible webservers -m apt -a "name=nginx state=present" -i inventory.ini --becomeInstalar nginx nos webservers via comando ad-hoc
ansible-playbook site.yml -i inventory.iniExecutar um playbook
ansible-playbook site.yml --check --diffExecucao a seco com saida diff
ansible-playbook site.yml --limit web1.example.comExecutar playbook em um unico host
ansible-playbook site.yml --tags "nginx,security"Executar apenas tarefas com tags especificas
ansible-playbook site.yml --start-at-task "Install nginx"Retomar playbook a partir de uma tarefa especifica
ansible-vault create secrets.ymlCriar um novo arquivo criptografado
ansible-vault edit secrets.ymlEditar um arquivo criptografado
ansible-galaxy init roles/myroleCriar estrutura de diretorio de uma nova role
ansible-galaxy install geerlingguy.nginxInstalar uma role do Ansible Galaxy
ansible-inventory -i inventory.ini --graphExibir grafo de hosts do inventario
ansible-doc aptVer documentacao do modulo

Resumo

Ansible fornece um caminho poderoso e acessivel para a automatizacao de infraestrutura. Sua arquitetura sem agente significa que voce pode comecar a automatizar imediatamente — se voce pode se conectar por SSH aos seus servidores, pode gerencia-los com Ansible. Comece com comandos ad-hoc simples, avance para playbooks para tarefas repetitivas e organize configuracoes complexas em roles. A combinacao de legibilidade YAML, execucao idempotente e milhares de modulos integrados faz do Ansible a ferramenta preferida para gerenciamento de configuracao em ambientes Linux e Windows.

Para provisionar a infraestrutura em si — criar servidores cloud, redes e registros DNS antes de configura-los — explore nosso guia de infraestrutura como codigo com Terraform. Para garantir que os servidores que o Ansible gerencia estejam seguros desde o inicio, siga nosso guia de hardening SSH para proteger o acesso remoto com autenticacao baseada em chaves, fail2ban e regras de firewall.