{"id":87084,"date":"2020-07-03T13:42:34","date_gmt":"2020-07-03T11:42:34","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron"},"modified":"2020-07-03T13:42:34","modified_gmt":"2020-07-03T11:42:34","slug":"osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","title":{"rendered":"Fundamentos do Ansible, sem os quais seus playbooks s\u00e3o um emaranhado de macarr\u00e3o grudado","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Eu fa\u00e7o muitas an\u00e1lises de c\u00f3digo de terceiros no Ansible e tamb\u00e9m escrevo bastante. Durante a an\u00e1lise de erros (tanto os meus quanto os de outros), al\u00e9m de algumas entrevistas, percebi o principal erro que os usu\u00e1rios do Ansible cometem \u2014 eles se aventuram em complexidades sem dominar o b\u00e1sico.<\/p>\n<p><\/p>\n<p>Para corrigir essa injusti\u00e7a universal, decidi escrever uma introdu\u00e7\u00e3o ao Ansible para aqueles que j\u00e1 t\u00eam alguma familiaridade. Aviso que isso n\u00e3o \u00e9 um resumo de manuais, \u00e9 um longo texto cheio de letras e sem imagens.<\/p>\n<p><\/p>\n<p>O n\u00edvel esperado do leitor \u00e9 que j\u00e1 tenha escrito algumas milhares de linhas em YAML, j\u00e1 tenha algo em produ\u00e7\u00e3o, mas \"tudo parece um pouco torto\".<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1>Nomes<\/h1>\n<p><\/p>\n<p>O erro principal do usu\u00e1rio do Ansible \u00e9 n\u00e3o saber como as coisas se chamam. Se voc\u00ea n\u00e3o souber os nomes, n\u00e3o poder\u00e1 entender o que est\u00e1 escrito na documenta\u00e7\u00e3o. Um exemplo vivo: em uma entrevista, uma pessoa, que supostamente afirmava que havia escrito muito em Ansible, n\u00e3o conseguiu responder \u00e0 pergunta \"de quais elementos consiste um playbook?\". E quando eu sugeri que \"a resposta esperada era que o playbook consiste em plays\", veio o coment\u00e1rio devastador \"n\u00f3s n\u00e3o usamos isso\". As pessoas escrevem em Ansible por dinheiro e n\u00e3o usam plays. <em>Na verdade, elas usam, mas n\u00e3o sabem o que \u00e9.<\/em><\/p>\n<p><\/p>\n<p>Ent\u00e3o, vamos come\u00e7ar com o b\u00e1sico: como as coisas s\u00e3o chamadas. Voc\u00ea pode j\u00e1 saber disso, ou pode n\u00e3o saber, porque n\u00e3o prestou aten\u00e7\u00e3o ao ler a documenta\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p>ansible-playbook executa playbooks. Playbook \u2014 \u00e9 um arquivo com a extens\u00e3o yml\/yaml, dentro do qual tem algo assim:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">---\n- hosts: group1\n  roles:\n    - role1\n\n- hosts: group2,group3\n  tasks:\n    - debug:<\/code><\/pre>\n<p><\/p>\n<p>J\u00e1 entendemos que todo esse arquivo \u00e9 um playbook. Podemos mostrar onde est\u00e3o as roles, onde est\u00e3o as tasks. Mas onde est\u00e1 o play aqui? E qual a diferen\u00e7a entre play, role ou playbook?<\/p>\n<p><\/p>\n<p>Tudo isso est\u00e1 na documenta\u00e7\u00e3o. E as pessoas ignoram. Os iniciantes \u2014 porque h\u00e1 muita informa\u00e7\u00e3o e tudo de uma vez \u00e9 dif\u00edcil de lembrar. Os experientes \u2014 porque consideram \"coisas triviais\". Se voc\u00ea \u00e9 experiente, releia essas p\u00e1ginas pelo menos uma vez a cada seis meses, e seu c\u00f3digo ficar\u00e1 muito melhor.<\/p>\n<p><\/p>\n<p>E assim, memorizem: Playbook \u2014 \u00e9 uma lista que consiste em play e <code>import_playbook<\/code>.<br \/>\nEssa \u00e9 uma play:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: group1\n  roles:\n    - role1<\/code><\/pre>\n<p><\/p>\n<p>e essa tamb\u00e9m \u00e9 outra play:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: group2,group3\n  tasks:\n    - debug:<\/code><\/pre>\n<p><\/p>\n<p>O que \u00e9 play? Para que serve?<\/p>\n<p><\/p>\n<p>Play \u2014 \u00e9 o elemento chave do playbook, porque play e apenas play conecta a lista de roles e\/ou tasks \u00e0 lista de hosts onde elas devem ser executadas. Nas profundezas da documenta\u00e7\u00e3o voc\u00ea pode encontrar men\u00e7\u00f5es sobre <code>delegate_to<\/code>, plugins de lookup locais, configura\u00e7\u00f5es espec\u00edficas de network-cli, hosts de salto, etc. Eles permitem mudar ligeiramente o local de execu\u00e7\u00e3o das tarefas. Mas, esque\u00e7a isso. Cada uma dessas op\u00e7\u00f5es engenhosas tem aplica\u00e7\u00f5es muito espec\u00edficas, e definitivamente n\u00e3o s\u00e3o universais. Estamos falando sobre as coisas b\u00e1sicas que todos devem saber e usar.<\/p>\n<p><\/p>\n<p>Se voc\u00ea quer executar algo \"em algum lugar\" \u2014 voc\u00ea escreve um play. N\u00e3o uma role. N\u00e3o uma role com m\u00f3dulos e delega\u00e7\u00f5es. Voc\u00ea simplesmente escreve um play. No qual, no campo hosts, voc\u00ea lista onde executar, e em roles\/tasks \u2014 o que executar.<\/p>\n<p><\/p>\n<p>F\u00e1cil, certo? E como poderia ser diferente?<\/p>\n<p><\/p>\n<p>Um dos momentos caracter\u00edsticos em que as pessoas t\u00eam vontade de fazer isso n\u00e3o atrav\u00e9s de plays, \u00e9 \"uma role que configura tudo\". A vontade \u00e9 ter uma role que configure e <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/pt\/server\/dts-los-angeles\/\"   title=\"servidor\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"3633\">servidor<\/a> do primeiro tipo, e servidores do segundo tipo.<\/p>\n<p><\/p>\n<p>Um exemplo arquet\u00edpico \u00e9 a monitora\u00e7\u00e3o. A vontade \u00e9 ter um papel de monitora\u00e7\u00e3o que configure a monitora\u00e7\u00e3o. O papel de monitora\u00e7\u00e3o \u00e9 atribu\u00eddo aos hosts de monitora\u00e7\u00e3o (no respectivo play). Mas, acontece que para monitorar precisamos instalar pacotes nos hosts que estamos monitorando. Por que n\u00e3o usar o delegate? Al\u00e9m disso, \u00e9 necess\u00e1rio configurar os iptables. delegate? E ainda, \u00e9 preciso escrever\/corrigir a configura\u00e7\u00e3o do SGBD para que a monitora\u00e7\u00e3o funcione. delegate! E se a criatividade surgir, pode-se fazer a delega\u00e7\u00e3o <code>include_role<\/code> em um ciclo aninhado com um filtro engenhoso na lista de grupos, e dentro <code>include_role<\/code> pode-se ainda fazer <code>delegate_to<\/code> novamente. E l\u00e1 vamos n\u00f3s\u2026<\/p>\n<p><\/p>\n<p>Um bom desejo \u2014 ter uma \u00fanica role de monitoramento que \"fa\u00e7a tudo\" \u2014 nos leva a um verdadeiro inferno do qual, na maioria das vezes, a \u00fanica sa\u00edda \u00e9 reescrever tudo do zero.<\/p>\n<p><\/p>\n<p>Onde ocorreu o erro? No momento em que voc\u00ea percebeu que, para executar a tarefa \"x\" no host X, voc\u00ea precisava ir ao host Y e fazer \"y\", voc\u00ea deveria ter feito um simples exerc\u00edcio: ir e escrever um play que, no host Y, faz y. N\u00e3o adicionar algo em \"x\", mas escrever do zero. Mesmo que com vari\u00e1veis hardcoded.<\/p>\n<p><\/p>\n<p>Aparentemente, nos par\u00e1grafos acima tudo foi dito corretamente. Mas esse n\u00e3o \u00e9 o seu caso! Porque voc\u00ea quer escrever c\u00f3digo reutiliz\u00e1vel, que seja DRY e parecido com uma biblioteca, e precisa encontrar um jeito de fazer isso.<\/p>\n<p><\/p>\n<p>Aqui est\u00e1 mais um erro grosseiro escondido. Um erro que transformou muitos projetos de textos at\u00e9 aceit\u00e1veis (pode ser melhor, mas tudo funciona e \u00e9 f\u00e1cil de adicionar) em um completo caos, onde at\u00e9 mesmo o autor n\u00e3o consegue se entender. Funciona, mas que Deus nos proteja de mudar algo.<\/p>\n<p><\/p>\n<p>Esse erro soa assim: a fun\u00e7\u00e3o de um papel \u00e9 uma fun\u00e7\u00e3o de biblioteca. Essa analogia prejudicou tantas boas iniciativas que \u00e9 triste de ver. Papel n\u00e3o \u00e9 uma fun\u00e7\u00e3o de biblioteca. Ele n\u00e3o pode fazer c\u00e1lculos e n\u00e3o pode tomar decis\u00f5es em n\u00edvel de play. Me lembre, quais decis\u00f5es o play toma?<\/p>\n<p><\/p>\n<p>Obrigado, voc\u00ea est\u00e1 certo. O play toma a decis\u00e3o (mais precisamente, cont\u00e9m a informa\u00e7\u00e3o) sobre quais tarefas e pap\u00e9is realizar em quais hosts.<\/p>\n<p><\/p>\n<p>Se voc\u00ea delegar essa decis\u00e3o a um papel, e ainda por cima com c\u00e1lculos, voc\u00ea est\u00e1 condenando a si mesmo (e aquele que tentar entender seu c\u00f3digo) a uma exist\u00eancia lament\u00e1vel. O papel n\u00e3o decide onde deve ser executado. Essa decis\u00e3o \u00e9 feita pelo play. O papel faz o que lhe foi dito, onde lhe foi dito.<\/p>\n<p><\/p>\n<p>Por que programar em Ansible \u00e9 perigoso e por que COBOL \u00e9 melhor que Ansible, vamos discutir no cap\u00edtulo sobre vari\u00e1veis e jinja. Por enquanto, vamos apenas dizer uma coisa \u2014 cada c\u00e1lculo seu deixa uma marca indel\u00e9vel de altera\u00e7\u00e3o de vari\u00e1veis globais, e voc\u00ea n\u00e3o pode fazer nada a respeito. Assim que duas \"marcas\" se cruzarem \u2014 tudo est\u00e1 perdido.<\/p>\n<p><\/p>\n<p>Observa\u00e7\u00e3o para os mais meticulosos: o papel, sem d\u00favida, pode influenciar o fluxo de controle. Existe <code>delegate_to<\/code> e ele tem aplica\u00e7\u00f5es razo\u00e1veis. Existe <code>meta: end host\/play<\/code>. Mas! Lembre-se, estamos aprendendo os fundamentos? Esqueceram sobre <code>delegate_to<\/code>. Estamos falando sobre o c\u00f3digo mais simples e bonito em Ansible. Que \u00e9 f\u00e1cil de ler, f\u00e1cil de escrever, f\u00e1cil de depurar, f\u00e1cil de testar e f\u00e1cil de adicionar. Ent\u00e3o, mais uma vez:<\/p>\n<p><\/p>\n<p><strong>o play e somente o play decide em quais hosts o que \u00e9 executado.<\/strong><\/p>\n<p><\/p>\n<p>Nesta se\u00e7\u00e3o, discutimos a oposi\u00e7\u00e3o entre play e papel. Agora vamos falar sobre a rela\u00e7\u00e3o entre tarefas vs papel.<\/p>\n<p><\/p>\n<h1>Tarefas e Pap\u00e9is<\/h1>\n<p><\/p>\n<p>Vamos considerar o play:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: somegroup\n  pre_tasks:\n    - some_tasks1:\n  roles:\n     - role1\n     - role2\n  post_tasks:\n     - some_task2:\n     - some_task3:<\/code><\/pre>\n<p><\/p>\n<p>Suponha que voc\u00ea precise fazer foo. E isso se parece com <code>foo: name=foobar state=present<\/code>. Onde isso deve ser escrito? em pre? post? Criar um papel?<\/p>\n<p><\/p>\n<p>\u2026 E onde foram parar as tarefas?<\/p>\n<p><\/p>\n<p>Come\u00e7amos novamente do b\u00e1sico \u2014 o play. Se voc\u00ea est\u00e1 perdido nesse assunto, n\u00e3o pode usar o play como base para todo o resto, e seu resultado se torna \"inst\u00e1vel\".<\/p>\n<p><\/p>\n<p>Diretiva play: hosts, configura\u00e7\u00f5es do pr\u00f3prio play e das se\u00e7\u00f5es pre_tasks, tasks, roles, post_tasks. Outros par\u00e2metros para o play n\u00e3o s\u00e3o importantes agora.<\/p>\n<p><\/p>\n<p>A ordem das se\u00e7\u00f5es com tarefas e fun\u00e7\u00f5es: <code>pre_tasks<\/code>, <code>roles<\/code>, <code>tasks<\/code>, <code>post_tasks<\/code>. Como a ordem de execu\u00e7\u00e3o entre <code>tasks<\/code> e <code>roles<\/code> n\u00e3o \u00e9 clara, as melhores pr\u00e1ticas dizem que devemos adicionar a se\u00e7\u00e3o <code>tasks<\/code>, apenas se n\u00e3o houver <code>roles<\/code>. Se existir <code>roles<\/code>, todas as tarefas correspondentes s\u00e3o colocadas nas se\u00e7\u00f5es <code>pre_tasks<\/code>\/<code>post_tasks<\/code>.<\/p>\n<p><\/p>\n<p>Resta apenas o que \u00e9 semanticamente claro: primeiro <code>pre_tasks<\/code>, depois <code>roles<\/code>, depois <code>post_tasks<\/code>.<\/p>\n<p><\/p>\n<p>Mas ainda n\u00e3o respondemos \u00e0 pergunta: onde devemos escrever a chamada do m\u00f3dulo <code>foo<\/code> ? Precisamos escrever um papel inteiro para cada m\u00f3dulo? Ou \u00e9 melhor ter um papel abrangente para tudo? E se n\u00e3o for um papel, onde devemos escrever \u2014 no pre ou no post?<\/p>\n<p><\/p>\n<p>Se n\u00e3o houver uma resposta argumentada para essas perguntas, isso \u00e9 um sinal de falta de intui\u00e7\u00e3o, ou seja, essas \"basics inst\u00e1veis\". Vamos entender isso. Primeiro, uma pergunta de controle: se o play tem <code>pre_tasks<\/code> e <code>post_tasks<\/code> (e n\u00e3o houver nenhuma tarefa nem fun\u00e7\u00e3o), algo pode quebrar se eu mover a primeira tarefa de <code>post_tasks<\/code> para o final? <code>pre_tasks<\/code>?<\/p>\n<p><\/p>\n<p>Certamente, a formula\u00e7\u00e3o da pergunta sugere que algo vai quebrar. Mas o que exatamente?<\/p>\n<p><\/p>\n<p>\u2026 manipuladores. Ler as funda\u00e7\u00f5es revela um fato importante: todos os manipuladores s\u00e3o acionados automaticamente ap\u00f3s cada se\u00e7\u00e3o. Ou seja, todas as tarefas de <code>pre_tasks<\/code>, depois todos os handlers que foram notificados. Em seguida, todas as fun\u00e7\u00f5es e todos os handlers que foram notificados nas fun\u00e7\u00f5es. Depois, <code>post_tasks<\/code> e seus handlers.<\/p>\n<p><\/p>\n<p>Assim, se voc\u00ea mover uma tarefa de <code>post_tasks<\/code> em <code>pre_tasks<\/code>, ent\u00e3o, potencialmente, voc\u00ea a executar\u00e1 antes do executor. Por exemplo, se em <code>pre_tasks<\/code> algo est\u00e1 sendo instalado e configurado <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/pt\/server\/\"   title=\"servidor web\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"1155\">servidor web<\/a>, e no <code>post_tasks<\/code> , se algo \u00e9 enviado para ele, mover esta tarefa para a se\u00e7\u00e3o <code>pre_tasks<\/code> isso resultar em um momento em que o \"envio\" o servidor ainda n\u00e3o estar\u00e1 ativo e tudo falhar\u00e1.<\/p>\n<p><\/p>\n<p>Agora, vamos pensar mais uma vez, por que precisamos de <code>pre_tasks<\/code> e <code>post_tasks<\/code>? \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0432\u0441\u0451 \u043d\u0443\u0436\u043d\u043e\u0435 (\u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0445\u044d\u043d\u0434\u043b\u0435\u0440\u044b) \u0434\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0440\u043e\u043b\u0438. \u0410 <code>post_tasks<\/code> nos permitir\u00e1 trabalhar com os resultados da execu\u00e7\u00e3o das fun\u00e7\u00f5es (incluindo os handlers).<\/p>\n<p><\/p>\n<p>Um conhecedor detalhista do Ansible dir\u00e1 que existe <code>meta: flush_handlers<\/code>, mas por que precisamos de flush_handlers, se podemos confiar na ordem de execu\u00e7\u00e3o das se\u00e7\u00f5es no play? Al\u00e9m disso, o uso de meta: flush_handlers pode nos trazer surpresas com handlers repetidos, gerar avisos estranhos em caso de uso de <code>when<\/code> u <code>block<\/code> E assim por diante. Quanto melhor voc\u00ea conhecer o Ansible, mais nuances poder\u00e1 citar para uma solu\u00e7\u00e3o \"inteligente\". E uma solu\u00e7\u00e3o simples \u2014 o uso de uma separa\u00e7\u00e3o natural entre pre\/roles\/post \u2014 n\u00e3o levanta nuances.<\/p>\n<p><\/p>\n<p>E, voltando ao nosso 'foo'. Onde coloc\u00e1-lo? Em pre, post ou roles? Isso claramente depende de precisarmos dos resultados do trabalho do manipulador para o foo. Se n\u00e3o precisamos, ent\u00e3o foo n\u00e3o deve ser colocado em pre nem em post \u2014 essas se\u00e7\u00f5es t\u00eam um significado especial \u2014 a execu\u00e7\u00e3o das tarefas antes e depois do bloco de c\u00f3digo principal.<\/p>\n<p><\/p>\n<p>Agora, a resposta \u00e0 pergunta \"papel ou tarefa\" se baseia no que j\u00e1 existe no play \u2014 se l\u00e1 existem tasks, ent\u00e3o deve-se adicionar \u00e0s tasks. Se existem roles \u2014 \u00e9 necess\u00e1rio criar uma role (mesmo que de uma \u00fanica task). Lembro que tasks e roles n\u00e3o s\u00e3o usadas simultaneamente.<\/p>\n<p><\/p>\n<p>Entender os fundamentos do Ansible fornece respostas fundamentadas para quest\u00f5es que, \u00e0 primeira vista, parecem de gosto particular.<\/p>\n<p><\/p>\n<h1>Tarefas e pap\u00e9is (parte dois)<\/h1>\n<p><\/p>\n<p>Agora vamos discutir a situa\u00e7\u00e3o em que voc\u00ea est\u00e1 apenas come\u00e7ando a escrever um playbook. Voc\u00ea precisa fazer foo, bar e baz. S\u00e3o tr\u00eas tarefas, um papel ou tr\u00eas pap\u00e9is? Resumindo a quest\u00e3o: em que momento devemos come\u00e7ar a escrever pap\u00e9is? Qual \u00e9 o sentido de escrever pap\u00e9is quando podemos escrever tarefas?\u2026 E o que \u00e9 um papel?<\/p>\n<p><\/p>\n<p>Um dos maiores erros (j\u00e1 mencionei isso) \u00e9 pensar que um papel \u00e9 como uma fun\u00e7\u00e3o em uma biblioteca de um programa. Como se parece uma descri\u00e7\u00e3o gen\u00e9rica de uma fun\u00e7\u00e3o? Ela recebe argumentos de entrada, interage com causas secund\u00e1rias, realiza efeitos colaterais e retorna um valor.<\/p>\n<p><\/p>\n<p>Agora, aten\u00e7\u00e3o. O que disso pode ser feito em uma role? Causar efeitos colaterais \u2014 sempre sim, essa \u00e9 a ess\u00eancia de todo o Ansible \u2014 causar efeitos colaterais. Ter causas secund\u00e1rias? Elementar. Mas com \"passar um valor e retorn\u00e1-lo\" \u2014 aqui \u00e9 que n\u00e3o. Em primeiro lugar, voc\u00ea n\u00e3o pode passar um valor para uma role. Voc\u00ea pode definir uma vari\u00e1vel global com um tempo de vida da dura\u00e7\u00e3o do play na se\u00e7\u00e3o vars da role. Voc\u00ea pode estabelecer uma vari\u00e1vel global com um tempo de vida no play dentro da role. Ou mesmo com um tempo de vida do playbook (<code>set_fact<\/code>\/<code>register<\/code>). Mas voc\u00ea n\u00e3o pode ter \"vari\u00e1veis locais\". Voc\u00ea n\u00e3o pode \"receber um valor\" e \"retorn\u00e1-lo\".<\/p>\n<p><\/p>\n<p>Dessa forma, conclui-se o principal: n\u00e3o se pode escrever algo em ansible e n\u00e3o causar efeitos colaterais. A modifica\u00e7\u00e3o de vari\u00e1veis globais \u00e9 sempre um efeito colateral para uma fun\u00e7\u00e3o. No Rust, por exemplo, a altera\u00e7\u00e3o de uma vari\u00e1vel global \u00e9 <code>unsafe<\/code>. No Ansible, o \u00fanico m\u00e9todo para alterar os valores de um papel. Preste aten\u00e7\u00e3o \u00e0s palavras utilizadas: n\u00e3o \u00e9 &quot;passar valor para o papel&quot;, mas sim &quot;alterar os valores que o papel utiliza&quot;. N\u00e3o h\u00e1 isolamento entre os pap\u00e9is. N\u00e3o h\u00e1 isolamento entre tarefas e pap\u00e9is.<\/p>\n<p><\/p>\n<p>No total: <strong>um papel n\u00e3o \u00e9 uma fun\u00e7\u00e3o<\/strong>.<\/p>\n<p><\/p>\n<p>O que h\u00e1 de bom em um papel? Primeiro, um papel possui valores padr\u00e3o (<code>\/default\/main.yaml<\/code>), em segundo lugar, um papel tem diret\u00f3rios adicionais para armazenar arquivos.<\/p>\n<p><\/p>\n<p>Quais s\u00e3o as vantagens dos valores padr\u00e3o? O fato \u00e9 que, na tabela de prioridades bastante distorcida da pir\u00e2mide de Maslow em Ansible, os valores padr\u00e3o de papel \u2014 s\u00e3o os menos priorit\u00e1rios (exceto por par\u00e2metros de linha de comando do Ansible). Isso significa que, se voc\u00ea precisar fornecer valores padr\u00e3o e n\u00e3o se preocupar que eles sobrescrevam os valores do invent\u00e1rio ou vari\u00e1veis de grupo, ent\u00e3o os valores padr\u00e3o do papel s\u00e3o o \u00fanico lugar certo para voc\u00ea. (Estou mentindo um pouco \u2014 h\u00e1 tamb\u00e9m <code>|d(your_default_here)<\/code>, mas falando sobre locais fixos \u2014 s\u00e3o apenas os valores padr\u00e3o dos pap\u00e9is).<\/p>\n<p><\/p>\n<p>O que mais \u00e9 bom nos pap\u00e9is? O fato de que eles t\u00eam seus pr\u00f3prios diret\u00f3rios. Esses s\u00e3o diret\u00f3rios para vari\u00e1veis, tanto fixas (ou seja, calculadas para o papel), quanto din\u00e2micas (existe um padr\u00e3o ou anti-padr\u00e3o \u2014 <code>include_vars<\/code> junto com <code>{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yml<\/code>.). Esses s\u00e3o diret\u00f3rios para <code>files\/<\/code>, <code>templates\/<\/code>. Al\u00e9m disso, permite que os pap\u00e9is tenham seus pr\u00f3prios m\u00f3dulos e plugins (<code>library\/<\/code>). No entanto, em compara\u00e7\u00e3o com as tarefas do playbook (que tamb\u00e9m podem ter tudo isso), a vantagem aqui \u00e9 apenas que os arquivos n\u00e3o est\u00e3o todos em uma \u00fanica pilha, mas em v\u00e1rias pilhas separadas.<\/p>\n<p><\/p>\n<p>Outro detalhe: voc\u00ea pode tentar criar pap\u00e9is que estar\u00e3o dispon\u00edveis para reutiliza\u00e7\u00e3o (via galaxy). Ap\u00f3s o surgimento de cole\u00e7\u00f5es, a dissemina\u00e7\u00e3o de pap\u00e9is pode ser considerada quase esquecida.<\/p>\n<p><\/p>\n<p>Assim, os pap\u00e9is possuem duas caracter\u00edsticas importantes: eles t\u00eam valores padr\u00e3o (uma caracter\u00edstica \u00fanica) e permitem estruturar o c\u00f3digo.<\/p>\n<p><\/p>\n<p>Retornando \u00e0 pergunta inicial: quando usar tarefas e quando usar pap\u00e9is? As tarefas em um playbook geralmente s\u00e3o usadas como &quot;adesivo&quot; antes\/depois dos pap\u00e9is, ou como um elemento de constru\u00e7\u00e3o aut\u00f4nomo (neste caso, o c\u00f3digo n\u00e3o deve conter pap\u00e9is). Um monte de tarefas normais misturadas com pap\u00e9is \u00e9 indiscutivelmente desleixado. Deve-se seguir um estilo espec\u00edfico \u2014 ou tarefas ou pap\u00e9is. Os pap\u00e9is oferecem separa\u00e7\u00e3o de entidades e padr\u00f5es, enquanto as tarefas permitem uma leitura de c\u00f3digo mais r\u00e1pida. Normalmente, os pap\u00e9is cont\u00eam c\u00f3digo mais &quot;estacion\u00e1rio&quot; (importante e complexo), enquanto o estilo de tarefas \u00e9 usado para escrever scripts auxiliares.<\/p>\n<p><\/p>\n<p>Existe a possibilidade de fazer import_role como uma tarefa, mas se voc\u00ea estiver fazendo isso, esteja preparado para justificar seu senso est\u00e9tico sobre por que deseja faz\u00ea-lo.<\/p>\n<p><\/p>\n<p>Um leitor atencioso pode afirmar que fun\u00e7\u00f5es podem importar fun\u00e7\u00f5es, que fun\u00e7\u00f5es podem ter depend\u00eancias atrav\u00e9s do galaxy.yml, e ainda h\u00e1 o assustador e terr\u00edvel <code>include_role<\/code> \u2014 lembre-se, estamos aprimorando habilidades b\u00e1sicas em Ansible, e n\u00e3o em gin\u00e1stica r\u00edtmica.<\/p>\n<p><\/p>\n<h1>Handlers e Tarefas<\/h1>\n<p><\/p>\n<p>Vamos discutir mais uma coisa \u00f3bvia: handlers. Saber us\u00e1-los corretamente \u00e9 quase uma arte. Qual \u00e9 a diferen\u00e7a entre um handler e uma tarefa?<\/p>\n<p><\/p>\n<p>Como estamos relembrando o b\u00e1sico, aqui est\u00e1 um exemplo:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">- hosts: group1\n  tasks:\n    - foo:\n      notify: handler1\n  handlers:\n     - name: handler1\n       bar:<\/code><\/pre>\n<p><\/p>\n<p>Os handlers do papel est\u00e3o localizados em rolename\/handlers\/main.yaml. Os handlers s\u00e3o compartilhados entre todos os participantes do play: pr\u00e9\/post_tarefas podem chamar os handlers do papel, e o papel pode chamar os handlers do play. No entanto, chamadas de handlers &quot;entre pap\u00e9is&quot; geram muito mais confus\u00e3o do que a repeti\u00e7\u00e3o de um handler trivial. (Outro elemento das melhores pr\u00e1ticas \u2014 tentar evitar repeti\u00e7\u00f5es nos nomes dos handlers).<\/p>\n<p><\/p>\n<p>A principal diferen\u00e7a \u00e9 que uma tarefa \u00e9 executada (de forma idempotente) sempre (mais ou menos com tags e <code>when<\/code>), enquanto um handler \u00e9 ativado por uma mudan\u00e7a de estado (notify \u00e9 acionado apenas se houve altera\u00e7\u00e3o). Quais as implica\u00e7\u00f5es disso? Por exemplo, o que acontece se, ao executar novamente, n\u00e3o houve altera\u00e7\u00e3o? Ent\u00e3o, n\u00e3o haver\u00e1 handler tamb\u00e9m. Mas por que precisar\u00edamos executar um handler quando n\u00e3o houve altera\u00e7\u00e3o na tarefa que o gerou? Por exemplo, porque algo quebrou e houve altera\u00e7\u00e3o, mas a execu\u00e7\u00e3o n\u00e3o chegou ao handler. Por exemplo, porque a rede estava temporariamente fora. A configura\u00e7\u00e3o mudou, mas o servi\u00e7o n\u00e3o foi reiniciado. Na pr\u00f3xima execu\u00e7\u00e3o, a configura\u00e7\u00e3o j\u00e1 n\u00e3o muda, e o servi\u00e7o permanece com a vers\u00e3o antiga da configura\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p>A situa\u00e7\u00e3o com a configura\u00e7\u00e3o n\u00e3o \u00e9 resolv\u00edvel (mais precisamente, voc\u00ea pode inventar um protocolo especial de reinicializa\u00e7\u00e3o com flags de arquivo etc., mas isso j\u00e1 n\u00e3o \u00e9 'ansible b\u00e1sico' de forma alguma). No entanto, existe outra hist\u00f3ria comum: instalamos o aplicativo, gravamos suas informa\u00e7\u00f5es. <code>.service<\/code>- arquivo, e agora queremos <code>daemon_reload<\/code> e <code>state=started<\/code>. E o lugar natural para isso parece ser um handler. Mas se torn\u00e1-lo uma tarefa no final da lista de tarefas ou um papel, ele ser\u00e1 executado de forma idempotente toda vez. Mesmo que o playbook tenha falhado no meio. Isso n\u00e3o resolve o problema de restarted (n\u00e3o se pode fazer uma tarefa com o atributo restarted, pois a idempot\u00eancia se perde), mas definitivamente vale a pena definir o state=started, a estabilidade geral dos playbooks aumenta, pois diminui o n\u00famero de depend\u00eancias e estados din\u00e2micos.<\/p>\n<p><\/p>\n<p>Outra caracter\u00edstica positiva do handler \u00e9 que ele n\u00e3o polui a sa\u00edda. N\u00e3o houve altera\u00e7\u00f5es \u2014 n\u00e3o h\u00e1 skips in\u00fateis ou ok na sa\u00edda \u2014 mais f\u00e1cil de ler. Por\u00e9m, isso tamb\u00e9m \u00e9 uma caracter\u00edstica negativa \u2014 se voc\u00ea encontrar um erro de digita\u00e7\u00e3o em uma tarefa execut\u00e1vel linear logo na primeira execu\u00e7\u00e3o, os handlers s\u00f3 ser\u00e3o executados quando houver altera\u00e7\u00f5es, ou seja, em algumas condi\u00e7\u00f5es \u2014 muito raramente. Por exemplo, a primeira vez na vida depois de cinco anos. E, claro, haver\u00e1 um erro na nomenclatura e tudo ir\u00e1 quebrar. Na segunda vez, eles n\u00e3o poder\u00e3o ser acionados \u2014 j\u00e1 que n\u00e3o houve altera\u00e7\u00f5es.<\/p>\n<p><\/p>\n<p>Deve-se falar separadamente sobre a acessibilidade das vari\u00e1veis. Por exemplo, se voc\u00ea notifica uma tarefa com um loop, o que estar\u00e1 nas vari\u00e1veis? Pode-se deduzir analiticamente, mas nem sempre isso \u00e9 trivial, especialmente se as vari\u00e1veis v\u00eam de lugares diferentes.<\/p>\n<p><\/p>\n<p>Portanto, os handlers s\u00e3o muito menos \u00fateis e muito mais problem\u00e1ticos do que parece. Se for poss\u00edvel escrever algo de forma elegante (sem complica\u00e7\u00f5es) sem handlers, \u00e9 melhor faz\u00ea-lo sem eles. Se n\u00e3o conseguir fazer isso de forma elegante, \u00e9 melhor us\u00e1-los.<\/p>\n<p><\/p>\n<p>O leitor atento observa com raz\u00e3o que n\u00e3o discutimos <code>listen<\/code>, que o handler pode chamar notify para outro handler, que o handler pode incluir import_tasks (que pode fazer include_role com with_items), que o sistema de handlers no Ansible \u00e9 Turing-completo, que os handlers de include_role se sobrep\u00f5em de forma interessante aos handlers do play, etc. \u2014 tudo isso claramente n\u00e3o s\u00e3o \"fundamentos\").<\/p>\n<p><\/p>\n<p>Embora haja um WTF espec\u00edfico que na verdade \u00e9 uma feature e que deve ser lembrado. Se voc\u00ea tem uma tarefa que \u00e9 executada com <code>delegate_to<\/code> e ela tem notify, o handler correspondente \u00e9 executado sem <code>delegate_to<\/code>, ou seja, na m\u00e1quina onde o play est\u00e1 designado. (Embora o handler possa, naturalmente, ter <code>delegate_to<\/code> tamb\u00e9m).<\/p>\n<p><\/p>\n<p>Eu gostaria de dizer algumas palavras sobre roles reutiliz\u00e1veis. Antes do surgimento das cole\u00e7\u00f5es, havia a ideia de criar roles universais que poderiam ser <code>ansible-galaxy install<\/code> e fui. Funciona em todos os sistemas operacionais, em todas as variantes, em todas as situa\u00e7\u00f5es. Ent\u00e3o, aqui est\u00e1 minha opini\u00e3o: isso n\u00e3o funciona. Qualquer papel com suporte a 100500 casos est\u00e1 fadado a abismos de bugs corner case. Eles podem ser contidos com testes massivos, mas, como em qualquer teste, ou voc\u00ea tem o produto cartesiano dos valores de entrada e uma fun\u00e7\u00e3o total, ou voc\u00ea tem \"cen\u00e1rios individuais cobertos\". Minha opini\u00e3o \u00e9 que \u00e9 muito melhor se o papel for linear (complexidade ciclom\u00e1tica 1). <code>include_vars<\/code>, suportando um n\u00famero infinito de casos, est\u00e1 condenada \u00e0s profundezas dos bugs de corner case. Eles podem ser corrigidos com testes maci\u00e7os, mas como em qualquer teste, ou voc\u00ea tem o produto cartesiano dos valores de entrada e uma fun\u00e7\u00e3o total, ou cobre \"cen\u00e1rios espec\u00edficos\". Na minha opini\u00e3o, \u00e9 muito melhor se o papel for linear (complexidade ciclom\u00e1tica 1).<\/p>\n<p><\/p>\n<p>Quanto menos ifs (expl\u00edcitos ou declarativos \u2014 na forma <code>when<\/code> por conjunto de vari\u00e1veis), melhor ser\u00e1 o papel. \u00c0s vezes \u00e9 necess\u00e1rio fazer ramifica\u00e7\u00f5es, mas, repito, quanto menos, melhor. Portanto, um papel que parece bom com galaxy (funciona, certo!) com um monte de <code>include_vars<\/code> pode ser menos prefer\u00edvel do que \"seu\" papel composto por cinco tarefas. O momento em que o papel com galaxy \u00e9 melhor \u2014 \u00e9 quando voc\u00ea come\u00e7a a escrever algo. O momento em que ele se torna pior \u2014 \u00e9 quando algo quebra e voc\u00ea suspeita que isso seja devido \u00e0 \"papel com galaxy\". Voc\u00ea o abre e l\u00e1 est\u00e3o cinco inclus\u00f5es, oito listas de tarefas e uma pilha <code>when<\/code> pode ser menos prefer\u00edvel do que um \"papel\" pr\u00f3prio de cinco tarefas. O momento em que um papel com galaxy \u00e9 melhor \u2014 \u00e9 quando voc\u00ea come\u00e7a a escrever algo. O momento em que se torna pior \u2014 \u00e9 quando algo quebra, e voc\u00ea suspeita que \u00e9 por causa do \"papel com galaxy\". Voc\u00ea o abre e l\u00e1 est\u00e3o cinco inclus\u00f5es, oito listas de tarefas e uma pilha <code>when<\/code>\u2026 E \u00e9 nisso que voc\u00ea precisa se aprofundar. Em vez de 5 tarefas em uma lista linear, na qual n\u00e3o h\u00e1 nada para quebrar.<\/p>\n<p><\/p>\n<h1>Um pouco sobre invent\u00e1rio, vari\u00e1veis de grupo, plugin host_group_vars, hostvars. Como amarrar o n\u00f3 g\u00f3rdio em um emaranhado. Escopo e preced\u00eancia de vari\u00e1veis, modelo de mem\u00f3ria do Ansible. \"Ent\u00e3o, onde realmente devemos armazenar o nome de usu\u00e1rio para o banco de dados?\".<\/h1>\n<p><\/p>\n<ul>\n<li>Um pouco sobre invent\u00e1rio, vari\u00e1veis de grupo, plugin host_group_vars, hostvars. Como amarrar a espaguete em um n\u00f3 g\u00f3rdio. Escopo e preced\u00eancia de vari\u00e1veis, modelo de mem\u00f3ria do Ansible. \"Ent\u00e3o, onde exatamente armazenar o nome de usu\u00e1rio para o banco de dados?\".<\/li>\n<li><code>\u2014 nosql notype nosense, uma massa male\u00e1vel. Est\u00e1 em todo lugar, at\u00e9 mesmo onde voc\u00ea n\u00e3o espera. Um pouco sobre<\/code> !!unsafe <code>e yaml saboroso.<\/code> Fa\u00e7o muitas an\u00e1lises de c\u00f3digo de outras pessoas no Ansible e escrevo muito eu mesmo.<\/li>\n<\/ul>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/508762\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c. \u0412 \u0445\u043e\u0434\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043e\u0448\u0438\u0431\u043e\u043a (\u043a\u0430\u043a \u0447\u0443\u0436\u0438\u0445, \u0442\u0430\u043a \u0438 \u0441\u0432\u043e\u0438\u0445), \u0430 \u0442\u0430\u043a \u0436\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0439, \u044f \u043f\u043e\u043d\u044f\u043b \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0434\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0410\u043d\u0441\u0438\u0431\u043b\u0430 \u2014 \u043e\u043d\u0438 \u043b\u0435\u0437\u0443\u0442 \u0432 \u0441\u043b\u043e\u0436\u043d\u043e\u0435, \u043d\u0435 \u043e\u0441\u0432\u043e\u0438\u0432 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e. \u0414\u043b\u044f \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u0432\u0441\u0435\u043b\u0435\u043d\u0441\u043a\u043e\u0439 \u043d\u0435\u0441\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 \u0410\u043d\u0441\u0438\u0431\u043b [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-87084","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041e\u0441\u043d\u043e\u0432\u044b Ansible, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0430\u0448\u0438 \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0438 \u2014 \u043a\u043e\u043c\u043e\u043a \u0441\u043b\u0438\u043f\u0448\u0438\u0445\u0441\u044f \u043c\u0430\u043a\u0430\u0440\u043e\u043d | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-07-03T11:42:34+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-07-03T11:42:34+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Fundamentos do Ansible, sem os quais seus playbooks s\u00e3o um monte de macarr\u00e3o grudado | ProHoster","description":"\ud83e\udd47Fundamentos do Ansible, sem os quais seus playbooks s\u00e3o um bloco de macarr\u00e3o grudado | ProHoster","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041e\u0441\u043d\u043e\u0432\u044b Ansible, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u0430\u0448\u0438 \u043f\u043b\u0435\u0439\u0431\u0443\u043a\u0438 \u2014 \u043a\u043e\u043c\u043e\u043a \u0441\u043b\u0438\u043f\u0448\u0438\u0445\u0441\u044f \u043c\u0430\u043a\u0430\u0440\u043e\u043d | ProHoster","og:description":"\u042f \u0434\u0435\u043b\u0430\u044e \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0432\u044c\u044e \u0434\u043b\u044f \u0447\u0443\u0436\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 \u0410\u043d\u0441\u0438\u0431\u043b \u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u0438\u0448\u0443 \u0441\u0430\u043c.","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/osnovy-ansible-bez-kotoryh-vashi-plejbuki-komok-slipshihsya-makaron","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-07-03T11:42:34+00:00","article:modified_time":"2020-07-03T11:42:34+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"87084","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:58:53","updated":"2026-02-22 15:29:30","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/87084","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=87084"}],"version-history":[{"count":2,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/87084\/revisions"}],"predecessor-version":[{"id":162161,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/87084\/revisions\/162161"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=87084"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=87084"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=87084"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}