britho / Ansible-HedHat

0 stars 0 forks source link

Aula-10 #7

Open britho opened 3 years ago

britho commented 3 years ago

Meta | Automatizar tarefas comuns de administração de sistemas Linux com o Ansible. -- | -- Objetivos | Registrar sistemas, configurar canais e repositórios de software e gerenciar pacotes RPM em hosts gerenciados. Gerenciar usuários e grupos do Linux, configurar SSH e modificar a configuração do Sudo em hosts gerenciados. Gerenciar a inicialização de serviços, agendar processos com at, cron e systemd, reinicializar e controlar o destino de inicialização padrão em hosts gerenciados. Particionar dispositivos de armazenamento, configurar o LVM, formatar partições ou volumes lógicos, montar sistemas de arquivos e adicionar arquivos ou espaços de troca. Seções | Gerenciamento de software e subscrições (exercício orientado) Gerenciamento de usuários e autenticação (exercício orientado) Gerenciamento do processo de inicialização e dos processos agendados (exercício orientado) Gerenciamento de armazenamento (exercício orientado) Gerenciamento da configuração de rede (exercício orientado) Laboratório | Automatização de tarefas de administração do Linux

Objetivos

Depois de concluir esta seção, você deverá ser capaz de subscrever sistemas, configurar canais e repositórios de software e gerenciar pacotes RPM em hosts gerenciados.

Gerenciamento de pacotes com o Ansible

O módulo yum do Ansible usa o Yum Package Manager nos hosts gerenciados para processar as operações de pacote. O exemplo a seguir é um playbook que instala o pacote httpd no host gerenciado servera.lab.example.com.

---
- name: Install the required packages on the web server
  hosts: servera.lab.example.com
  tasks:
    - name: Install the httpd packages
      yum:
        name: httpd    1
        state: present 2
  | A palavra-chave name fornece o nome do pacote a ser instalado. -- | --   | A palavra-chave state indica o estado esperado do pacote no host gerenciado:presentO Ansible instala o pacote, caso ele ainda não esteja instalado.absentO Ansible remove o pacote se ele estiver instalado.latestO Ansible atualiza o pacote se ele ainda não estiver na versão disponível mais recente. Se o pacote não estiver instalado, o Ansible fará a instalação.

A tabela a seguir compara o uso do módulo yum do Ansible com o comando yum equivalente.

Tarefa do Ansible | Comando Yum -- | -- - name: Install httpd yum: name: httpd state: present | yum install httpd - name: Install or update httpd yum: name: httpd state: latest | yum update httpd ou yum install httpd se o pacote ainda não estiver instalado. - name: Update all packages yum: name: '*' state: latest | yum update - name: Remove httpd yum: name: httpd state: absent | yum remove httpd - name: Install Development Tools yum: name: '@Development Tools' state: present Com o módulo yum do Ansible, você deve prefixar os nomes dos grupos com @. Lembre-se de que você pode recuperar a lista de grupos com o comando yum group list. |   | Com o módulo yum do Ansible, você deve prefixar os nomes dos grupos com @. Lembre-se de que você pode recuperar a lista de grupos com o comando yum group list. | yum group install "Development Tools"   | Com o módulo yum do Ansible, você deve prefixar os nomes dos grupos com @. Lembre-se de que você pode recuperar a lista de grupos com o comando yum group list. - name: Remove Development Tools yum: name: '@Development Tools' state: absent | yum group remove "Development Tools" - name: Inst perl AppStream module yum: name: '@perl:5.26/minimal' state: present Para gerenciar um módulo Yum do AppStream, prefixe o nome com @. A sintaxe é a mesma do comando yum. Por exemplo, você pode omitir a parte do perfil para usar o perfil padrão: @perl:5.26. Lembre-se de que você pode listar os módulos Yum do AppStream disponíveis com o comando yum module list. |   | Para gerenciar um módulo Yum do AppStream, prefixe o nome com @. A sintaxe é a mesma do comando yum. Por exemplo, você pode omitir a parte do perfil para usar o perfil padrão: @perl:5.26. Lembre-se de que você pode listar os módulos Yum do AppStream disponíveis com o comando yum module list. | yum module install perl:5.26/minimal   | Para gerenciar um módulo Yum do AppStream, prefixe o nome com @. A sintaxe é a mesma do comando yum. Por exemplo, você pode omitir a parte do perfil para usar o perfil padrão: @perl:5.26. Lembre-se de que você pode listar os módulos Yum do AppStream disponíveis com o comando yum module list.

Execute o comando ansible-doc yum para obter mais parâmetros e exemplos de playbooks.

Otimização da instalação de vários pacotes

Para operar em vários pacotes, a palavra-chave name aceita uma lista. O exemplo a seguir mostra um playbook que instala três pacotes em servera.lab.example.com.

---
- name: Install the required packages on the web server
  hosts: servera.lab.example.com
  tasks:
    - name: Install the packages
      yum:
        name:
          - httpd
          - mod_ssl
          - httpd-tools
        state: present

Com essa sintaxe, o Ansible instala os pacotes em uma única transação do Yum. Isso é equivalente a executar o comando yum install httpd mod_ssl httpd-tools.

Uma versão comumente vista, mas menos eficiente e mais lenta, dessa tarefa é usar um loop.

---
- name: Install the required packages on the web server
  hosts: servera.lab.example.com
  tasks:
    - name: Install the packages
      yum:
        name: "{{ item }}""
        state: present
      loop:
        - httpd
        - mod_ssl
        - httpd-tools

Evite usar esse método, pois ele exige que o módulo realize três transações individuais, uma para cada pacote.

Coleta de fatos sobre os pacotes instalados

O módulo package_facts do Ansible coleta os detalhes dos pacotes instalados em hosts gerenciados. Ele define a variável ansible_facts.packages com os detalhes do pacote.

O playbook a seguir chama o módulo package_facts, o módulo debug para exibir o conteúdo da variável ansible_facts.packages e o módulo debug novamente para visualizar a versão do pacote NetworkManager instalado.

---
- name: Display installed packages
  hosts: servera.lab.example.com
  tasks:
    - name: Gather info on installed packages
      package_facts:
        manager: auto
    - name: List installed packages
      debug:
        var: ansible_facts.packages
    - name: Display NetworkManager version
      debug:
        msg: "Version {{ansible_facts.packages['NetworkManager'][0].version}}"
      when: "'NetworkManager' in ansible_facts.packages"

Quando executado, o playbook exibe a lista de pacotes e a versão do pacote NetworkManager:

[user@controlnode ~]$ ansible-playbook lspackages.yml
PLAY [Display installed packages] ******************************************
TASK [Gathering Facts] *****************************************************
ok: [servera.lab.example.com]
TASK [Gather info on installed packages] ***********************************
ok: [servera.lab.example.com]
TASK [List installed packages] *********************************************
ok: [servera.lab.example.com] => {
    "ansible_facts.packages": {
        "NetworkManager": [
            {
                "arch": "x86_64",
                "epoch": 1,
                "name": "NetworkManager",
                "release": "14.el8",
                "source": "rpm",
                "version": "1.14.0"
            }
        ],
...output omitted...
        "zlib": [
            {
                "arch": "x86_64",
                "epoch": null,
                "name": "zlib",
                "release": "10.el8",
                "source": "rpm",
                "version": "1.2.11"
            }
        ]
    }
}
TASK [Display NetworkManager version] **************************************
ok: [servera.lab.example.com] => {
    "msg": "Version 1.14.0"
}
PLAY RECAP *****************************************************************
servera.lab.example.com    : ok=4    changed=0    unreachable=0    failed=0

Revisão de módulos alternativos para gerenciar pacotes

O módulo yum do Ansible funciona em hosts gerenciados que estão usando o Yum Package Manager. Para outros gerenciadores de pacotes, o Ansible geralmente fornece um módulo dedicado. Por exemplo, o módulo dnf gerencia pacotes em sistemas operacionais como o Fedora usando o gerenciador de pacotes DNF. O módulo apt usa a ferramenta de pacotes APT disponível no Debian ou no Ubuntu. O módulo win_package pode instalar software em sistemas Microsoft Windows.

O playbook a seguir usa condicionais para selecionar o módulo apropriado em um ambiente composto por sistemas Red Hat Enterprise Linux e Fedora.

---
- name: Install the required packages on the web servers
  hosts: webservers
  tasks:
    - name: Install httpd on RHEL
      yum:
        name: httpd
        state: present
      when: "ansible_distribution == 'RedHat'"
    - name: Install httpd on Fedora
      dnf:
        name: httpd
        state: present
      when: "ansible_distribution == 'Fedora'"

Como alternativa, o módulo genérico package detecta automaticamente e usa o gerenciador de pacotes disponível nos hosts gerenciados. Com o módulo package, você pode reescrever o playbook anterior da forma a seguir.

---
- name: Install the required packages on the web servers
  hosts: webservers
  tasks:
    - name: Install httpd
      package:
        name: httpd
        state: present

No entanto, observe que o módulo package não é compatível com todos os recursos que os módulos mais especializados oferecem. Além disso, os sistemas operacionais geralmente têm nomes diferentes para os pacotes que eles fornecem. Por exemplo, o pacote que instala o Apache HTTP Server é httpd no Red Hat Enterprise Linux e apache2 no Ubuntu. Nessa situação, você ainda precisa de uma condicional para selecionar o nome do pacote correto, dependendo do sistema operacional do host gerenciado.

Registro e gerenciamento de sistemas com o Red Hat Subscription Management

Para habilitar seus novos sistemas Red Hat Enterprise Linux para subscrições de produtos, o Ansible fornece os módulos redhat_subscription e rhsm_repository. Esses módulos interagem com a ferramenta do Red Hat Subscription Manager nos hosts gerenciados.

Registro e subscrição de novos sistemas

As duas primeiras tarefas que você normalmente executa com a ferramenta do Red Hat Subscription Management é registrar o novo sistema e anexar uma subscrição disponível.

Sem o Ansible, essas tarefas são realizadas com o comando subscription-manager:

[user@host ~]$ subscription-manager register --username=yourusername \
> --password=yourpassword
[user@host ~]$ subscription-manager attach --pool=poolID

Lembre-se de que você lista os pools disponíveis em sua conta com o comando subscription-manager list --available.

O módulo redhat_subscription do Ansible realiza o registro e a subscrição em uma tarefa.

- name: Register and subscribe the system
  redhat_subscription:
    username: yourusername
    password: yourpassword
    pool_ids: poolID
    state: present

Uma palavra-chave state definida como present indica que o sistema deve ser registrado e subscrito. Quando estiver definida como absent, o módulo cancelará o registro do sistema.

Ativação dos repositórios de software da Red Hat

A próxima tarefa após a subscrição é ativar os repositórios de software da Red Hat no novo sistema.

Sem o Ansible, você normalmente executa o comando subscription-manager para essa finalidade:

[user@host ~]$ subscription-manager repos \
> --enable "rhel-8-for-x86_64-baseos-rpms" \
> --enable "rhel-8-for-x86_64-baseos-debug-rpms"
 

Lembre-se de que você pode listar os repositórios disponíveis com o comando subscription-manager repos --list.

Com o Ansible, use o módulo rhsm_repository:

- name: Enable Red Hat repositories
  rhsm_repository:
    name:
      - rhel-8-for-x86_64-baseos-rpms
      - rhel-8-for-x86_64-baseos-debug-rpms
    state: present

Configuração de um repositório yum

Para ativar o suporte para um repositório de terceiros em um host gerenciado, o Ansible fornece o módulo yum_repository.

Declaração de um repositório yum

Quando executado, o playbook a seguir declara um novo repositório em servera.lab.example.com.

---
- name: Configure the company Yum repositories
  hosts: servera.lab.example.com
  tasks:
    - name: Ensure Example Repo exists
      yum_repository:
        file: example   1
        name: example-internal
        description: Example Inc. Internal YUM repo
        baseurl: http://materials.example.com/yum/repository/
        enabled: yes
        gpgcheck: yes   2
        state: present  3
  | A palavra-chave file fornece o nome do arquivo a ser criado no diretório /etc/yum.repos.d/. O módulo adiciona automaticamente a extensão .repo a esse nome. -- | --   | Normalmente, os provedores de software assinam digitalmente os pacotes RPM usando chaves GPG. Ao definir a palavra-chave gpgcheck como yes, o sistema RPM verifica a integridade do pacote confirmando se o pacote foi assinado pela chave GPG apropriada. Ele se recusará a instalar um pacote se a assinatura GPG não corresponder. Use o módulo rpm_key do Ansible, descrito posteriormente, para instalar a chave pública GPG necessária.   | Quando você define a palavra-chave state como present, o Ansible cria ou atualiza o arquivo .repo. Quando state está definido como absent, o Ansible exclui o arquivo.

O arquivo /etc/yum.repos.d/example.repo resultante em servera.lab.example.com é o seguinte.

[example-internal]
baseurl = http://materials.example.com/yum/repository/
enabled = 1
gpgcheck = 1
name = Example Inc. Internal YUM repo

O módulo yum_repository expõe a maioria dos parâmetros de configuração do repositório Yum como palavras-chave. Execute o comando ansible-doc yum_repository para obter mais parâmetros e exemplos de playbooks.

Alguns repositórios de terceiros fornecem o arquivo de configuração e a chave pública GPG como parte de um pacote RPM, que pode ser baixado e instalado usando o comando yum install. Por exemplo, o projeto Extra Packages for Enterprise Linux (EPEL) fornece o pacote https://dl.fedoraproject.org/pub/epel/epel-release-latest-VER.noarch.rpm que implanta o arquivo de configuração /etc/yum.repos.d/epel.repo. Para esse repositório, use o módulo yum do Ansible para instalar o pacote EPEL em vez do módulo yum_repository.

Importação de uma chave GPG do RPM

Quando a palavra-chave gpgcheck está definida como yes no módulo yum_repository, você também precisa instalar a chave GPG no host gerenciado. O módulo rpm_key no exemplo a seguir implanta em servera.lab.example.com a chave pública GPG hospedada em um servidor web remoto.

---
- name: Configure the company Yum repositories
  hosts: servera.lab.example.com
  tasks:
    - name: Deploy the GPG public key
      rpm_key:
        key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
        state: present
    - name: Ensure Example Repo exists
      yum_repository:
        file: example
        name: example-internal
        description: Example Inc. Internal YUM repo
        baseurl: http://materials.example.com/yum/repository/
        enabled: yes
        gpgcheck: yes
        state: present
britho commented 3 years ago

Neste exercício você configurará um novo repositório Yum e instalará pacotes dele nos seus hosts gerenciados.

Resultados

Você deverá ser capaz de:

  • Configurar um repositório yum usando o módulo yum_repository.

  • Gerenciar chaves GPG do RPM usando o módulo rpm_key.

  • Obter informações sobre os pacotes instalados em um host usando o módulo package_facts.

Na workstation, execute o script de início do laboratório para confirmar se o ambiente está pronto para que o laboratório comece. O script cria o diretório de trabalho, chamado de system-software, e o preenche com um arquivo de configuração do Ansible, um inventário de host e arquivos de laboratório.

[student@workstation ~]$ lab system-software start

Visão geral do cenário

Sua organização exige que todos os hosts tenham o pacote example-motd instalado. Esse pacote é fornecido por um repositório Yum interno mantido pela sua organização para hospedar pacotes de software desenvolvidos internamente.

Você está encarregado de escrever um playbook para garantir que o pacote example-motd está instalado no host remoto. O playbook deve garantir a configuração do repositório Yum interno.

