britho / Ansible-HedHat

0 stars 0 forks source link

Aula-6 #4

Open britho opened 3 years ago

britho commented 3 years ago

Meta | Implantar, gerenciar e ajustar arquivos em hosts gerenciados pelo Ansible. -- | -- Objetivos | Criar, instalar, editar e remover arquivos em hosts gerenciados, além de gerenciar permissões, propriedade, contexto do SELinux e outras características desses arquivos. Personalizar arquivos usando templates Jinja2 e implantá-los em hosts gerenciados. Seções | Modificação e cópia de arquivos para hosts (e exercício orientado) Implantação de arquivos personalizados com templates Jinja2 (e exercício orientado) Laboratório | Implantação de arquivos em hosts gerenciados

Objetivos

Depois de concluir esta seção, você deverá ser capaz de criar, instalar, editar e remover arquivos em hosts gerenciados, além de gerenciar permissões, propriedade, contexto do SELinux e outras características desses arquivos.

Descrição dos módulos de arquivos

O RedHat Ansible Engine é fornecido com uma grande coleção de módulos (a biblioteca de módulos) desenvolvidos como parte do projeto upstream do Ansible. Para facilitar a organização, a documentação e o gerenciamento, eles são organizados em grupos com base na função da documentação e em quando são instalados em um sistema.

A biblioteca de módulos Files inclui módulos que permitem realizar a maioria das tarefas relacionadas ao gerenciamento de arquivos do Linux, como criar, copiar, editar e modificar permissões e outros atributos de arquivos. A seguinte tabela fornece uma lista dos módulos de gerenciamento de arquivos usados com frequência:

Nome do módulo | Descrição do módulo -- | -- blockinfile | Insira, atualize ou remova um bloco de texto de várias linhas cercado por linhas de marcadores personalizáveis. copy | Copie um arquivo da máquina local ou remota para um local em um host gerenciado. Semelhante ao módulo file, o módulo copy também pode definir atributos de arquivos, incluindo o contexto do SELinux. fetch | Este módulo funciona como o módulo copy, mas em sentido inverso. Ele é usado para buscar arquivos de máquinas remotas para o nó de controle e armazená-los em uma árvore de arquivos, organizada pelo nome do host. file | Defina atributos, como permissões, propriedade, contextos do SELinux e carimbos de data/hora, de arquivos comuns, symlinks, hardlinks e diretórios. Este módulo também pode criar ou remover arquivos comuns, symlinks, hardlinks e diretórios. Vários outros módulos relacionados a arquivos suportam as mesmas opções de definição de atributos do módulo file, inclusive o módulo copy. lineinfile | Verifique se uma determinada linha está presente em um arquivo ou substitua uma linha existente usando uma expressão regular de referência inversa. Este módulo é útil principalmente quando você deseja alterar uma única linha em um arquivo. stat | Recupera informações de status de um arquivo, semelhante ao comando stat do Linux. synchronize | Um wrapper ao redor do comando rsync para tornar as tarefas comuns rápidas e fáceis. O módulo synchronize não se destina a dar acesso a todos os recursos do comando rsync, mas facilita a implementação das invocações mais comuns. Talvez você ainda precise chamar o comando rsync diretamente usando o módulo run command, dependendo do seu caso de uso.

Exemplos de automação com módulos de arquivos

Criar, copiar, editar e remover arquivos em hosts gerenciados são tarefas comuns que você pode implementar usando módulos da biblioteca de módulos Files. Os exemplos a seguir mostram maneiras de usar esses módulos para automatizar tarefas comuns de gerenciamento de arquivos.

Certificação de que um arquivo existe nos hosts gerenciados

Use o módulo file para usar o comando touch em um arquivo nos hosts gerenciados. Ele funciona da mesma forma que o comando touch: se o arquivo não existir, será criado um arquivo vazio; se ele já existir, seu horário de modificação será atualizado. Neste exemplo, além de fazer tocar no arquivo, o Ansible verifica se o usuário proprietário, o grupo e as permissões do arquivo estão definidos com valores específicos.

- name: Touch a file and set permissions
  file:
    path: /path/to/file
    owner: user1
    group: group1
    mode: 0640
    state: touch

Exemplo de resultado:

$ ls -l file
-rw-r-----  user1 group1 0 Nov 25 08:00 file

Modificação de atributos dos arquivos

Você pode usar o módulo file para garantir que um arquivo novo ou existente tenha as permissões corretas ou também o tipo SELinux.

Por exemplo, o arquivo a seguir reteve o contexto do SELinux padrão relativo ao diretório pessoal de um usuário, que não é o contexto desejado.

$ ls -Z samba_file
-rw-r--r-- owner group unconfined_u:object_r:user_home_t:s0 samba_file

A tarefa a seguir assegura que o atributo de tipo de contexto do SELinux do arquivo samba_file seja o tipo samba_share_t desejado. Esse comportamento é semelhante ao do comando chcon do Linux.

- name: SELinux type is set to samba_share_t
  file:
    path: /path/to/samba_file
    setype: samba_share_t

Exemplo de resultado:

$ ls -Z samba_file
-rw-r--r--  owner group unconfined_u:object_r:samba_share_t:s0 samba_file

Os parâmetros de atributos de arquivo estão disponíveis em vários módulos de gerenciamento de arquivos. Execute os comandos ansible-doc file e ansible-doc copy para obter informações adicionais.

Mudanças persistentes no contexto do SELinux de arquivos

