Introdução
Neste laboratório, você explorará duas funcionalidades poderosas do Ansible: condicionais e loops. Esses conceitos permitem que você crie playbooks mais dinâmicos e eficientes, controlando a execução de tarefas com base em condições específicas e repetindo tarefas para múltiplos itens. Ao final deste laboratório, você entenderá como usar condicionais para tomar decisões em seus playbooks e como implementar loops para realizar tarefas repetitivas de forma eficiente. Este conhecimento o ajudará a criar playbooks Ansible mais flexíveis e poderosos para gerenciar sua infraestrutura.
Configurando o Ambiente
Antes de mergulharmos em condicionais e loops do Ansible, vamos configurar nosso ambiente de trabalho. Esta etapa é crucial, pois prepara a base para todas as nossas tarefas subsequentes.
Primeiramente, vamos navegar para o diretório do projeto. No terminal, digite:
cd ~/project
Este comando altera seu diretório atual para ~/project, que é nosso espaço de trabalho designado para este laboratório.
Agora, criaremos um arquivo de inventário. No Ansible, um arquivo de inventário define os hosts e grupos de hosts nos quais comandos, módulos e tarefas em um playbook operam. Para este laboratório, usaremos um inventário simples que inclui apenas o localhost.
Crie um novo arquivo chamado inventory.ini:
nano inventory.ini
Este comando abre o editor de texto nano. Se você não estiver familiarizado com o nano, não se preocupe - é um editor de texto simples e fácil de usar. O cursor será posicionado no arquivo, pronto para você digitar.
Agora, vamos adicionar o seguinte conteúdo ao arquivo:
[local]
localhost ansible_connection=local
Vamos detalhar isso:
[local]define um grupo chamado "local"localhosté o nome do hostansible_connection=localdiz ao Ansible para executar comandos localmente em vez de via SSH
Para salvar o arquivo e sair do nano:
- Pressione
Ctrl + X - Você será perguntado se deseja salvar o buffer modificado. Pressione
Ypara sim. - Pressione
Enterpara confirmar o nome do arquivo.
Em seguida, vamos criar um diretório para nossos playbooks:
mkdir playbooks
cd playbooks
O comando mkdir cria um novo diretório chamado "playbooks", e então usamos cd para entrar neste novo diretório.
Por que estamos fazendo isso? Organizar seus arquivos Ansible em diretórios é uma prática recomendada. Ele mantém seu projeto organizado, especialmente à medida que ele cresce e se torna mais complexo.
Ao seguir estas etapas, você configurou um ambiente Ansible básico. Você tem um arquivo de inventário que diz ao Ansible com quais hosts trabalhar e um diretório dedicado para seus playbooks. Essa estrutura facilitará o gerenciamento de seus projetos Ansible à medida que você aprende e experimenta recursos mais complexos.
Introdução aos Condicionais
Os condicionais no Ansible permitem que você controle a execução de tarefas com base em certas condições. Isso é incrivelmente útil quando você precisa realizar ações diferentes dependendo do estado do seu sistema ou do valor de certas variáveis.
Vamos criar um playbook simples que demonstra o uso de condicionais:
nano conditional_example.yml
Este comando abre o editor de texto nano para criar um novo arquivo chamado conditional_example.yml. Agora, vamos adicionar o seguinte conteúdo:
---
- name: Exemplo Condicional
hosts: localhost
gather_facts: yes
tasks:
- name: Verificar família do SO
debug:
msg: "Este é um sistema baseado em Debian"
when: ansible_os_family == "Debian"
- name: Verificar família do SO (alternativo)
debug:
msg: "Este não é um sistema baseado em Debian"
when: ansible_os_family != "Debian"
Vamos detalhar isso:
---no topo do arquivo indica o início de um documento YAML.name: Exemplo Condicionaldá um nome ao nosso playbook.hosts: localhostespecifica que este playbook será executado na máquina local.gather_facts: yesdiz ao Ansible para coletar informações sobre o sistema antes de executar as tarefas. Isso é importante porque usaremos esses fatos em nossas condições.tasks:inicia a lista de tarefas a serem executadas.
Cada tarefa usa o módulo debug para imprimir uma mensagem, mas a execução é controlada pela cláusula when:
- A primeira tarefa só será executada se o sistema for baseado em Debian (
ansible_os_family == "Debian"). - A segunda tarefa só será executada se o sistema não for baseado em Debian (
ansible_os_family != "Debian").
ansible_os_family é um fato coletado pelo Ansible sobre o sistema de destino. Ele é usado aqui para demonstrar como os condicionais funcionam.
Salve e saia do editor nano (Ctrl+X, depois Y, depois Enter).
Agora, vamos executar o playbook:
ansible-playbook -i ../inventory.ini conditional_example.yml
Este comando diz ao Ansible para executar nosso playbook. A opção -i ../inventory.ini especifica o arquivo de inventário que criamos anteriormente.
Você deve ver a saída indicando se seu sistema é baseado em Debian ou não. Apenas uma das mensagens de depuração será exibida, dependendo da família do SO do seu sistema.
Este exemplo demonstra como os condicionais podem ser usados para tornar seus playbooks adaptáveis a diferentes ambientes. Em cenários do mundo real, você pode usar condicionais para instalar pacotes diferentes em diferentes tipos de SO ou para pular certas tarefas se um arquivo já existir.
Lembre-se, o poder dos condicionais reside em sua capacidade de tornar seus playbooks flexíveis e capazes de lidar com vários cenários sem a necessidade de playbooks separados para cada caso.
Trabalhando com Múltiplas Condições
Em cenários do mundo real, você frequentemente precisa verificar múltiplas condições antes de executar uma tarefa. O Ansible permite que você combine múltiplas condições usando operadores lógicos. Vamos criar outro playbook para demonstrar este uso mais avançado de condicionais.
Crie um novo arquivo chamado multiple_conditions.yml:
nano multiple_conditions.yml
Agora, vamos adicionar o seguinte conteúdo ao arquivo:
---
- name: Exemplo de Múltiplas Condições
hosts: localhost
gather_facts: yes
vars:
check_memory: true
tasks:
- name: Verificar SO e Memória
debug:
msg: "Este é um sistema baseado em Debian com mais de 1GB de memória"
when:
- ansible_os_family == "Debian"
- ansible_memtotal_mb > 1024
- check_memory | bool
- name: Imprimir Informações do Sistema
debug:
msg: "SO: {{ ansible_distribution }}, Memória: {{ ansible_memtotal_mb }} MB"
when: ansible_distribution == "Ubuntu" or ansible_memtotal_mb < 2048
Vamos detalhar este playbook:
Definimos uma variável
check_memoryno nível do playbook. Isso pode ser definido dinamicamente ou passado como uma variável extra ao executar o playbook.A primeira tarefa usa múltiplas condições:
- Verifica se a família do SO é Debian
- Verifica se a memória total é maior que 1024 MB (1 GB)
- Verifica se a variável
check_memoryé verdadeira
Todas essas condições devem ser verdadeiras para que a tarefa seja executada. O
|emcheck_memory | boolé um filtro que converte o valor em um booleano.A segunda tarefa demonstra o uso do operador
or. Ela será executada se a distribuição for Ubuntu OU a memória total for menor que 2048 MB (2 GB).Estamos usando mais fatos do Ansible aqui:
ansible_distributionfornece o nome específico da distribuição eansible_memtotal_mbfornece a memória total do sistema em megabytes.
Salve e saia do editor nano.
Agora, vamos executar este playbook:
ansible-playbook -i ../inventory.ini multiple_conditions.yml
Observe a saída. Dependendo das características do seu sistema, você pode ver uma ou ambas as mensagens de depuração.
Este exemplo mostra como você pode criar condições complexas para tornar seus playbooks altamente adaptáveis a diferentes cenários. Você pode combinar vários fatos do sistema, variáveis personalizadas e operadores lógicos para ajustar quando suas tarefas devem ser executadas.
Introdução aos Loops
Loops no Ansible permitem que você repita uma tarefa várias vezes com valores diferentes. Isso é extremamente útil quando você precisa realizar a mesma ação com múltiplos itens, como criar vários usuários, instalar múltiplos pacotes ou criar vários diretórios.
Vamos criar um playbook para demonstrar o uso de loops. Crie um novo arquivo chamado loop_example.yml:
nano loop_example.yml
Agora, adicione o seguinte conteúdo:
---
- name: Exemplo de Loop
hosts: localhost
vars:
fruits:
- apple
- banana
- cherry
tasks:
- name: Imprimir nomes de frutas
debug:
msg: "Fruta atual: {{ item }}"
loop: "{{ fruits }}"
- name: Criar diretórios
file:
path: "/tmp/{{ item }}"
state: directory
loop:
- dir1
- dir2
- dir3
Vamos detalhar isso:
Definimos uma variável
fruitscomo uma lista de nomes de frutas.A primeira tarefa usa um loop para iterar sobre a lista
fruits. Para cada iteração, o valor atual está disponível como{{ item }}.A segunda tarefa demonstra como usar um loop com o módulo
filepara criar múltiplos diretórios. Estamos criando três diretórios na pasta/tmp.Observe que podemos usar o loop diretamente na tarefa (como na segunda tarefa) ou referenciar uma variável (como na primeira tarefa).
Salve e saia do editor nano.
Agora, vamos executar este playbook:
ansible-playbook -i ../inventory.ini loop_example.yml
Quando você executar este playbook, você verá que a primeira tarefa imprime cada nome de fruta e a segunda tarefa cria três diretórios em /tmp.
Loops são um recurso poderoso no Ansible que pode reduzir significativamente a quantidade de código repetitivo em seus playbooks. Eles são especialmente úteis ao trabalhar com listas de itens como usuários, pacotes ou arquivos.
Técnicas Avançadas de Loop
O Ansible fornece técnicas de loop mais avançadas que permitem que você trabalhe com estruturas de dados complexas e tenha mais controle sobre o processo de loop. Vamos explorar algumas dessas técnicas criando um novo playbook.
Crie um novo arquivo chamado advanced_loops.yml:
nano advanced_loops.yml
Agora, adicione o seguinte conteúdo:
---
- name: Técnicas Avançadas de Loop
hosts: localhost
vars:
users:
- name: alice
groups: ["developers", "testers"]
- name: bob
groups: ["managers", "developers"]
tasks:
- name: Criar usuários com grupos
debug:
msg: "Criando usuário {{ item.name }} com grupos: {{ item.groups | join(', ') }}"
loop: "{{ users }}"
- name: Demonstrar loop_control
debug:
msg: "Processando item {{ index }} - {{ item }}"
loop: ["a", "b", "c", "d"]
loop_control:
index_var: index
- name: Loop sobre dicionário
debug:
msg: "{{ key }}: {{ value }}"
loop: "{{ {'x': 1, 'y': 2, 'z': 3} | dict2items }}"
vars:
key: "{{ item.key }}"
value: "{{ item.value }}"
Vamos detalhar essas técnicas avançadas:
Loop sobre uma lista de dicionários: A primeira tarefa faz um loop sobre a lista
users, onde cada item é um dicionário contendo um nome e uma lista de grupos. Podemos acessar esses elementos aninhados usando a notação de ponto (item.name,item.groups).Usando
loop_control: A segunda tarefa demonstraloop_control, que nos permite alterar o nome da variável de loop (o padrão éitem) e acessar o índice do loop atual. Aqui, usamosindex_var: indexpara criar uma variávelindexque acompanha o número da iteração atual.Loop sobre um dicionário: A última tarefa mostra como fazer um loop sobre um dicionário. Usamos o filtro
dict2itemspara converter o dicionário em uma lista de pares chave-valor que podem ser iterados. Em seguida, usamositem.keyeitem.valuepara acessar as chaves e os valores do dicionário.
Salve e saia do editor nano.
Agora, vamos executar este playbook:
ansible-playbook -i ../inventory.ini advanced_loops.yml
Quando você executar este playbook, você verá como essas técnicas avançadas de loop funcionam. A saída mostrará:
- Mensagens de criação de usuário com seus respectivos grupos
- Itens sendo processados com seus índices
- Pares chave-valor do dicionário
Essas técnicas avançadas permitem que você trabalhe com estruturas de dados mais complexas e fornecem um controle mais preciso sobre seus loops. Elas são particularmente úteis ao lidar com dados aninhados, quando você precisa acompanhar o índice do loop ou ao trabalhar com dicionários.
Resumo
Neste laboratório, você aprendeu sobre condicionais e loops do Ansible, dois recursos poderosos que permitem criar playbooks mais dinâmicos e eficientes. Aqui estão os principais pontos:
- Condicionais (cláusula
when) permitem que você controle a execução de tarefas com base em condições específicas, como fatos sobre o sistema de destino ou variáveis definidas pelo usuário. - Você pode combinar múltiplas condições usando operadores lógicos como
andeorpara criar declarações condicionais mais complexas. - Loops (palavra-chave
loop) permitem que você repita tarefas com valores diferentes, aumentando a eficiência e reduzindo a complexidade do playbook. - O Ansible suporta vários tipos de loop, incluindo loop sobre listas, dicionários e estruturas de dados mais complexas.
- Técnicas avançadas de loop, como
loop_controle loop sobre dicionários, fornecem ainda mais flexibilidade no tratamento de tarefas repetitivas.
Esses recursos são essenciais para criar playbooks Ansible flexíveis e poderosos que podem se adaptar a diferentes cenários e gerenciar eficientemente múltiplos itens. Ao continuar trabalhando com o Ansible, pratique a incorporação de condicionais e loops em seus playbooks para torná-los mais dinâmicos e eficientes.
Lembre-se de sempre considerar a legibilidade e a capacidade de manutenção de seus playbooks ao usar esses recursos. Embora eles possam simplificar muito seu código, o uso excessivo ou condições e loops excessivamente complexos podem tornar os playbooks mais difíceis de entender e manter.