O repositório está localizado em http://materials.example.com/yum/repository. Todos os pacotes do RPM são assinados com um par de chaves GPG organizacional. A chave pública GPG está disponível em http://materials.example.com/yum/repository/RPM-GPG-KEY-example.

  1. Na workstation, como o usuário student, acesse o diretório de trabalho /home/student/system-software.

    [student@workstation ~]$ cd ~/system-software
    [student@workstation system-software]$ 
  2. Comece a escrever o playbook repo_playbook.yml. Defina uma única ação no playbook que tenha como destino todos os hosts. Adicione uma cláusula vars que defina uma única variável custom_pkg com um valor de example-motd. Adicione a cláusula tasks ao playbook.

    O playbook agora contém:

    ---
    - name: Repository Configuration
      hosts: all
      vars:
        custom_pkg: example-motd
      tasks:
  3. Adicione duas tarefas ao playbook.

    Use o módulo package_facts na primeira tarefa para reunir informações sobre os pacotes instalados no host remoto. Essa tarefa preenche o fato ansible_facts.packages.

    Use o módulo debug na segunda tarefa para imprimir a versão instalada do pacote referenciado pela variável custom_pkg. Só execute essa tarefa se o pacote personalizado for encontrado no fato ansible_facts.packages.

    Execute o playbook repo_playbook.yml.

    1. Adicione a primeira tarefa ao playbook. Configure a palavra-chave manager do módulo package_facts com um valor de auto. A primeira tarefa contém o seguinte:

          - name: Gather Package Facts
            package_facts:
              manager: auto
    2. Adicione uma segunda tarefa ao playbook que usa o módulo debug para exibir o valor da variável ansible_facts.packages[custom_pkg]. Adicione uma cláusula when à tarefa para verificar se o valor da variável custom_pkg está contida na variável ansible_facts.packages. A segunda tarefa contém o seguinte:

          - name: Show Package Facts for the custom package
            debug:
              var: ansible_facts.packages[custom_pkg]
            when: custom_pkg in ansible_facts.packages
    3. Execute o playbook:

      [student@workstation system-software]$ ansible-playbook repo_playbook.yml
      PLAY [Repository Configuration] **********************************************
      TASK [Gathering Facts] *******************************************************
      ok: [servera.lab.example.com]
      TASK [Gather Package Facts] **************************************************
      ok: [servera.lab.example.com]
      TASK [Show Package Facts for the custom package] *****************************
      skipping: [servera.lab.example.com]
      PLAY RECAP *******************************************************************
      servera.lab.example.com    : ok=2    changed=0    unreachable=0    failed=0    
      skipped=1    rescued=0    ignored=0

      A tarefa de depuração é ignorada porque o pacote example-motd não está instalado no host remoto.

  4. Adicione uma terceira tarefa que usa o módulo yum_repository para garantir a configuração do repositório yum interno no host remoto. Certifique-se de que:

    • A configuração do repositório está armazenada no arquivo /etc/yum.repos.d/example.repo

    • A ID do repositório é example-internal

    • O URL de base é http://materials.example.com/yum/repository

    • O repositório está configurado para verificar as assinaturas GPG do RPM

    • A descrição do repositório é Example Inc. Internal YUM repo

    A terceira tarefa contém o seguinte:

        - name: Ensure Example Repo exists
          yum_repository:
            name: example-internal
            description: Example Inc. Internal YUM repo
            file: example
            baseurl: http://materials.example.com/yum/repository/
            gpgcheck: yes
  5. Adicione uma quarta tarefa à ação que use o módulo rpm_key para garantir que a chave pública do repositório esteja presente no host remoto. O URL da chave pública do repositório é http://materials.example.com/yum/repository/RPM-GPG-KEY-example.

    A quarta tarefa aparece conforme segue:

        - name: Ensure Repo RPM Key is Installed
          rpm_key:
            key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
            state: present
  6. Adicione uma quinta tarefa para garantir que o pacote referenciado pela variável custom_pkg está instalado no host remoto.

    A quinta tarefa aparece conforme segue:

        - name: Install Example motd package
          yum:
            name: "{{ custom_pkg }}"
            state: present
  7. O fato ansible_facts.packages não é atualizado quando um novo pacote é instalado em um host remoto.

    Copie a segunda tarefa e adicione-a como a sexta tarefa da ação. Execute o playbook e verifique se o fato ansible_facts.packages não contém informações sobre o example-motd instalado no host remoto.

    1. A sexta tarefa contém uma cópia da segunda tarefa:

          - name: Show Package Facts for the custom package
            debug:
              var: ansible_facts.packages[custom_pkg]
            when: custom_pkg in ansible_facts.packages

      Agora, todo o playbook aparecerá conforme segue:

      ---
      - name: Repository Configuration
        hosts: all
        vars:
          custom_pkg: example-motd
        tasks:
          - name: Gather Package Facts
            package_facts:
              manager: auto
          - name: Show Package Facts for the custom package
            debug:
              var: ansible_facts.packages[custom_pkg]
            when: custom_pkg in ansible_facts.packages
          - name: Ensure Example Repo exists
            yum_repository:
              name: example-internal
              description: Example Inc. Internal YUM repo
              file: example
              baseurl: http://materials.example.com/yum/repository/
              gpgcheck: yes
          - name: Ensure Repo RPM Key is Installed
            rpm_key:
              key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
              state: present
          - name: Install Example motd package
            yum:
              name: "{{ custom_pkg }}"
              state: present
          - name: Show Package Facts for the custom package
            debug:
              var: ansible_facts.packages[custom_pkg]
            when: custom_pkg in ansible_facts.packages
    2. Execute o playbook.

      [student@workstation system-software]$ ansible-playbook repo_playbook.yml
      PLAY [Repository Configuration] **********************************************
      TASK [Gathering Facts] *******************************************************
      ok: [servera.lab.example.com]
      TASK [Gather Package Facts] **************************************************
      ok: [servera.lab.example.com]1
      TASK [Show Package Facts for the custom package] *****************************
      skipping: [servera.lab.example.com]
      TASK [Ensure Example Repo exists] ********************************************
      changed: [servera.lab.example.com]
      TASK [Ensure Repo RPM Key is Installed] **************************************
      changed: [servera.lab.example.com]
      TASK [Install Example motd package] ******************************************
      changed: [servera.lab.example.com]
      TASK [Show Package Facts for the custom package] *****************************
      skipping: [servera.lab.example.com]2
      PLAY RECAP *******************************************************************
      servera.lab.example.com    : ok=5    changed=3    unreachable=0    failed=0    
      skipped=2    rescued=0    ignored=0
        | A tarefa Gather Package Facts determina os dados contidos no fato ansible_facts.packages. -- | --   | A tarefa é ignorada porque o pacote example-motd é instalado após a tarefa Gather Package Facts.
  8. Insira uma tarefa imediatamente após a tarefa Install Example motd package usando o módulo package_facts para atualizar os fatos do pacote. Defina a palavra-chave do módulo manager com um valor auto.

    O playbook completo é mostrado abaixo:

    ---
    - name: Repository Configuration
      hosts: all
      vars:
        custom_pkg: example-motd
      tasks:
        - name: Gather Package Facts
          package_facts:
            manager: auto
        - name: Show Package Facts for the custom package
          debug:
            var: ansible_facts.packages[custom_pkg]
          when: custom_pkg in ansible_facts.packages
        - name: Ensure Example Repo exists
          yum_repository:
            name: example-internal
            description: Example Inc. Internal YUM repo
            file: example
            baseurl: http://materials.example.com/yum/repository/
            gpgcheck: yes
        - name: Ensure Repo RPM Key is Installed
          rpm_key:
            key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
            state: present
        - name: Install Example motd package
          yum:
            name: "{{ custom_pkg }}"
            state: present
    
        - name: Gather Package Facts
          package_facts:
            manager: auto
    
        - name: Show Package Facts for the custom package
          debug:
            var: ansible_facts.packages[custom_pkg]
          when: custom_pkg in ansible_facts.packages
  9. Use um comando ad hoc do Ansible para remover o pacote example-motd instalado durante a execução anterior do playbook. Execute o playbook com a tarefa package_facts inserida e use a saída para verificar a instalação do pacote example-motd.

    1. Para remover o pacote example-motd de todos os hosts, use o comando ansible all com as opções -m yum e -a 'name=example-motd state=absent'.

      [student@workstation system-software]$ ansible all -m yum \
      > -a 'name=example-motd state=absent'
      servera.lab.example.com | CHANGED => {
      ...output omitted...
          "changed": true,
          "msg": "",
          "rc": 0,
          "results": [
              "Removed: example-motd-1.0-1.el7.x86_64"
          ]
      ...output omitted...
    2. Execute o playbook.

      [student@workstation system-software]$ ansible-playbook repo_playbook.yml
      PLAY [Repository Configuration] **********************************************
      TASK [Gathering Facts] *******************************************************
      ok: [servera.lab.example.com]
      TASK [Gather Package Facts] **************************************************
      ok: [servera.lab.example.com]
      TASK [Show Package Facts for the custom package] *****************************
      skipping: [servera.lab.example.com]1
      ...output omitted...
      TASK [Install Example motd package] ******************************************
      changed: [servera.lab.example.com]2
      TASK [Gather Package Facts] **************************************************
      ok: [servera.lab.example.com]3
      TASK [Show Package Facts for example-motd] ***********************************
      ok: [servera.lab.example.com] => {
          "ansible_facts.packages[custom_pkg]": [4
              {
                  "arch": "x86_64",
                  "epoch": null,
                  "name": "example-motd",
                  "release": "1.el7",
                  "source": "rpm",
                  "version": "1.0"
              }
          ]
      }
      PLAY RECAP *******************************************************************
      servera.lab.example.com    : ok=7    changed=1    unreachable=0    failed=0    
      skipped=1    rescued=0    ignored=0
        | Não há fatos de pacote para o pacote example-motd porque ele não está instalado no host remoto. -- | --   | O pacote example-motd é instalado como resultado dessa tarefa, conforme indicado pelo status changed.   | Essa tarefa atualiza os fatos do pacote com informações sobre o pacote example-motd.   | O fato do pacote example-motd existe e indica que apenas um pacote example-motd está instalado. O pacote instalado está na versão 1.0.

Encerramento

Em workstation, execute o script lab system-software finish para limpar os recursos criados neste exercício.

[student@workstation ~]$ lab system-software finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Objetivos

Depois de concluir esta seção, você deverá ser capaz de:

  • Provisionar várias contas de usuário em vários servidores.

  • Gerenciar usuários e grupos do Linux, configurar SSH e modificar a configuração do Sudo em hosts gerenciados.

O módulo user

O módulo user do Ansible permite gerenciar contas de usuário em um host remoto. Você pode gerenciar vários parâmetros, incluindo remoção de usuário, definição de diretório pessoal, definição da UID de contas do sistema, gerenciamento de senhas e agrupamentos associados. Para criar um usuário que possa fazer login na máquina, você precisa fornecer uma senha com hash para o parâmetro de senha. Consulte a seção de referência para obter um link para "How do I generate encrypted passwords for the user module?"

Exemplo do módulo user

- name: Add new user to the development machine and assign the appropriate groups.
  user:
    name: devops_user 1
    shell: /bin/bash 2
    groups: sys_admins, developers 3
    append: yes
  | O parâmetro name é o único requisito no módulo user e geralmente é a conta de serviço ou conta de usuário. -- | --   | O parâmetro shell opcionalmente define o shell do usuário. Em outros sistemas operacionais, o shell padrão é decidido pela ferramenta que está sendo usada.   | O parâmetro groups, junto com o parâmetro append, informa à máquina que desejamos anexar os grupos sys_asmins e developers a esse usuário. Se você não usar o parâmetro append, os grupos serão substituídos.

Ao criar um usuário, você pode especificá-lo com generate_ssh_key . Isso não substituirá uma chave SSH existente.

Exemplo de geração de chave SSH pelo módulo user

- name: Create a SSH key for user1
  user:
    name: user1
    generate_ssh_key: yes
    ssh_key_bits: 2048
    ssh_key_file: .ssh/id_my_rsa

O módulo user também oferece alguns valores de retorno. Os módulos do Ansible podem obter um valor de retorno e registrá-lo em uma variável. Saiba mais com o ansible-doc e no site de doc principal.

Parâmetro | Comentários -- | -- comment | Opcionalmente, define a descrição de uma conta de usuário. group | Opcionalmente, define o grupo principal do usuário. groups | Lista de vários grupos. Quando definido como um valor nulo, todos os grupos, exceto o grupo principal, são removidos. home | Opcionalmente, define o diretório pessoal do usuário. create_home | Obtém um valor booleano de sim ou não. Um diretório pessoal será criado para o usuário se o valor estiver definido como sim. system | Ao criar uma conta com state=present, definir esse parâmetro como sim torna o usuário uma conta do sistema. Essa configuração não pode ser alterada em usuários existentes. uid | Define a UID do usuário.

O módulo group

O módulo group permite que você gerencie (adicione, exclua, modifique) grupos nos hosts gerenciados. Você precisa ter groupadd, groupdel ou groupmod. Para destinos do Windows, use o módulo win_group.

Exemplo do módulo group

- name: Verify that auditors group exists
  group:
    name: auditors
    state: present

Parâmetro | Comentários -- | -- gid | GID opcional para definir para o grupo. local | Força o uso de alternativas de comando "locais" nas plataformas que o implementam. name | Nome do grupo a ser gerenciado. state | Se o grupo deve estar presente ou não no host remoto. system | Se configurado como sim, indica que o grupo criado é um grupo do sistema.

O módulo known hosts

Se você tiver um grande número de chaves de host para gerenciar, use o módulo known_hosts. O módulo known_hosts permite adicionar ou remover chaves de host do arquivo known_hosts no host gerenciado.

Exemplo de tarefas do known_host

- name: copy host keys to remote servers
  known_hosts:
    path: /etc/ssh/ssh_known_hosts
    name: user1
    key: "{{ lookup('file', 'pubkeys/user1') }}"1
  | Um plugin lookup permite ao Ansible acessar dados de fontes externas. -- | --

O módulo authorized key

O módulo authorized_key permite adicionar ou remover chaves SSH autorizadas por contas de usuário. Ao adicionar e subtrair usuários em um grande banco de servidores, você precisa ser capaz de gerenciar chaves SSH.

Exemplo de tarefas do authorized_key

- name: Set authorized key
  authorized_key:
    user: user1
    state: present
    key: "{{ lookup('file', '/home/user1/.ssh/id_rsa.pub') }}1
  | Uma chave também pode ser obtida a partir de uma URL: https://github.com/user1.keys. -- | --
britho commented 3 years ago

Neste exercício, você criará vários usuários em seus hosts gerenciados e preencherá as chaves SSH autorizadas para eles.

Resultados

Você deverá ser capaz de:

Criar um novo grupo de usuários.

Gerenciar usuários com o módulo user.

Preencher as chaves SSH autorizadas usando o módulo authorized_key.

Modificar os arquivos sudoers e sshd_config usando o módulo lineinfile. 

Na workstation, execute o script de início do laboratório para confirmar se o ambiente está pronto para que o laboratório comece. O script cria o diretório de trabalho, chamado de system-users, e o preenche com um arquivo de configuração do Ansible, um inventário de host e alguns arquivos de laboratório.

[student@workstation ~]$ lab system-users start

Visão geral do cenário

Sua organização exige que todos os hosts tenham os mesmos usuários locais disponíveis. Esses usuários devem pertencer ao grupo de usuários webadmin, que tem a capacidade de usar o comando sudo sem especificar uma senha. Além disso, as chaves públicas SSH dos usuários devem ser distribuídas no ambiente e o usuário root não deve ter permissão para fazer login usando SSH diretamente.

Você está encarregado de escrever um playbook para garantir que os usuários e o grupo de usuários estejam presentes no host remoto. O playbook deve garantir que os usuários possam fazer login usando a chave SSH autorizada, bem como usar sudo sem especificar uma senha, e que o usuário root não possa fazer login diretamente usando SSH.

Na workstation, como o usuário student, acesse o diretório de trabalho /home/student/system-users.

[student@workstation ~]$ cd ~/system-users
[student@workstation system-users]$ 

Dê uma olhada no arquivo vars/users_vars.yml existente da variável.

[student@workstation system-users]$ cat vars/users_vars.yml
---
users:
  - username: user1
    groups: webadmin
  - username: user2
    groups: webadmin
  - username: user3
    groups: webadmin
  - username: user4
    groups: webadmin
  - username: user5
    groups: webadmin

Ele usa o nome da variável username para definir o nome de usuário correto e a variável groups para definir grupos adicionais aos quais o usuário deve pertencer.

Comece a escrever o users.yml playbook. Defina uma única ação no playbook que tenha como destino o grupo de hosts webservers. Adicione uma cláusula vars_files que defina a localização do nome de arquivo vars/users_vars.yml, que foi criado para você, e contém todos os nomes de usuário necessários para este exercício. Adicione a cláusula tasks ao playbook.

Use um editor de texto para criar o playbook users.yml. O playbook deve conter o seguinte:

---
- name: Create multiple local users
  hosts: webservers
  vars_files:
    - vars/users_vars.yml
  tasks:

Adicione duas tarefas ao playbook.

Use o módulo group na primeira tarefa para criar o grupo de usuários webadmin no host remoto. Esta tarefa cria o grupo webadmin.

Use o módulo user na segunda tarefa para criar os usuários do arquivo vars/users_vars.yml.

Execute o playbook users.yml.

    Adicione a primeira tarefa ao playbook. A primeira tarefa contém o seguinte:

      - name: Add webadmin group
        group:
          name: webadmin
          state: present

    Adicione uma segunda tarefa ao playbook que usa o módulo user para criar os usuários. Adicione uma cláusula loop: "{{ users }}" à tarefa para fazer loop no arquivo de variável para cada nome de usuário encontrado no arquivo vars/users_vars.yml. Como name: para os usuários, use item.username como o nome da variável. Isso permite que o arquivo de variável contenha informações adicionais que podem ser úteis para criar usuários, como os grupos aos quais eles devem pertencer. A segunda tarefa contém o seguinte:

      - name: Create user accounts
        user:
          name: "{{ item.username }}"
          groups: webadmin
        loop: "{{ users }}"

    Execute o playbook:

    [student@workstation system-users]$ ansible-playbook users.yml

    PLAY [Create multiple local users] *******************************************

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

    TASK [Add webadmin group] ****************************************************
    changed: [servera.lab.example.com]

    TASK [Create user accounts] **************************************************
    changed: [servera.lab.example.com] => (item={u'username': u'user1', u'groups': u'webadmin'})
    changed: [servera.lab.example.com] => (item={u'username': u'user2', u'groups': u'webadmin'})
    changed: [servera.lab.example.com] => (item={u'username': u'user3', u'groups': u'webadmin'})
    changed: [servera.lab.example.com] => (item={u'username': u'user4', u'groups': u'webadmin'})
    changed: [servera.lab.example.com] => (item={u'username': u'user5', u'groups': u'webadmin'})

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

Adicione uma terceira tarefa que use o módulo authorized_key para garantir que as chaves públicas SSH tenham sido adequadamente distribuídas no host remoto. No diretório files, cada um dos usuários tem um único arquivo de chave pública SSH. O módulo percorre a lista de usuários por loop, localiza a chave apropriada usando a variável username e envia a chave para o host remoto.

A terceira tarefa contém o seguinte:

  - name: Add authorized keys
    authorized_key:
      user: "{{ item.username }}"
      key: "{{ lookup('file', 'files/'+ item.username + '.key.pub') }}"
    loop: "{{ users }}"

Adicione uma quarta tarefa à ação que usa o módulo copy para modificar o arquivo de configuração sudo e permitir que os membros do grupo webadmin usem sudo sem uma senha no host remoto.

A quarta tarefa aparece conforme segue:

  - name: Modify sudo config to allow webadmin users sudo without a password
    copy:
      content: "%webadmin ALL=(ALL) NOPASSWD: ALL"
      dest: /etc/sudoers.d/webadmin
      mode: 0440

Adicione uma quinta tarefa para garantir que o usuário root não tenha permissão para fazer login usando SSH diretamente. Use notify: "Restart sshd" para acionar um manipulador para que reinicie o SSH.

A quinta tarefa aparece conforme segue:

  - name: Disable root login via SSH
    lineinfile:
      dest: /etc/ssh/sshd_config
      regexp: "^PermitRootLogin"
      line: "PermitRootLogin no"
    notify: Restart sshd

Na primeira linha após o local do arquivo da variável, inclua uma nova definição de manipulador. Dê a ele o nome Restart sshd.

    O manipulador deverá ser definido assim:

    ...output omitted...
        - vars/users_vars.yml
      handlers:
      - name: Restart sshd
        service:
          name: sshd
          state: restarted

    Agora, todo o playbook aparecerá conforme segue:

    ---
    - name: Create multiple local users
      hosts: webservers
      vars_files:
        - vars/users_vars.yml
      handlers:
      - name: Restart sshd
        service:
          name: sshd
          state: restarted

      tasks:

      - name: Add webadmin group
        group:
          name: webadmin
          state: present

      - name: Create user accounts
        user:
          name: "{{ item.username }}"
          groups: webadmin
        loop: "{{ users }}"

      - name: Add authorized keys
        authorized_key:
          user: "{{ item.username }}"
          key: "{{ lookup('file', 'files/'+ item.username + '.key.pub') }}"
        loop: "{{ users }}"

      - name: Modify sudo config to allow webadmin users sudo without a password
        copy:
          content: "%webadmin ALL=(ALL) NOPASSWD: ALL"
          dest: /etc/sudoers.d/webadmin
          mode: 0440

      - name: Disable root login via SSH
        lineinfile:
          dest: /etc/ssh/sshd_config
          regexp: "^PermitRootLogin"
          line: "PermitRootLogin no"
        notify: "Restart sshd"

    Execute o playbook.

    [student@workstation system-users]$ ansible-playbook users.yml

    PLAY [Create multiple local users] *******************************************

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

    TASK [Add webadmin group] ****************************************************
    ok: [servera.lab.example.com]

    TASK [Create user accounts] **************************************************
    ok: [servera.lab.example.com] => (item={u'username': u'user1', u'groups': u'webadmin'})
    ok: [servera.lab.example.com] => (item={u'username': u'user2', u'groups': u'webadmin'})
    ok: [servera.lab.example.com] => (item={u'username': u'user3', u'groups': u'webadmin'})
    ok: [servera.lab.example.com] => (item={u'username': u'user4', u'groups': u'webadmin'})
    ok: [servera.lab.example.com] => (item={u'username': u'user5', u'groups': u'webadmin'})

    TASK [Add authorized keys] ***************************************************
    changed: [servera.lab.example.com] => (item={u'username': u'user1', u'groups': u'webadmin'})
    changed: [servera.lab.example.com] => (item={u'username': u'user2', u'groups': u'webadmin'})
    changed: [servera.lab.example.com] => (item={u'username': u'user3', u'groups': u'webadmin'})
    changed: [servera.lab.example.com] => (item={u'username': u'user4', u'groups': u'webadmin'})
    changed: [servera.lab.example.com] => (item={u'username': u'user5', u'groups': u'webadmin'})

    TASK [Modify sudo config to allow webadmin users sudo without a password] ***
    changed: [servera.lab.example.com]

    TASK [Disable root login via SSH] *******************************************
    changed: [servera.lab.example.com]

    RUNNING HANDLER [Restart sshd] **********************************************
    changed: [servera.lab.example.com]

    PLAY RECAP ******************************************************************
    servera.lab.example.com    : ok=7    changed=4    unreachable=0    failed=0

Como usuário user1, faça login no servidor servera usando SSH. Depois de conectado, use o comando sudo su - para alternar a identidade para o usuário root.

    Use SSH como usuário user1 e faça login no servidor servera.

    [student@workstation system-users]$ ssh user1@servera
    Activate the web console with: systemctl enable --now cockpit.socket

    [user1@servera ~]$ 

    Alterne a identidade para o usuário root.

    [user1@servera ~]$ sudo su -
    Last login: Wed Dec 19 05:39:53 EST 2018 on pts/0
    root@servera ~]# 

    Faça o logout do servidor servera.

    [root@servera ~]$ exit
    logout
    [user1@servera ~]$ exit
    logout
    Connection to servera closed.
    [student@workstation system-users]$ 

