Tags: Ansible · Automação · IaC · YAML · Linux · Windows · SSH · Playbooks

Por Duarte Spínola · 4 de Julho de 2026

Ansible: Automação de Configuração para PMEs em 2026

O Ansible é a ferramenta open-source de automação de configuração mais popular do mundo. Sem agentes (agentless), usa SSH para Linux e WinRM para Windows. Este guia prático mostra como instalar, criar playbooks, gerir inventário misto Windows/Linux, usar roles e proteger segredos com Ansible Vault, com base na documentação oficial.

Para complementar, consulta os artigos sobre Git para Sysadmins, WSL2 para Sysadmins, PowerShell 7, Diagnóstico de Conectividade Linux e Grafana para PMEs.

Conteúdos

1. O Que é o Ansible e Como Funciona

O Ansible é uma ferramenta de Infrastructure as Code (IaC) que automatiza configuração, deployment e orquestração. Diferente de Puppet/Chef, o Ansible é agentless — não precisa de instalar nada nos alvos. Usa SSH (Linux) ou WinRM (Windows) para executar comandos.

Característica Ansible
Agentes Não (agentless)
Protocolo SSH (Linux), WinRM (Windows)
Linguagem YAML (playbooks) + Jinja2 (templates)
Idempotência Sim — executar N vezes = mesmo resultado
Instalado em Máquina de gestão (control node)
Licença GPL-3.0 (Ansible Community)

2. Instalar Ansible

# Instalar Ansible no Ubuntu/Debian (control node)
sudo apt update
sudo apt install -y ansible

# Ou via pip (versão mais recente)
pip install ansible

# Verificar instalação
ansible --version
# ansible [core 2.18.0]

# Instalar coleções adicionais (Windows, community.general)
ansible-galaxy collection install ansible.windows
ansible-galaxy collection install community.general
ansible-galaxy collection install community.windows

# Verificar colecções instaladas
ansible-galaxy collection list

# Configuração básica
mkdir -p ~/ansible/{inventory,playbooks,roles,group_vars,host_vars}
cd ~/ansible

# Criar ansible.cfg
cat > ansible.cfg << 'EOF'
[defaults]
inventory = inventory/hosts
host_key_checking = False
retry_files_enabled = False
stdout_callback = yaml
EOF

3. Inventário: Linux e Windows

# ~/ansible/inventory/hosts — inventário INI

[linux_servers]
web01 ansible_host=192.168.1.10 ansible_user=sysadmin
web02 ansible_host=192.168.1.11 ansible_user=sysadmin
db01 ansible_host=192.168.1.20 ansible_user=sysadmin

[windows_servers]
dc01 ansible_host=192.168.1.5 ansible_user=admin@EMPRESA
file01 ansible_host=192.168.1.6 ansible_user=admin@EMPRESA

[linux_servers:vars]
ansible_ssh_private_key_file=~/.ssh/id_ed25519
ansible_python_interpreter=/usr/bin/python3

[windows_servers:vars]
ansible_connection=winrm
ansible_winrm_transport=ntlm
ansible_winrm_server_cert_validation=ignore
ansible_port=5986

# Testar conectividade
ansible linux_servers -m ping
ansible windows_servers -m win_ping

# Verificar inventário
ansible-inventory --list
ansible-inventory --graph

4. Primeiro Playbook

# ~/ansible/playbooks/update-linux.yml
---
- name: Actualizar servidores Linux
  hosts: linux_servers
  become: yes
  tasks:
    - name: Actualizar pacotes APT
      apt:
        update_cache: yes
        upgrade: dist
      when: ansible_os_family == "Debian"

    - name: Actualizar pacotes DNF
      dnf:
        name: "*"
        state: latest
      when: ansible_os_family == "RedHat"

    - name: Instalar pacotes essenciais
      package:
        name:
          - htop
          - vim
          - curl
          - wget
          - net-tools
        state: present

    - name: Configurar timezone
      timezone:
        name: Europe/Lisbon

    - name: Reiniciar se necessário
      reboot:
        msg: "Reiniciar após actualização"
        reboot_timeout: 300
      when: ansible_facts['needs_reboot'] | default(false)

# Executar playbook
ansible-playbook playbooks/update-linux.yml -v

# Executar apenas num host
ansible-playbook playbooks/update-linux.yml -l web01

# Verificar sem aplicar (dry-run)
ansible-playbook playbooks/update-linux.yml --check

5. Módulos Essenciais

Módulo Função Plataforma
apt/dnf/yum Gestão de pacotes Linux
win_package Instalar software MSI/MSIX Windows
service/systemd Gerir serviços Linux
win_service Gerir serviços Windows Windows
copy/template Enviar ficheiros/configurações Ambos
user/group Gerir utilizadores e grupos Linux
win_user Gerir utilizadores Windows Windows
file Ficheiros, permissões, links Linux
firewalld/ufw Configurar firewall Linux
git Clonar repositórios Ambos

