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
- 2. Instalar Ansible
- 3. Inventário: Linux e Windows
- 4. Primeiro Playbook
- 5. Módulos Essenciais
- 6. Variáveis e Templates Jinja2
- 7. Roles: Estrutura Reutilizável
- 8. Gerir Windows com Ansible
- 9. Ansible Vault: Proteger Segredos
- 10. Handlers e Notificações
- 11. Cenário Prático PME
- 12. Boas Práticas
- 13. Problemas Comuns
- 14. Checklist de Implementação
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
- Git para Sysadmins: Configuração
- WSL2 para Sysadmins e Developers
- Migrar de PowerShell 5.1 para PowerShell 7
- Diagnóstico de Conectividade Linux Avançado
- Grafana para PMEs: Dashboards com Prometheus
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.