Tente fazer login no servidor servera como usuário root diretamente. Essa etapa deve apresentar falha, porque a configuração do SSH foi modificada para não permitir logins de usuário root diretos.

    Em workstation, use SSH como root para fazer login no servidor servera.

    [student@workstation system-users]$ ssh root@servera
    root@servera's password: redhat
    Permission denied, please try again.
    root@servera's password: 

    Isso confirma que a configuração SSH negou acesso direto ao sistema para o usuário root. 

Encerramento

Em workstation, execute o script lab system-users finish para limpar os recursos criados neste exercício.

[student@workstation ~]$ lab system-users finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Objetivos

Depois de concluir esta seção, você deverá ser capaz de gerenciar a inicialização de serviços, agendar processos com at, cron e systemd, reinicializar e controlar o destino de boot padrão em hosts gerenciados.

Agendamento com o módulo at

O agendamento rápido e único é feito com o módulo at. Você cria a tarefa para uma execução futura, e ela é retida até o momento da execução. Existem seis parâmetros que acompanham esse módulo. Eles são: command, count, script_file, state, unique e units.

Exemplo do módulo at:

- name: remove tempuser.
  at:
    command: userdel -r tempuser
    count: 20
    units: minutes
    unique: yes

Parâmetro | Opções | Comentários -- | -- | -- command | Null | Um comando agendado para execução. count | Null | A contagem de unidades. (Deve ser executado com unidades) script_file | Null | Um arquivo de script existente a ser executado no futuro. state | absent, present | O estado adiciona ou remove um comando ou script. unique | yes, no | Se uma tarefa já estiver em execução, ela não será executada novamente. units | minutes/hours/days/weeks | As denominações de tempo.

Anexação de comandos com o módulo cron.

Ao definir uma tarefa agendada de trabalho, o módulo cron é usado. O módulo cron anexará comandos diretamente no crontab do usuário designado.

Exemplo do módulo cron:

- cron:
  name: "Flush Bolt"
  user: "root"
  minute: 45
  hour: 11
  job: "php ./app/nut cache:clear"

Essa ação usa um comando cache:clear da empresa que imediatamente libera o cache Bolt, removendo arquivos e diretórios em cache, além de limpar o cache do servidor CMS todas as manhãs às 11:45.

O Ansible gravará a ação no crontab usando a sintaxe correta conforme a instrução do usuário.

Examinar o crontab verificará se ele foi anexado.

Alguns parâmetros comumente usados para o módulo cron são:

Parâmetro | Opções | Comentários -- | -- | -- special_time | reboot, yearly, annually, monthly, weekly, daily, hourly | Um conjunto de definições de recorrência. state | absent, present | Se definido como presente, ele criará o comando. Ausente o removerá. cron_file | Null | Se você tem grandes bancos de servidores a serem mantidos, às vezes é melhor ter um arquivo crontab pré-escrito. backup | yes, no | Faz o backup do arquivo crontab antes de ser editado.

Gerenciamento de serviços com os módulos systemd e Modules

Para gerenciar serviços ou recarregar daemons, o Ansible tem os módulos systemd e service. O service oferece um conjunto básico de opções para iniciar, parar, reiniciar e ativar. O módulo systemd oferece mais opções de configuração. O systemd permitirá que você faça um recarregamento de daemons em casos em que o módulo service não o faz.

Exemplo do módulo service:

- name: start nginx
  service:
    name: nginx
    state: started"

O daemon init está sendo substituído pelo systemd. Então, em muitos casos, o systemd será a melhor opção.

Exemplo do módulo systemd:

- name: reload web server
  systemd:
    name: apache2
    state: reload
    daemon-reload: yes

O módulo reboot

Outro módulo de sistemas do Ansible bastante usado é o reboot . É considerado mais seguro do que usar o módulo shell para iniciar o desligamento. Durante a execução de uma ação, o módulo reboot desligará o host gerenciado e, em seguida, aguardará até que ele fique disponível novamente antes de prosseguir com a ação.

Exemplo do módulo reboot:

- name: "Reboot after patching"
  reboot:
    reboot_timeout: 180
- name: force a quick reboot
  reboot:

Os módulos shell e command

Assim como os módulos service e systemd, o shell e o command podem trocar algumas tarefas. O módulo command é considerado mais seguro, mas algumas variáveis de ambiente não estão disponíveis. Além disso, os operadores de fluxo não funcionarão. Se você precisar transmitir seus comandos, o módulo shell fará isso.

Exemplo do módulo shell:

- name: Run a templated variable (always use quote filter to avoid injection)
    shell: cat {{ myfile|quote }}1

  | Para limpar variáveis, é recomendado que você use “{{ var \| quote }}” em vez de “{{ var }}” -- | --

Exemplo do módulo command:

- name: This command only
  command: /usr/bin/scrape_logs.py arg1 arg2
    args:1
      chdir: scripts/
      creates: /path/to/script
  

  | Você pode passar argumentos para o formulário para fornecer as opções. -- | --

O módulo command é considerado mais seguro porque não é afetado pelo ambiente dos usuários.

A coleta de fatos no host gerenciado permitirá que você acesse as variáveis de ambiente. Há uma sublista ansible_env que contém todas as variáveis de ambiente.

---
- name:
  hosts: webservers
  vars:
    local_shell:  "{{ ansible_env }}"1
  tasks:
    - name: Printing all the environment​ variables in Ansible
      debug:
        msg: "{{ local_shell }}"

  | Você pode isolar a variável que deseja retornar usando o plugin de pesquisa. msg: "{{ lookup('env','USER','HOME','SHELL') }}" -- | --
britho commented 3 years ago

Neste exercício, você gerenciará o processo de inicialização, agendará tarefas recorrentes e reinicializará os hosts gerenciados.

Resultados

Você deverá ser capaz de usar um playbook para:

Agendar uma tarefa do cron.

Remover uma tarefa do cron específica de um arquivo crontab.

Agendar uma tarefa at.

Definir o destino de inicialização padrão em hosts gerenciados.

Reiniciar os hosts gerenciados. 

Em workstation, execute o script lab system-process start para configurar o ambiente para o exercício. O script cria o diretório de trabalho system-process e faz o download dos arquivos de configuração e inventário de host do Ansible necessários para o exercício.

[student@workstation ~]$ lab system-process start

Em workstation, como usuário student, acesse o diretório de trabalho /home/student/system-process.

[student@workstation ~]$ cd ~/system-process
[student@workstation system-process]$

Crie um playbook, create_crontab_file.yml, no diretório de trabalho atual. Configure o playbook para usar o módulo cron para criar o arquivo crontab /etc/cron.d/add-date-time que agenda uma tarefa do cron recorrente. A tarefa deve ser executada como o usuário devops a cada dois minutos entre 09:00 e 16:59 de segunda-feira a sexta-feira. A tarefa deve anexar a data e a hora atuais ao arquivo /home/devops/my_datetime_cron_job

    Crie um novo playbook, create_crontab_file.yml, e adicione as linhas necessárias para iniciar a ação. Ele deve ser direcionado ao hosts gerenciados no grupo webservers e ativar o escalonamento de privilégios.

    ---
    - name: Recurring cron job
      hosts: webservers
      become: true

    Defina uma tarefa que usa o módulo cron para agendar uma tarefa do cron recorrente.

    O módulo cron fornece uma opção name para descrever exclusivamente a entrada do arquivo crontab e garantir os resultados esperados. A descrição é adicionada ao arquivo crontab. Por exemplo, a opção name é necessária se você estiver removendo uma entrada do crontab usando state=absent. Além disso, a opção name impede que uma nova entrada do crontab seja sempre criada quando o estado padrão, state=present, estiver definido.

      tasks:
        - name: Crontab file exists
          cron:
            name: Add date and time to a file

    Configure a tarefa para que seja executada a cada dois minutos entre 09:00 e 16:59 de segunda-feira a sexta-feira.

            minute: "*/2"
            hour: 9-16
            weekday: 1-5

    Use o parâmetro cron_file para usar o arquivo crontab /etc/cron.d/add-date-time em vez de usar o crontab de um usuário individual em /var/spool/cron/. Um caminho relativo colocará o arquivo no diretório /etc/cron.d. Se o parâmetro cron_file for usado, você também deverá especificar o parâmetro user.

            user: devops
            job: date >> /home/devops/my_date_time_cron_job
            cron_file: add-date-time
            state: present

    Quando concluído, o playbook deverá ficar desta forma: Revise o playbook para garantir a precisão.

    ---
    - name: Recurring cron job
      hosts: webservers
      become: true

      tasks:
        - name: Crontab file exists
          cron:
            name: Add date and time to a file
            minute: "*/2"
            hour: 9-16
            weekday: 1-5
            user: devops
            job: date >> /home/devops/my_date_time_cron_job
            cron_file: add-date-time
            state: present

    Verifique a sintaxe do playbook executando o comando ansible-playbook --syntax-check create_crontab_file.yml. Corrija os erros antes de passar para a próxima etapa.

    [student@workstation system-process]$ ansible-playbook --syntax-check \
    > create_crontab_file.yml

    playbook: create_crontab_file.yml

    Execute o playbook.

    [student@workstation system-process]$ ansible-playbook create_crontab_file.yml

    PLAY [Recurring cron job] *************************************************

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

    TASK [Crontab file exists] ************************************************
    changed: [servera.lab.example.com]

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

    Execute um comando ad hoc para verificar se o arquivo cron /etc/cron.d/add-date-time existe e se o seu conteúdo está correto.

    [student@workstation system-process]$ ansible webservers -u devops -b \
    > -a "cat /etc/cron.d/add-date-time"
    servera.lab.example.com | CHANGED | rc=0 >>
    #Ansible: Add date and time to a file
    */2 9-16 * * 1-5 devops date >> /home/devops/my_date_time_cron_job

