Pesquisa de site

Como criar peças e playbooks Ansible - Parte 5


Nesta Parte 5 da série Ansible, explicaremos como criar Ansible Plays e Playbooks usando módulos Ansible.

O Ansible vem com scripts independentes chamados módulos que são usados em manuais para a execução de tarefas especializadas em nós remotos.

Módulos são úteis para automatizar tarefas como gerenciamento de pacotes, arquivamento e cópia de arquivos, para mencionar apenas alguns. Eles permitem que você faça ajustes nos arquivos de configuração e gerencie dispositivos como roteadores, switches, balanceadores de carga, firewalls e uma série de outros dispositivos.

O objetivo deste subtópico é fornecer uma visão geral das diversas tarefas que podem ser realizadas pelos módulos Ansible:

Gerenciamento de pacotes no Linux

O gerenciamento de pacotes é uma das tarefas mais essenciais e frequentes realizadas pelos administradores de sistemas. O Ansible vem com módulos que ajudam você a executar tarefas de gerenciamento de pacotes em sistemas baseados em RedHat e Debian.

Eles são relativamente fáceis de adivinhar. Existe o módulo apt para gerenciamento de pacotes APT para base Debian, o antigo módulo yum para gerenciamento de pacotes YUM e o módulo dnf associado às distribuições RHEL mais recentes .

Abaixo estão alguns exemplos de como os módulos podem ser usados em um manual:

Exemplo 1: Instalando o servidor Web Apache no RHEL 8

---
- name: install Apache webserver
  hosts: webservers

  tasks:
       - name: install httpd
         dnf:  
          name: httpd  
          State: latest

Exemplo 2: Instalando o servidor Web Apache no Debian 10

---
- name: install Apache webserver
  hosts: databases

  tasks:
       - name: install Apache webserver
         apt:  
          name: apache2  
          State: latest

Módulo de serviço

O módulo de serviço permite que os administradores do sistema iniciem, parem, atualizem, atualizem e recarreguem serviços no sistema.

Exemplo 1: Iniciando o servidor Web Apache

---
- name: Start service httpd, if not started
  service:
    name: httpd
    state: started

Exemplo 2: Parando o servidor Web Apache

---
- name: Stop service httpd
  service:
    name: httpd
    state: stopped

Exemplo 3: Reiniciando uma interface de rede enp2s0

---
- name: Restart network service for interface eth0
  service:
    name: network
    state: restarted
    args: enp2s0

Módulo de cópia

Como o nome sugere, o módulo copy copia arquivos de um local na máquina remota para um local diferente na mesma máquina.

Exemplo 1: Copiando arquivos do Linux local para remoto

---
- name: Copy file with owner and permissions
  copy:
    src: /etc/files/tecmint.conf
    dest: /srv/tecmint.conf
    owner: tecmint
    group: tecmint
    mode: '0644'

O manual copia o arquivo de configuração tecmint.conf do diretório /etc/files/ para o diretório /srv/ como tecmint usuário com permissões 0644.

As permissões também podem ser representadas usando representação simbólica conforme mostrado na última linha.

Exemplo 2: Copiando arquivos do Linux local para remoto

---
- name: Copy file with owner and permissions
  copy:
    src: /etc/files/tecmint.conf
    dest: /srv/tecmint.conf
    owner: tecmint
    group: tecmint
    mode: u=rw, g=r, o=r

As permissões no exemplo anterior podem ser representadas conforme mostrado na última linha. O usuário recebe permissões de leitura e gravação, o grupo recebe permissões de gravação e o restante o mundo recebe permissões de leitura.

Módulo de arquivo

O módulo de arquivo é usado para realizar muitas operações de arquivo, incluindo criação de arquivos e diretórios, atribuição de permissões de arquivo e configuração de links simbólicos.

Exemplo 1: Execute permissões de arquivo Linux