O módulo file atua como chcon ao definir contextos de arquivos. As alterações feitas com esse módulo podem ser desfeitas inesperadamente executando restorecon. Depois de usar file para definir o contexto, você pode usar sefcontext da coleção de módulos System para atualizar a política do SELinux parasemanage fcontext.

- name: SELinux type is persistently set to samba_share_t
  sefcontext:
    target: /path/to/samba_file
    setype: samba_share_t
    state: present

Exemplo de resultado:

$ ls -Z samba_file
-rw-r--r--  owner group unconfined_u:object_r:samba_share_t:s0 samba_file

O módulo sefcontext atualiza o contexto padrão para o destino na política do SELinux, mas não altera o contexto nos arquivos existentes.

Cópia e edição de arquivos em hosts gerenciados

Neste exemplo, o módulo copy é usado para copiar um arquivo localizado no diretório de trabalho do Ansible nó de controle para hosts gerenciados selecionados.

Por padrão, esse módulo presume que force: yes está definido. Esse comando forçará o módulo a substituir o arquivo remoto se ele existir e tiver conteúdo diferente do arquivo que está sendo copiado. Se force: no estiver definido, o comando copiará o arquivo para o host gerenciado apenas se ele ainda não existir.

- name: Copy a file to managed hosts
  copy:
    src: file
    dest: /path/to/file

Para recuperar arquivos de hosts gerenciados, use o módulo fetch. Isso pode ser usado para recuperar um arquivo, como uma chave pública SSH, de um sistema de referência antes de distribuí-lo para outros hosts gerenciados.

- name: Retrieve SSH key from reference host
  fetch:
    src: "/home/{{ user }}/.ssh/id_rsa.pub
    dest: "files/keys/{{ user }}.pub"

Para garantir que exista uma única linha de texto específica em um arquivo existente, use o módulo lineinfile:

- name: Add a line of text to a file
  lineinfile:
    path: /path/to/file
    line: 'Add this line to the file'
    state: present

Para adicionar um bloco de texto a um arquivo existente, use o módulo blockinfile:

- name: Add additional lines to a file
  blockinfile:
    path: /path/to/file
    block: |
      First line in the additional block of text
      Second line in the additional block of text
    state: present

Ao usar o módulo blockinfile, marcadores de bloco comentados são inseridos no início e no final do bloco para garantir a idempotência.

# BEGIN ANSIBLE MANAGED BLOCK
First line in the additional block of text
Second line in the additional block of text
# END ANSIBLE MANAGED BLOCK

Você pode usar o parâmetro marker no módulo para garantir que o texto ou o caractere de comentário correto esteja sendo usado para o arquivo em questão.

Remoção de um arquivo dos hosts gerenciados

Um exemplo básico de como remover um arquivo dos hosts gerenciados é usar o módulo file com o parâmetro state: absent. O parâmetro state é opcional em muitos módulos. Você deve sempre deixar claro se quer state: present ou state: absent por várias razões. Alguns módulos também dão suporte a outras opções. É possível que o padrão mude em algum momento, mas talvez o mais importante seja facilitar a compreensão do estado em que o sistema deve estar com base em sua tarefa.

- name: Make sure a file does not exist on managed hosts
  file:
    dest: /path/to/file
    state: absent

Recuperação do status de um arquivo em hosts gerenciados

O módulo stat recupera fatos de um arquivo, semelhante ao comando stat do Linux. Os parâmetros fornecem a funcionalidade para recuperar atributos de arquivo, determinar a soma de verificação de um arquivo, entre outras ações.

O módulo stat retorna um dicionário de hash de valores que contêm os dados de status do arquivo, permitindo que você se refira a partes individuais das informações usando variáveis separadas.

O exemplo a seguir registra os resultados de um módulo stat e imprime a soma de verificação MD5 do arquivo que ele verificou. (O algoritmo SHA256 mais moderno também está disponível; o MD5 está sendo usado aqui para facilitar a legibilidade.)

- name: Verify the checksum of a file
  stat:
    path: /path/to/file
    checksum_algorithm: md5
  register: result
- debug
    msg: "The checksum of the file is {{ result.stat.checksum }}"

A saída será semelhante à seguinte:

TASK [Get md5 checksum of a file] *****************************************
ok: [hostname]
TASK [debug] **************************************************************
ok: [hostname] => {
    "msg": "The checksum of the file is 5f76590425303022e933c43a7f2092a3"
}

As informações sobre os valores retornados pelo módulo stat são documentadas por ansible-doc, ou você pode registrar uma variável e exibir seu conteúdo para ver o que está disponível:

- name: Examine all stat output of /etc/passwd
  hosts: localhost
  tasks:
    - name: stat /etc/passwd
      stat:
        path: /etc/passwd
      register: results
    - name: Display stat results
      debug:
        var: results

Sincronização de arquivos entre o nó de controle e os hosts gerenciados

O módulo synchronize é um wrapper que envolve a ferramenta rsync, simplificando as tarefas comuns de gerenciamento de arquivos em seus playbooks. A ferramenta rsync deve ser instalada tanto no host local quanto no remoto. Por padrão, ao usar o módulo synchronize, o local host é o host em que a tarefa de sincronização se origina (geralmente, o nó de controle), e o destination host é o host ao qual o synchronize se conecta.

O exemplo a seguir sincroniza um arquivo localizado no diretório de trabalho do Ansible com os hosts gerenciados:

- name: synchronize local file to remote files
  synchronize:
    src: file
    dest: /path/to/file

Há muitas maneiras de usar o módulo synchronize e seus muitos parâmetros, inclusive sincronizar diretórios. Execute o comando ansible-doc synchronize para obter mais parâmetros e exemplos de playbooks.