Crie um playbook, remove_cron_job.yml, no diretório de trabalho atual. Configure o playbook para usar o módulo para remover a tarefa do cron Add date and time to a file do arquivo crontab /etc/cron.d/add-date-time

    Crie um novo playbook, remove_cron_job.yml, e adicione as seguintes linhas:

    ---
    - name: Remove scheduled cron job
      hosts: webservers
      become: true

      tasks:
        - name: Cron job removed
          cron:
            name: Add date and time to a file
            user: devops
            cron_file: add-date-time
            state: absent

    Verifique a sintaxe do playbook executando o comando ansible-playbook --syntax-check remove_cron_job.yml. Corrija os erros antes de passar para a próxima etapa.

    [student@workstation system-process]$ ansible-playbook --syntax-check \
    > remove_cron_job.yml

    playbook: remove_cron_job.yml

    Execute o playbook.

    [student@workstation system-process]$ ansible-playbook remove_cron_job.yml

    PLAY [Remove scheduled cron job] ******************************************

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

    TASK [Cron job removed] ***************************************************
    changed: [servera.lab.example.com]

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

    Execute um comando ad hoc para verificar se o arquivo cron /etc/cron.d/add-date-time continua existindo, mas se a tarefa do cron foi removida.

    [student@workstation system-process]$ ansible webservers -u devops -b \
    > -a "cat /etc/cron.d/add-date-time"
    servera.lab.example.com | CHANGED | rc=0 >>

Crie um playbook, schedule_at_task.yml, no diretório de trabalho atual. Configure o playbook para usar o módulo at para agendar uma tarefa que é executada um minuto no futuro. A tarefa deve executar o comando date e redirecionar sua saída para o arquivo /home/devops/my_at_date_time. Use a opção unique: yes para garantir que, se o comando já existir na fila at, uma nova tarefa não será adicionada.

    Crie um novo playbook, schedule_at_task.yml, e adicione as seguintes linhas:

    ---
    - name: Schedule at task
      hosts: webservers
      become: true
      become_user: devops

      tasks:
        - name: Create date and time file
          at:
            command: "date > ~/my_at_date_time\n"
            count: 1
            units: minutes
            unique: yes
            state: present

    Verifique a sintaxe do playbook executando o comando ansible-playbook -syntax-check schedule_at_task.yml. Corrija os erros antes de passar para a próxima etapa.

    [student@workstation system-process]$ ansible-playbook --syntax-check \
    > schedule_at_task.yml

    playbook: schedule_at_task.yml

    Execute o playbook.

    [student@workstation system-process]$ ansible-playbook schedule_at_task.yml

    PLAY [Schedule at task] ***************************************************

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

    TASK [Create date and time file] ******************************************
    changed: [servera.lab.example.com]

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

    Depois de esperar um minuto para que o comandoat seja concluído, execute comandos ad hoc para verificar se o arquivo /home/devops/my_at_date_time existe e tem o conteúdo correto.

    [student@workstation system-process]$ ansible webservers -u devops -b \
    > -a "ls -l my_at_date_time"
    servera.lab.example.com | CHANGED | rc=0 >>
    -rw-rw-r--. 1 devops devops 30 abr 17 06:15 my_at_date_time

    [student@workstation system-process]$ ansible webservers -u devops -b \
    > -a "cat my_at_date_time"
    servera.lab.example.com | CHANGED | rc=0 >>
    mié abr 17 06:15:00 EDT 2019

Crie um playbook, set_default_boot_target_graphical.yml, no diretório de trabalho atual. Configure o playbook para que use o módulo file para alterar o link simbólico em hosts gerenciados e fazer referência ao destino de inicialização graphical-target.

No módulo file a seguir, o link simbólico faz referência ao valor do parâmetro src. O valor do parâmetro dest é o link simbólico.

    Crie um novo playbook, set_default_boot_target_graphical.yml, e adicione as seguintes linhas:

    ---
    - name: Change default boot target
      hosts: webservers
      become: true

      tasks:
        - name: Default boot target is graphical
          file:
            src: /usr/lib/systemd/system/graphical.target
            dest: /etc/systemd/system/default.target
            state: link

    Verifique a sintaxe do playbook executando o comando ansible-playbook --syntax-check set_default_boot_target_graphical.yml. Corrija os erros antes de passar para a próxima etapa.

    [student@workstation system-process]$ ansible-playbook --syntax-check \
    > set_default_boot_target_graphical.yml

    playbook: set_default_boot_target_graphical.yml

    Antes de executar o playbook, execute um comando ad hoc para verificar se o destino de inicialização padrão atual é multi-user.target:

    [student@workstation system-process]$ ansible webservers -u devops -b \
    > -a "systemctl get-default"
    servera.lab.example.com | CHANGED | rc=0 >>
    multi-user.target

    Execute o playbook.

    [student@workstation system-process]$ ansible-playbook \
    > set_default_boot_target_graphical.yml

    PLAY [Change default boot target] *****************************************

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

    TASK [Default boot target is graphical] ***********************************
    changed: [servera.lab.example.com]

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

    Execute um comando ad hoc para verificar se o destino de inicialização padrão agora é graphical.target.

    [student@workstation system-process]$ ansible webservers -u devops -b \
    > -a "systemctl get-default"
    servera.lab.example.com | CHANGED | rc=0 >>
    graphical.target

Crie um playbook, reboot_hosts.yml, no diretório de trabalho atual que reinicialize os hosts gerenciados. Não é necessário reinicializar um servidor depois de alterar o destino padrão. No entanto, saber criar um playbook que reinicia os hosts gerenciados pode ser útil.

    Crie um novo playbook, reboot_hosts.yml, e adicione as seguintes linhas:

    ---
    - name: Reboot hosts
      hosts: webservers
      become: true

      tasks:
        - name: Hosts are rebooted
          reboot:

    Verifique a sintaxe do playbook executando o comando ansible-playbook --syntax-check reboot_hosts.yml. Corrija os erros antes de passar para a próxima etapa.

    [student@workstation system-process]$ ansible-playbook --syntax-check \
    > reboot_hosts.yml

    playbook: reboot_hosts.yml

    Antes de executar o playbook, execute um comando ad hoc para determinar o carimbo de data/hora da última reinicialização do sistema.

    [student@workstation system-process]$ ansible webservers -u devops -b \
    > -a "who -b"
    servera.lab.example.com | CHANGED | rc=0 >>
             system boot  2019-04-12 06:01

    Execute o playbook.

    [student@workstation system-process]$ ansible-playbook reboot_hosts.yml

    PLAY [Reboot hosts] *******************************************************

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

    TASK [Hosts are rebooted] *************************************************
    changed: [servera.lab.example.com]

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

    Execute um comando ad hoc para determinar o carimbo de data/hora da última reinicialização do sistema. O carimbo de data/hora exibido após a execução do playbook deve ser posterior.

    [student@workstation system-process]$ ansible webservers -u devops -b \
    > -a "who -b"
    servera.lab.example.com | CHANGED | rc=0 >>
             system boot  2019-04-12 06:20

    Execute um segundo comando ad hoc para determinar se a reinicialização de graphical.target sobreviveu à reinicialização.

    [student@workstation system-process]$ ansible webservers -u devops -b \
    > -a "systemctl get-default"
    servera.lab.example.com | CHANGED | rc=0 >>
    graphical.target

Para manter a consistência em todos os exercícios restantes, altere o destino de inicialização padrão para a configuração anterior, multi-user.target. Crie um playbook, set_default_boot_target_multi-user.yml, no diretório de trabalho atual. Configure o playbook para que use o módulo file para alterar o link simbólico em hosts gerenciados e fazer referência ao destino de inicialização multi-user.target.

    Crie um novo playbook, set_default_boot_target_multi-user.yml, e adicione as seguintes linhas:

    ---
    - name: Change default runlevel target
      hosts: webservers
      become: true

      tasks:
        - name: Default runlevel is multi-user target
          file:
            src: /usr/lib/systemd/system/multi-user.target
            dest: /etc/systemd/system/default.target
            state: link

    Verifique a sintaxe do playbook executando o comando ansible-playbook --syntax-check set_default_boot_target_multi-user.yml. Corrija os erros antes de passar para a próxima etapa.

    [student@workstation system-process]$ ansible-playbook --syntax-check \
    > set_default_boot_target_multi-user.yml

    playbook: set_default_boot_target_multi-user.yml

    Execute o playbook.

    [student@workstation system-process]$ ansible-playbook \
    > set_default_boot_target_multi-user.yml

    PLAY [Change default runlevel target] *************************************

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

    TASK [Default runlevel is multi-user target] ******************************
    changed: [servera.lab.example.com]

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

    Execute um comando ad hoc para verificar se o destino de boot padrão agora é multi-user.target.

    [student@workstation system-process]$ ansible webservers -u devops -b \
    > -a "systemctl get-default"
    servera.lab.example.com | CHANGED | rc=0 >>
    multi-user.target

Encerramento

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

[student@workstation ~]$ lab system-process finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Objetivos

Depois de concluir esta seção, você deverá ser capaz de particionar dispositivos de armazenamento, configurar o LVM, formatar partições ou volumes lógicos, montar sistemas de arquivos e adicionar arquivos ou espaços de swap.

Configuração de armazenamento com módulos do Ansible

O RedHat Ansible Engine fornece uma coleção de módulos para configurar dispositivos de armazenamento em hosts gerenciados. Esses módulos são compatíveis com o particionamento de dispositivos, a criação de volumes lógicos e a criação e montagem de sistemas de arquivos.

O módulo parted

O módulo parted dá suporte ao particionamento de dispositivos de bloco. Esse módulo inclui a funcionalidade do comando parted e permite criar partições com um tamanho, sinalizador e alinhamento específicos. A tabela a seguir lista alguns dos parâmetros para o módulo parted.

Nome do parâmetro | Descrição -- | -- align | Configura o alinhamento da partição. device | Dispositivo de bloco. flags | Sinalizadores da partição. number | O número da partição. part_end | Tamanho da partição desde o início do disco especificado nas unidades compatíveis com o parted. state | Cria ou remove a partição. unit | Unidades de tamanho para as informações da partição.

O exemplo a seguir cria uma nova partição de 10GB.

- name: New 10GB partition
  parted:
    device: /dev/vdb 1
    number: 1 2
    state: present 3
    part_end: 10GB 4

  | Usa vdb como o dispositivo de bloco a ser particionado. -- | --   | Cria a partição número um.   | Garante que a partição esteja disponível.   | Define o tamanho da partição como 10GB.

Os módulos lvg e lvol

Os módulos lvg e lvol são compatíveis com a criação de volumes lógicos, incluindo a configuração de volumes físicos, e grupos de volumes. O módulo lvg toma como parâmetros os dispositivos de bloco para configurar como os volumes físicos de back-end para o grupo de volumes. A tabela a seguir lista alguns dos parâmetros do módulo lvg.

Nome do parâmetro | Descrição -- | -- pesize | O tamanho da extensão física. Deve ser uma potência de 2 ou um múltiplo de 128KiB. pvs | Lista separada por vírgulas de dispositivos a serem configurados como volumes físicos para o grupo de volumes. vg | O nome do grupo de volumes. state | Cria ou remove o volume.

A tarefa a seguir cria um grupo de volumes com um tamanho de extensão física específico usando um dispositivo de bloco como back-end.

- name: Creates a volume group
  lvg:
    vg: vg1 1
    pvs: /dev/vda1 2
    pesize: 32 3

  | O nome do grupo de volumes é vg1. -- | --   | Usa /dev/vda1 como o volume físico de back-end para o grupo de volumes.   | Define o tamanho de extensão física como 32.

No exemplo a seguir, se o grupo de volumes vg1 já está disponível com /dev/vdb1 como um volume físico, o volume é aumentado ao adicionar um novo volume físico /dev/vdc1.

- name: Resize a volume group
  lvg:
    vg: vg1
    pvs: /dev/vdb1,/dev/vdc1

O módulo lvol cria volumes lógicos e dá suporte ao redimensionamento e à diminuição desses volumes e dos sistemas de arquivos acima deles. Esse módulo também dá suporte à criação de snapshots dos volumes lógicos. A tabela a seguir lista alguns dos parâmetros do módulo lvol.

Nome do parâmetro | Descrição -- | -- lv | O nome do volume lógico. resizefs | Redimensiona o sistema de arquivos com o volume lógico. shrink | Ativa a diminuição do volume lógico. size | O tamanho do volume lógico. snapshot | O nome do snapshot do volume lógico. state | Cria ou remove o volume lógico. vg | O grupo de volumes principal do volume lógico.

A tarefa a seguir cria um volume lógico de 2GB.

- name: Create a logical volume of 2GB
  lvol:
    vg: vg1 1
    lv: lv1 2
    size: 2g 3

  | O nome do grupo de volumes principal é vg1. -- | --   | O nome do volume lógico é lv1.   | O tamanho do volume lógico é 2GB.

O módulo filesystem

O módulo filesystem dá suporte à criação e ao redimensionamento de um sistema de arquivos. Esse módulo é compatível com o redimensionamento do sistema de arquivos para ext2, ext3, ext4, ext4dev, f2fs, lvm, xfs e vfat. A tabela a seguir lista alguns dos parâmetros do módulo filesystem.

Nome do parâmetro | Descrição -- | -- dev | Nome do dispositivo de bloco. fstype | Tipo do sistema de arquivos. resizefs | Aumenta o tamanho do sistema de arquivos para o tamanho do dispositivo de bloco.

O exemplo a seguir cria um sistema de arquivos em uma partição.

- name: Create an XFS filesystem
  filesystem:
    fstype: xfs 1
    dev: /dev/vdb1 2

  | Usa o sistema de arquivos XFS. -- | --   | Usa o dispositivo /dev/vdb1.

O módulo mount

O módulo mount dá suporte à configuração de pontos de montagem em /etc/fstab. A tabela a seguir lista alguns dos parâmetros do módulo mount.

Nome do parâmetro | Descrição -- | -- fstype | Tipo do sistema de arquivos. opts | Opções de montagem. path | Caminho do ponto de montagem. src | Dispositivo a ser montado. state | Especifique o status de montagem. Se definido como mounted, o sistema monta o dispositivo e configura /etc/fstab com essa informação de montagem. Para desmontar o dispositivo e removê-lo de /etc/fstab, use absent.

O exemplo a seguir monta um dispositivo com uma ID específica.

- name: Mount device with ID
  mount:
    path: /data 1
    src: UUID=a8063676-44dd-409a-b584-68be2c9f5570 2
    fstype: xfs 3
    state: present 4

  | Usa /data como o caminho do ponto de montagem. -- | --   | Monta o dispositivo com a ID a8063676-44dd-409a-b584-68be2c9f5570.   | Usa o sistema de arquivos XFS.   | Monta o dispositivo e configura /etc/fstab adequadamente.