---
- name: Change file ownership, group, and permissions
  file:
    path: /etc/tecmint.conf
    owner: tecmint
    group: tecmint
    mode: '0644'

A peça acima cria um arquivo chamado tecmint.conf no diretório /etc definindo as permissões para 0644.

Exemplo 2: Excluir arquivo Linux

---
- name: Remove file (delete file)
  file:
    path: /etc/tecmint.conf
    state: absent

Isso remove ou exclui o arquivo tecmint.conf.

Exemplo 3: Crie um diretório

---
- name: create a directory if it doesn’t exist
  file:
    path: /etc/mydirectory
    State: directory
    mode: '0777'

Isto criará um diretório no diretório /etc definindo as permissões para 0777.

Exemplo 4: excluir recursivamente um diretório

---
- name: Recursively deleting a  directory
  file:
    path: /etc/tecmint.conf
    state: absent

A reprodução acima exclui recursivamente um diretório.

Módulo de arquivo de linha

O módulo lineinfile é útil quando você deseja alterar uma única linha em um arquivo. Ele pode substituir uma linha existente.

Exemplo 1: Manipular arquivos no Linux

---
 - name: Ensure SELinux is set to enforcing mode
  lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: SELINUX=disabled

A peça acima define o valor SELINUX como desativado.

SELINUX=disabled

Exemplo 2: Alterar arquivos no Linux

---
- name: Add a line to a file if the file does not exist, without         passing regexp
  lineinfile:
    path: /etc/hosts
    line: 10.200.50.51 linux-console.net
    create: yes

Isso adiciona a entrada 10.200.50.51 linux-console.net ao arquivo /etc/hosts.

Módulo de arquivo

Um módulo Archive é usado para a criação de um arquivo compactado de um único ou vários arquivos. Ele assume que a fonte de compactação existe e está presente no destino alvo. Após o arquivamento, o arquivo de origem pode ser excluído ou removido posteriormente usando a instrução remove=True.

Exemplo 1: Crie um arquivo compactado

- name: Compress directory /path/to/tecmint_dir/ into /path/to/tecmint.tgz
  archive:
    path: /path/to/tecmint_dir
    dest: /path/to/tecmint.tgz

This compresses the /path/to/tecmint_dir  directory to /path/to/tecmint.tgz

Exemplo 2: Crie um arquivo compactado e remova

- name: Compress regular file /path/to/tecmint into /path/to/foo.gz and remove it
  archive:
    path: /path/to/tecmint
    dest: /path/to/tecmint.tgz
    remove: yes

Na reprodução acima, o arquivo fonte /path/to/tecmint é excluído após a conclusão do arquivamento.

Exemplo 3: Crie um arquivo compactado

- name: Create a bz2 archive of /path/to/tecmint
  archive:
    path: /path/to/tecmint
    format: bz2

Isso cria um arquivo compactado no formato bz2 a partir do arquivo /path/to/tecmint.

Módulo Git

O módulo gerencia checkouts git de repositórios de software.

Exemplo 1: verifique os repositórios Git

- git:
    repo: 'https://foosball.example.org/path/to/repo.git'
    dest: /srv/checkout
    version: release-0.22

Módulo de comando

Um dos módulos mais comumente usados, o módulo comando leva o nome do comando e depois é seguido por uma lista de argumentos. O comando é passado da mesma forma que você digitaria em um shell do Linux.

Exemplo 1: execute um comando

- name: Executing a command using the command module
  command: cat helloworld.txt

Exemplo 2: Verifique o tempo de atividade do Linux remoto

---
 - name: Check the remote host uptime
    hosts: servers
    tasks:
      - name: Execute the Uptime command over Command module
        register: uptimeoutput
        command: "uptime"

- debug:
          var: uptimeoutput.stdout_lines

O módulo de comando recupera o tempo de atividade de servidores remotos.

Variáveis para recuperar os resultados da execução de comandos

