<h2>Ansible Fundamentos: Inventário, Playbooks e Módulos</h2>
<p>Ansible é uma ferramenta de automação de infraestrutura que revoluciona a forma como gerenciamos servidores e ambientes. Diferente de outras soluções que exigem agentes instalados em cada máquina, Ansible utiliza SSH para se comunicar com seus hosts, tornando a implementação simples e segura. Neste artigo, você aprenderá os três pilares do Ansible: como organizar seus hosts através de inventários, como orquestrar tarefas com playbooks e como executar operações específicas usando módulos.</p>
<p>O aprendizado deve ser progressivo. Começaremos entendendo como estruturar um inventário adequado, depois exploraremos a sintaxe e lógica dos playbooks, e finalmente mergulharemos nos módulos que realizam o trabalho pesado. Todos esses conceitos se conectam de forma orgânica — um inventário bem estruturado facilita a escrita de playbooks reutilizáveis, e playbooks eficientes dependem do conhecimento profundo dos módulos disponíveis.</p>
<h2>Inventário: Organizando sua Infraestrutura</h2>
<h3>Entendendo o Propósito do Inventário</h3>
<p>O inventário é o mapa de sua infraestrutura dentro do Ansible. Ele define quais máquinas você deseja gerenciar, como agrupá-las logicamente e quais variáveis associar a cada host ou grupo. Sem um inventário bem estruturado, seus playbooks se tornam frágeis e difíceis de manter. O inventário responde perguntas fundamentais: quais são meus servidores web? Quais máquinas rodam banco de dados? Quais credenciais usar para cada grupo?</p>
<p>Existem dois formatos principais para inventários: INI (tradicional e simples) e YAML (mais poderoso e legível). A escolha entre eles depende da complexidade de sua infraestrutura. Para pequenos ambientes, INI é suficiente. Para infraestruturas complexas com muitas variáveis e hierarquias, YAML é o caminho certo.</p>
<h3>Inventário em Formato INI</h3>
<p>O formato INI é direto e intuitivo. Você define grupos entre colchetes e lista os hosts dentro deles. Variáveis podem ser associadas a hosts individuais ou a grupos inteiros através de seções especiais.</p>
<pre><code class="language-ini"># /etc/ansible/hosts ou seu_inventario.ini
[webservers]
web1.example.com ansible_user=ubuntu
web2.example.com ansible_user=ubuntu
192.168.1.10 ansible_port=2222
[databases]
db1.example.com ansible_user=deploy
db2.example.com ansible_user=deploy
[all:vars]
ansible_connection=ssh
ansible_become=yes
ansible_become_user=root
[webservers:vars]
server_role=frontend
http_port=80</code></pre>
<p>Neste exemplo, criamos dois grupos: <code>webservers</code> e <code>databases</code>. Os hosts podem ser especificados por FQDN ou IP. As variáveis como <code>ansible_user</code> definem como Ansible se conectará. A seção <code>[all:vars]</code> aplica variáveis a todos os hosts, enquanto <code>[webservers:vars]</code> aplica apenas ao grupo webservers.</p>
<h3>Inventário em Formato YAML</h3>
<p>YAML permite uma estrutura mais clara e hierárquica. É ideal quando você precisa de várias variáveis por host ou quando quer organizar inventários dinâmicos.</p>
<pre><code class="language-yaml"># inventario.yml
all:
children:
webservers:
hosts:
web1.example.com:
ansible_user: ubuntu
server_role: frontend
http_port: 80
web2.example.com:
ansible_user: ubuntu
server_role: frontend
http_port: 80
vars:
environment: production
databases:
hosts:
db1.example.com:
ansible_user: deploy
db_type: postgresql
db2.example.com:
ansible_user: deploy
db_type: mysql
vars:
backup_enabled: true
vars:
ansible_connection: ssh
ansible_become: yes</code></pre>
<p>A estrutura YAML é aninhada e clara. <code>children</code> define subgrupos, <code>hosts</code> lista as máquinas, e <code>vars</code> aplica variáveis. Este formato é especialmente útil em ambientes grandes onde a clareza estrutural facilita a manutenção.</p>
<h3>Testando e Validando seu Inventário</h3>
<p>Antes de executar qualquer playbook, verifique se seu inventário está correto. Ansible oferece comandos simples para isso.</p>
<pre><code class="language-bash"># Listar todos os hosts
ansible-inventory -i inventario.yml --list
Listar hosts de um grupo específico
ansible-inventory -i inventario.yml --graph
Testar conectividade com todos os hosts
ansible all -i inventario.yml -m ping
Executar um comando simples em um grupo
ansible webservers -i inventario.yml -m command -a "hostname"</code></pre>
<p>O módulo <code>ping</code> verifica se Ansible consegue se conectar aos hosts. Se receber um erro, verifique as credenciais, conectividade de rede e acesso SSH.</p>
<h2>Playbooks: Orquestrando Automação</h2>
<h3>Estrutura e Anatomia de um Playbook</h3>
<p>Um playbook é um arquivo YAML que define uma sequência de tarefas (tasks) a serem executadas em hosts específicos. A estrutura fundamental consiste em uma lista de plays, onde cada play mapeia um conjunto de tarefas a um grupo de hosts. Um playbook pode conter um ou múltiplos plays, permitindo orquestração complexa de múltiplos grupos de máquinas.</p>
<p>A beleza do Ansible está em sua sintaxe declarativa. Você descreve o estado desejado, não os passos imperativos para alcançá-lo. Isso torna playbooks idempotentes: executá-los múltiplas vezes leva ao mesmo resultado final.</p>
<h3>Seu Primeiro Playbook</h3>
<p>Vamos criar um playbook prático que configura um servidor web básico.</p>
<pre><code class="language-yaml">---
- name: Configurar servidores web
hosts: webservers
become: yes
vars:
nginx_port: 80
nginx_user: www-data
tasks:
- name: Atualizar cache de pacotes
apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: Instalar Nginx
apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: Criar diretório de conteúdo
file:
path: /var/www/meu_site
state: directory
owner: "{{ nginx_user }}"
group: "{{ nginx_user }}"
mode: '0755'
- name: Copiar arquivo index.html
copy:
content: |
<!DOCTYPE html>
<html>
<body>
<h1>Bem-vindo!</h1>
<p>Servidor configurado pelo Ansible</p>
</body>
</html>
dest: /var/www/meu_site/index.html
owner: "{{ nginx_user }}"
mode: '0644'
- name: Configurar Nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/sites-available/default
backup: yes
notify: reiniciar nginx
- name: Ativar Nginx
systemd:
name: nginx
enabled: yes
state: started
handlers:
- name: reiniciar nginx
systemd:
name: nginx
state: restarted</code></pre>
<p>Este playbook demonstra conceitos-chave: <code>hosts</code> especifica o grupo alvo, <code>vars</code> define variáveis, <code>tasks</code> lista as ações. Cada tarefa tem um nome descritivo (boa prática) e um módulo com seus parâmetros. A cláusula <code>when</code> adiciona condicionalidade — a tarefa só executa se a condição for verdadeira. Handlers são disparados por notificações — neste caso, Nginx reinicia apenas se sua configuração mudou.</p>
<h3>Playbooks Avançados: Variáveis e Lógica</h3>
<p>Playbooks reais precisam lidar com complexidade. Variáveis permitem reutilização, loops processam listas, e condicionais tratam diferentes cenários.</p>
<pre><code class="language-yaml">---
- name: Deploy da aplicação web
hosts: webservers
become: yes
vars:
app_version: "1.2.3"
app_port: 8080
deploy_user: deployer
required_packages:
- git
- python3
- python3-pip
- curl
tasks:
- name: Instalar pacotes obrigatórios
apt:
name: "{{ item }}"
state: present
loop: "{{ required_packages }}"
- name: Criar usuário de deploy
user:
name: "{{ deploy_user }}"
shell: /bin/bash
createhome: yes
- name: Clonar repositório da aplicação
git:
repo: https://github.com/usuario/app.git
dest: /opt/app
version: "v{{ app_version }}"
become_user: "{{ deploy_user }}"
- name: Instalar dependências Python
pip:
requirements: /opt/app/requirements.txt
virtualenv: /opt/app/venv
virtualenv_command: python3 -m venv
become_user: "{{ deploy_user }}"
- name: Gerar configuração da aplicação
template:
src: app_config.j2
dest: /opt/app/config.yml
become_user: "{{ deploy_user }}"
- name: Iniciar serviço da aplicação
systemd:
name: app
state: started
enabled: yes
daemon_reload: yes
register: service_status
- name: Verificar saúde da aplicação
uri:
url: "http://localhost:{{ app_port }}/health"
method: GET
status_code: 200
retries: 3
delay: 5
until: result.status == 200
- name: Exibir mensagem de sucesso
debug:
msg: "Aplicação v{{ app_version }} deployada com sucesso!"
when: service_status.changed</code></pre>
<p>Aqui utilizamos <code>loop</code> para iterar sobre uma lista de pacotes. <code>register</code> captura a saída de uma tarefa em uma variável (<code>service_status</code>), permitindo verificar se houve mudanças. <code>retries</code> e <code>until</code> implementam retry logic — útil ao aguardar que um serviço fique disponível. <code>uri</code> testa endpoints HTTP, validando que a aplicação está saudável.</p>
<h2>Módulos: Os Executores do Trabalho</h2>
<h3>Entendendo Módulos</h3>
<p>Módulos são os blocos de construção do Ansible. Cada módulo encapsula uma funcionalidade específica: instalar pacotes, gerenciar arquivos, reiniciar serviços, executar comandos. Ansible vem com centenas de módulos built-in, e você pode criar módulos customizados em Python ou qualquer linguagem que gere JSON.</p>
<p>A chave para dominar Ansible é conhecer os módulos relevantes para seu trabalho. Não é necessário decorar todos, mas você deve saber quais existem, o que fazem, e como utilizá-los. A documentação oficial é excelente — <code>ansible-doc nome_do_modulo</code> exibe documentação completa no terminal.</p>
<h3>Módulos Essenciais para Administração</h3>
<pre><code class="language-yaml">---
- name: Exemplo de módulos essenciais
hosts: all
become: yes
tasks:
Módulo command: executar comandos shell
- name: Executar comando shell
command: /usr/bin/uptime
register: uptime_output
- name: Exibir resultado do comando
debug:
var: uptime_output.stdout
Módulo shell: similar a command, mas com pipes e redirecionamento
- name: Processar saída com pipes
shell: ps aux | grep nginx | wc -l
register: nginx_processes
Módulo file: gerenciar arquivos e diretórios
- name: Criar diretório
file:
path: /opt/app/data
state: directory
owner: app
group: app
mode: '0755'
- name: Remover arquivo antigo
file:
path: /var/log/old_app.log
state: absent
- name: Criar link simbólico
file:
src: /opt/app/current
dest: /opt/app/latest
state: link
Módulo copy: copiar arquivos locais para hosts remotos
- name: Copiar arquivo de configuração
copy:
src: /local/path/config.yml
dest: /etc/myapp/config.yml
owner: root
group: root
mode: '0600'
backup: yes
Módulo template: processar Jinja2 e copiar
- name: Gerar config com variáveis
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
validate: /usr/sbin/nginx -t -c %s
notify: restart nginx
Módulo lineinfile: modificar linhas em arquivos
- name: Adicionar linha ao arquivo
lineinfile:
path: /etc/hosts
line: "192.168.1.100 myserver.local"
state: present
- name: Modificar parâmetro em arquivo de configuração
lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin no'
state: present
notify: restart sshd
Módulo apt/yum: gerenciar pacotes
- name: Instalar múltiplos pacotes
apt:
name: ['curl', 'wget', 'git', 'vim']
state: present
update_cache: yes
- name: Remover pacote
apt:
name: apache2
state: absent
Módulo systemd: gerenciar serviços
- name: Iniciar e ativar serviço
systemd:
name: nginx
state: started
enabled: yes
daemon_reload: yes
- name: Reiniciar serviço se necessário
systemd:
name: mysql
state: restarted
when: database_config_changed
Módulo user: gerenciar usuários
- name: Criar usuário do sistema
user:
name: appuser
shell: /bin/bash
home: /opt/app
createhome: yes
state: present
- name: Adicionar chave SSH pública
authorized_key:
user: appuser
key: "{{ lookup('file', '/local/ssh_key.pub') }}"
state: present
Módulo cron: gerenciar agendamentos
- name: Agendar backup diário
cron:
name: "Daily backup"
hour: "2"
minute: "0"
job: "/opt/scripts/backup.sh > /dev/null 2>&1"
user: root
handlers:
- name: restart nginx
systemd:
name: nginx
state: restarted
- name: restart sshd
systemd:
name: sshd
state: restarted</code></pre>
<p>Estes módulos cobrem 80% das tarefas de administração. <code>command</code> executa comandos sem processamento shell, enquanto <code>shell</code> permite pipes e redirecionamento. <code>file</code> é versátil para criar, remover e gerenciar permissões. <code>lineinfile</code> é perfeito para modificações cirurgicais em arquivos de configuração. <code>systemd</code> é o padrão moderno para gerenciar serviços em distribuições Linux atuais.</p>
<h3>Módulos Avançados para Aplicações</h3>
<pre><code class="language-yaml">---
- name: Deploy e configuração de aplicação
hosts: webservers
tasks:
Módulo git: clonar e atualizar repositórios
- name: Clonar repositório
git:
repo: https://github.com/usuario/projeto.git
dest: /opt/projeto
version: main
depth: 1
become: yes
Módulo pip: gerenciar pacotes Python
- name: Instalar dependências Python
pip:
requirements: /opt/projeto/requirements.txt
virtualenv: /opt/projeto/venv
virtualenv_command: python3 -m venv
Módulo mysql_db: gerenciar bancos de dados MySQL
- name: Criar banco de dados
mysql_db:
name: myapp_db
state: present
login_user: root
login_password: "{{ mysql_root_password }}"
Módulo postgresql_db: gerenciar bancos PostgreSQL
- name: Criar usuário PostgreSQL
postgresql_user:
name: appuser
password: "{{ db_password }}"
state: present
become_user: postgres
Módulo docker_container: gerenciar containers Docker
- name: Executar container da aplicação
docker_container:
name: myapp
image: "myapp:{{ app_version }}"
state: started
restart_policy: always
ports:
- "8080:8080"
env:
DATABASE_URL: "{{ database_url }}"
Módulo uri: fazer requisições HTTP
- name: Testar endpoint da API
uri:
url: "http://localhost:8080/api/status"
method: GET
status_code: 200
retries: 5
delay: 10
until: result.status == 200
Módulo assert: validações customizadas
- name: Validar versão da aplicação
assert:
that:
- app_version is defined
- app_version | length > 0
fail_msg: "app_version deve ser definido e não vazio"</code></pre>
<p>Estes módulos lidam com cenários mais específicos: repositories, dependências de linguagem, bancos de dados, containers e validações.</p>
<h3>Documentação e Descoberta de Módulos</h3>
<p>Nunca tente memorizar todos os módulos. Use a documentação disponível.</p>
<pre><code class="language-bash"># Listar todos os módulos instalados
ansible-doc -l
Ver documentação de um módulo específico
ansible-doc apt
Buscar módulos por palavra-chave
ansible-doc -l | grep user
Ver exemplos práticos
ansible-doc -s user</code></pre>
<p>A flag <code>-s</code> mostra o "snippet" — estrutura básica com parâmetros principais. Sempre consulte a documentação quando tiver dúvidas sobre sintaxe ou comportamento de um módulo.</p>
<h2>Conclusão</h2>
<p>Você aprendeu que <strong>Ansible funciona em três camadas interdependentes</strong>: o inventário define sua infraestrutura, playbooks orquestram o fluxo de trabalho, e módulos executam as ações concretas. Uma das lições mais importantes é que <strong>Ansible é declarativo, não imperativo</strong> — você descreve o estado desejado, e Ansible converge para ele. Isso torna sua automação robusta e reutilizável.</p>
<p>O terceiro ponto crucial é que <strong>a maestria em Ansible vem da prática e do conhecimento dos módulos disponíveis</strong>. Você não precisa decorar tudo no início — precisa saber onde procurar e como estruturar seu código para ser mantível. Invista tempo em escrever playbooks claros, use nomes descritivos para tarefas, organize seu inventário logicamente, e consulte a documentação frequentemente. Comece com playbooks simples, evolua para orquestrações complexas, e nunca deixe de testar sua automação múltiplas vezes antes de usar em produção.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://docs.ansible.com/" target="_blank" rel="noopener noreferrer">Documentação Oficial do Ansible</a></li>
<li><a href="https://galaxy.ansible.com/" target="_blank" rel="noopener noreferrer">Ansible Galaxy - Roles Compartilhadas</a></li>
<li><a href="https://docs.ansible.com/ansible/latest/tips_tricks/ansible_tips_tricks.html" target="_blank" rel="noopener noreferrer">Best Practices - Estruturando Playbooks</a></li>
<li><a href="https://docs.ansible.com/ansible/latest/modules/modules_by_category.html" target="_blank" rel="noopener noreferrer">Ansible Module Index</a></li>
<li><a href="https://www.ansible.com/resources/get-started" target="_blank" rel="noopener noreferrer">Interactive Tutorials - Learn Ansible</a></li>
</ul>
<p><!-- FIM --></p>