O exemplo a seguir monta o compartilhamento NFS disponível em 172.25.250.100:/share no diretório /nfsshare no host gerenciado.

- name: Mount NFS share
        mount: name=/nfsshare src=172.25.250.100:/share fstype=nfs opts=defaults,nobootwait dump=0 passno=2 state=mounted

Configuração de swap com módulos

O RedHat Ansible Engine atualmente não inclui módulos para gerenciar a memória de swap. Para adicionar memória de swap a um sistema com o Ansible com volumes lógicos, é necessário criar um novo grupo de volumes e um volume lógico com os módulos lvg e lvol. Quando estiver pronto, é necessário formatar o novo volume lógico como swap usando o módulo command com o comando mkswap. Por fim, você precisa ativar o novo dispositivo de swap usando o módulo command com o comando swapon. O RedHat Ansible Engine tem a variável ansible_swaptotal_mb que inclui a memória de swap total. Você pode usar essa variável para acionar a configuração e a ativação de swap quando a memória de swap estiver baixa. As tarefas a seguir criam um grupo de volumes e um volume lógico para a memória de swap, formatam esse volume lógico como swap e o ativam.

- name: Create new swap VG
  lvg: vg=vgswap pvs=/dev/vda1 state=present
- name: Create new swap LV
  lvol: vg=vgswap lv=lvswap size=10g
- name: Format swap LV
  command: mkswap /dev/vgswap/lvswap
  when: ansible_swaptotal_mb < 128
- name: Activate swap LV
  command: swapon /dev/vgswap/lvswap
  when: ansible_swaptotal_mb < 128

Fatos do Ansible para configuração de armazenamento

O Ansible usa fatos para recuperar informações para o nó de controle sobre a configuração dos hosts gerenciados. Você pode usar o módulo setup do Ansible para recuperar todos os fatos do Ansible de um host gerenciado.

[user@controlnode ~]$ ansible webservers -m setup
host.lab.example.com | SUCCESS => {
    "ansible_facts": {
...output omitted...
    }

A opção filter do módulo setup é compatível com filtragem refinada baseada em curingas de estilo shell.

O elemento ansible_devices inclui todos os dispositivos de armazenamento disponíveis no host gerenciado. O elemento de cada dispositivo de armazenamento inclui informações adicionais, como partições ou tamanho total. O exemplo a seguir exibe o elemento ansible_devices de um host gerenciado com três dispositivos de armazenamento: sr0, vda e vdb.

[user@controlnode ~]$ ansible webservers -m setup -a 'filter=ansible_devices'
host.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "ansible_devices": {
            "sr0": {
                "holders": [],
                "host": "IDE interface: Intel Corporation 82371SB PIIX3 IDE [Natoma/Triton II]",
                "links": {
                    "ids": [
                        "ata-QEMU_DVD-ROM_QM00003"
                    ],
                    "labels": [],
                    "masters": [],
                    "uuids": []
                },
                "model": "QEMU DVD-ROM",
                "partitions": {},
                "removable": "1",
                "rotational": "1",
                "sas_address": null,
                "sas_device_handle": null,
                "scheduler_mode": "mq-deadline",
                "sectors": "2097151",
                "sectorsize": "512",
                "size": "1024.00 MB",
                "support_discard": "0",
                "vendor": "QEMU",
                "virtual": 1
            },
            "vda": {
                "holders": [],
                "host": "SCSI storage controller: Red Hat, Inc. Virtio block device",
                "links": {
                    "ids": [],
                    "labels": [],
                    "masters": [],
                    "uuids": []
                },
                "model": null,
                "partitions": {
                    "vda1": {
                        "holders": [],
                        "links": {
                            "ids": [],
                            "labels": [],
                            "masters": [],
                            "uuids": [
                                "a8063676-44dd-409a-b584-68be2c9f5570"
                            ]
                        },
                        "sectors": "20969439",
                        "sectorsize": 512,
                        "size": "10.00 GB",
                        "start": "2048",
                        "uuid": "a8063676-44dd-409a-b584-68be2c9f5570"
                    }
                },
                "removable": "0",
                "rotational": "1",
                "sas_address": null,
                "sas_device_handle": null,
                "scheduler_mode": "mq-deadline",
                "sectors": "20971520",
                "sectorsize": "512",
                "size": "10.00 GB",
                "support_discard": "0",
                "vendor": "0x1af4",
                "virtual": 1
            },
            "vdb": {
                "holders": [],
                "host": "SCSI storage controller: Red Hat, Inc. Virtio block device",
                "links": {
                    "ids": [],
                    "labels": [],
                    "masters": [],
                    "uuids": []
                },
                "model": null,
                "partitions": {},
                "removable": "0",
                "rotational": "1",
                "sas_address": null,
                "sas_device_handle": null,
                "scheduler_mode": "mq-deadline",
                "sectors": "10485760",
                "sectorsize": "512",
                "size": "5.00 GB",
                "support_discard": "0",
                "vendor": "0x1af4",
                "virtual": 1
            }
        }
    },
    "changed": false
}

O elemento ansible_device_links inclui todos os links disponíveis para cada dispositivo de armazenamento. O exemplo a seguir exibe o elemento ansible_device_links de um host gerenciado com dois dispositivos de armazenamento, sr0 e vda1, que têm uma ID associada.

[user@controlnode ~]$ ansible webservers -m setup -a 'filter=ansible_device_links'
host.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "ansible_device_links": {
            "ids": {
                "sr0": [
                    "ata-QEMU_DVD-ROM_QM00003"
                ]
            },
            "labels": {},
            "masters": {},
            "uuids": {
                "vda1": [
                    "a8063676-44dd-409a-b584-68be2c9f5570"
                ]
            }
        }
    },
    "changed": false
}

O elemento ansible_mounts inclui informações sobre os dispositivos atuais montados no host gerenciado, como o dispositivo montado, o ponto de montagem e as opções. A saída a seguir exibe o elemento ansible_mounts de um host gerenciado com uma montagem ativa, /dev/vda1 no diretório /.

[user@controlnode ~]$ ansible webservers -m setup -a 'filter=ansible_mounts'
host.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "ansible_mounts": [
            {
                "block_available": 2225732,
                "block_size": 4096,
                "block_total": 2618619,
                "block_used": 392887,
                "device": "/dev/vda1",
                "fstype": "xfs",
                "inode_available": 5196602,
                "inode_total": 5242304,
                "inode_used": 45702,
                "mount": "/",
                "options": "rw,seclabel,relatime,attr2,inode64,noquota",
                "size_available": 9116598272,
                "size_total": 10725863424,
                "uuid": "a8063676-44dd-409a-b584-68be2c9f5570"
            }
        ]
    },
    "changed": false
}
britho commented 3 years ago

Neste exercício, você particionará um novo disco, criará volumes lógicos e os formatará com os sistemas de arquivos XFS, montando-os imediata e automaticamente no momento da inicialização nos hosts gerenciados.

Resultados

Você deverá ser capaz de:

  • Usar o módulo parted para configurar as partições de dispositivos de bloco.

  • Usar o módulo lvg para gerenciar grupos de volume do LVM.

  • Usar o módulo lvol para gerenciar volumes lógicos LVM.

  • Usar o módulo filesystem para criar sistemas de arquivos.

  • Usar o módulo mount para controlar e configurar pontos de montagem em /etc/fstab.

Em workstation, execute o script lab system-storage start para configurar o ambiente para o exercício. O script cria o diretório do projeto system-storage e faz o download dos arquivos de configuração e inventário de host do Ansible necessários para o exercício.

[student@workstation ~]$ lab system-storage start

Visão geral do cenário

Você é responsável por gerenciar um conjunto de servidores da web. Uma prática recomendada para a configuração do servidor web é armazenar dados do servidor web em uma partição separada ou em um volume lógico.

Você escreverá um playbook para:

  • Gerenciar partições do dispositivo /dev/vdb

  • Gerenciar um grupo de volumes chamado apache-vg para dados do servidor web

  • Criar dois volumes lógicos chamados content-lv e logs-lv, ambos apoiados pelo grupo de volumes apache-vg

  • Criar um sistema de arquivo XFS em ambos os volumes lógicos

  • Montar o volume lógico content-lv em /var/www

  • Montar o volume lógico logs-lv em /var/log/httpd