Normalmente, os playbooks do Ansible são usados para executar tarefas em hosts gerenciados sem exibir a saída na linha de comando. Há casos, no entanto, em que pode ser necessário capturar a saída ou os resultados. Nesta seção, mostramos como capturar a saída de um playbook em uma variável e exibi-la posteriormente.

Um registro ansible é usado para capturar a saída de uma tarefa e salvá-la como uma variável. A partir de então, a variável conterá o stdout da tarefa.

Por exemplo, vamos supor que você deseja verificar o uso do disco de nós gerenciados nos respectivos diretórios raiz usando o comando df -Th /. Você usará o módulo ‘command’ para definir o comando e ‘register’ para salvar a saída padrão em uma variável.

Para exibir o comando, você usará o módulo ‘debug’ junto com o valor de retorno stdout.

---

 - hosts: all
   become: yes

   tasks:
     - name: Execute /boot usage on Hosts
       command: 'df -Th /'
       register: df

     - debug: var=df.stdout

Agora, vamos executar o manual. Nesse caso, nomeamos nosso manual de check_disk_space.yml.

ansible-playbook check_disk_space.yml

Como você viu, o resultado está todo confuso e dificulta o acompanhamento.

Para alinhar a saída e facilitar a leitura, substitua o valor de retorno stdout por stdout_lines.

---

 - hosts: all
   become: yes

   tasks:
     - name: Execute /boot usage on Hosts
       command: 'df -Th /'
       register: df

     - debug: var=df.stdout_lines

Use condicionais para controlar a execução do jogo

Assim como nas linguagens de programação, declarações condicionais são usadas quando mais de um resultado é possível. Vamos dar uma olhada em algumas das instruções condicionais comumente usadas nos manuais do Ansible.

Quando declaração

Às vezes, você pode querer executar tarefas em nós específicos e não em outros. A instrução condicional 'when' é bastante fácil de usar e implementar em um manual. Ao usar a cláusula 'when' simplesmente declare a condição adjacente à cláusula conforme mostrado:

when: condition

Quando a condição for satisfeita, a tarefa será executada no sistema remoto.

Vejamos alguns exemplos:

Exemplo 1: Usando o Operador When

---
- hosts: all

  tasks:
  - name: Install Nginx on Debian
     apt: name=nginx state=present
     when: ansible_os_family == “Debian”

A peça acima instala o servidor web Nginx em hosts que executam a família de distros Debian.

Você também pode usar os operadores OR e AND junto com a instrução condicional.

Exemplo 2: Usando o operador AND com When

---
- hosts: all

  tasks:
  - name: Install Nginx on Debian
     apt: name=nginx state=present
     when: ansible_os_family == “Debian” and
           ansible_distribution_version == “18.04”

Ao usar o operador AND, ambas as instruções devem ser satisfeitas para que a tarefa seja executada.

A peça acima instala o Nginx em nós que executam uma família de sistemas operacionais Debian, versão 18.04. Obviamente, este será o Ubuntu 18.04.

Exemplo 3: Usando o operador OR com When

Com o operador OR, a tarefa é executada se alguma das condições for atendida.

---
- hosts: all

  tasks:
  - name: Install Nginx on Debian
     apt: name=nginx state=present
     when: ansible_os_family == “Debian” or
	      Ansible_os_family == “SUSE”

A peça acima instala servidores web Nginx na família de sistemas operacionais Debian ou SUSE ou em ambos.

NOTA: Sempre certifique-se de usar o sinal de igualdade duplo == ao testar uma condição.

Condicionais em loops

Condicionais também podem ser usados em um loop. Digamos, por exemplo, que você tenha uma lista de vários pacotes que precisam ser instalados em nós remotos.

No manual abaixo, temos um array chamado pacotes contendo uma lista de pacotes que precisam ser instalados. Estas tarefas serão realizadas uma após a outra se a cláusula required estiver definida como True.