6. Variáveis e Templates Jinja2

# ~/ansible/group_vars/linux_servers.yml
---
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_root: /var/www/html
nginx_port: 80
server_name: empresa.pt

# ~/ansible/host_vars/web01.yml
---
nginx_port: 443
ssl_certificate: /etc/ssl/empresa.pt.crt
ssl_key: /etc/ssl/empresa.pt.key

# Template Jinja2: ~/ansible/templates/nginx.conf.j2
# worker_processes {{ nginx_worker_processes }};
# events {
#     worker_connections {{ nginx_worker_connections }};
# }
# server {
#     listen {{ nginx_port }};
#     server_name {{ server_name }};
#     root {{ nginx_root }};
#     {% if nginx_port == 443 %}
#     ssl_certificate {{ ssl_certificate }};
#     ssl_certificate_key {{ ssl_key }};
#     {% endif %}
# }

# Playbook que usa o template
- name: Configurar Nginx
  hosts: linux_servers
  become: yes
  tasks:
    - name: Instalar Nginx
      package:
        name: nginx
        state: present

    - name: Configurar Nginx via template
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/nginx.conf
        validate: nginx -t -c %s
      notify: restart nginx

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

7. Roles: Estrutura Reutilizável

# Criar estrutura de role
ansible-galaxy init roles/nginx

# Estrutura criada:
# roles/nginx/
#   tasks/main.yml       - tarefas principais
#   handlers/main.yml    - handlers (restart, reload)
#   templates/           - templates Jinja2
#   files/               - ficheiros estáticos
#   vars/main.yml        - variáveis da role
#   defaults/main.yml    - variáveis com defaults
#   meta/main.yml        - metadados e dependências
#   README.md

# roles/nginx/tasks/main.yml
---
- name: Instalar Nginx
  package:
    name: nginx
    state: present

- name: Configurar Nginx
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: restart nginx

- name: Activar e iniciar Nginx
  service:
    name: nginx
    state: started
    enabled: yes

# Usar role num playbook
- name: Configurar servidores web
  hosts: linux_servers
  roles:
    - nginx
    - { role: hardening, when: ansible_os_family == "Debian" }

8. Gerir Windows com Ansible

# Pré-requisito: configurar WinRM nos alvos Windows
# Correr no PowerShell do Windows (como Admin):

# Download do script de configuração WinRM
$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
Invoke-WebRequest -Uri $url -OutFile ConfigureRemotingForAnsible.ps1
.\ConfigureRemotingForAnsible.ps1

# Playbook para Windows
- name: Configurar servidores Windows
  hosts: windows_servers
  tasks:
    - name: Instalar 7-Zip
      win_package:
        path: https://www.7-zip.org/a/7z2409-x64.msi
        product_id: '{23170F69-40C1-2702-0920-000001000000}'
        state: present

    - name: Criar utilizador
      win_user:
        name: svc_backup
        password: "{{ vault_backup_password }}"
        state: present
        groups:
          - Backup Operators

    - name: Configurar Windows Update
      win_updates:
        category_names:
          - SecurityUpdates
          - CriticalUpdates
        state: installed
        reboot: yes

    - name: Configurar firewall
      win_firewall_rule:
        name: Allow RDP
        localport: 3389
        action: allow
        direction: in
        protocol: tcp
        state: present
        enabled: yes

    - name: Executar script PowerShell
      win_shell: |
        Get-Service | Where-Object {$_.Status -eq 'Running'} | Select-Object Name
      register: running_services

    - name: Mostrar serviços em execução
      debug:
        var: running_services.stdout_lines

9. Ansible Vault: Proteger Segredos

# Criar ficheiro encriptado
ansible-vault create group_vars/all/vault.yml
# Pedir password do vault
# Dentro do ficheiro:
# ---
# vault_db_password: SubstituirPasswordForte
# vault_backup_password: OutraPasswordForte

# Editar ficheiro encriptado
ansible-vault edit group_vars/all/vault.yml

# Encriptar ficheiro existente
ansible-vault encrypt group_vars/all/secrets.yml

# Ver conteúdo encriptado (pede password)
ansible-vault view group_vars/all/vault.yml

# Executar playbook com vault
ansible-playbook playbooks/deploy.yml --ask-vault-pass

# Ou usar ficheiro de password
echo "minha_password_vault" > ~/.vault_pass
chmod 600 ~/.vault_pass

# No ansible.cfg:
# [defaults]
# vault_password_file = ~/.vault_pass

# Executar sem pedir password
ansible-playbook playbooks/deploy.yml

⚠ Aviso: Nunca faças commit de ficheiros vault com a password do vault no repositório Git. O ficheiro .vault_pass deve estar em .gitignore.

