{"id":782,"date":"2026-09-07T12:29:23","date_gmt":"2026-09-07T15:29:23","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/2026\/09\/primeiros-passos-com-ansible\/"},"modified":"2026-09-23T13:54:21","modified_gmt":"2026-09-23T16:54:21","slug":"primeiros-passos-com-ansible","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/es\/2026\/09\/primeiros-passos-com-ansible\/","title":{"rendered":"Primeros pasos con Ansible"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/09\/primeiros-passos-com-ansible-v4.webp\" alt=\"Mascote LinuxPro aperta o bot\u00e3o de play com o playbook aberto na m\u00e3o, e feixes de luz levam a configura\u00e7\u00e3o a tr\u00eas servidores, sob o logo do Ansible, com o cachorro caramelo cyborg sentado ao lado\" width=\"1486\" height=\"856\" \/><\/p>\n<p>Se voc\u00ea ainda configura servidor na m\u00e3o, entrando por SSH, editando arquivo, instalando pacote e repetindo tudo na m\u00e1quina seguinte, o <strong>Ansible<\/strong> \u00e9 a ferramenta que aposenta esse ritual. Voc\u00ea descreve em arquivos YAML como cada servidor deve ficar, e o Ansible aplica isso por SSH, sem instalar agente nenhum nas m\u00e1quinas. Pode rodar mil vezes: o resultado \u00e9 o mesmo. Neste guia voc\u00ea vai instalar o Ansible no Ubuntu, montar um projeto com invent\u00e1rio, rodar comandos avulsos e escrever um playbook com vari\u00e1vel, template e handler. Todos os comandos foram testados com o ansible-core 2.21 num laborat\u00f3rio com tr\u00eas servidores Ubuntu 24.04.<\/p>\n<p><!-- more --><\/p>\n<h2>Como nasceu o Ansible<\/h2>\n<p>O primeiro commit do Ansible, com a mensagem &#8220;Genesis.&#8221;, \u00e9 de <strong>23 de fevereiro de 2012<\/strong>, feito por <strong>Michael DeHaan<\/strong>. Ele conhecia o problema de perto: na Red Hat, tinha criado o <strong>Cobbler<\/strong>, de provisionamento de servidores, e participado do <strong>Func<\/strong>, de execu\u00e7\u00e3o remota de comandos. As ferramentas de ger\u00eancia da \u00e9poca, como Puppet e Chef, exigiam um agente instalado em cada servidor e uma linguagem pr\u00f3pria. O Ansible nasceu com tr\u00eas princ\u00edpios que valem at\u00e9 hoje: <strong>sem agente<\/strong> (s\u00f3 SSH e Python, que j\u00e1 existem em qualquer Linux), <strong>YAML leg\u00edvel<\/strong> em vez de linguagem de programa\u00e7\u00e3o e curva de aprendizado curta.<\/p>\n<p>O nome vem da fic\u00e7\u00e3o cient\u00edfica. <em>Ans\u00edvel<\/em> \u00e9 o comunicador instant\u00e2neo entre planetas que Ursula K. Le Guin inventou em 1966, depois popularizado por <em>O Jogo do Exterminador<\/em>, de Orson Scott Card. A met\u00e1fora combina: comandar m\u00e1quinas distantes na hora, sem intermedi\u00e1rios.<\/p>\n<p>O projeto virou empresa, a AnsibleWorks, depois Ansible Inc., e foi <strong>comprado pela Red Hat em outubro de 2015<\/strong>, que o mant\u00e9m open source. Hoje o motor fica no pacote <code>ansible-core<\/code>, e o pacote <code>ansible<\/code> junta o motor com dezenas de <em>collections<\/em> da comunidade, os conjuntos de m\u00f3dulos para cada tecnologia.<\/p>\n<h2>Como o Ansible trabalha<\/h2>\n<p>O Ansible \u00e9 instalado numa \u00fanica m\u00e1quina, a <strong>m\u00e1quina de controle<\/strong>: o seu notebook ou um servidor de administra\u00e7\u00e3o. Os servidores gerenciados s\u00f3 precisam de SSH e Python 3, que o Ubuntu e o Debian j\u00e1 trazem. Nada de agente, nada de servi\u00e7o extra rodando neles.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/09\/ansible-arquitetura-sem-agente.webp\" alt=\"Diagrama: a m\u00e1quina de controle, com ansible.cfg, invent\u00e1rio, playbook, group_vars e roles, se conecta por SSH na porta 22 aos servidores web01, web02 e db01, que s\u00f3 precisam de sshd e Python 3\" width=\"1200\" height=\"660\" loading=\"lazy\" \/><\/p>\n<p>Para cada tarefa, o Ansible abre SSH nos servidores em paralelo (cinco por vez, por padr\u00e3o), envia um pequeno programa Python, o <strong>m\u00f3dulo<\/strong>, executa, recebe o resultado em JSON e apaga o arquivo tempor\u00e1rio. O m\u00f3dulo compara o estado atual com o que voc\u00ea pediu e s\u00f3 mexe se for preciso.<\/p>\n<p><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/09\/ansible-fluxo-tarefa.webp\" alt=\"Diagrama do ciclo de uma tarefa: l\u00ea o invent\u00e1rio e a tarefa, conecta por SSH, envia o m\u00f3dulo Python, compara o estado atual com o desejado e responde em JSON com ok, changed ou failed; handlers rodam uma vez no fim do play\" width=\"1200\" height=\"600\" loading=\"lazy\" \/><\/p>\n<h2>Instalando no Ubuntu<\/h2>\n<p>H\u00e1 tr\u00eas caminhos, e a diferen\u00e7a \u00e9 a vers\u00e3o:<\/p>\n<ul>\n<li><strong>Reposit\u00f3rio do Ubuntu<\/strong>: o mais simples. No Ubuntu 24.04 ele traz o pacote <code>ansible<\/code> 9.2, com ansible-core 2.16. Serve para aprender.<\/li>\n<li><strong>PPA oficial do projeto<\/strong>: vers\u00e3o atual. Em setembro de 2026, o PPA entrega o <code>ansible<\/code> 14.4.0, com <strong>ansible-core 2.21.4<\/strong>, para o Ubuntu 24.04 e o 26.04. Foi o que usamos nos testes.<\/li>\n<li><strong>pipx<\/strong>: isola o Ansible do Python do sistema e funciona em qualquer distribui\u00e7\u00e3o.<\/li>\n<\/ul>\n<pre><code class=\"language-bash\"># Op\u00e7\u00e3o 1: reposit\u00f3rio do Ubuntu\nsudo apt update\nsudo apt install -y ansible\n\n# Op\u00e7\u00e3o 2: PPA oficial (vers\u00e3o atual)\nsudo apt install -y software-properties-common\nsudo add-apt-repository --yes --update ppa:ansible\/ansible\nsudo apt install -y ansible\n\n# Op\u00e7\u00e3o 3: pipx\nsudo apt install -y pipx\npipx install --include-deps ansible\npipx ensurepath   # abra um novo terminal depois deste comando<\/code><\/pre>\n<pre><code class=\"language-bash\">ansible --version<\/code><\/pre>\n<pre><code class=\"language-text\">ansible [core 2.21.4]\n  config file = \/etc\/ansible\/ansible.cfg\n  ...\n  python version = 3.12.3 (main, Aug 31 2026, 10:18:26) [GCC 13.3.0] (\/usr\/bin\/python3)\n  jinja version = 3.1.2<\/code><\/pre>\n<h2>A estrutura de um projeto<\/h2>\n<p>O Ansible roda de qualquer diret\u00f3rio, mas vale adotar a estrutura convencional desde o primeiro dia:<\/p>\n<pre><code class=\"language-text\">meu-projeto\/\n\u251c\u2500\u2500 ansible.cfg            # configura\u00e7\u00e3o do projeto\n\u251c\u2500\u2500 inventory.ini          # quais m\u00e1quinas gerenciar\n\u251c\u2500\u2500 site.yml               # playbook principal\n\u251c\u2500\u2500 group_vars\/            # vari\u00e1veis por grupo de hosts\n\u2502   \u2514\u2500\u2500 webservers.yml\n\u251c\u2500\u2500 host_vars\/             # vari\u00e1veis de um host espec\u00edfico\n\u2502   \u2514\u2500\u2500 web01.yml\n\u2514\u2500\u2500 roles\/                 # partes reutiliz\u00e1veis\n    \u2514\u2500\u2500 nginx\/\n        \u251c\u2500\u2500 tasks\/main.yml\n        \u251c\u2500\u2500 handlers\/main.yml\n        \u251c\u2500\u2500 templates\/\n        \u251c\u2500\u2500 files\/\n        \u2514\u2500\u2500 defaults\/main.yml<\/code><\/pre>\n<ul>\n<li><strong>ansible.cfg<\/strong>: configura\u00e7\u00f5es do projeto. O Ansible usa o arquivo do diret\u00f3rio atual antes do global, em <code>\/etc\/ansible\/ansible.cfg<\/code>.<\/li>\n<li><strong>Invent\u00e1rio<\/strong>: a lista de m\u00e1quinas, organizada em grupos.<\/li>\n<li><strong>Playbook<\/strong>: o roteiro em YAML, &#8220;nestes hosts, garanta estas tarefas&#8221;.<\/li>\n<li><strong>group_vars e host_vars<\/strong>: valores que mudam por grupo ou por m\u00e1quina, separados da l\u00f3gica.<\/li>\n<li><strong>Roles<\/strong>: playbooks empacotados para reaproveitar em outros projetos.<\/li>\n<\/ul>\n<h2>Invent\u00e1rio, chave SSH e o primeiro ping<\/h2>\n<p>Crie o projeto com tr\u00eas servidores em dois grupos. Troque os IPs pelos seus:<\/p>\n<pre><code class=\"language-bash\">mkdir meu-projeto &amp;&amp; cd meu-projeto\n\ncat &gt; inventory.ini &lt;&lt;'EOF'\n[webservers]\nweb01 ansible_host=192.168.64.2\nweb02 ansible_host=192.168.64.3\n\n[dbservers]\ndb01 ansible_host=192.168.64.4\n\n[all:vars]\nansible_user=ubuntu\nansible_python_interpreter=\/usr\/bin\/python3\nEOF\n\ncat &gt; ansible.cfg &lt;&lt;'EOF'\n[defaults]\ninventory = inventory.ini\nEOF\n\nansible-inventory --graph<\/code><\/pre>\n<pre><code class=\"language-text\">@all:\n  |--@ungrouped:\n  |--@webservers:\n  |  |--web01\n  |  |--web02\n  |--@dbservers:\n  |  |--db01<\/code><\/pre>\n<p>A linha <code>ansible_python_interpreter<\/code> fixa o Python usado nos servidores. Sem ela, o ansible-core 2.21 funciona, mas imprime um aviso em cada host dizendo que usou o Python &#8220;descoberto&#8221; e que isso pode mudar se outro Python for instalado.<\/p>\n<p>O Ansible entra nos servidores com a sua chave SSH. Se voc\u00ea ainda n\u00e3o tem uma, gere e copie para cada servidor:<\/p>\n<pre><code class=\"language-bash\">ssh-keygen -t ed25519\nfor ip in 192.168.64.2 192.168.64.3 192.168.64.4; do ssh-copy-id ubuntu@$ip; done<\/code><\/pre>\n<p>O <code>ssh-copy-id<\/code> tamb\u00e9m pede para voc\u00ea confirmar a chave de cada servidor na primeira conex\u00e3o. Se voc\u00ea usar outro caminho para distribuir a chave, o Ansible vai parar com <code>Host key verification failed<\/code>, e \u00e9 bom que pare: \u00e9 a prote\u00e7\u00e3o contra servidor falso. Para registrar as chaves de uma vez, sem desligar a checagem:<\/p>\n<pre><code class=\"language-bash\">ssh-keyscan -H 192.168.64.2 192.168.64.3 192.168.64.4 &gt;&gt; ~\/.ssh\/known_hosts<\/code><\/pre>\n<p>Confira as chaves se o servidor n\u00e3o for de laborat\u00f3rio. Muito tutorial manda colocar <code>host_key_checking = False<\/code> no <code>ansible.cfg<\/code>; evite em produ\u00e7\u00e3o. E se colocar qualquer op\u00e7\u00e3o, cuidado com coment\u00e1rios: no <code>ansible.cfg<\/code>, o <code>#<\/code> s\u00f3 vale no come\u00e7o da linha. No nosso teste, a linha <code>host_key_checking = True   # coment\u00e1rio<\/code> foi lida como <strong>False<\/strong>, porque o Ansible pegou o texto inteiro como valor, n\u00e3o reconheceu como verdadeiro e desligou a checagem sem avisar. Coment\u00e1rio na mesma linha s\u00f3 com <code>;<\/code>, ou numa linha pr\u00f3pria.<\/p>\n<p>Agora o teste de comunica\u00e7\u00e3o:<\/p>\n<pre><code class=\"language-bash\">ansible all -m ansible.builtin.ping<\/code><\/pre>\n<pre><code class=\"language-text\">web01 | SUCCESS =&gt; {\n    \"changed\": false,\n    \"ping\": \"pong\"\n}\nweb02 | SUCCESS =&gt; { ... }\ndb01 | SUCCESS =&gt; { ... }<\/code><\/pre>\n<p>O m\u00f3dulo <code>ping<\/code> n\u00e3o \u00e9 o ping de rede (ICMP): ele confirma que o Ansible entra por SSH e executa Python do outro lado, que \u00e9 o que importa. Sem servidor \u00e0 m\u00e3o? Tudo funciona contra a pr\u00f3pria m\u00e1quina com <code>ansible localhost -m ansible.builtin.ping<\/code>, que usa conex\u00e3o local.<\/p>\n<h2>Comandos ad-hoc<\/h2>\n<p>Antes de escrever playbooks, d\u00e1 para resolver muita coisa com comandos avulsos. <code>-m<\/code> escolhe o m\u00f3dulo, <code>-a<\/code> passa os argumentos e <code>--become<\/code> executa com sudo do outro lado:<\/p>\n<pre><code class=\"language-bash\">ansible all -a \"uptime -p\"                                     # comando em todos\nansible webservers -m ansible.builtin.apt \\\n  -a \"name=htop state=present update_cache=true\" --become      # instala pacote\nansible db01 -m ansible.builtin.setup -a \"filter=ansible_distribution*\"   # fatos\nansible-doc ansible.builtin.apt                                # documenta\u00e7\u00e3o do m\u00f3dulo<\/code><\/pre>\n<p>Rode o comando do <code>htop<\/code> duas vezes. Na primeira, os hosts aparecem como <code>CHANGED<\/code>; na segunda, como <code>SUCCESS<\/code>, porque o pacote j\u00e1 estava l\u00e1. Se o seu usu\u00e1rio pede senha no <code>sudo<\/code>, acrescente <code>-K<\/code> (<code>--ask-become-pass<\/code>) para o Ansible perguntar. E prefira os m\u00f3dulos espec\u00edficos ao <code>shell<\/code>: o <code>apt<\/code> sabe dizer se mudou algo, e um comando solto n\u00e3o sabe.<\/p>\n<h2>O primeiro playbook<\/h2>\n<p>Agora um roteiro completo: instalar o Nginx nos servidores web, publicar uma p\u00e1gina gerada a partir de um template com vari\u00e1vel, manter o servi\u00e7o ativo e recarreg\u00e1-lo s\u00f3 quando a p\u00e1gina mudar. Primeiro a vari\u00e1vel do grupo, em <code>group_vars\/webservers.yml<\/code>:<\/p>\n<pre><code class=\"language-yaml\">---\nsite_titulo: \"Servidor gerenciado pelo Ansible\"<\/code><\/pre>\n<p>O template, em <code>templates\/index.html.j2<\/code>, usa a sintaxe Jinja2. <code>inventory_hostname<\/code> e <code>ansible_facts<\/code> s\u00e3o preenchidos pelo pr\u00f3prio Ansible:<\/p>\n<pre><code class=\"language-html\">&lt;!doctype html&gt;\n&lt;html lang=\"pt-br\"&gt;\n&lt;head&gt;&lt;meta charset=\"utf-8\"&gt;&lt;title&gt;{{ site_titulo }}&lt;\/title&gt;&lt;\/head&gt;\n&lt;body&gt;\n  &lt;h1&gt;{{ site_titulo }}&lt;\/h1&gt;\n  &lt;p&gt;Host: {{ inventory_hostname }} ({{ ansible_facts[\"distribution\"] }} {{ ansible_facts[\"distribution_version\"] }})&lt;\/p&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre>\n<p>E o playbook, <code>site.yml<\/code>:<\/p>\n<pre><code class=\"language-yaml\">---\n- name: Configurar servidores web\n  hosts: webservers\n  become: true\n\n  tasks:\n    - name: Instalar o Nginx\n      ansible.builtin.apt:\n        name: nginx\n        state: present\n        update_cache: true\n        cache_valid_time: 3600\n\n    - name: Publicar a p\u00e1gina inicial\n      ansible.builtin.template:\n        src: templates\/index.html.j2\n        dest: \/var\/www\/html\/index.html\n        owner: root\n        group: root\n        mode: \"0644\"\n      notify: Recarregar o Nginx\n\n    - name: Garantir o Nginx ativo e habilitado no boot\n      ansible.builtin.service:\n        name: nginx\n        state: started\n        enabled: true\n\n  handlers:\n    - name: Recarregar o Nginx\n      ansible.builtin.service:\n        name: nginx\n        state: reloaded<\/code><\/pre>\n<p>Os nomes dos m\u00f3dulos aparecem completos, como <code>ansible.builtin.apt<\/code>. \u00c9 o formato recomendado desde o Ansible 2.10: deixa claro de qual collection vem cada m\u00f3dulo. O <code>cache_valid_time<\/code> evita rodar <code>apt update<\/code> de novo se ele foi feito na \u00faltima hora.<\/p>\n<pre><code class=\"language-bash\">ansible-playbook site.yml --syntax-check\nansible-playbook site.yml<\/code><\/pre>\n<pre><code class=\"language-text\">TASK [Instalar o Nginx] ********************************************************\nchanged: [web01]\nchanged: [web02]\n\nTASK [Publicar a p\u00e1gina inicial] ***********************************************\nchanged: [web01]\nchanged: [web02]\n\nTASK [Garantir o Nginx ativo e habilitado no boot] *****************************\nchanged: [web02]\nchanged: [web01]\n\nRUNNING HANDLER [Recarregar o Nginx] *******************************************\nchanged: [web02]\nchanged: [web01]\n\nPLAY RECAP *********************************************************************\nweb01                      : ok=5    changed=4    unreachable=0    failed=0    skipped=0 ...\nweb02                      : ok=5    changed=4    unreachable=0    failed=0    skipped=0 ...<\/code><\/pre>\n<h3>Idempot\u00eancia: rode de novo<\/h3>\n<p>Execute o mesmo comando outra vez e olhe o resumo:<\/p>\n<pre><code class=\"language-text\">web01                      : ok=4    changed=0    unreachable=0    failed=0 ...\nweb02                      : ok=4    changed=0    unreachable=0    failed=0 ...<\/code><\/pre>\n<p><code>changed=0<\/code>. Essa \u00e9 a <strong>idempot\u00eancia<\/strong>, o cora\u00e7\u00e3o do Ansible: ele n\u00e3o &#8220;executa comandos&#8221;, ele garante estados. O Nginx j\u00e1 estava instalado, a p\u00e1gina j\u00e1 era a certa, o servi\u00e7o j\u00e1 estava ativo, e nada foi tocado. O handler tamb\u00e9m n\u00e3o rodou, porque nenhuma tarefa mudou.<\/p>\n<h3>Simular antes de aplicar: <code>--check<\/code> e <code>--diff<\/code><\/h3>\n<p>Mude o t\u00edtulo em <code>group_vars\/webservers.yml<\/code> para &#8220;Servidor web do LinuxPro&#8221; e simule, s\u00f3 no <code>web01<\/code>:<\/p>\n<pre><code class=\"language-bash\">ansible-playbook site.yml --check --diff --limit web01<\/code><\/pre>\n<pre><code class=\"language-text\">TASK [Publicar a p\u00e1gina inicial] ***********************************************\n--- before: \/var\/www\/html\/index.html\n+++ after: \/root\/.ansible\/tmp\/ansible-local-586tfwktpl6\/tmp5owga2ot\/index.html.j2\n@@ -1,8 +1,8 @@\n &lt;!doctype html&gt;\n &lt;html lang=\"pt-br\"&gt;\n-&lt;head&gt;&lt;meta charset=\"utf-8\"&gt;&lt;title&gt;Servidor gerenciado pelo Ansible&lt;\/title&gt;&lt;\/head&gt;\n+&lt;head&gt;&lt;meta charset=\"utf-8\"&gt;&lt;title&gt;Servidor web do LinuxPro&lt;\/title&gt;&lt;\/head&gt;\n &lt;body&gt;\n-  &lt;h1&gt;Servidor gerenciado pelo Ansible&lt;\/h1&gt;\n+  &lt;h1&gt;Servidor web do LinuxPro&lt;\/h1&gt;\n   &lt;p&gt;Host: web01 (Ubuntu 24.04)&lt;\/p&gt;\n &lt;\/body&gt;\n &lt;\/html&gt;\n\nchanged: [web01]<\/code><\/pre>\n<p>O <code>--check<\/code> n\u00e3o altera nada, e o <code>--diff<\/code> mostra exatamente o que mudaria. Aplicando de verdade, s\u00f3 a p\u00e1gina e o handler aparecem como <code>changed<\/code>, e o Nginx \u00e9 recarregado uma \u00fanica vez.<\/p>\n<p>Dois limites do <code>--check<\/code>, vistos nos testes:<\/p>\n<ul>\n<li><strong>Num servidor limpo, ele pode falhar no meio.<\/strong> Na simula\u00e7\u00e3o, o Nginx n\u00e3o \u00e9 instalado de verdade, ent\u00e3o a tarefa seguinte, a do servi\u00e7o, termina com <code>Could not find the requested service nginx<\/code>. \u00c9 esperado: a simula\u00e7\u00e3o vale mais para revisar mudan\u00e7as em servidores que j\u00e1 est\u00e3o configurados.<\/li>\n<li><strong>O m\u00f3dulo <code>apt<\/code> precisa do pacote <code>python3-apt<\/code><\/strong> para simular. O Ubuntu Server j\u00e1 o traz; imagens m\u00ednimas, como as de cont\u00eainer, n\u00e3o, e o erro diz <code>python3-apt must be installed to use check mode<\/code>. Numa execu\u00e7\u00e3o normal, o pr\u00f3prio m\u00f3dulo instala o pacote.<\/li>\n<\/ul>\n<h2>Transformando o playbook em role<\/h2>\n<p>Quando o playbook cresce, as tarefas viram uma role, que pode ser usada em qualquer projeto:<\/p>\n<pre><code class=\"language-bash\">ansible-galaxy role init roles\/nginx<\/code><\/pre>\n<p>O comando cria a estrutura em <code>roles\/nginx\/<\/code>. Mova as tarefas para <code>roles\/nginx\/tasks\/main.yml<\/code>, o handler para <code>roles\/nginx\/handlers\/main.yml<\/code> e o template para <code>roles\/nginx\/templates\/<\/code>. Dentro da role, o <code>src<\/code> do template passa a ser s\u00f3 <code>index.html.j2<\/code>, porque o Ansible procura na pasta <code>templates\/<\/code> da pr\u00f3pria role. O <code>site.yml<\/code> fica curto:<\/p>\n<pre><code class=\"language-yaml\">---\n- name: Configurar servidores web\n  hosts: webservers\n  become: true\n  roles:\n    - nginx<\/code><\/pre>\n<p>Rodando de novo, as tarefas aparecem com o prefixo da role (<code>nginx : Instalar o Nginx<\/code>) e o resultado continua <code>changed=0<\/code>: mudou a organiza\u00e7\u00e3o, n\u00e3o o estado dos servidores.<\/p>\n<h2>Pr\u00f3ximos passos<\/h2>\n<p>Com esta base, os caminhos naturais s\u00e3o:<\/p>\n<ul>\n<li><strong>Continua\u00e7\u00e3o:<\/strong> em <a href=\"\/2026\/09\/usuarios-linux-ansible-ssh-sudo-git\/\">Usu\u00e1rios no Linux com Ansible: chaves SSH, sudo e hist\u00f3rico no Git<\/a>, o projeto vai para o Git e passa a criar, bloquear e remover contas, com login por chave SSH sem senha e acesso sudo. O c\u00f3digo completo, testado no Ubuntu 24.04 e no Debian 13, est\u00e1 no reposit\u00f3rio <a href=\"https:\/\/github.com\/jniltinho\/ansible-linux-users\">jniltinho\/ansible-linux-users<\/a>.<\/li>\n<li><strong>Ir para um cen\u00e1rio real<\/strong>: o guia <a href=\"\/2026\/09\/automatizando-servidores-linux-com-ansible\/\">Automatizando servidores Linux com Ansible<\/a> mostra firewall, segredos com <code>ansible-vault<\/code> e atualiza\u00e7\u00e3o em ondas.<\/li>\n<li><strong>Explorar os m\u00f3dulos<\/strong> na <a href=\"https:\/\/docs.ansible.com\/\">documenta\u00e7\u00e3o oficial<\/a> ou com <code>ansible-doc -l<\/code>.<\/li>\n<li><strong>Carreira:<\/strong> se automa\u00e7\u00e3o virar profiss\u00e3o, o Ansible \u00e9 pe\u00e7a central da <a href=\"\/2026\/09\/certificacao-lpi-devops\/\">certifica\u00e7\u00e3o LPI DevOps Tools Engineer<\/a>.<\/li>\n<\/ul>\n<p>Instale, fa\u00e7a o ping, rode o playbook duas vezes e veja o <code>changed=0<\/code>: nesse momento fica claro por que tanta gente parou de configurar servidor na m\u00e3o.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Instala Ansible en Ubuntu, configura el inventario y la clave SSH, ejecuta comandos ad-hoc y escribe el primer playbook con variable, template y handler, simulando antes de aplicar. Todo probado con ansible-core 2.21.<\/p>","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[46,2,120,3],"tags":[121,122,47,378,240,505,506,5,377],"class_list":["post-782","post","type-post","status-publish","format-standard","hentry","category-devops","category-linux","category-servidores","category-ubuntu","tag-ansible","tag-automacao","tag-devops","tag-iniciantes","tag-nginx","tag-playbook","tag-ssh","tag-ubuntu","tag-yaml"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/782","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/comments?post=782"}],"version-history":[{"count":8,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/782\/revisions"}],"predecessor-version":[{"id":1742,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/posts\/782\/revisions\/1742"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/media?parent=782"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/categories?post=782"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/es\/wp-json\/wp\/v2\/tags?post=782"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}