---
 - name: Install Software packages
    hosts: all
    vars:
	packages:
    • name: nginx
required: True
    • name: mysql
required: True
    • name: apache
required: False



   tasks:
    • name: Install “{{ item.name }}”on Debian
apt: 
 name: “{{ item.name }}”
 state: present 
When: item.required == True
loop: “{{ packages }}”  

Configurar tratamento de erros

Às vezes, as tarefas falham ao executar manuais. Vamos supor que você esteja executando 5 tarefas em 3 servidores, conforme mostrado no manual abaixo. Se ocorrer um erro na tarefa 3 (Iniciando o MySQL) no servidor 2, o Ansible interromperá a execução das tarefas restantes no servidor 2 e tentará concluir as tarefas restantes nos demais servidores.

---
 - name: Install Software packages
   hosts: server1, server2, server3
   tasks:
- name: Install dependencies
<< some code >>

- name: Install MySQL database
<< some code >>

- name: Start MySQL
<< some code >>

- name: Install Nginx
<< some code >>

- name: Start Nginx
<< some code >>

Se você deseja consistência na execução do playbook, por exemplo, interromper a execução de um playbook, caso um dos servidores falhe, adicione a opção.

---
 - name: Install Software packages
   hosts: server1, server2, server3
   any_errors_fatal:  true
   tasks:

Dessa forma, se uma tarefa falhar em um servidor, o Ansible interromperá a execução de todo o playbook em todos os servidores e sairá.

Se desejar que o manual ignore os erros e prossiga com a execução do conjunto restante de tarefas, use a opção ignore_errors: True.

---
 - name: Install Software packages
   hosts: server1, server2, server3
   tasks:
- name: Install dependencies
<< some code >>
     ignore_errors: True

Crie manuais para configurar sistemas para um estado específico

Nesta seção, veremos algumas opções adicionais disponíveis ao executar um playbook.

Vamos começar com o modo Verificar ou a opção Teste. A opção de simulação ou modo de verificação é usada ao executar um playbook para verificar se algum erro será encontrado e se há alguma alteração que será feita nos hosts gerenciados. No entanto, não faz nenhuma alteração nos nós remotos.

Por exemplo, para executar um playbook chamado httpd.yml que instala e inicia a execução do servidor web Apache:

ansible-playbook httpd.yml --check

A outra opção que precisamos observar é a opção --start-at-task. Isso é usado ao especificar o nome da tarefa na qual o playbook deve começar ou começar.

Vejamos um exemplo: O manual abaixo descreve 2 tarefas: a primeira instala o servidor web Apache e a segunda instala o utilitário htop.

---
 - name: Install httpd

   hosts: all
   tasks:
    yum:	 
name: httpd
     state: Installed

- name: Install htop

      yum:  
      name: htop
      state: started

Se você quiser pular a instalação do servidor web Apache e, em vez disso, instalar o utilitário htop, execute:

ansible-playbook playbook.yml --start-at-task “Install htop”

Por último, você pode marcar suas tarefas ou jogadas adicionando a opção tags ao seu manual, conforme mostrado. Isso é útil quando você tem um manual bastante grande e deseja executar tarefas específicas de todo o manual.

---
 - name: Install httpd
   tags: Install and start
   hosts: all
   tasks:
    yum:	 
name: httpd
     state: Installed

   tags: Install

    • service: 
name: httpd
state: started
ansible-playbook playbook.yml -tags "Install"

Para omitir as tags use as opções --skip-tags conforme mostrado.

ansible-playbook playbook.yml --skip-tags "Install"
Conclusão

Neste tópico, mostramos os módulos comumente usados no Ansible, como recuperar stdout da execução de um playbook para análise, usando condicionais no playbook e como gerenciar erros que podem ocorrer durante a execução tarefas. Por fim, recapitulamos a configuração dos playbooks e como você pode usar opções adicionais para decidir quais tarefas executar caso não pretenda executar o playbook inteiro.