10. Handlers e Notificações

# Handlers executam apenas quando notificados por uma task
# E executam apenas uma vez no fim do play, mesmo se notificados N vezes

- name: Configurar Apache
  hosts: web_servers
  tasks:
    - name: Instalar Apache
      package:
        name: apache2
        state: present
      notify: enable apache

    - name: Configurar vhost
      template:
        src: vhost.conf.j2
        dest: /etc/apache2/sites-available/empresa.conf
      notify: reload apache

    - name: Activar módulo SSL
      command: a2enmod ssl
      notify: restart apache

  handlers:
    - name: enable apache
      service:
        name: apache2
        state: started
        enabled: yes

    - name: reload apache
      service:
        name: apache2
        state: reloaded

    - name: restart apache
      service:
        name: apache2
        state: restarted
      # handlers executam por ordem de definição, não de notificação

11. Cenário Prático PME

# PME com 3 servidores Linux + 2 Windows
# Tarefa: hardening + actualização mensal

# ~/ansible/playbooks/monthly-maintenance.yml
---
- name: Manutenção mensal — Linux
  hosts: linux_servers
  become: yes
  tasks:
    - name: Actualizar todos os pacotes
      apt:
        update_cache: yes
        upgrade: safe

    - name: Verificar discos
      command: df -h
      register: disk_status

    - name: Verificar uptime
      command: uptime
      register: uptime_status

    - name: Limpar logs antigos
      shell: find /var/log -name "*.gz" -mtime +30 -delete

    - name: Reiniciar se kernel actualizado
      reboot:
        reboot_timeout: 300
      when: ansible_facts['needs_reboot'] | default(false)

- name: Manutenção mensal — Windows
  hosts: windows_servers
  tasks:
    - name: Instalar updates de segurança
      win_updates:
        category_names: [SecurityUpdates, CriticalUpdates]
        state: installed
        reboot: yes

    - name: Limpar temp
      win_shell: |
        Remove-Item -Path $env:TEMP\* -Recurse -Force -ErrorAction SilentlyContinue

    - name: Verificar espaço em disco
      win_shell: Get-PSDrive -PSProvider FileSystem | Select-Object Name, Used, Free

# Executar
ansible-playbook playbooks/monthly-maintenance.yml --ask-vault-pass

# Agendar via cron no control node
# 0 2 1 * * cd /home/sysadmin/ansible && ansible-playbook playbooks/monthly-maintenance.yml

12. Boas Práticas

  • Usar Git para versionar todos os playbooks, roles e inventário
  • Ansible Vault para todas as passwords e segredos
  • Nunca hardcode passwords em playbooks
  • Usar roles em vez de playbooks monolíticos
  • Testar com --check antes de aplicar em produção
  • Usar tags para executar apenas partes específicas
  • Idempotência — garantir que executar N vezes não causa problemas
  • Inventário em YAML em vez de INI para ambientes grandes
  • group_vars e host_vars para organizar variáveis
  • Ansible Lint para validar playbooks antes de executar
  • Chaves SSH com passphrase e vault para a passphrase

13. Problemas Comuns

Problema Causa Solução
SSH connection refused SSH não instalado ou firewall Instalar openssh-server, abrir porta 22
WinRM connection failed WinRM não configurado Correr ConfigureRemotingForAnsible.ps1
Permission denied Sem sudo ou chave SSH errada Configurar sudoers, verificar chave
Python not found Python não instalado no alvo Instalar python3, configurar interpreter
Host key verification Primeira conexão SSH host_key_checking = False no ansible.cfg

14. Checklist de Implementação

  • ☐ Instalar Ansible no control node (Linux ou WSL2)
  • ☐ Configurar chaves SSH para acesso Linux
  • ☐ Configurar WinRM nos servidores Windows
  • ☐ Criar estrutura de directórios (inventory, playbooks, roles)
  • ☐ Configurar ansible.cfg
  • ☐ Criar ficheiro de inventário com Linux e Windows
  • ☐ Testar conectividade (ping e win_ping)
  • ☐ Configurar Ansible Vault para segredos
  • ☐ Criar primeiro playbook de hardening
  • ☐ Testar com --check (dry-run)
  • ☐ Aplicar em ambiente de teste
  • ☐ Criar role reutilizável (ex: nginx, hardening)
  • ☐ Configurar Git para versionar playbooks
  • ☐ Agendar manutenção mensal via cron
  • ☐ Documentar topologia e procedimentos

Artigos Relacionados

Baseado na documentação oficial Ansible (ansible.com/docs) e experiência prática de automação em ambientes mistos Windows/Linux. Licença: CC BY-SA 4.0.

Este artigo foi útil?

Duarte Spínola

Deixe um Comentário