Se os requisitos de armazenamento para o servidor web forem alterados, atualize as variáveis apropriadas e execute o playbook novamente. O playbook deve ser idempotente.

  1. Em workstation, como usuário student, acesse o diretório de trabalho /home/student/system-storage.

    [student@workstation ~]$ cd ~/system-storage
    [student@workstation system-storage]$
    
  2. Revise o arquivo storage.yml do playbook do esqueleto e o arquivo storage_vars.yml de variáveis associadas no diretório do projeto. Execute o playbook.

    1. Revise o playbook storage.yml.

      ---
      - name: Ensure Apache Storage Configuration
        hosts: webservers
        vars_files:
          - storage_vars.yml
        tasks:
          - name: Correct partitions exist on /dev/vdb
            debug:
              msg: TODO
            loop: "{{ partitions }}"
          - name: Ensure Volume Groups Exist
            debug:
              msg: TODO
            loop: "{{  volume_groups }}"
          - name: Create each Logical Volume (LV) if needed
            debug:
              msg: TODO
            loop: "{{ logical_volumes }}"
            when: true
          - name: Ensure XFS Filesystem exists on each LV
            debug:
              msg: TODO
            loop: "{{ logical_volumes }}"
          - name: Ensure the correct capacity for each LV
            debug:
              msg: TODO
            loop: "{{ logical_volumes }}"
          - name: Each Logical Volume is mounted
            debug:
              msg: TODO
            loop: "{{ logical_volumes }}"

      O nome de cada tarefa funciona como um esboço do procedimento pretendido a ser implementado. Em etapas posteriores, você atualizará e alterará essas seis tarefas.

    2. Revise o arquivo de variáveis storage_vars.yml.

      ---
      partitions:
        - number: 1
          start: 1MiB
          end: 257MiB
      volume_groups:
        - name: apache-vg
          devices: /dev/vdb1
      logical_volumes:
        - name: content-lv
          size: 64M
          vgroup: apache-vg
          mount_path: /var/www
        - name: logs-lv
          size: 128M
          vgroup: apache-vg
          mount_path: /var/log/httpd

      Esse arquivo descreve a estrutura pretendida de partições, grupos de volumes e volumes lógicos em cada servidor web. A primeira partição começa com um deslocamento de 1 MiB desde o início do dispositivo /dev/vdb e termina em um deslocamento de 257 MiB, com um tamanho total de 256 MiB.

      Cada servidor web tem um grupo de volumes, denominado apache-vg, que contém a primeira partição do dispositivo /dev/vdb.

      Cada servidor web tem dois volumes lógicos. O primeiro volume lógico é denominado content-lv, com um tamanho de 64 MiB, anexado ao grupo de volumes apache-vg e montado em /var/www. O segundo volume lógico é denominado content-lv, com um tamanho de 128 MiB, anexado ao grupo de volumes apache-vg e montado em /var/log/httpd.

      O grupo de volumes apache-vg tem uma capacidade de 256 MiB porque é apoiado pela partição /dev/vdb1. Ele oferece capacidade suficiente para ambos os volumes lógicos.

    3. Execute o playbook storage.yml.

      [student@workstation system-storage]$ ansible-playbook storage.yml
      PLAY [Ensure Apache Storage Configuration] ***********************************
      TASK [Gathering Facts] *******************************************************
      ok: [servera.lab.example.com]
      TASK [Correct partitions exist on /dev/vdb] **********************************
      ok: [servera.lab.example.com] => (item={u'start': u'1MiB', u'end': u'257MiB', u'number': 1}) => {
          "msg": "TODO"
      }
      ...output omitted...
      TASK [Each Logical Volume is mounted] ****************************************
      ok: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'64M', u'mount_path': u'/var/www', u'name': u'content-lv'}) => {
          "msg": "TODO"
      }
      ok: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'128M', u'mount_path': u'/var/log/httpd', u'name': u'logs-lv'}) => {
          "msg": "TODO"
      }
      PLAY RECAP *******************************************************************
      servera.lab.example.com    : ok=7    changed=0    unreachable=0    failed=0
  3. Altere a primeira tarefa para usar o módulo parted para configurar uma partição para cada item de loop. Cada item descreve uma partição pretendida do dispositivo /dev/vdb em cada servidor web:

    number

    O número da partição. Use isso como o valor da palavra-chave number para o módulo parted.

    start

    O início da partição, como um deslocamento desde o início do dispositivo de bloco. Use isso como o valor da palavra-chave part_start para o módulo parted.

    end

    O final da partição, como um deslocamento desde o início do dispositivo de bloco. Use isso como o valor da palavra-chave part_end para o módulo parted.

    O conteúdo da primeira tarefa deve ser:

        - name: Correct partitions exist on /dev/vdb
          parted:
            device: /dev/vdb
            state: present
            number: "{{ item.number }}"
            part_start: "{{ item.start }}"
            part_end: "{{ item.end }}"
          loop: "{{ partitions }}"
  4. Altere a segunda tarefa da ação para que use o módulo lvg para configurar um grupo de volumes para cada item de loop. Cada item da variável volume_groups descreve um grupo de volumes que deve existir em cada servidor web:

    name

    O nome do grupo de volumes. Use isso como o valor da palavra-chave vg para o módulo lvg.

    devices

    Uma lista de dispositivos ou partições separados por vírgulas que formam o grupo de volumes. Use isso como o valor da palavra-chave pvs para o módulo lvg.

    O conteúdo da segunda tarefa deve ser:

        - name: Ensure Volume Groups Exist
          lvg:
            vg: "{{ item.name }}"
            pvs: "{{ item.devices }}"
          loop: "{{  volume_groups }}"
  5. Altere a terceira tarefa da ação para que use o módulo lvol para criar um volume lógico para cada item. Use as palavras-chave do item para criar o novo volume lógico:

    name

    O nome do volume lógico. Use isso como o valor da palavra-chave lv para o módulo lvol.

    vgroup

    O nome do grupo de volumes que fornece armazenamento para o volume lógico.

    size

    O tamanho do volume lógico. O valor dessa palavra-chave é qualquer valor aceitável para a opção -L do comando lvcreate.

    Apenas execute a tarefa se um volume lógico ainda não existir. Atualize a instrução when para verificar se não há um volume lógico com um nome que corresponda ao valor da palavra-chave do item name.

    1. Altere a terceira tarefa para que use o módulo lvol. Defina o nome do grupo de volumes, o nome do volume lógico e o tamanho do volume lógico usando as palavras-chave de cada item. O conteúdo da terceira tarefa agora é:

          - name: Create each Logical Volume (LV) if needed
            lvol:
              vg: "{{ item.vgroup }}"
              lv: "{{ item.name }}"
              size: "{{ item.size }}"
            loop: "{{ logical_volumes }}"
            when: true
    2. O fato ansible_lvm do Ansible contém informações sobre objetos do gerenciamento de volume lógico em cada host. Use um comando ad hoc para ver o conjunto atual de volumes lógicos no host remoto:

      [student@workstation system-storage]$ ansible all -m setup -a \
      > "filter=ansible_lvm"
      servera.lab.example.com | SUCCESS => {
          "ansible_facts": {
              "ansible_lvm": {
                  "lvs": {},
                  "pvs": {},
                  "vgs": {}
              },
              "discovered_interpreter_python": "/usr/libexec/platform-python"
          },
          "changed": false
      }

      O valor da palavra-chave lvs indica que não há volumes lógicos no host remoto.

    3. Execute o playbook para criar os volumes lógicos no host remoto.

      [student@workstation system-storage]$ ansible-playbook storage.yml
      PLAY [Ensure Apache Storage Configuration] ***********************************
      TASK [Gathering Facts] *******************************************************
      ok: [servera.lab.example.com]
      TASK [Correct partitions exist on /dev/vdb] **********************************
      changed: [servera.lab.example.com] => (item={...output omitted...})
      TASK [Ensure Volume Groups Exist] ********************************************
      changed: [servera.lab.example.com] => (item={...output omitted...})
      TASK [Create each Logical Volume (LV) if needed] *****************************
      changed: [servera.lab.example.com] => (item={...output omitted...})
      changed: [servera.lab.example.com] => (item={...output omitted...})
      TASK [Ensure XFS Filesystem exists on each LV] *******************************
      ok: [servera.lab.example.com] => (item={...output omitted...}) => {
          "msg": "TODO"
      }
      ...output omitted...
      PLAY RECAP *******************************************************************
      servera.lab.example.com    : ok=7    changed=3    unreachable=0    failed=0
    4. Execute outro comando ad hoc para ver a estrutura da variável ansible_lvm quando existem volumes lógicos no host remoto.

      [student@workstation system-storage]$ ansible all -m setup -a \
      > "filter=ansible_lvm"
      servera.lab.example.com | SUCCESS => {
          "ansible_facts": {
              "ansible_lvm": {
                  "lvs": 1{
                      "content-lv": {
                          "size_g": "0.06",
                          "vg": "apache-vg"
                      },
                      "logs-lv": {
                          "size_g": "0.12",
                          "vg": "apache-vg"
                      }
                  },
                  "pvs": 2{
                      "/dev/vdb1": {
                          "free_g": "0.06",
                          "size_g": "0.25",
                          "vg": "apache-vg"
                      }
                  },
                  "vgs": 3{
                      "apache-vg": {
                          "free_g": "0.06",
                          "num_lvs": "2",
                          "num_pvs": "1",
                          "size_g": "0.25"
                      }
                  }
              }
          },
          "changed": false
      }
        | O valor da palavra-chave lvs é uma estrutura de dados do par de chaves. As chaves dessa estrutura são os nomes de quaisquer volumes lógicos no host. Isso indica que ambos os volumes lógicos content-lv e logs-lv existem. Para cada volume lógico, o grupo de volumes correspondente é fornecido pela palavra-chave vg. -- | --   | A palavra-chave pvs contém informações sobre volumes físicos no host. A informação indica que a partição /dev/vdb1 pertence ao grupo de volumes apache-vg.   | A palavra-chave vgs contém informações sobre grupos de volumes no host.
    5. Atualize a instrução when para verificar se não há um volume lógico com um nome que corresponda ao valor da palavra-chave do item name. O conteúdo da terceira tarefa agora é:

          - name: Create each Logical Volume (LV) if needed
            lvol:
              vg: "{{ item.vgroup }}"
              lv: "{{ item.name }}"
              size: "{{ item.size }}"
            loop: "{{ logical_volumes }}"
            when: item.name not in ansible_lvm["lvs"]
  6. Altere a quarta tarefa para que use o módulo filesystem. Configure a tarefa para garantir que cada volume lógico seja formatado como um sistema de arquivos XFS. Lembre-se de que um volume lógico está associado ao dispositivo lógico /dev/<volume group name>/<logical volume name>.

    O conteúdo da quarta tarefa deve ser:

        - name: Ensure XFS Filesystem exists on each LV
          filesystem:
            dev: "/dev/{{ item.vgroup }}/{{ item.name }}"
            fstype: xfs
          loop: "{{ logical_volumes }}"
  7. Configure a quinta tarefa para garantir que cada volume lógico tenha a capacidade de armazenamento correta. Se o volume lógico aumentar em capacidade, certifique-se de forçar a expansão do sistema de arquivos do volume.

    Se um volume lógico precisar ter sua capacidade diminuída, essa tarefa apresentará falha porque um sistema de arquivos XFS não é compatível com a capacidade de diminuição.

    O conteúdo da quinta tarefa deve ser:

        - name: Ensure the correct capacity for each LV
          lvol:
            vg: "{{ item.vgroup }}"
            lv: "{{ item.name }}"
            size: "{{ item.size }}"
            resizefs: yes
            force: yes
          loop: "{{ logical_volumes }}"
  8. Use o módulo mount na sexta tarefa para garantir que cada volume lógico seja montado no caminho de montagem correspondente e persista após uma reinicialização.

    O conteúdo da sexta tarefa deve ser:

        - name: Each Logical Volume is mounted
          mount:
            path: "{{ item.mount_path }}"
            src: "/dev/{{ item.vgroup }}/{{ item.name }}"
            fstype: xfs
            opts: noatime
            state: mounted
          loop: "{{ logical_volumes }}"
  9. Revise o playbook storage.yml concluído. Execute o playbook e verifique se cada volume lógico está montado.

    1. Revise o playbook:

      ---
      - name: Ensure Apache Storage Configuration
        hosts: webservers
        vars_files:
          - storage_vars.yml
        tasks:
          - name: Correct partitions exist on /dev/vdb
            parted:
              device: /dev/vdb
              state: present
              number: "{{ item.number }}"
              part_start: "{{ item.start }}"
              part_end: "{{ item.end }}"
            loop: "{{ partitions }}"
          - name: Ensure Volume Groups Exist
            lvg:
              vg: "{{ item.name }}"
              pvs: "{{ item.devices }}"
            loop: "{{  volume_groups }}"
          - name: Create each Logical Volume (LV) if needed
            lvol:
              vg: "{{ item.vgroup }}"
              lv: "{{ item.name }}"
              size: "{{ item.size }}"
            loop: "{{ logical_volumes }}"
            when: item.name not in ansible_lvm["lvs"]
          - name: Ensure XFS Filesystem exists on each LV
            filesystem:
              dev: "/dev/{{ item.vgroup }}/{{ item.name }}"
              fstype: xfs
            loop: "{{ logical_volumes }}"
          - name: Ensure the correct capacity for each LV
            lvol:
              vg: "{{ item.vgroup }}"
              lv: "{{ item.name }}"
              size: "{{ item.size }}"
              resizefs: yes
              force: yes
            loop: "{{ logical_volumes }}"
          - name: Each Logical Volume is mounted
            mount:
              path: "{{ item.mount_path }}"
              src: "/dev/{{ item.vgroup }}/{{ item.name }}"
              fstype: xfs
              opts: noatime
              state: mounted
            loop: "{{ logical_volumes }}"
    2. Execute o playbook.

      [student@workstation system-storage]$ ansible-playbook storage.yml
      PLAY [Ensure Apache Storage Configuration] ***********************************
      TASK [Gathering Facts] *******************************************************
      ok: [servera.lab.example.com]
      TASK [Correct partitions exist on /dev/vdb] **********************************
      ok: [servera.lab.example.com] => (item={...output omitted...})
      TASK [Ensure Volume Groups Exist] ********************************************
      ok: [servera.lab.example.com] => (item={...output omitted...})
      ...output omitted...
      TASK [Create each Logical Volume (LV) if needed] *****************************
      skipping: [servera.lab.example.com] => (item={...output omitted...})
      skipping: [servera.lab.example.com] => (item={...output omitted...})
      TASK [Ensure XFS Filesystem exists on each LV] *******************************
      changed: [servera.lab.example.com] => (item={...output omitted...})
      changed: [servera.lab.example.com] => (item={...output omitted...})
      TASK [Ensure the correct capacity for each LV] *******************************
      ok: [servera.lab.example.com] => (item={...output omitted...})
      ok: [servera.lab.example.com] => (item={...output omitted...})
      TASK [Each Logical Volume is mounted] ****************************************
      changed: [servera.lab.example.com] => (item={...output omitted...})
      changed: [servera.lab.example.com] => (item={...output omitted...})
      PLAY RECAP *******************************************************************
      servera.lab.example.com    : ok=6    changed=2    unreachable=0    failed=0    
      skipped=1    rescued=0    ignored=0

      Uma tarefa é ignorada durante a execução porque o playbook foi executado anteriormente com os mesmos valores de variáveis. Os volumes lógicos não precisaram ser criados.

    3. Use um comando ad hoc do Ansible para executar o comando lsblk no host remoto. A saída indica os pontos de montagem para os volumes lógicos.

      [student@workstation system-storage]$ ansible all -a lsblk
      servera.lab.example.com | CHANGED | rc=0 >>
      NAME                       MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
      sr0                         11:0    1 1024M  0 rom
      vda                        252:0    0   10G  0 disk
      └─vda1                     252:1    0   10G  0 part /
      vdb                        252:16   0    1G  0 disk
      └─vdb1                     252:17   0  256M  0 part
        ├─apache--vg-content--lv 253:0    0   64M  0 lvm  /var/www
        └─apache--vg-logs--lv    253:1    0  128M  0 lvm  /var/log/httpd
  10. Aumente a capacidade do volume lógico content-lv para 128 MiB e do volume lógico logs-lv para 256 MiB. Isso exige um aumento na capacidade do grupo de volumes apache-vg.

    Crie uma nova partição com uma capacidade de 256 MiB e adicione-a ao grupo de volumes apache-vg.

    1. Edite a definição da variável partitions no arquivo storage_vars.yml para adicionar uma segunda partição ao dispositivo /dev/vdb. O conteúdo da variável partitions deve ser:

      partitions:
        - number: 1
          start: 1MiB
          end: 257MiB
        - number: 2
          start: 257MiB
          end: 513MiB
    2. Edite a definição da variável volume_groups no arquivo storage_vars.yml. Adicione a segunda partição à lista de dispositivos que suportam o grupo de volumes. O conteúdo da variável volume_groups deve ser:

      volume_groups:
        - name: apache-vg
          devices: /dev/vdb1,/dev/vdb2
    3. Dobre a capacidade de cada volume lógico definido no arquivo storage_vars.yml. O conteúdo da variável logical_volumes deve ser:

      logical_volumes:
        - name: content-lv
          size: 128M
          vgroup: apache-vg
          mount_path: /var/www
        - name: logs-lv
          size: 256M
          vgroup: apache-vg
          mount_path: /var/log/httpd
    4. Execute o playbook. Verifique a nova capacidade de cada volume lógico.

      [student@workstation system-storage]$ ansible-playbook storage.yml
      PLAY [Ensure Apache Storage Configuration] ***********************************
      TASK [Gathering Facts] *******************************************************
      ok: [servera.lab.example.com]
      TASK [Correct partitions exist on /dev/vdb] **********************************
      ok: [servera.lab.example.com] => (item={...output omitted...})
      changed: [servera.lab.example.com] => (item={u'start': u'257MiB', u'end': u'513MiB', u'number': 2})
      TASK [Ensure Volume Groups Exist] ********************************************
      changed: [servera.lab.example.com] => (item={u'name': u'apache-vg', u'devices': u'/dev/vdb1,/dev/vdb2'})
      ...output omitted...
      TASK [Create each Logical Volume (LV) if needed] *****************************
      skipping: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'128M', u'mount_path': u'/var/www', u'name': u'content-lv'})
      skipping: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'256M', u'mount_path': u'/var/log/httpd', u'name': u'logs-lv'})
      TASK [Ensure XFS Filesystem exists on each LV] *******************************
      ok: [servera.lab.example.com] => (item={...output omitted...})
      ok: [servera.lab.example.com] => (item={...output omitted...})
      TASK [Ensure the correct capacity for each LV] *******************************
      changed: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'128M', u'mount_path': u'/var/www', u'name': u'content-lv'})
      changed: [servera.lab.example.com] => (item={u'vgroup': u'apache-vg', u'size': u'256M', u'mount_path': u'/var/log/httpd', u'name': u'logs-lv'})
      TASK [Each Logical Volume is mounted] ****************************************
      ok: [servera.lab.example.com] => (item={...output omitted...})
      ok: [servera.lab.example.com] => (item={...output omitted...})
      PLAY RECAP *******************************************************************
      servera.lab.example.com    : ok=6    changed=3    unreachable=0    failed=0    
      skipped=1    rescued=0    ignored=0

      A saída indica mudanças nas partições e no grupo de volumes no host remoto e que ambos os volumes lógicos foram redimensionados.

    5. Use um comando ad hoc do Ansible para executar o comando lsblk no host remoto.

      [student@workstation system-storage]$ ansible all -a lsblk
      servera.lab.example.com | CHANGED | rc=0 >>
      NAME                       MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
      sr0                         11:0    1 1024M  0 rom
      vda                        252:0    0   10G  0 disk
      └─vda1                     252:1    0   10G  0 part /
      vdb                        252:16   0    1G  0 disk
      ├─vdb1                     252:17   0  256M  0 part
      │ ├─apache--vg-content--lv 253:0    0  128M  0 lvm  /var/www
      │ └─apache--vg-logs--lv    253:1    0  256M  0 lvm  /var/log/httpd
      └─vdb2                     252:18   0  256M  0 part
        ├─apache--vg-content--lv 253:0    0  128M  0 lvm  /var/www
        └─apache--vg-logs--lv    253:1    0  256M  0 lvm  /var/log/httpd

      A saída indica que cada volume lógico tem o tamanho correto e está montado no diretório correto. Há duas entradas para cada volume lógico porque os arquivos armazenados no volume lógico podem estar fisicamente localizados em qualquer partição (/dev/vdb1 ou /dev/vdb2).

Encerramento

Execute o comando lab system-storage finish para limpar o host gerenciado.

[student@workstation ~]$ lab system-storage finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Objetivos

Depois de concluir esta seção, você deverá ser capaz de definir as configurações de rede e a resolução de nomes em hosts gerenciados, bem como coletar fatos do Ansible relacionados à rede.

Configuração de rede com a função de sistema de rede

O Red Hat Enterprise Linux 8 inclui uma coleção de funções Ansible do sistema para configurar sistemas baseados no RHEL. O pacote rhel-system-roles instala essas funções do sistema que, por exemplo, dão suporte para a configuração de sincronização de horário ou rede. Você pode listar as funções do sistema atualmente instaladas com o comando ansible-galaxy list.

[user@controlnode ~]$ ansible-galaxy list
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)

As funções estão localizadas no diretório /usr/share/ansible/roles. Uma função que comece com linux-system-roles é um symlink para a função rhel-system-roles correspondente.

A função de sistema de rede dá suporte à configuração de rede em hosts gerenciados. Essa função dá suporte para a configuração de interfaces ethernet, interfaces bridge, interfaces vinculadas, interfaces VLAN, interfaces MacVLAN e interfaces Infiniband. A função de rede é configurada com duas variáveis, network_provider e network_connections .

---
network_provider: nm
network_connections:
  - name: ens4
    type: ethernet
    ip:
      address:
        - 172.25.250.30/24

A variável network_provider configura o provedor de back-end, que é nm (NetworkManager) ou initscripts. No Red Hat Enterprise Linux 8, a função de rede usa nm (NetworkManager) como provedor de rede padrão. O provedor initscripts provedor é usado para sistemas RHEL 6 e requer que o serviço network esteja disponível. A variável network_connections configura as diferentes conexões, especificadas como uma lista de dicionários, usando o nome da interface como o nome da conexão.

A tabela a seguir lista as opções da variável network_connections.

Nome da opção | Descrição -- | -- name | Identifica o perfil de conexão. state | O estado do tempo de execução de um perfil de conexão. up se o perfil de conexão estiver ativo ou down se não estiver. persistent_state | Identifica se um perfil de conexão é persistente. present se o perfil de conexão for persistente ou absent se não for. type | Identifica o tipo de conexão. Os valores válidos são ethernet, bridge, bond, team, vlan, macvlan e infiniband. autoconnect | Determina se a conexão é iniciada automaticamente. mac | Restringe a conexão a ser usada em dispositivos com um endereço MAC específico. interface_name | Restringe o perfil de conexão a ser usado por uma interface específica. zone | Configura a zona do FirewallD para a interface. ip | Determina a configuração de IP da conexão. É compatível com opções como address, para especificar um endereço IP estático, ou dns, para configurar um servidor DNS.

O seguinte exemplo usa algumas das opções anteriores:

