↓Pular para o conteúdo principal
  1. blog/
ARTIGO TÉCNICO

Ansible via Semaphore: 4 armadilhas que dão erro silencioso, não crash

O ansible.cfg do seu repo provavelmente não é o que roda em produção no Semaphore, become nunca é default, e a diferença entre 'Extra Variables' e 'Environment Variables' que não dá erro nenhum — só silenciosamente não funciona.

·3 minutos

Por que isso importa #

O pior tipo de bug em automação não é o que quebra na hora — é o que parece configurado e não faz efeito nenhum. Rodar Ansible via orquestrador (Semaphore, no meu caso) em vez de ansible-playbook direto introduz uma camada de indireção que gera exatamente esse tipo de armadilha, repetidas vezes.


1. Seu ansible.cfg local provavelmente não é o de produção #

Sintoma: playbook com roles: funciona liso rodando local, mas falha no orquestrador com “role not found” mostrando um path de busca default puro do Ansible, sem nenhum roles_path customizado.

Causa raiz: o Semaphore normalmente define seu próprio ansible.cfg fixo no host onde ele roda — completamente independente do ansible.cfg que existe dentro do repositório do projeto. Ansible só procura ansible.cfg no diretório atual (ou via ANSIBLE_CONFIG), nunca sobe a árvore de diretórios.

Fix que generaliza bem: não depender de roles_path customizado nenhum. Ansible sempre tenta <diretório do playbook>/roles automaticamente, independente de qualquer ansible.cfg. Se os playbooks vivem em playbooks/ e as roles em roles/ como irmãos, um symlink resolve pra sempre:

1
2
3
cd playbooks/
ln -s ../roles roles
git add roles   # git versiona o symlink (modo 120000), não o conteúdo

2. become: true nunca é default — nem no seu ambiente, nem em nenhum #

Sintoma: Permission denied numa task que claramente precisa de root, mesmo com credencial SSH correta.

Causa raiz: become: true não é o default do Ansible. Se o ansible.cfg de dev tem become = True na seção de privilege escalation, os testes locais escondem esse requisito — e o ansible.cfg real de produção pode não ter essa seção, quebrando na primeira task com sudo.

Fix: todo play com qualquer task que precisa de privilégio declara become: true explicitamente, no play ou na task — nunca dependendo de default herdado.


3. “Extra Variables” ≠ “Environment Variables” — e não dá erro nenhum #

A armadilha mais traiçoeira das quatro. O Semaphore tem dois campos fáceis de confundir:

  • Extra Variables (json na API) → vira ansible-playbook --extra-vars. Só cria variável Jinja dentro do playbook ({{ minha_var }}) — não afeta o processo Ansible em si.
  • Environment Variables (env na API) → essas sim viram variável de ambiente real do processo.

Se a variável precisa mudar comportamento do próprio Ansible (ANSIBLE_ROLES_PATH, config file, credencial que uma lib externa lê de os.environ), ela tem que estar em Environment Variables, não em Extra Variables. Colocar no campo errado não dá erro — só silenciosamente não faz efeito. Parece configurado. Não está.


4. Variável customizada em add_host pode sumir na play seguinte #

Injetar host em memória via add_host com uma variável customizada (ex.: hostname: "{{ algo }}") e depois não conseguir acessá-la na próxima play, mesmo via hostvars[inventory_hostname] — nome de variável que colide com atributo especial do Ansible (hostname é um dos candidatos clássicos) se perde silenciosamente no meio do caminho. Prefixar variável customizada injetada por add_host evita a colisão.


O padrão geral #

Nenhuma dessas quatro dá crash óbvio. Todas dão comportamento que parece certo até você notar que não é. A lição que generaliza: quando automação via orquestrador se comporta diferente de rodar local, a primeira suspeita não deveria ser “bug no playbook” — deveria ser “o que o orquestrador está fazendo de diferente do que eu assumi”.


Tecnologias #

Ansible · Ansible Semaphore

TEM UM CENÁRIO PARECIDO?

Me chama.

Manda o contexto, os sintomas e o que já foi testado. Bora organizar as evidências antes de sair mexendo.

Falar com Castro →
Sem enrolação. Com evidência.