Páginas de manual ansible-doc(1), chmod(1), chown(1), rsync(1), stat(1) e touch(1)

Módulos de arquivos

britho commented 3 years ago

Neste exercício, você criará, instalará, editará e removerá arquivos em hosts gerenciados e gerenciará as permissões, a propriedade e os contextos do SELinux desses arquivos.

Resultados

Você deverá ser capaz de:

  • Recuperar arquivos de hosts gerenciados, por nome do host, e armazená-los localmente.

  • Criar playbooks que usam módulos comuns de gerenciamento de arquivos, como copy, file, lineinfile e blockinfile.

Faça login na workstation como student usando a senha student.

Na workstation, execute o comando lab file-manage start. O script cria o diretório de projeto file-manage e faz download dos arquivos de configuração e de inventário de host do Ansible necessários para o exercício.

[student@workstation ~]$ lab file-manage start
  1. Em workstation, como usuário student, acesse o diretório de trabalho /home/student/file-manage. Crie um playbook chamado secure_log_backups.yml no diretório de trabalho atual. Configure o playbook para usar o módulo fetch para recuperar o arquivo de log /var/log/secure de cada um dos hosts gerenciados e armazená-los no nó de controle. O playbook deve criar o diretório secure-backups com subdiretórios com o nome do host de cada host gerenciado. Armazene os arquivos de backup em seus respectivos subdiretórios.

    1. Navegue até o diretório de trabalho /home/student/file-manage.

      [student@workstation ~]$ cd ~/file-manage
      [student@workstation file-manage]$
    2. Crie o playbook secure_log_backups.yml com o conteúdo inicial:

      ---
      - name: Use the fetch module to retrieve secure log files
        hosts: all
        remote_user: root
    3. Adicione uma tarefa ao playbook secure_log_backups.yml que recupere o arquivo de log /var/log/secure dos hosts gerenciados e os armazene no diretório ~/file-manage/secure-backups. O módulo fetch cria o diretório ~/file-manage/secure-backups se ele ainda não existir. Use o parâmetro flat: no para garantir o comportamento padrão de anexar o nome do host, o caminho e o nome do arquivo ao destino:

        tasks:
          - name: Fetch the /var/log/secure log file from managed hosts
            fetch:
              src: /var/log/secure
              dest: secure-backups
              flat: no
    4. Antes de executar o playbook, execute o comando ansible-playbook --syntax-check secure_log_backups.yml para verificar sua sintaxe. Corrija os erros antes de passar para a próxima etapa.

      [student@workstation file-manage]$ ansible-playbook --syntax-check \
      > secure_log_backups.yml
      playbook: secure_log_backups.yml
    5. Execute o comando ansible-playbook secure_log_backups.yml para executar o playbook:

      [student@workstation file-manage]$ ansible-playbook secure_log_backups.yml
      PLAY [Use the fetch module to retrieve secure log files] ******************
      TASK [Gathering Facts] ****************************************************
      ok: [servera.lab.example.com]
      ok: [serverb.lab.example.com]
      TASK [Fetch the /var/log/secure file from managed hosts] ******************
      changed: [serverb.lab.example.com]
      changed: [servera.lab.example.com]
      PLAY RECAP ****************************************************************
      servera.lab.example.com    : ok=2    changed=1    unreachable=0    failed=0
      serverb.lab.example.com    : ok=2    changed=1    unreachable=0    failed=0
    6. Verifique os resultados do playbook:

      [student@workstation file-manage]$ tree -F secure-backups
      secure-backups
      ├── servera.lab.example.com/
      │   └── var/
      │       └── log/
      │           └── secure
      └── serverb.lab.example.com/
          └── var/
              └── log/
                  └── secure
  2. Crie o playbook copy_file.yml no diretório de trabalho atual. Configure o playbook para copiar o arquivo /home/student/file-manage/files/users.txt em todos os hosts gerenciados como o usuário root.

    1. Adicione o seguinte conteúdo inicial ao playbook copy_file.yml:

      ---
      - name: Using the copy module
        hosts: all
        remote_user: root
    2. Adicione uma tarefa para usar o módulo copy para copiar o arquivo /home/student/file-manage/files/users.txt para todos os hosts gerenciados. Use o módulo copy para definir os seguintes parâmetros para o arquivo users.txt:

      Parâmetro | Valores -- | -- src | files/users.txt dest | /home/devops/users.txt owner | devops group | devops mode | u+rw,g-wx,o-rwx setype | samba_share_t

        tasks:
          - name: Copy a file to managed hosts and set attributes
            copy:
              src: files/users.txt
              dest: /home/devops/users.txt
              owner: devops
              group: devops
              mode: u+rw,g-wx,o-rwx
              setype: samba_share_t
    3. Use o comando ansible-playbook --syntax-check copy_file.yml para verificar a sintaxe do playbook copy_file.yml.

      [student@workstation file-manage]$ ansible-playbook --syntax-check copy_file.yml
      playbook: copy_file.yml
    4. Execute o playbook:

      [student@workstation file-manage]$ ansible-playbook copy_file.yml
      PLAY [Using the copy module] *******************************************
      TASK [Gathering Facts] *************************************************
      ok: [serverb.lab.example.com]
      ok: [servera.lab.example.com]
      TASK [Copy a file to managed hosts and set attributes] *****************
      changed: [servera.lab.example.com]
      changed: [serverb.lab.example.com]
      PLAY RECAP *************************************************************
      servera.lab.example.com : ok=2    changed=1    unreachable=0    failed=0
      serverb.lab.example.com : ok=2    changed=1    unreachable=0    failed=0
    5. Use um comando ad hoc para executar o comando ls -Z como usuário devops para verificar os atributos do arquivo users.txtnos hosts gerenciados.

      [student@workstation file-manage]$ ansible all -m command -a 'ls -Z' -u devops
      servera.lab.example.com | CHANGED | rc=0 >>
      unconfined_u:object_r:samba_share_t:s0 users.txt
      serverb.lab.example.com | CHANGED | rc=0 >>
      unconfined_u:object_r:samba_share_t:s0 users.txt
  3. Em uma etapa anterior, o campo do tipo do SELinux samba_share_t foi definido para o arquivo users.txt. No entanto, agora foi determinado que os valores padrão devem ser definidos para o contexto do arquivo do SELinux.

    Crie um playbook chamado selinux_defaults.yml no diretório de trabalho atual. Configure o playbook para usar o módulo file para garantir o contexto padrão do SELinux nos campos user, role, type e level.

    No mundo real, você também editaria o copy_file.yml e removeria a palavra-chave setype.

    1. Crie o playbook selinux_defaults.yml:

      ---
      - name: Using the file module to ensure SELinux file context
        hosts: all
        remote_user: root
        tasks:
          - name:  SELinux file context is set to defaults
            file:
              path: /home/devops/users.txt
              seuser: _default
              serole: _default
              setype: _default
              selevel: _default
    2. Use o comando ansible-playbook --syntax-check selinux_defaults.yml para verificar a sintaxe do playbook selinux_defaults.yml.

      [student@workstation file-manage]$ ansible-playbook --syntax-check \
      > selinux_defaults.yml
      playbook: selinux_defaults.yml
    3. Execute o playbook:

      [student@workstation file-manage]$ ansible-playbook selinux_defaults.yml
      PLAY [Using the file module to ensure SELinux file context] ************
      TASK [Gathering Facts] *************************************************
      ok: [serverb.lab.example.com]
      ok: [servera.lab.example.com]
      TASK [SELinux file context is set to defaults] *************************
      changed: [serverb.lab.example.com]
      changed: [servera.lab.example.com]
      PLAY RECAP *************************************************************
      servera.lab.example.com : ok=2    changed=1    unreachable=0    failed=0
      serverb.lab.example.com : ok=2    changed=1    unreachable=0    failed=0
    4. Use um comando ad hoc para executar o comando ls -Z como usuário devops para verificar os atributos do arquivo padrão de unconfined_u:object_r:user_home_t:s0.

      [student@workstation file-manage]$ ansible all -m command -a 'ls -Z' -u devops
      servera.lab.example.com | CHANGED | rc=0 >>
      unconfined_u:object_r:user_home_t:s0 users.txt
      serverb.lab.example.com | CHANGED | rc=0 >>
      unconfined_u:object_r:user_home_t:s0 users.txt
  4. Crie um playbook chamado add_line.yml no diretório de trabalho atual. Configure o playbook para usar o módulo lineinfile a fim de anexar a linha This line was added by the lineinfile module. ao arquivo /home/devops/users.txt em todos os hosts gerenciados.

    1. Crie o playbook add_line.yml:

      ---
      - name: Add text to an existing file
        hosts: all
        remote_user: devops
        tasks:
          - name: Add a single line of text to a file
            lineinfile:
              path: /home/devops/users.txt
              line: This line was added by the lineinfile module.
              state: present
    2. Use o comando ansible-playbook --syntax-check add_line.yml para verificar a sintaxe do playbook add_line.yml.

      [student@workstation file-manage]$ ansible-playbook --syntax-check add_line.yml
      playbook: add_line.yml
    3. Execute o playbook:

      [student@workstation file-manage]$ ansible-playbook add_line.yml
      PLAY [Add text to an existing file] ************************************
      TASK [Gathering Facts] *************************************************
      ok: [serverb.lab.example.com]
      ok: [servera.lab.example.com]
      TASK [Add a single line of text to a file] *****************************
      changed: [servera.lab.example.com]
      changed: [serverb.lab.example.com]
      PLAY RECAP *************************************************************
      servera.lab.example.com : ok=2    changed=1    unreachable=0    failed=0
      serverb.lab.example.com : ok=2    changed=1    unreachable=0    failed=0
    4. Como usuário devops, use o módulo command com a opção cat para verificar o conteúdo do arquivo users.txt nos hosts gerenciados.

      [student@workstation file-manage]$ ansible all -m command \
      > -a 'cat users.txt' -u devops
      serverb.lab.example.com | CHANGED | rc=0 >>
      This line was added by the lineinfile module.
      servera.lab.example.com | CHANGED | rc=0 >>
      This line was added by the lineinfile module.
  5. Crie um playbook chamado add_block.yml no diretório de trabalho atual. Configure o playbook para usar o módulo blockinfile a fim de acrescentar o seguinte bloco de texto ao arquivo /home/devops/users.txt em todos os hosts gerenciados.

    This block of text consists of two lines.
    They have been added by the blockinfile module.
    1. Crie o playbook add_block.yml:

      ---
      - name: Add block of text to a file
        hosts: all
        remote_user: devops
        tasks:
          - name: Add a block of text to an existing file
            blockinfile:
              path: /home/devops/users.txt
              block: |
                This block of text consists of two lines.
                They have been added by the blockinfile module.
              state: present
    2. Use o comando ansible-playbook --syntax-check add_block.yml para verificar a sintaxe do playbook add_block.yml.

      [student@workstation file-manage]$ ansible-playbook --syntax-check add_block.yml
      playbook: add_block.yml
    3. Execute o playbook:

      [student@workstation file-manage]$ ansible-playbook add_block.yml
      PLAY [Add block of text to a file] ****************************************
      TASK [Gathering Facts] ****************************************************
      ok: [serverb.lab.example.com]
      ok: [servera.lab.example.com]
      TASK [Add a block of text to an existing file] ****************************
      changed: [servera.lab.example.com]
      changed: [serverb.lab.example.com]
      PLAY RECAP ****************************************************************
      servera.lab.example.com    : ok=2    changed=1    unreachable=0    failed=0
      serverb.lab.example.com    : ok=2    changed=1    unreachable=0    failed=0
    4. Use o módulo command com o comando cat para verificar o conteúdo correto do arquivo /home/devops/users.txt no host gerenciado.

      [student@workstation file-manage]$ ansible all -m command \
      > -a 'cat users.txt' -u devops
      serverb.lab.example.com | CHANGED | rc=0 >>
      This line was added by the lineinfile module.
      # BEGIN ANSIBLE MANAGED BLOCK
      This block of text consists of two lines.
      They have been added by the blockinfile module.
      # END ANSIBLE MANAGED BLOCK
      servera.lab.example.com | CHANGED | rc=0 >>
      This line was added by the lineinfile module.
      # BEGIN ANSIBLE MANAGED BLOCK
      This block of text consists of two lines.
      They have been added by the blockinfile module.
      # END ANSIBLE MANAGED BLOCK
  6. Crie um playbook chamado remove_file.yml no diretório de trabalho atual. Configure o playbook para usar o módulo file a fim de remover o arquivo /home/devops/users.txt de todos os hosts gerenciados.

    1. Crie o playbook remove_file.yml:

      ---
      - name: Use the file module to remove a file
        hosts: all
        remote_user: devops
        tasks:
          - name: Remove a file from managed hosts
            file:
              path: /home/devops/users.txt
              state: absent
    2. Use o comando ansible-playbook --syntax-check remove_file.yml para verificar a sintaxe do playbook remove_file.yml.

      [student@workstation file-manage]$ ansible-playbook --syntax-check remove_file.yml
      playbook: remove_file.yml
    3. Execute o playbook:

      [student@workstation file-manage]$ ansible-playbook remove_file.yml
      PLAY [Use the file module to remove a file] *******************************
      TASK [Gathering Facts] ****************************************************
      ok: [serverb.lab.example.com]
      ok: [servera.lab.example.com]
      TASK [Remove a file from managed hosts] ***********************************
      changed: [serverb.lab.example.com]
      changed: [servera.lab.example.com]
      PLAY RECAP ****************************************************************
      servera.lab.example.com    : ok=2    changed=1    unreachable=0    failed=0
      serverb.lab.example.com    : ok=2    changed=1    unreachable=0    failed=0
    4. Use um comando ad hoc para executar o comando ls -l para confirmar se o arquivo users.txt não existe mais nos hosts gerenciados.

      [student@workstation file-manage]$ ansible all -m command -a 'ls -l'
      serverb.lab.example.com | CHANGED | rc=0 >>
      total 0
      servera.lab.example.com | CHANGED | rc=0 >>
      total 0