network_connections:
- name: eth0 1
   persistent_state: present  2
   type: ethernet  3
   autoconnect: yes  4
   mac: 00:00:5e:00:53:5d  5
   ip:
     address:
       - 172.25.250.40/24  6
   zone: external  7

  | Usa eth0 como o nome da conexão. -- | --   | Torna a conexão persistente. Esse é o valor padrão.   | Define o tipo de conexão como ethernet .   | Inicia automaticamente a conexão durante o boot. Esse é o valor padrão.   | Restringe o uso da conexão a um dispositivo com esse endereço MAC.   | Configura o endereço IP 172.25.250.40/24 para a conexão.   | Configura a zona external como a zona do FirewallD da conexão.

Para usar a função de sistema de rede, é necessário especificar o nome da função na cláusula roles do seu playbook da seguinte forma:

- name: NIC Configuration
  hosts: webservers
  vars:
    network_connections:
      - name: ens4
        type: ethernet
        ip:
          address:
            - 172.25.250.30/24
  roles:
    - rhel-system-roles.network

Você pode especificar variáveis para a função de rede com a cláusula vars, como no exemplo anterior, ou criar um arquivo YAML com essas variáveis nos diretórios group_vars ou host_vars, dependendo do seu caso de uso.

Configuração de rede com módulos

Como alternativa à função de sistema network, o Red Hat Ansible Engine inclui uma coleção de módulos que dão suporte à configuração de rede em um sistema. O módulo nmcli dá suporte ao gerenciamento de conexões de rede e dispositivos. Esse módulo dá suporte à configuração de agrupamento e vinculação para interfaces de rede, bem como endereçamento IPv4 e IPv6.

A tabela a seguir lista alguns dos parâmetros do módulo nmcli.

Nome do parâmetro | Descrição -- | -- conn_name | Configura o nome da conexão. autoconnect | Permite a ativação automática da conexão durante o boot. dns4 | Configura servidores DNS para IPv4 (até 3). gw4 | Configura o gateway IPv4 da interface. ifname | Interface a ser vinculada à conexão. ip4 | Endereço IP (IPv4) da interface. state | Ativa ou desativa a interface de rede. type | Tipo de dispositivo ou conexão de rede.

O exemplo a seguir define uma configuração de IP estático para uma conexão de rede e um dispositivo.

- name: NIC configuration
  nmcli:
    conn_name: ens4-conn 1
    ifname: ens4 2
    type: ethernet 3
    ip4: 172.25.250.30/24 4
    gw4: 172.25.250.1 5
    state: present 6

  | Configura ens4-conn como o nome da conexão. -- | --   | Vincula a conexão ens4-conn à interface de rede ens4.   | Configura a interface de rede como ethernet.   | Configura o endereço IP 172.25.250.30/24 na interface.   | Define o gateway como 172.25.250.1.   | Garante que a conexão esteja disponível.

O módulo hostname define o nome do host de um host gerenciado sem modificar o arquivo /etc/hosts. Esse módulo usa o parâmetro name para especificar o novo nome do host, como na tarefa mostrada abaixo:

- name: Change hostname
  hostname:
    name: managedhost1

O módulo firewalld dá suporte ao gerenciamento de FirewallD em hosts gerenciados. Esse módulo dá suporte à configuração de regras do FirewallD para serviços e portas. Ele também dá suporte ao gerenciamento de zona, incluindo a associação ou as interfaces de rede e as regras de uma zona específica.

A tarefa a seguir mostra como criar uma regra do FirewallD para o serviço http na zona padrão (public). A tarefa configura a regra como permanente e garante que esteja ativa.

- name: Enabling http rule
  firewalld:
    service: http
    permanent: yes
    state: enabled

Essa tarefa configura eth0 na zona external do FirewallD.

- name: Moving eth0 to external
  firewalld:
    zone: external
    interface: eth0
    permanent: yes
    state: enabled

A tabela a seguir lista alguns dos parâmetros do módulo firewalld.

Nome do parâmetro | Descrição -- | -- interface | O nome da interface a ser gerenciada com o FirewallD. port | Porta ou intervalo de portas. Usa o formato porta/protocolo ou porta-porta/protocolo. rich_rule | Regra avançada do FirewallD. service | Nome do serviço a ser gerenciado com o FirewallD. source | Rede de origem a ser gerenciada com o FirewallD. zone | A zona do FirewallD. state | Ativa ou desativa uma configuração do FirewallD. type | Tipo de dispositivo ou conexão de rede.

Fatos do Ansible para configuração de rede

O Ansible usa fatos para recuperar informações para o nó de controle sobre a configuração dos hosts gerenciados. Você pode usar o módulo setup do Ansible para recuperar todos os fatos do Ansible de um host gerenciado.

[user@controlnode ~]$ ansible webservers -m setup
host.lab.example.com | SUCCESS => {
    "ansible_facts": {
...output omitted...
    }

Todas as interfaces de rede de um host gerenciado estão disponíveis sob o elemento ansible_interfaces. Você pode usar o parâmetro gather_subset=network para o módulo setup a fim de restringir os fatos aos incluídos no subconjunto network. A opção filter do módulo setup é compatível com filtragem refinada baseada em curingas de estilo shell.

[user@controlnode ~]$ ansible webservers -m setup \
> -a 'gather_subset=network filter=ansible_interfaces'
host.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "ansible_interfaces": [
            "ens4",
            "lo",
            "ens3"
        ]
    },
    "changed": false
}

O comando anterior mostra que três interfaces de rede estão disponíveis no host gerenciado, host.lab.example.com: lo, ens3 e ens4.

Você pode recuperar informações adicionais sobre a configuração de uma interface de rede com o filtro ansible_NIC_name do módulo setup. Por exemplo, para recuperar a configuração da interface de rede ens4, use o filtro ansible_ens4.

[user@controlnode ~]$ ansible webservers -m setup \
> -a 'gather_subset=network filter=ansible_ens4'
host.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "ansible_ens4": {
            "active": true,
            "device": "ens4",
            "features": {
            },
            "hw_timestamp_filters": [],
            "ipv4": {
                "address": "172.25.250.30",
                "broadcast": "172.25.250.255",
                "netmask": "255.255.255.0",
                "network": "172.25.250.0"
            },
            "ipv6": [
                {
                    "address": "fe80::5b42:8c94:1fc7:40ae",
                    "prefix": "64",
                    "scope": "link"
                }
            ],
            "macaddress": "52:54:00:01:fa:0a",
            "module": "virtio_net",
            "mtu": 1500,
            "pciid": "virtio1",
            "promisc": false,
            "speed": -1,
            "timestamping": [
                "tx_software",
                "rx_software",
                "software"
            ],
            "type": "ether"
        }
    },
    "changed": false
}

O comando anterior exibe detalhes adicionais de configuração, como a configuração do endereço IP de IPv4 e IPv6, o dispositivo associado e o tipo.

A tabela a seguir lista alguns dos fatos disponíveis para o subconjunto network.

Nome do fato | Descrição -- | -- ansible_dns | Inclui o endereço IP dos servidores DNS e os domínios de pesquisa. ansible_domain | Inclui o subdomínio do host gerenciado. ansible_all_ipv4_addresses | Inclui todos os endereços IPv4 configurados no host gerenciado. ansible_all_ipv6_addresses | Inclui todos os endereços IPv6 configurados no host gerenciado. ansible_fqdn | Inclui o FQDN do host gerenciado. ansible_hostname | Inclui o nome do host não qualificado, a string no FQDN antes do primeiro ponto. ansible_nodename | Inclui o nome do host para o host gerenciado, conforme relatado pelo sistema.

O Ansible também fornece a variável inventory_hostname, que inclui o nome do host conforme configurado no arquivo de inventário do Ansible.

britho commented 3 years ago

Neste exercício, você ajustará a configuração de rede de um host gerenciado e coletará informações sobre ela em um arquivo criado por um template.

Resultados

Você deverá ser capaz de definir as configurações de rede e a resolução de nomes em hosts gerenciados, bem como coletar fatos do Ansible relacionados à rede.

Na workstation, execute o script lab system-network start para configurar o ambiente para o exercício. O script cria o diretório de trabalho system-network e faz o download dos arquivos de configuração e inventário de host do Ansible necessários para o exercício.

[student@workstation ~]$ lab system-network start

Revise o arquivo de inventário no diretório /home/student/system-network.

    Na workstation, como o usuário student, acesse o diretório de trabalho /home/student/system-network.

    [student@workstation ~]$ cd ~/system-network
    [student@workstation system-network]$

    Verifique se servera.lab.example.com faz parte do grupo de hosts webservers. Esse servidor tem uma interface de rede sobressalente.

    [student@workstation system-network]$ cat inventory
    [webservers]
    servera.lab.example.com

Use o comando ansible-galaxy para verificar se as funções do sistema estão disponíveis. Se nenhuma função estiver disponível, você precisará instalar o rhel-system-roles pacote.

[student@workstation system-network]$ ansible-galaxy list
# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
 [WARNING]: - the configured path /home/student/.ansible/roles does not exist.

Crie um playbook que use a função linux-system-roles.network para configurar a interface de rede sobressalente ens4 no servera.lab.example.com com o endereço IP 172.25.250.30.

    Crie um playbook, playbook.yml, com uma ação que tenha como destino o grupo de hosts webservers. Inclua a função rhel-system-roles.network na seção roles da ação.

    ---
    - name: NIC Configuration
      hosts: webservers

      roles:
        - rhel-system-roles.network

    Revise a seção Role Variables do arquivo README.md para a função rhel-system-roles.network. Determine as variáveis da função para configurar a interface de rede ens4 com o endereço IP 172.25.250.30.

    [student@workstation system-network]$ cat \
    > /usr/share/doc/rhel-system-roles/network/README.md
    ...output omitted...
    Setting the IP configuration:
    ...output omitted...

    Crie o subdiretório group_vars/webservers.

    [student@workstation system-network]$ mkdir -pv group_vars/webservers
    mkdir: created directory 'group_vars'
    mkdir: created directory 'group_vars/webservers'

    Crie um novo arquivo network.yml para definir variáveis da função. Como esses valores de variável se aplicam aos hosts no grupo de hosts webservers, você precisa criar esse arquivo no diretório group_vars/webservers. Adicione definições de variável para dar suporte à configuração da interface de rede ens4. O arquivo agora contém:

    ---
    network_connections:
      - name: ens4
        type: ethernet
        ip:
          address:
            - 172.25.250.30/24

    Execute o playbook para configurar a interface de rede secundária em servera.

    [student@workstation system-network]$ ansible-playbook playbook.yml

    PLAY [NIC Configuration] *******************************************************

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

    TASK [rhel-system-roles.network : Check which services are running] ************
    ok: [servera.lab.example.com]

    TASK [rhel-system-roles.network : Check which packages are installed] **********
    ok: [servera.lab.example.com]

    TASK [rhel-system-roles.network : Print network provider] **********************
    ok: [servera.lab.example.com] => {
        "msg": "Using network provider: nm"
    }

    TASK [rhel-system-roles.network : Install packages] ****************************
    skipping: [servera.lab.example.com]

    TASK [rhel-system-roles.network : Enable network service] **********************
    ok: [servera.lab.example.com]

    TASK [rhel-system-roles.network : Configure networking connection profiles] ****
    ...output omitted...

    changed: [servera.lab.example.com]

    TASK [rhel-system-roles.network : Re-test connectivity] ************************
    ok: [servera.lab.example.com]

    PLAY RECAP *********************************************************************
    servera.lab.example.com    : ok=7    changed=1    unreachable=0    failed=0    
    skipped=1    rescued=0    ignored=0