Encerramento

Na workstation, execute o script lab file-manage finish para limpar este exercício.

[student@workstation ~]$ lab file-manage finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Objetivos

Depois de concluir esta seção, os alunos deverão ser capazes de usar templates Jinja2 para implantar arquivos personalizados em hosts gerenciados. Transformação de arquivos em templates

O RedHat Ansible Engine tem vários módulos que podem ser usados para modificar os arquivos existentes. Eles incluem lineinfile e blockinfile, entre outros. No entanto, nem sempre são fáceis de usar de forma eficaz e correta.

Uma maneira muito mais poderosa de gerenciar arquivos é transformá-los em template. Com esse método, você pode gravar um template do arquivo de configuração, que é personalizado automaticamente para o host gerenciado quando o arquivo é implantado, usando variáveis e fatos Ansible. Esse método pode ser mais fácil de controlar e é menos propenso a erros. Introdução ao Jinja2

O Ansible usa o sistema de templates Jinja2 para arquivos de template. O Ansible também usa a sintaxe Jinja2 para fazer referência a variáveis nos playbooks, então você já sabe um pouco sobre como usá-la.

Uso de delimitadores

As variáveis e expressões lógicas são colocadas entre tags ou delimitadores. Por exemplo, os templates Jinja2 usam {%EXPR%} para expressões ou lógica (por exemplo, loops), enquanto {{EXPR}} são usados para a saída de resultados de uma expressão ou uma variável para o usuário final. A última tag, quando renderizada, é substituída por um valor ou por valores e é vista pelo usuário final. Use a sintaxe para incluir comentários que não devem aparecer no arquivo final.

No exemplo a seguir, a primeira linha inclui um comentário que não será incluído no arquivo final. As referências a variáveis na segunda linha são substituídas pelos valores dos fatos do sistema que estão sendo referenciados.

{​# /etc/hosts line #​} {{ ansible_facts['default_ipv4']['address'] }} {{ ansible_facts['hostname'] }}

Gerar um template Jinja2

Um template Jinja2 é composto de diversos elementos: dados, variáveis e expressões. Essas variáveis e expressões são substituídas por seus valores quando o template Jinja2 é renderizado. As variáveis usadas no template podem ser especificadas na seção vars do playbook. É possível usar fatos de hosts gerenciados como variáveis em um modelo.

Lembre-se de que os fatos associados a um host gerenciado podem ser obtidos com o comando ansible system_hostname -i inventory_file -m setup.

O exemplo a seguir mostrar como criar um template para /etc/ssh/sshd_config com variáveis e fatos recuperados de hosts gerenciados pelo Ansible. Quando o playbook associado for executado, os fatos serão substituídos por seus valores no host gerenciado que está sendo configurado.

Um arquivo que contém um template Jinja2 não precisa ter uma extensão de arquivo específica (por exemplo, .j2). No entanto, fornecer essa extensão pode facilitar a memorização de que se trata de um template de arquivo.

{{ ansible_managed }}

DO NOT MAKE LOCAL MODIFICATIONS TO THIS FILE AS THEY WILL BE LOST

Port {{ ssh_port }} ListenAddress {{ ansible_facts['default_ipv4']['address'] }}

HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ed25519_key

SyslogFacility AUTHPRIV

PermitRootLogin {{ root_allowed }} AllowGroups {{ groups_allowed }}

AuthorizedKeysFile /etc/.rht_authorized_keys .ssh/authorized_keys

PasswordAuthentication {{ passwords_allowed }}

ChallengeResponseAuthentication no

GSSAPIAuthentication yes GSSAPICleanupCredentials no

UsePAM yes

X11Forwarding yes UsePrivilegeSeparation sandbox

AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE AcceptEnv XMODIFIERS

Subsystem sftp /usr/libexec/openssh/sftp-server

Implantação de templates Jinja2

Os templates Jinja2 são uma excelente ferramenta para personalizar arquivos de configuração que serão implantados em hosts gerenciados. Quando o template Jinja2 de um arquivo de configuração tiver sido criado, ele poderá ser implantado nos hosts gerenciados usando o módulo template, que permite a transferência de um arquivo local do nó de controle para os hosts gerenciados.

Para usar o módulo template, utilize a sintaxe a seguir. O valor associado à chave src especifica o template Jinja2 de origem, e o valor associado à chave dest especifica o arquivo a ser criado nos hosts de destino.

tasks:

O módulo template também permite que você especifique o proprietário (o usuário que é proprietário do arquivo), o grupo, as permissões e o contexto do SELinux do arquivo implantado, assim como o módulo file. Também é possível usar a opção validate para executar um comando arbitrário (como visudo -c) para verificar se a sintaxe de um arquivo está correta antes de copiá-lo.

Para obter mais detalhes, consulte ansible-doc template. Gerenciamento de arquivos transformados em templates

Para evitar que os administradores de sistema modifiquem os arquivos implantados pelo Ansible, é recomendável incluir um comentário na parte superior do template para indicar que o arquivo não deve ser editado manualmente.

Uma maneira de fazer isso é usar a string Ansible managed definida na diretiva ansible_managed. Ela não é uma variável normal, mas pode ser usada como uma em um template. A diretiva ansible_managed é definida no arquivo ansible.cfg:

ansible_managed = Ansible managed

Para incluir a variável ansible_managed em um template Jinja2, use a seguinte sintaxe:

{{ ansible_managed }}

Estruturas de controle

Você pode usar estruturas de controle do Jinja2 em templates de arquivos para reduzir a digitação repetitiva, inserir entradas para cada host em uma ação de forma dinâmica ou inserir um texto condicionalmente em um arquivo.

Uso de loops

O Jinja2 usa a instrução for para criar o recurso de looping. No exemplo a seguir, a variável user é substituída por todos os valores incluídos na variável users, sendo um valor por linha.

{% for user in users %} {{ user }} {% endfor %}

O exemplo de template a seguir usa a instrução for para executar todos os valores na variável users, substituindo myuser por cada valor, exceto quando o valor for root.

{​# for statement #​} {% for myuser in users if not myuser == "root" %} User number {{ loop.index }} - {{ myuser }} {% endfor %}

A variável loop.index vai até o número de índice em que o loop se encontra atualmente. Ele tem o valor 1 na primeira vez em que é executado e incrementa em 1 a cada nova iteração.

Em outro exemplo, este template também usa a instrução for e presume que a variável myhosts tenha sido definida no arquivo de inventário que está sendo utilizado. Essa variável deve conter uma lista dos hosts a serem gerenciados. Com a instrução for a seguir, todos os hosts do grupo myhosts do inventário serão listados no arquivo.

{% for myhost in groups['myhosts'] %} {{ myhost }} {% endfor %}

Para ver um exemplo mais prático, você pode usar isso para gerar um arquivo /etc/hosts a partir dos fatos do host de maneira dinâmica. Imagine que você tem este playbook:

O template templates/hosts.j2 de três linhas a seguir constrói o arquivo com todos os hosts do grupo all. (A linha do meio é extremamente longa no template devido ao comprimento dos nomes das variáveis). Ele itera em cada host do grupo para obter três fatos para o arquivo /etc/hosts.

{% for host in groups['all'] %} {{ hostvars['host']['ansible_facts']['default_ipv4']['address'] }} {{ hostvars['host']['ansible_facts']['fqdn'] }} {{ hostvars['host']['ansible_facts']['hostname'] }} {% endfor %}

Uso de condicionais

O Jinja2 usa a instrução if para proporcionar controle de condicionais. Isso permite que você coloque uma linha em um arquivo implantado se determinadas condições forem atendidas.

No exemplo a seguir, o valor da variável result será incluído no arquivo implantado somente se o valor da variável finished for True.

{% if finished %} {{ result }} {% endif %}

Você pode usar loops e condicionais do Jinja2 em templates do Ansible, mas não em playbooks do Ansible. Filtros de variáveis

O Jinja2 oferece filtros que alteram o formato de saída para expressões do template (por exemplo, para JSON). Existem filtros disponíveis para as linguagens, como YAML e JSON. O filtro to_json formata a saída da expressão usando JSON, e o filtro to_yaml formata a saída da expressão usando YAML.

{{ output | to_json }} {{ output | to_yaml }}

Filtros adicionais estão disponíveis, como os filtros to_nice_json e to_nice_yaml, que formatam a saída da expressão em formato legível tanto JSON quanto YAML.

{{ output | to_nice_json }} {{ output | to_nice_yaml }}

Os filtros from_json e from_yaml esperam strings em formato JSON ou YAML, respectivamente, para analisá-las.

{{ output | from_json }} {{ output | from_yaml }}

Testes de variáveis

As expressões usadas com cláusulas when nos playbooks do Ansible são expressões Jinja2. Os testes incorporados do Ansible usados para testar valores devolvidos incluem failed, changed, succeeded e skipped. A tarefa a seguir mostra como os testes podem ser usados dentro de expressões condicionais.

tasks: ...output omitted...

template - Templates a file out to a remote server — Ansible Documentation

Variables — Ansible Documentation

Filters — Ansible Documentation

britho commented 3 years ago

Neste exercício, você criará um arquivo de template simples que seu playbook usará para instalar um arquivo personalizado da Mensagem do Dia em cada host gerenciado.

Resultados

Você deverá ser capaz de:

Gerar um arquivo de modelo.

Usar o arquivo de template em um playbook. 

Faça login na workstation como student usando a senha student.

Na workstation, execute o comando lab file-template start. Esse script confirma se o Ansible está instalado na workstation, cria o diretório /home/student/file-template e faz o download do arquivo ansible.cfg nesse diretório.

[student@workstation ~]$ lab file-template start

Todos os arquivos usados durante este exercício estão disponíveis para referência na workstation no diretório /home/student/file-template/files.

Na workstation, navegue até o diretório de trabalho /home/student/file-template. Crie o arquivo inventory no diretório de trabalho atual. Esse arquivo configura dois grupos: webservers e workstations. Inclua o sistema servera.lab.example.com no grupo webservers e o sistema workstation.lab.example.com no grupo workstations.

[webservers]
servera.lab.example.com

[workstations]
workstation.lab.example.com

Crie um template para a Mensagem do Dia e a inclua no arquivo motd.j2 no diretório de trabalho atual. Inclua as seguintes variáveis e fatos no template:

    ansible_facts['fqdn'], para inserir o FQDN do host gerenciado.

    ansible_facts['distribution'] e ansible_facts['distribution_version'], para fornecer informações de distribuição.

    system_owner, para o e-mail do proprietário do sistema. Essa variável precisa ser definida com um valor adequado na seção vars do template do playbook. 

This is the system {{ ansible_facts['fqdn'] }}.
This is a {{ ansible_facts['distribution'] }} version {{ ansible_facts['distribution_version'] }} system.
Only use this system with permission.
You can request access from {{ system_owner }}.

Crie um arquivo de playbook chamado motd.yml no diretório de trabalho atual. Defina a variável system_owner na seção vars e inclua uma tarefa para o módulo template, que mapeia o template Jinja2 motd.j2 para o arquivo remoto /etc/motd nos hosts gerenciados. Defina o proprietário e o grupo como root e o modo como 0644.

---
- name: configure SOE
  hosts: all
  remote_user: devops
  become: true
  vars:
    - system_owner: clyde@example.com
  tasks:
    - name: configure /etc/motd
      template:
        src: motd.j2
        dest: /etc/motd
        owner: root
        group: root
        mode: 0644

Antes de executar o playbook, use o comando ansible-playbook --syntax-check para verificar a sintaxe. Se ela relatar algum erro, corrija-o antes de ir para a próxima etapa. Você verá uma saída semelhante à seguinte:

[student@workstation file-template]$ ansible-playbook --syntax-check motd.yml

playbook: motd.yml

Execute o playbook motd.yml.

[student@workstation file-template]$ ansible-playbook motd.yml
PLAY [all] ******************************************************************

TASK [Gathering Facts] ******************************************************
ok: [servera.lab.example.com]
ok: [workstation.lab.example.com]

TASK [template] *************************************************************
changed: [servera.lab.example.com]
changed: [workstation.lab.example.com]

PLAY RECAP ******************************************************************
servera.lab.example.com      : ok=2    changed=1    unreachable=0    failed=0
workstation.lab.example.com  : ok=2    changed=1    unreachable=0    failed=0

Faça login em servera.lab.example.com com o usuário devops para verificar se o MOTD é exibido corretamente após o login. Faça logout quando terminar.

[student@workstation file-template]$ ssh devops@servera.lab.example.com
This is the system servera.lab.example.com.
This is a RedHat version 8.0 system.
Only use this system with permission.
You can request access from clyde@example.com.
...output omitted...
[devops@servera ~]# exit
Connection to servera.lab.example.com closed.

Encerramento

Execute o comando lab file-template finish para limpar após o exercício.

[student@workstation ~]$ lab file-template finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Lista de verificação de desempenho

Neste laboratório, você executará um playbook para criar um arquivo personalizado em seus hosts gerenciados usando o template Jinja2.

Resultados

Você deverá ser capaz de:

Gerar um arquivo de modelo.

Usar o arquivo de template em um playbook. 

Faça login na workstation como student usando a senha student.

Na workstation, execute o comando lab file-review start. Isso confirma se o Ansible está instalado na workstation, cria o diretório /home/student/file-review e faz o download do arquivo ansible.cfg nesse diretório. Ele também faz o download dos arquivos motd.yml, motd.j2, issue e inventory para o diretório /home/student/file-review/files.

[student@workstation ~]$ lab file-review start

Todos os arquivos usados neste exercício estão disponíveis na workstation no diretório /home/student/file-review/files.

Crie um arquivo de inventário chamado inventory no diretório /home/student/file-review. Esse arquivo de inventário define o grupo servers, que tem o host gerenciado serverb.lab.example.com associado a ele.

    Em workstation, acesse o diretório /home/student/file-review.

    [student@workstation ~]$ cd ~/file-review/

    Crie o arquivo inventory no diretório atual. Esse arquivo configura um grupo chamado servers. Inclua o sistema serverb.lab.example.com no grupo servers.

    [servers]
    serverb.lab.example.com

Identifique os fatos do serverb.lab.example.com que mostram a quantidade total de memória do sistema e o número de processadores.

Use o módulo setup para obter uma lista de todos os fatos do host gerenciado serverb.lab.example.com. Os fatos ansible_processor_count e ansible_memtotal_mb apresentam informações sobre os limites de recursos do host gerenciado.

[student@workstation file-review]$ ansible serverb.lab.example.com -m setup serverb.lab.example.com | SUCCESS => { "ansible_facts": { ...output omitted... "ansible_processor_count": 1, ...output omitted... "ansible_memtotal_mb": 821, ...output omitted... }, "changed": false }

Crie um template para a Mensagem do Dia, chamado motd.j2, no diretório atual. Quando o usuário devops fizer login em serverb.lab.example.com, deverá ser exibida uma mensagem mostrando a memória total do sistema e a contagem dos processadores. Use os fatos ansible_facts['memtotal_mb'] e ansible_facts['processor_count'] para fornecer as informações de memória para a mensagem.

System total memory: {{ ansible_facts['memtotal_mb'] }} MiB. System processor count: {{ ansible_facts['processor_count'] }}

Crie um novo arquivo de playbook chamado motd.yml no diretório atual. Usando o módulo template, configure o arquivo de template do Jinja2 motd.j2 criado anteriormente para que seja mapeado para o arquivo /etc/motd nos hosts gerenciados. Esse arquivo tem o usuário root como proprietário e grupo, e suas permissões são 0644. Usando os módulos stat e debug, crie tarefas para verificar se /etc/motd existe nos hosts gerenciados e exibe as informações do arquivo para /etc/motd . Use o módulo copy para colocar files/issue no diretório /etc/ do host gerenciado e use a mesma propriedade e permissões do /etc/motd. Use o módulo file para garantir que /etc/issue.net é um link simbólico para /etc/issue no host gerenciado. Configure o playbook para que ele utilize o usuário devops e defina o parâmetro become como true.


Execute o playbook incluído no arquivo motd.yml.

Antes de executar o playbook, use o comando ansible-playbook --syntax-check para verificar sua sintaxe. Se ela relatar algum erro, corrija-o antes de ir para a próxima etapa. Você verá uma saída semelhante à seguinte:

[student@workstation file-review]$ ansible-playbook --syntax-check motd.yml

playbook: motd.yml

Execute o playbook incluído no arquivo motd.yml.

[student@workstation file-review]$ ansible-playbook motd.yml

PLAY [Configure system] ****************************************************

TASK [Gathering Facts] *****************************************************
ok: [serverb.lab.example.com]

TASK [Configure a custom /etc/motd] ****************************************
changed: [serverb.lab.example.com]

TASK [Check file exists] ***************************************************
ok: [serverb.lab.example.com]

TASK [Display stat results] ************************************************
ok: [serverb.lab.example.com] => {
    "motd": {
        "changed": false,
        "failed": false,
...output omitted...

TASK [Copy custom /etc/issue file] *****************************************
changed: [serverb.lab.example.com]

TASK [Ensure /etc/issue.net is a symlink to /etc/issue] ********************
changed: [serverb.lab.example.com]

PLAY RECAP *****************************************************************
serverb.lab.example.com    : ok=6    changed=3    unreachable=0    failed=0

Verifique se o playbook incluído no arquivo motd.yml foi executado corretamente.

Faça login em serverb.lab.example.com com o usuário devops e verifique se o conteúdo de /etc/motd e /etc/issue é exibido ao fazer login. Faça logout quando terminar.

[student@workstation file-review]$ ssh devops@serverb.lab.example.com ------------------------------- PRIVATE SYSTEM -----------------------------

Last login: Thu Apr 25 22:09:33 2019 from 172.25.250.9 [devops@serverb ~]$ logout

Avaliação

Na workstation, execute o script lab file-review grade para confirmar a conclusão com êxito deste exercício.

[student@workstation ~]$ lab file-review grade

Encerramento

Na workstation, execute o script lab file-review finish para limpar o laboratório.

[student@workstation ~]$ lab file-review finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Neste capítulo, você aprendeu que:

A biblioteca de módulos Files inclui módulos que permitem realizar a maioria das tarefas relacionadas ao gerenciamento de arquivos, como criar, copiar, editar e modificar permissões e outros atributos de arquivos.

Você pode usar templates Jinja2 para construir dinamicamente arquivos para implantação.

Geralmente, um template Jinja2 é composto por dois elementos: variáveis e expressões. Essas variáveis e expressões são substituídas por valores quando o template Jinja2 é renderizado.

Os filtros do Jinja2 transformam expressões do template de um tipo ou formato de dados para outro.