Use o módulo setup do Ansible em um comando adhoc do Ansible para verificar se a configuração da interface de rede ens4 em servera está correta.

    Use o módulo servera do Ansible para listar todos os fatos do Ansible disponíveis para servera. Filtre os resultados para a interface de rede ens4 com a opção -a 'filter=filter_string'. Verifique se a interface de rede ens4 usa o endereço IP 172.25.250.30. A configuração do endereço IP pode levar até um minuto.

    [student@workstation system-network]$ ansible webservers -m setup \
    > -a 'filter=ansible_ens4'
    servera.lab.example.com | SUCCESS => {
        "ansible_facts": {
            "ansible_ens4": {
    ...output omitted...
                "ipv4": {
                    "address": "172.25.250.30",
                    "broadcast": "172.25.250.255",
                    "netmask": "255.255.255.0",
                    "network": "172.25.250.0"
                },
    ...output omitted...

Encerramento

Em workstation, execute o script lab system-network finish para limpar os recursos criados neste exercício.

[student@workstation ~]$ lab system-network finish

Isso conclui o exercício orientado.

britho commented 3 years ago

Lista de verificação de desempenho

Neste laboratório, você configurará e realizará tarefas administrativas em hosts gerenciados usando um playbook.

Resultados

Você deverá ser capaz de criar playbooks para configurar em um host gerenciado um repositório de software, usuários e grupos, volumes lógicos, tarefas do cron e interfaces de rede adicionais.

Na workstation, execute o script de início do laboratório para confirmar se o ambiente está pronto para que o laboratório comece. O script cria o diretório de trabalho, chamado de system-review, e o preenche com um arquivo de configuração do Ansible, um inventário de host e arquivos de laboratório.

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

Crie e execute no grupo de hosts webservers um playbook que configure o repositório interno Yum localizado em http://materials.example.com/yum/repository e instale o pacote example-motd disponível nesse repositório. Todos os pacotes RPM são assinados com um par de chaves GPG organizacional. A chave pública GPG está disponível em http://materials.example.com/yum/repository/RPM-GPG-KEY-example.

    Na workstation, como o usuário student, acesse o diretório de trabalho /home/student/system-review.

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

    Crie o playbook repo_playbook.yml, que é executado nos hosts gerenciados no grupo de hosts webservers. Adicione uma tarefa que use o módulo yum_repository para garantir a configuração do repositório yum interno no host remoto. Certifique-se de que:

        A configuração do repositório está armazenada no arquivo /etc/yum.repos.d/example.repo

        A ID do repositório é example-internal

        O URL de base é http://materials.example.com/yum/repository

        O repositório está configurado para verificar as assinaturas GPG do RPM

        A descrição do repositório é Example Inc. Internal YUM repo 

    O playbook contém o seguinte:

    ---
    - name: Repository Configuration
      hosts: webservers
      tasks:
        - name: Ensure Example Repo exists
          yum_repository:
            name: example-internal
            description: Example Inc. Internal YUM repo
            file: example
            baseurl: http://materials.example.com/yum/repository/
            gpgcheck: yes

    Adicione uma segunda tarefa à ação que use o módulo rpm_key para garantir que a chave pública do repositório esteja presente no host remoto. A URL da chave pública do repositório é http://materials.example.com/yum/repository/RPM-GPG-KEY-example.

    A segunda tarefa aparece conforme segue:

        - name: Ensure Repo RPM Key is Installed
          rpm_key:
            key: http://materials.example.com/yum/repository/RPM-GPG-KEY-example
            state: present

    Adicione uma terceira tarefa para instalar o pacote example-motd disponível no repositório interno Yum.

    A terceira tarefa aparece conforme segue:

        - name: Install Example motd package
          yum:
            name: example-motd
            state: present

    Execute o playbook:

    [student@workstation system-review]$ ansible-playbook repo_playbook.yml

    PLAY [Repository Configuration] ************************************************

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

    TASK [Ensure Example Repo exists] **********************************************
    changed: [serverb.lab.example.com]

    TASK [Ensure Repo RPM Key is Installed] ****************************************
    changed: [serverb.lab.example.com]

    TASK [Install Example motd package] ********************************************
    changed: [serverb.lab.example.com]

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

Crie e execute no grupo de hosts webservers um playbook que crie o grupo de usuários webadmin e adicione dois usuários a esse grupo, ops1 e ops2.

Crie um arquivo de variável vars/users_vars.yml definindo dois usuários, ops1 e ops2, que pertencem ao grupo de usuários webadmin. Poderá ser necessário criar o subdiretório vars.

[student@workstation system-review]$ mkdir vars
[student@workstation system-review]$ vi vars/users_vars.yml
---
users:
  - username: ops1
    groups: webadmin
  - username: ops2
    groups: webadmin

Crie o playbook users.yml. Defina uma única ação no playbook que tenha como destino o grupo de hosts webservers. Adicione uma cláusula vars_files que define o local do nome do arquivo vars/users_vars.yml. Adicione uma tarefa que use o módulo group para criar o grupo de usuários webadmin no host remoto.

---
- name: Create multiple local users
  hosts: webservers
  vars_files:
    - vars/users_vars.yml
  tasks:
    - name: Add webadmin group
      group:
        name: webadmin
        state: present

Adicione uma segunda tarefa ao playbook que usa o módulo user para criar os usuários. Adicione uma cláusula loop: "{{ users }}" à tarefa para fazer loop no arquivo da variável para cada nome de usuário encontrado no arquivo vars/users_vars.yml. Como name: para os usuários, use o nome da variável item.username. Assim, o arquivo da variável pode conter informações adicionais que podem ser úteis para criar usuários, como os grupos aos quais os eles devem pertencer. A segunda tarefa contém o seguinte:

    - name: Create user accounts
      user:
        name: "{{ item.username }}"
        groups: webadmin
      loop: "{{ users }}"

Execute o playbook:

[student@workstation system-review]$ ansible-playbook users.yml

PLAY [Create multiple local users] ****************************************************

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

TASK [Add webadmin group] *************************************************************
changed: [serverb.lab.example.com]

TASK [Create user accounts] ***********************************************************
changed: [serverb.lab.example.com] => (item={'username': 'ops1', 'groups': 'webadmin'})
changed: [serverb.lab.example.com] => (item={'username': 'ops2', 'groups': 'webadmin'})

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

Crie e execute no grupo de hosts webservers um playbook que use o dispositivo /dev/vdb para criar um grupo de volumes chamado apache-vg. Esse playbook também cria dois volumes lógicos, chamados content-lv e logs-lv, ambos apoiados pelo grupo de volumes apache-vg. Por fim, crie um sistema de arquivos XFS em cada volume lógico e monte o volume lógico content-lv em /var/www e o volume lógico logs-lv em /var/log/httpd. O script de laboratório preenche dois arquivos em ~/system-review: storage.yml, que fornece um esqueleto inicial para o playbook, e storage_vars.xml, que fornece valores para todas as variáveis necessárias para os diferentes módulos.

Revise o arquivo de variável storage_vars.yml.

[student@workstation system-review]$ cat storage_vars.yml
---

partitions:
  - number: 1
    start: 1MiB
    end: 257MiB

volume_groups:
  - name: apache-vg
    devices: /dev/vdb1

logical_volumes:
  - name: content-lv
    size: 64M
    vgroup: apache-vg
    mount_path: /var/www

  - name: logs-lv
    size: 128M
    vgroup: apache-vg
    mount_path: /var/log/httpd

Esse arquivo descreve a estrutura pretendida de partições, grupos de volumes e volumes lógicos em cada servidor web. A primeira partição começa com um deslocamento de 1MiB desde o início do dispositivo /dev/vdb e termina em um deslocamento de 257MiB, em um tamanho total de 256MiB.

Cada servidor web tem um grupo de volumes, denominado apache-vg, que contém a primeira partição do dispositivo /dev/vdb.

Cada servidor web tem dois volumes lógicos. O primeiro volume lógico é denominado content-lv, com um tamanho de 64MiB, anexado ao grupo de volumes apache-vg e montado em /var/www. O segundo volume lógico é denominado content-lv, com um tamanho de 128MiB, anexado ao grupo de volumes apache-vg e montado em /var/log/httpd.

O grupo de volumes apache-vg tem uma capacidade de 256MiB porque é apoiado pela partição /dev/vdb1. Ele oferece capacidade suficiente para ambos os volumes lógicos.

Altere a primeira tarefa no playbook storage.yml para usar o módulo parted para configurar uma partição para cada item de loop. Cada item descreve uma partição pretendida do dispositivo /dev/vdb em cada servidor web:

number

    O número da partição. Use isso como o valor da palavra-chave number para o módulo parted. 
start

    O início da partição, como um deslocamento desde o início do dispositivo de bloco. Use isso como o valor da palavra-chave part_start para o módulo parted. 
end

    O final da partição, como um deslocamento desde o início do dispositivo de bloco. Use isso como o valor da palavra-chave part_end para o módulo parted. 

O conteúdo da primeira tarefa deve ser:

    - name: Correct partitions exist on /dev/vdb
      parted:
        device: /dev/vdb
        state: present
        number: "{{ item.number }}"
        part_start: "{{ item.start }}"
        part_end: "{{ item.end }}"
      loop: "{{ partitions }}"

Altere a segunda tarefa da ação para que use o módulo lvg para configurar um grupo de volumes para cada item de loop. Cada item da variável volume_groups descreve um grupo de volumes que deve existir em cada servidor web:

name

    O nome do grupo de volumes. Use isso como o valor da palavra-chave vg para o módulo lvg. 
devices

    Uma lista de dispositivos ou partições separados por vírgulas que formam o grupo de volumes. Use isso como o valor da palavra-chave pvs para o módulo lvg. 

O conteúdo da segunda tarefa deve ser:

    - name: Ensure Volume Groups Exist
      lvg:
        vg: "{{ item.name }}"
        pvs: "{{ item.devices }}"
      loop: "{{  volume_groups }}"

Altere a terceira tarefa para que use o módulo lvol. Defina o nome do grupo de volumes, o nome do volume lógico e o tamanho do volume lógico usando as palavras-chave de cada item. O conteúdo da terceira tarefa agora é:

    - name: Create each Logical Volume (LV) if needed
      lvol:
        vg: "{{ item.vgroup }}"
        lv: "{{ item.name }}"
        size: "{{ item.size }}"
      loop: "{{ logical_volumes }}"

Altere a quarta tarefa para que use o módulo filesystem. Configure a tarefa para garantir que cada volume lógico seja formatado como um sistema de arquivos XFS. Lembre-se de que um volume lógico está associado ao dispositivo lógico /dev/<volume group name>/<logical volume name>.

O conteúdo da quarta tarefa deve ser:

    - name: Ensure XFS Filesystem exists on each LV
      filesystem:
        dev: "/dev/{{ item.vgroup }}/{{ item.name }}"
        fstype: xfs
      loop: "{{ logical_volumes }}"

Configure a quinta tarefa para garantir que cada volume lógico tenha a capacidade de armazenamento correta. Se o volume lógico aumentar em capacidade, certifique-se de forçar a expansão do sistema de arquivos do volume.

Se um volume lógico precisar ter sua capacidade diminuída, essa tarefa apresentará falha porque um sistema de arquivos XFS não é compatível com a capacidade de diminuição.

O conteúdo da quinta tarefa deve ser:

    - name: Ensure the correct capacity for each LV
      lvol:
        vg: "{{ item.vgroup }}"
        lv: "{{ item.name }}"
        size: "{{ item.size }}"
        resizefs: yes
        force: yes
      loop: "{{ logical_volumes }}"

Use o módulo mount na sexta tarefa para garantir que cada volume lógico seja montado no caminho de montagem correspondente e persista após uma reinicialização.

O conteúdo da sexta tarefa deve ser:

    - name: Each Logical Volume is mounted
      mount:
        path: "{{ item.mount_path }}"
        src: "/dev/{{ item.vgroup }}/{{ item.name }}"
        fstype: xfs
        state: mounted
      loop: "{{ logical_volumes }}"

Execute o playbook para criar os volumes lógicos no host remoto.

[student@workstation system-review]$ ansible-playbook storage.yml
PLAY [Ensure Apache Storage Configuration] *************************************************

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

TASK [Correct partitions exist on /dev/vdb] ************************************************
changed: [serverb.lab.example.com] => (item={'number': 1, 'start': '1MiB', 'end': '257MiB'})

TASK [Ensure Volume Groups Exist] **********************************************************
changed: [serverb.lab.example.com] => (item={'name': 'apache-vg', 'devices': '/dev/vdb1'})
...output omitted...

TASK [Create each Logical Volume (LV) if needed] *******************************************
changed: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M', 'vgroup': 'apache-vg', 'mount_path': '/var/www'})
changed: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M', 'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})

TASK [Ensure XFS Filesystem exists on each LV] *********************************************
changed: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M', 'vgroup': 'apache-vg', 'mount_path': '/var/www'})
changed: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M', 'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})

TASK [Ensure the correct capacity for each LV] *********************************************
ok: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M', 'vgroup': 'apache-vg', 'mount_path': '/var/www'})
ok: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M', 'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})

TASK [Each Logical Volume is mounted] ******************************************************
changed: [serverb.lab.example.com] => (item={'name': 'content-lv', 'size': '64M', 'vgroup': 'apache-vg', 'mount_path': '/var/www'})
changed: [serverb.lab.example.com] => (item={'name': 'logs-lv', 'size': '128M', 'vgroup': 'apache-vg', 'mount_path': '/var/log/httpd'})

PLAY RECAP *********************************************************************************
serverb.lab.example.com    : ok=7    changed=5    unreachable=0    failed=0

Crie e execute no grupo de hosts webservers um playbook que use o módulo cron para criar o arquivo crontab /etc/cron.d/disk_usage, que agenda uma tarefa do cron recorrente. A tarefa deve ser executada com o usuário devops a cada dois minutos entre 09:00 e 16:59 de segunda-feira a sexta-feira. A tarefa deve anexar a utilização atual do disco ao arquivo /home/devops/disk_usage.

Crie um novo playbook, create_crontab_file.yml, e adicione as linhas necessárias para iniciar a ação. Ele deve ser direcionado ao hosts gerenciados no grupo webservers e ativar o escalonamento de privilégios.

---
- name: Recurring cron job
  hosts: webservers
  become: true

Defina uma tarefa que usa o módulo cron para agendar uma tarefa do cron recorrente.

O módulo cron fornece uma opção name para descrever exclusivamente a entrada do arquivo crontab e garantir os resultados esperados. A descrição é adicionada ao arquivo crontab. Por exemplo, a opção name é necessária se você estiver removendo uma entrada crontab usando state=absent. Além disso, quando o estado padrão state=present é definido, a opção name impede que uma nova entrada crontab seja sempre criada, independentemente das existentes.

  tasks:
    - name: Crontab file exists
      cron:
        name: Add date and time to a file

Configure a tarefa para que seja executada a cada dois minutos entre 09:00 e 16:59 de segunda-feira a sexta-feira.

        minute: "*/2"
        hour: 9-16
        weekday: 1-5

Use o parâmetro cron_file para usar o arquivo crontab /etc/cron.d/disk_usage em vez de usar o crontab de um usuário individual em /var/spool/cron/. Um caminho relativo colocará o arquivo no diretório /etc/cron.d. Se o parâmetro cron_file for usado, você também deverá especificar o parâmetro user.

        user: devops
        job: df >> /home/devops/disk_usage
        cron_file: disk_usage
        state: present

Quando concluído, o playbook deverá ficar desta forma: Revise o playbook para garantir a precisão.

---
- name: Recurring cron job
  hosts: webservers
  become: true

  tasks:
    - name: Crontab file exists
      cron:
        name: Add date and time to a file
        minute: "*/2"
        hour: 9-16
        weekday: 1-5
        user: devops
        job: df >> /home/devops/disk_usage
        cron_file: disk_usage
        state: present

Execute o playbook.

[student@workstation system-review]$ ansible-playbook create_crontab_file.yml
PLAY [Recurring cron job] *********************************************************************

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

TASK [Crontab file exists] ********************************************************************
changed: [serverb.lab.example.com]

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

Crie e execute no grupo de hosts webservers um playbook que use a função linux-system-roles.network para configurar com o endereço IP 172.25.250.40/24 a interface de rede sobressalente, ens4.

Use ansible-galaxy para verificar se as funções do sistema estão disponíveis. Caso contrário, você precisa instalar o pacote rhel-system-roles.

[student@workstation system-review]$ ansible-galaxy list
# /usr/share/ansible/roles
- linux-system-roles.kdump, (unknown version)
- linux-system-roles.network, (unknown version)
- linux-system-roles.postfix, (unknown version)
- linux-system-roles.selinux, (unknown version)
- linux-system-roles.timesync, (unknown version)
- rhel-system-roles.kdump, (unknown version)
- rhel-system-roles.network, (unknown version)
- rhel-system-roles.postfix, (unknown version)
- rhel-system-roles.selinux, (unknown version)
- rhel-system-roles.timesync, (unknown version)
# /etc/ansible/roles
 [WARNING]: - the configured path /home/student/.ansible/roles does not exist.

Crie um playbook, network_playbook.yml, com uma ação que tenha como destino o grupo de hosts webservers. Inclua a função rhel-system-roles.network na seção roles da ação.

---
- name: NIC Configuration
  hosts: webservers

  roles:
    - rhel-system-roles.network

Crie o subdiretório group_vars/webservers.

[student@workstation system-review]$ mkdir -pv group_vars/webservers
mkdir: created directory 'group_vars'
mkdir: created directory 'group_vars/webservers'

Crie um novo arquivo network.yml para definir variáveis da função. Como esses valores de variável se aplicam aos hosts no grupo de hosts webservers, você precisa criar esse arquivo no diretório group_vars/webservers. Adicione definições de variável para dar suporte à configuração da interface de rede ens4. O arquivo agora contém:

[student@workstation system-review]$ vi group_vars/webservers/network.yml
---
network_connections:
  - name: ens4
    type: ethernet
    ip:
      address:
        - 172.25.250.40/24

Execute o playbook para configurar a interface de rede secundária.

[student@workstation system-review]$ ansible-playbook network_playbook.yml

PLAY [NIC Configuration] *******************************************************************

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

TASK [rhel-system-roles.network : Check which services are running] ************************
ok: [serverb.lab.example.com]

TASK [rhel-system-roles.network : Check which packages are installed] **********************
ok: [serverb.lab.example.com]

TASK [rhel-system-roles.network : Print network provider] **********************************
ok: [serverb.lab.example.com] => {
    "msg": "Using network provider: nm"
}

TASK [rhel-system-roles.network : Install packages] ****************************************
skipping: [serverb.lab.example.com]

TASK [rhel-system-roles.network : Enable network service] **********************************
ok: [serverb.lab.example.com]

TASK [rhel-system-roles.network : Configure networking connection profiles] ****************
 [WARNING]: [002] <info>  #0, state:None persistent_state:present, 'ens4': add connection
ens4, 38d63afd-e610-4929-ba1b-1d38413219fb

changed: [serverb.lab.example.com]

TASK [rhel-system-roles.network : Re-test connectivity] ************************************
ok: [serverb.lab.example.com]

PLAY RECAP *********************************************************************************
serverb.lab.example.com    : ok=7    changed=1    unreachable=0    failed=0

Verifique se a interface de rede ens4 usa o endereço IP 172.25.250.40. A configuração do endereço IP pode levar até um minuto.

[student@workstation system-review]$ ansible webservers -m setup \
> -a 'filter=ansible_ens4'
serverb.lab.example.com | SUCCESS => {
    "ansible_facts": {
        "ansible_ens4": {
...output omitted...
            "ipv4": {
                "address": "172.25.250.40",
                "broadcast": "172.25.250.255",
                "netmask": "255.255.255.0",
                "network": "172.25.250.0"
            },
...output omitted...

Execute lab system-review grade na workstation para classificar seu trabalho.

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

Encerramento

Na workstation, execute o script lab system-review finish para limpar os recursos criados neste laboratório.

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

Isso conclui o laboratório. Red Hat logo

Privac
britho commented 3 years ago

Neste capítulo, você aprendeu que:

O módulo yum_repository configura um repositório Yum em um host gerenciado. Para repositórios que usam chaves públicas, é possível verificar se a chave está disponível com o módulo rpm_key.

Os módulos user e group criam usuários e grupos, respectivamente, em um host gerenciado. Você pode configurar chaves autorizadas para um usuário com o módulo authorized_key.

Tarefas do cron podem ser configuradas em hosts gerenciados com o módulo cron.

O Ansible dá suporte à configuração de volumes lógicos com os módulos lvg e lvol. Os módulos parted e filesystem dão suporte, respectivamente, ao particionamento de dispositivos e à criação de sistemas de arquivos.

O RedHat Enterprise Linux8 inclui a função de sistema de rede que dá suporte à configuração de interfaces de rede em hosts gerenciados.