Automatizar Tarefas de Administração RHEL com Ansible

AnsibleBeginner
Pratique Agora

Introdução

Neste laboratório abrangente, você dominará a automação de tarefas críticas de administração Linux usando Ansible. Com base em sua base em gerenciamento de arquivos, você agora explorará como gerenciar o ciclo de vida completo da administração do sistema, desde a instalação de software até o gerenciamento de usuários, configuração de serviços, provisionamento de armazenamento e configuração de rede.

Você começará automatizando o gerenciamento de pacotes de software e a configuração de repositórios usando módulos como ansible.builtin.dnf, ansible.builtin.yum_repository e ansible.builtin.rpm_key. Em seguida, você criará e gerenciará contas de usuário, configurará o acesso SSH e definirá privilégios sudo. O laboratório avança para o gerenciamento de serviços, tarefas agendadas com cron e systemd, antes de avançar para o gerenciamento de armazenamento usando LVM e operações de sistema de arquivos. Finalmente, você configurará interfaces de rede e coletará informações do sistema.

Este laboratório enfatiza cenários do mundo real comumente encontrados em ambientes Linux corporativos, preparando você para implementar práticas de Infraestrutura como Código (Infrastructure as Code) de forma eficaz.

Este é um Lab Guiado, que fornece instruções passo a passo para ajudá-lo a aprender e praticar. Siga as instruções cuidadosamente para completar cada etapa e ganhar experiência prática. Dados históricos mostram que este é um laboratório de nível iniciante com uma taxa de conclusão de 86%. Recebeu uma taxa de avaliações positivas de 62% dos estudantes.

Configurar Repositório e Gerenciar Pacotes de Software

Nesta etapa, você aprenderá a automatizar o gerenciamento de pacotes de software em sistemas RHEL usando Ansible. Você configurará um repositório Yum, gerenciará chaves GPG RPM e coletará informações de pacotes em hosts gerenciados. Isso é essencial para manter instalações de software consistentes em sua infraestrutura.

Você usará vários módulos chave: ansible.builtin.yum_repository para gerenciamento de repositórios, ansible.builtin.rpm_key para manipulação de chaves GPG, ansible.builtin.package_facts para coletar informações de pacotes e ansible.builtin.dnf para instalação de pacotes.

  1. Primeiro, configure o ambiente do projeto e instale o Ansible.

    Instale o pacote ansible-core e navegue até o diretório do projeto.

    sudo dnf install -y ansible-core
    cd ~/project
    mkdir system-software
    cd system-software
  2. Crie um arquivo de inventário Ansible para definir nossos hosts gerenciados. Para este laboratório, gerenciaremos a máquina local.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    
    [all:children]
    webservers
    EOF
  3. Crie o playbook principal repo_playbook.yml que gerenciará a configuração do repositório e a instalação de pacotes. Este playbook demonstra um fluxo de trabalho completo de gerenciamento de software.

    nano repo_playbook.yml

    Adicione o seguinte conteúdo para criar um playbook abrangente de gerenciamento de software:

    ---
    - name: Repository Configuration and Software Management
      hosts: all
      become: true
      vars:
        custom_pkg: httpd
      tasks:
        - name: Gather Package Facts
          ansible.builtin.package_facts:
            manager: auto
    
        - name: Show Package Facts for the custom package (initial check)
          ansible.builtin.debug:
            var: ansible_facts['packages'][custom_pkg]
          when: custom_pkg in ansible_facts['packages']
    
        - name: Ensure EPEL repository is configured
          ansible.builtin.yum_repository:
            name: epel
            description: Extra Packages for Enterprise Linux 9
            file: epel
            baseurl: https://download.fedoraproject.org/pub/epel/9/Everything/x86_64/
            gpgcheck: yes
            gpgkey: https://download.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-9
            enabled: yes
            state: present
    
        - name: Import EPEL GPG key
          ansible.builtin.rpm_key:
            state: present
            key: https://download.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-9
    
        - name: Install the custom package
          ansible.builtin.dnf:
            name: "{{ custom_pkg }}"
            state: present
    
        - name: Gather Package Facts (after installation)
          ansible.builtin.package_facts:
            manager: auto
    
        - name: Show Package Facts for the custom package (post-installation)
          ansible.builtin.debug:
            var: ansible_facts['packages'][custom_pkg]
          when: custom_pkg in ansible_facts['packages']
    
        - name: Display installed package version
          ansible.builtin.debug:
            msg: "{{ custom_pkg }} version {{ ansible_facts['packages'][custom_pkg][0]['version'] }} is installed"
          when: custom_pkg in ansible_facts['packages']

    Nota: O arquivo de configuração neste laboratório é bastante extenso, portanto, não forneceremos explicações detalhadas aqui para manter a documentação concisa. Se precisar de esclarecimentos sobre qualquer parte, clique no botão "Explain Code" no canto inferior esquerdo do bloco de código para obter explicações detalhadas pelo Labby.

    Este playbook demonstra vários conceitos importantes:

    • Coleta de fatos de pacotes: Mostra como coletar informações sobre pacotes instalados
    • Gerenciamento de repositórios: Configura o repositório EPEL com validação GPG adequada
    • Gerenciamento de chaves GPG: Importa a chave GPG do repositório para segurança
    • Instalação de pacotes: Instala o pacote especificado usando o módulo dnf
    • Verificação: Confirma a instalação do pacote com fatos atualizados
  4. Execute o playbook para ver o fluxo de trabalho completo de gerenciamento de software em ação.

    ansible-playbook -i inventory.ini repo_playbook.yml

    Você deverá ver a saída mostrando:

    • Verificação inicial do pacote (provavelmente ignorada, pois o httpd não está instalado)
    • Configuração do repositório
    • Importação da chave GPG
    • Instalação do pacote
    • Verificação final mostrando o pacote instalado
  5. Verifique a configuração do repositório verificando o arquivo de repositório criado.

    cat /etc/yum.repos.d/epel.repo

    Você deverá ver a configuração do repositório EPEL com as configurações de baseurl, gpgcheck e gpgkey.

  6. Teste a idempotência do gerenciamento de pacotes executando o playbook novamente.

    ansible-playbook -i inventory.ini repo_playbook.yml

    Observe que o Ansible relata "ok" para tarefas que não precisam de alterações, demonstrando idempotência.

Você automatizou com sucesso o gerenciamento de pacotes de software, incluindo configuração de repositório, gerenciamento de chaves GPG e verificação de instalação de pacotes usando Ansible.

Automatizar Gerenciamento de Usuários e Configuração SSH

Nesta etapa, você aprenderá a automatizar o gerenciamento de contas de usuário, configuração SSH e privilégios sudo usando Ansible. Isso é crucial para manter políticas consistentes de acesso de usuário e segurança em sua infraestrutura.

Você usará módulos como ansible.builtin.user para gerenciamento de usuários, ansible.builtin.group para criação de grupos, ansible.posix.authorized_key para gerenciamento de chaves SSH e ansible.builtin.lineinfile para modificação de arquivos de configuração.

  1. Navegue para um novo diretório de projeto para tarefas de gerenciamento de usuários.

    cd ~/project
    mkdir system-users
    cd system-users

    Instale a coleção ansible.posix.

    ansible-galaxy collection install ansible.posix
  2. Crie o arquivo de inventário para este exercício.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Crie um arquivo de variáveis para definir os usuários e grupos que queremos gerenciar.

    mkdir vars
    nano vars/users_vars.yml

    Adicione o seguinte conteúdo para definir contas de usuário e suas associações de grupo:

    ---
    users:
      - username: webuser1
        groups: webadmin
      - username: webuser2
        groups: webadmin
      - username: devuser1
        groups: webadmin
  4. Gere pares de chaves SSH para nossos usuários. Em um ambiente real, os usuários forneceriam suas chaves públicas.

    mkdir files
    
    ## Generate SSH keys for each user
    ssh-keygen -t rsa -b 2048 -f files/webuser1.key -N "" -C "webuser1@example.com"
    ssh-keygen -t rsa -b 2048 -f files/webuser2.key -N "" -C "webuser2@example.com"
    ssh-keygen -t rsa -b 2048 -f files/devuser1.key -N "" -C "devuser1@example.com"
  5. Crie o playbook principal de gerenciamento de usuários users.yml. Este playbook criará grupos, usuários, distribuirá chaves SSH e configurará o acesso sudo.

    nano users.yml

    Adicione o seguinte playbook abrangente de gerenciamento de usuários:

    ---
    - name: Create and manage user accounts
      hosts: webservers
      become: true
      vars_files:
        - vars/users_vars.yml
      tasks:
        - name: Create webadmin group
          ansible.builtin.group:
            name: webadmin
            state: present
    
        - name: Create user accounts
          ansible.builtin.user:
            name: "{{ item['username'] }}"
            groups: "{{ item['groups'] }}"
            shell: /bin/bash
            create_home: yes
            state: present
          loop: "{{ users }}"
    
        - name: Set up SSH authorized keys
          ansible.posix.authorized_key:
            user: "{{ item['username'] }}"
            key: "{{ lookup('file', 'files/' + item['username'] + '.key.pub') }}"
            state: present
          loop: "{{ users }}"
    
        - name: Configure sudo access for webadmin group
          ansible.builtin.lineinfile:
            path: /etc/sudoers.d/webadmin
            state: present
            create: yes
            mode: "0440"
            line: "%webadmin ALL=(ALL) NOPASSWD: ALL"
            validate: /usr/sbin/visudo -cf %s
    
        - name: Configure SSH to disable root login
          ansible.builtin.lineinfile:
            dest: /etc/ssh/sshd_config
            regexp: "^PermitRootLogin"
            line: "PermitRootLogin no"
            backup: yes
          notify: restart sshd
    
        - name: Configure SSH to disable password authentication
          ansible.builtin.lineinfile:
            dest: /etc/ssh/sshd_config
            regexp: "^PasswordAuthentication"
            line: "PasswordAuthentication no"
            backup: yes
          notify: restart sshd
    
      handlers:
        - name: restart sshd
          ansible.builtin.service:
            name: sshd
            state: restarted

    Este playbook demonstra várias práticas recomendadas de gerenciamento de usuários:

    • Gerenciamento de grupos: Cria grupos administrativos
    • Criação de usuários: Configura contas de usuário com diretórios home adequados
    • Gerenciamento de chaves SSH: Distribui chaves públicas para autenticação baseada em chave
    • Configuração de Sudo: Concede privilégios administrativos de forma segura
    • Endurecimento SSH: Desabilita login de root e autenticação por senha
    • Gerenciamento de serviços: Reinicia o serviço SSH quando as configurações são alteradas
  6. Execute o playbook de gerenciamento de usuários.

    ansible-playbook -i inventory.ini users.yml

    O playbook criará usuários, configurará chaves SSH, configurará o acesso sudo e endurecerá a configuração SSH.

  7. Verifique a criação de usuários e a associação de grupos.

    ## Check if users were created
    getent passwd webuser1 webuser2 devuser1
    
    ## Check group membership
    groups webuser1
    groups webuser2
    groups devuser1
    
    ## Verify webadmin group exists
    getent group webadmin
  8. Teste a autenticação por chave SSH para um dos usuários criados.

    ## Test SSH key authentication (this will connect to localhost)
    ssh -i files/webuser1.key webuser1@localhost "whoami"
  9. Verifique a configuração do sudo testando o acesso sudo sem senha.

    ## Test sudo access for webuser1
    ssh -i files/webuser1.key webuser1@localhost "sudo whoami"
  10. Verifique as alterações na configuração do SSH.

    ## Verify SSH configuration
    sudo grep "PermitRootLogin\|PasswordAuthentication" /etc/ssh/sshd_config
    
    ## Check sudo configuration
    sudo cat /etc/sudoers.d/webadmin

Você automatizou com sucesso a criação de contas de usuário, distribuição de chaves SSH e configuração de segurança usando Ansible, estabelecendo uma base para gerenciamento seguro de usuários em sua infraestrutura.

Automatizar Gerenciamento de Serviços e Agendamento de Tarefas

Nesta etapa, você aprenderá a gerenciar serviços systemd, agendar cron jobs e configurar alvos de inicialização do sistema usando Ansible. Isso é essencial para manter a disponibilidade do serviço e automatizar tarefas rotineiras em sua infraestrutura.

Você usará módulos como ansible.builtin.service para gerenciamento de serviços, ansible.builtin.cron para agendamento de tarefas, ansible.posix.at para tarefas únicas e ansible.builtin.systemd para gerenciamento de alvos do sistema.

  1. Navegue para um novo diretório de projeto para gerenciamento de serviços e processos.

    cd ~/project
    mkdir system-process
    cd system-process
  2. Crie o arquivo de inventário para este exercício.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Crie um playbook para gerenciar o serviço do servidor HTTP Apache. Isso demonstrará o gerenciamento básico de serviços.

    nano service_management.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Manage Apache HTTP Server Service
      hosts: webservers
      become: true
      tasks:
        - name: Start and enable httpd service
          ansible.builtin.service:
            name: httpd
            state: started
            enabled: yes
    
        - name: Create a simple index.html
          ansible.builtin.copy:
            content: |
              <html>
              <head><title>Ansible Managed Server</title></head>
              <body>
              <h1>Welcome to Ansible Managed Apache Server</h1>
              <p>This server is configured and managed by Ansible.</p>
              <p>Service started at: $(date)</p>
              </body>
              </html>
            dest: /var/www/html/index.html
            owner: apache
            group: apache
            mode: "0644"
    
        - name: Verify httpd service is running
          ansible.builtin.service_facts:
    
        - name: Display httpd service status
          ansible.builtin.debug:
            var: ansible_facts.services['httpd.service']
  4. Crie um playbook para agendar cron jobs. Isso demonstra o agendamento automatizado de tarefas.

    nano create_crontab_file.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Schedule recurring cron jobs
      hosts: webservers
      become: true
      tasks:
        - name: Create labex user for cron jobs
          ansible.builtin.user:
            name: labex
            state: present
            create_home: yes
    
        - name: Schedule system monitoring cron job
          ansible.builtin.cron:
            name: System monitoring log
            job: "date >> /home/labex/system_monitor.log && df -h >> /home/labex/system_monitor.log"
            minute: "*/5"
            hour: "*"
            user: labex
            cron_file: system-monitoring
            state: present
    
        - name: Schedule daily log rotation
          ansible.builtin.cron:
            name: Daily log cleanup
            job: "find /home/labex -name '*.log' -mtime +7 -delete"
            minute: "0"
            hour: "2"
            weekday: "*"
            user: labex
            cron_file: log-cleanup
            state: present
    
        - name: Schedule weekly system update check
          ansible.builtin.cron:
            name: Weekly update check
            job: "dnf check-update > /home/labex/update_check.log 2>&1"
            minute: "0"
            hour: "3"
            weekday: "0"
            user: labex
            cron_file: update-check
            state: present
  5. Crie um playbook para agendamento de tarefas únicas usando at.

    nano schedule_at_task.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Schedule one-time tasks with at
      hosts: webservers
      become: true
      become_user: labex
      tasks:
        - name: Schedule immediate system info collection
          ansible.posix.at:
            command: "uname -a > ~/system_info_$(date +%Y%m%d_%H%M%S).txt"
            count: 2
            units: minutes
            unique: yes
            state: present
    
        - name: Schedule delayed service status check
          ansible.posix.at:
            command: "systemctl status httpd > ~/httpd_status_$(date +%Y%m%d_%H%M%S).txt"
            count: 5
            units: minutes
            unique: yes
            state: present
  6. Crie um playbook para gerenciar alvos de inicialização do sistema.

    nano boot_target_management.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Manage system boot targets
      hosts: webservers
      become: true
      tasks:
        - name: Check current default target
          ansible.builtin.command:
            cmd: systemctl get-default
          register: current_target
          changed_when: false
    
        - name: Display current boot target
          ansible.builtin.debug:
            msg: "Current default boot target: {{ current_target.stdout }}"
    
        - name: Set default boot target to multi-user
          ansible.builtin.systemd:
            name: multi-user.target
            enabled: yes
          when: current_target.stdout != "multi-user.target"
    
        - name: Verify the boot target change
          ansible.builtin.command:
            cmd: systemctl get-default
          register: new_target
          changed_when: false
    
        - name: Display new boot target
          ansible.builtin.debug:
            msg: "New default boot target: {{ new_target.stdout }}"
  7. Execute o playbook de gerenciamento de serviços.

    ansible-playbook -i inventory.ini service_management.yml

    Isso iniciará o serviço httpd e criará uma página de boas-vindas.

  8. Execute o playbook de agendamento de cron jobs.

    ansible-playbook -i inventory.ini create_crontab_file.yml

    Isso criará várias tarefas agendadas para monitoramento e manutenção do sistema.

  9. Execute o playbook de agendamento de tarefas únicas.

    ansible-playbook -i inventory.ini schedule_at_task.yml

    Isso agendará tarefas imediatas usando o comando at.

  10. Execute o playbook de gerenciamento de alvos de inicialização.

    ansible-playbook -i inventory.ini boot_target_management.yml

    Isso verificará e potencialmente modificará o alvo de inicialização padrão do sistema.

  11. Verifique as tarefas agendadas e os serviços.

    ## Check cron jobs
    sudo cat /etc/cron.d/system-monitoring
    sudo cat /etc/cron.d/log-cleanup
    sudo cat /etc/cron.d/update-check
    
    ## Check at jobs
    sudo atq
    
    ## Check httpd service status
    sudo systemctl status httpd
    
    ## Test the web server
    curl localhost
    
    ## Check system monitoring log (wait a few minutes for cron to run)
    sudo cat /home/labex/system_monitor.log
  12. Crie um playbook de limpeza para remover tarefas agendadas quando necessário.

    nano remove_scheduled_tasks.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Remove scheduled tasks
      hosts: webservers
      become: true
      tasks:
        - name: Remove system monitoring cron job
          ansible.builtin.cron:
            name: System monitoring log
            user: labex
            cron_file: system-monitoring
            state: absent
    
        - name: Remove log cleanup cron job
          ansible.builtin.cron:
            name: Daily log cleanup
            user: labex
            cron_file: log-cleanup
            state: absent
    
        - name: Remove update check cron job
          ansible.builtin.cron:
            name: Weekly update check
            user: labex
            cron_file: update-check
            state: absent

Você automatizou com sucesso o gerenciamento de serviços, o agendamento de tarefas e a configuração do sistema usando Ansible, fornecendo a base para manter e monitorar sua infraestrutura automaticamente.

Automatizar Gerenciamento de Armazenamento com LVM e Sistemas de Arquivos

Nesta etapa, você aprenderá a automatizar o gerenciamento de armazenamento usando Ansible para criar volumes físicos LVM, grupos de volumes, volumes lógicos e sistemas de arquivos. Isso é crucial para gerenciar recursos de armazenamento em sua infraestrutura de maneira consistente e escalável.

Você usará módulos como ansible.builtin.lvg para gerenciamento de grupos de volumes, ansible.builtin.lvol para criação de volumes lógicos, ansible.builtin.filesystem para criação de sistemas de arquivos e ansible.posix.mount para gerenciamento de pontos de montagem.

  1. Navegue para um novo diretório de projeto para gerenciamento de armazenamento.

    cd ~/project
    mkdir system-storage
    cd system-storage
  2. Crie o arquivo de inventário para este exercício.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Crie um dispositivo de loop para simular armazenamento adicional, já que estamos trabalhando em um ambiente virtual.

    ## Create a 1GB file to use as a virtual disk
    sudo dd if=/dev/zero of=/tmp/virtual_disk bs=1M count=1024
    
    ## Set up loop device
    sudo losetup /dev/loop0 /tmp/virtual_disk
    
    ## Verify the loop device
    lsblk | grep loop0
  4. Crie um playbook abrangente de gerenciamento de armazenamento. Isso demonstrará operações LVM e gerenciamento de sistemas de arquivos.

    nano storage.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Configure LVM storage and filesystems
      hosts: webservers
      become: true
      vars:
        storage_device: /dev/loop0
        volume_group: apache-vg
        content_lv: content-lv
        logs_lv: logs-lv
        backup_lv: backup-lv
      tasks:
        - name: Install LVM utilities
          ansible.builtin.dnf:
            name: lvm2
            state: present
    
        - name: Create physical volume
          community.general.lvg:
            vg: "{{ volume_group }}"
            pvs: "{{ storage_device }}"
            state: present
    
        - name: Create logical volume for web content
          community.general.lvol:
            vg: "{{ volume_group }}"
            lv: "{{ content_lv }}"
            size: 256m
            state: present
    
        - name: Create logical volume for logs
          community.general.lvol:
            vg: "{{ volume_group }}"
            lv: "{{ logs_lv }}"
            size: 256m
            state: present
    
        - name: Create logical volume for backup
          community.general.lvol:
            vg: "{{ volume_group }}"
            lv: "{{ backup_lv }}"
            size: 256m
            state: present
    
        - name: Create XFS filesystem on content volume
          community.general.filesystem:
            fstype: xfs
            dev: "/dev/{{ volume_group }}/{{ content_lv }}"
            force: no
    
        - name: Create XFS filesystem on logs volume
          community.general.filesystem:
            fstype: xfs
            dev: "/dev/{{ volume_group }}/{{ logs_lv }}"
            force: no
    
        - name: Create ext4 filesystem on backup volume
          community.general.filesystem:
            fstype: ext4
            dev: "/dev/{{ volume_group }}/{{ backup_lv }}"
            force: no
    
        - name: Create mount points
          ansible.builtin.file:
            path: "{{ item }}"
            state: directory
            mode: "0755"
          loop:
            - /var/www
            - /var/log/httpd
            - /backup
    
        - name: Mount web content volume
          ansible.posix.mount:
            path: /var/www
            src: "/dev/{{ volume_group }}/{{ content_lv }}"
            fstype: xfs
            opts: defaults
            state: mounted
    
        - name: Mount logs volume
          ansible.posix.mount:
            path: /var/log/httpd
            src: "/dev/{{ volume_group }}/{{ logs_lv }}"
            fstype: xfs
            opts: defaults
            state: mounted
    
        - name: Mount backup volume
          ansible.posix.mount:
            path: /backup
            src: "/dev/{{ volume_group }}/{{ backup_lv }}"
            fstype: ext4
            opts: defaults
            state: mounted
    
        - name: Set appropriate ownership for web content
          ansible.builtin.file:
            path: /var/www
            owner: apache
            group: apache
            recurse: yes
    
        - name: Set appropriate ownership for httpd logs
          ansible.builtin.file:
            path: /var/log/httpd
            owner: apache
            group: apache
            recurse: yes
    
        - name: Create html directory for web content
          ansible.builtin.file:
            path: /var/www/html
            state: directory
            owner: apache
            group: apache
            mode: "0755"
    
        - name: Create sample web content
          ansible.builtin.copy:
            content: |
              <html>
              <head><title>Storage Management Demo</title></head>
              <body>
              <h1>LVM Storage Configuration</h1>
              <p>This content is served from an LVM logical volume managed by Ansible.</p>
              <p>Volume Group: {{ volume_group }}</p>
              <p>Logical Volume: {{ content_lv }}</p>
              <p>Filesystem: XFS</p>
              </body>
              </html>
            dest: /var/www/html/storage.html
            owner: apache
            group: apache
            mode: "0644"
  5. Instale a coleção Ansible necessária para gerenciamento LVM.

    ansible-galaxy collection install community.general
  6. Execute o playbook de gerenciamento de armazenamento.

    ansible-playbook -i inventory.ini storage.yml

    Isso criará a estrutura LVM, sistemas de arquivos e pontos de montagem.

  7. Crie um playbook para coletar e exibir informações de armazenamento.

    nano get-storage.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Gather storage information
      hosts: webservers
      become: true
      tasks:
        - name: Gather disk facts
          ansible.builtin.setup:
            gather_subset:
              - hardware
    
        - name: Display volume group information
          ansible.builtin.command:
            cmd: vgdisplay apache-vg
          register: vg_info
          changed_when: false
    
        - name: Display logical volume information
          ansible.builtin.command:
            cmd: lvdisplay apache-vg
          register: lv_info
          changed_when: false
    
        - name: Display filesystem information
          ansible.builtin.command:
            cmd: df -h /var/www /var/log/httpd /backup
          register: fs_info
          changed_when: false
    
        - name: Display mount information
          ansible.builtin.command:
            cmd: cat /proc/mounts
          register: mount_info
          changed_when: false
    
        - name: Show volume group details
          ansible.builtin.debug:
            var: vg_info.stdout_lines
    
        - name: Show logical volume details
          ansible.builtin.debug:
            var: lv_info.stdout_lines
    
        - name: Show filesystem usage
          ansible.builtin.debug:
            var: fs_info.stdout_lines
    
        - name: Show fstab entries
          ansible.builtin.command:
            cmd: grep apache-vg /etc/fstab
          register: fstab_entries
          changed_when: false
          failed_when: false
    
        - name: Display fstab entries
          ansible.builtin.debug:
            var: fstab_entries.stdout_lines
  8. Execute o playbook de coleta de informações de armazenamento.

    ansible-playbook -i inventory.ini get-storage.yml

    Isso exibirá informações detalhadas sobre a estrutura de armazenamento criada.

  9. Verifique a configuração de armazenamento manualmente.

    ## Check LVM structure
    sudo vgs apache-vg
    sudo lvs apache-vg
    sudo pvs /dev/loop0
    
    ## Check filesystems
    df -h /var/www /var/log/httpd /backup
    
    ## Check mount points
    mount | grep apache-vg
    
    ## Check fstab entries
    grep apache-vg /etc/fstab
    
    ## Test the web content
    cat /var/www/html/storage.html
  10. Crie um playbook de expansão de armazenamento para demonstrar operações de escalonamento.

    nano expand_storage.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Expand storage volumes
      hosts: webservers
      become: true
      vars:
        volume_group: apache-vg
        content_lv: content-lv
      tasks:
        - name: Extend content logical volume
          community.general.lvol:
            vg: "{{ volume_group }}"
            lv: "{{ content_lv }}"
            size: 400m
            state: present
    
        - name: Extend XFS filesystem
          community.general.filesystem:
            fstype: xfs
            dev: "/dev/{{ volume_group }}/{{ content_lv }}"
            resizefs: yes
    
        - name: Display updated filesystem size
          ansible.builtin.command:
            cmd: df -h /var/www
          register: new_size
          changed_when: false
    
        - name: Show new filesystem size
          ansible.builtin.debug:
            var: new_size.stdout_lines
  11. Teste a expansão de armazenamento.

    ## Check current size before expansion
    df -h /var/www
    
    ## Run the expansion playbook
    ansible-playbook -i inventory.ini expand_storage.yml
    
    ## Verify the expansion
    df -h /var/www
    sudo lvs apache-vg/content-lv

Você automatizou com sucesso o gerenciamento de armazenamento LVM, incluindo a criação de volumes físicos, gerenciamento de volumes lógicos, criação de sistemas de arquivos e configuração de pontos de montagem usando Ansible.

Automatizar Configuração de Rede e Coleta de Informações

Nesta etapa final, você aprenderá a automatizar a configuração de interfaces de rede e a coletar informações abrangentes do sistema usando Ansible. Isso completa o espectro total de automação de administração de sistemas, desde software até armazenamento e redes.

Você usará módulos como ansible.builtin.template para arquivos de configuração de rede, coletará fatos de rede e criará relatórios abrangentes do sistema.

  1. Navegue para um novo diretório de projeto para gerenciamento de rede.

    cd ~/project
    mkdir system-network
    cd system-network
  2. Crie o arquivo de inventário para este exercício.

    cat << EOF > inventory.ini
    [webservers]
    localhost ansible_connection=local
    EOF
  3. Crie um playbook abrangente de coleta de informações de rede e sistema.

    nano network_info.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Gather comprehensive system information
      hosts: webservers
      become: true
      tasks:
        - name: Gather all system facts
          ansible.builtin.setup:
    
        - name: Create system report directory
          ansible.builtin.file:
            path: /tmp/system_reports
            state: directory
            mode: "0755"
    
        - name: Generate system information report
          ansible.builtin.template:
            src: system_report.j2
            dest: /tmp/system_reports/system_info_{{ ansible_facts['hostname'] }}.html
            mode: "0644"
    
        - name: Generate network configuration report
          ansible.builtin.template:
            src: network_report.j2
            dest: /tmp/system_reports/network_info_{{ ansible_facts['hostname'] }}.html
            mode: "0644"
    
        - name: Collect network interface information
          ansible.builtin.command:
            cmd: ip addr show
          register: ip_info
          changed_when: false
    
        - name: Collect routing information
          ansible.builtin.command:
            cmd: ip route show
          register: route_info
          changed_when: false
    
        - name: Collect DNS configuration
          ansible.builtin.command:
            cmd: cat /etc/resolv.conf
          register: dns_info
          changed_when: false
    
        - name: Display network summary
          ansible.builtin.debug:
            msg: |
              System: {{ ansible_facts['hostname'] }}
              OS: {{ ansible_facts['distribution'] }} {{ ansible_facts['distribution_version'] }}
              Kernel: {{ ansible_facts['kernel'] }}
              Default IPv4: {{ ansible_facts['default_ipv4']['address'] | default('N/A') }}
              Default Interface: {{ ansible_facts['default_ipv4']['interface'] | default('N/A') }}
              Total Memory: {{ ansible_facts['memtotal_mb'] }}MB
              CPU Cores: {{ ansible_facts['processor_vcpus'] }}
  4. Crie diretórios e arquivos de template para os relatórios.

    mkdir templates
    nano templates/system_report.j2

    Adicione o seguinte conteúdo para o template do relatório do sistema:

    <!doctype html>
    <html>
      <head>
        <title>System Report - {{ ansible_facts['hostname'] }}</title>
        <style>
          body {
            font-family: Arial, sans-serif;
            margin: 20px;
          }
          .section {
            margin-bottom: 20px;
            padding: 10px;
            border: 1px solid #ccc;
          }
          .header {
            background-color: #f5f5f5;
            padding: 10px;
          }
          table {
            border-collapse: collapse;
            width: 100%;
          }
          th,
          td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
          }
          th {
            background-color: #f2f2f2;
          }
        </style>
      </head>
      <body>
        <div class="header">
          <h1>System Report for {{ ansible_facts['hostname'] }}</h1>
          <p>
            Generated on: {{ ansible_date_time.date }} {{ ansible_date_time.time
            }}
          </p>
        </div>
    
        <div class="section">
          <h2>System Information</h2>
          <table>
            <tr>
              <th>Property</th>
              <th>Value</th>
            </tr>
            <tr>
              <td>Hostname</td>
              <td>{{ ansible_facts['hostname'] }}</td>
            </tr>
            <tr>
              <td>FQDN</td>
              <td>{{ ansible_facts['fqdn'] }}</td>
            </tr>
            <tr>
              <td>Operating System</td>
              <td>
                {{ ansible_facts['distribution'] }} {{
                ansible_facts['distribution_version'] }}
              </td>
            </tr>
            <tr>
              <td>Kernel</td>
              <td>{{ ansible_facts['kernel'] }}</td>
            </tr>
            <tr>
              <td>Architecture</td>
              <td>{{ ansible_facts['architecture'] }}</td>
            </tr>
            <tr>
              <td>CPU Cores</td>
              <td>{{ ansible_facts['processor_vcpus'] }}</td>
            </tr>
            <tr>
              <td>Total Memory</td>
              <td>{{ ansible_facts['memtotal_mb'] }}MB</td>
            </tr>
            <tr>
              <td>Uptime</td>
              <td>{{ ansible_facts['uptime_seconds'] }} seconds</td>
            </tr>
          </table>
        </div>
    
        <div class="section">
          <h2>Storage Information</h2>
          <table>
            <tr>
              <th>Mount Point</th>
              <th>Filesystem</th>
              <th>Size</th>
              <th>Used</th>
              <th>Available</th>
            </tr>
            {% for mount in ansible_facts['mounts'] %}
            <tr>
              <td>{{ mount.mount }}</td>
              <td>{{ mount.fstype }}</td>
              <td>
                {{ (mount.size_total / 1024 / 1024 / 1024) | round(2) }}GB
              </td>
              <td>
                {{ ((mount.size_total - mount.size_available) / 1024 / 1024 /
                1024) | round(2) }}GB
              </td>
              <td>
                {{ (mount.size_available / 1024 / 1024 / 1024) | round(2) }}GB
              </td>
            </tr>
            {% endfor %}
          </table>
        </div>
    
        <div class="section">
          <h2>Services Status</h2>
          <table>
            <tr>
              <th>Service</th>
              <th>Status</th>
            </tr>
            <tr>
              <td>httpd</td>
              <td>
                {{ ansible_facts.services['httpd.service']['state'] |
                default('not installed') }}
              </td>
            </tr>
            <tr>
              <td>sshd</td>
              <td>
                {{ ansible_facts.services['sshd.service']['state'] |
                default('unknown') }}
              </td>
            </tr>
            <tr>
              <td>NetworkManager</td>
              <td>
                {{ ansible_facts.services['NetworkManager.service']['state'] |
                default('unknown') }}
              </td>
            </tr>
          </table>
        </div>
      </body>
    </html>
  5. Crie o template do relatório de rede.

    nano templates/network_report.j2

    Adicione o seguinte conteúdo:

    <!doctype html>
    <html>
      <head>
        <title>Network Report - {{ ansible_facts['hostname'] }}</title>
        <style>
          body {
            font-family: Arial, sans-serif;
            margin: 20px;
          }
          .section {
            margin-bottom: 20px;
            padding: 10px;
            border: 1px solid #ccc;
          }
          .header {
            background-color: #f5f5f5;
            padding: 10px;
          }
          table {
            border-collapse: collapse;
            width: 100%;
          }
          th,
          td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
          }
          th {
            background-color: #f2f2f2;
          }
          pre {
            background-color: #f9f9f9;
            padding: 10px;
            overflow-x: auto;
          }
        </style>
      </head>
      <body>
        <div class="header">
          <h1>Network Configuration Report</h1>
          <p>Host: {{ ansible_facts['hostname'] }}</p>
          <p>
            Generated on: {{ ansible_date_time.date }} {{ ansible_date_time.time
            }}
          </p>
        </div>
    
        <div class="section">
          <h2>Network Interfaces</h2>
          <table>
            <tr>
              <th>Interface</th>
              <th>IPv4 Address</th>
              <th>IPv6 Address</th>
              <th>MAC Address</th>
              <th>Status</th>
            </tr>
            {% for interface_name in ansible_facts['interfaces'] %} {% if
            interface_name != 'lo' %} {% set interface_facts =
            ansible_facts[interface_name] %}
            <tr>
              <td>{{ interface_name }}</td>
              <td>
                {{ interface_facts.get('ipv4', {}).get('address', 'N/A') }}
              </td>
              <td>
                {{ interface_facts.get('ipv6', [{}])[0].get('address', 'N/A') if
                interface_facts.get('ipv6') else 'N/A' }}
              </td>
              <td>{{ interface_facts.get('macaddress', 'N/A') }}</td>
              <td>
                {{ interface_facts.get('active', false) | ternary('Active',
                'Inactive') }}
              </td>
            </tr>
            {% endif %} {% endfor %}
          </table>
        </div>
    
        <div class="section">
          <h2>Default Gateway</h2>
          <table>
            <tr>
              <th>Property</th>
              <th>Value</th>
            </tr>
            <tr>
              <td>Default IPv4 Address</td>
              <td>
                {{ ansible_facts['default_ipv4']['address'] | default('N/A') }}
              </td>
            </tr>
            <tr>
              <td>Default Interface</td>
              <td>
                {{ ansible_facts['default_ipv4']['interface'] | default('N/A')
                }}
              </td>
            </tr>
            <tr>
              <td>Default Gateway</td>
              <td>
                {{ ansible_facts['default_ipv4']['gateway'] | default('N/A') }}
              </td>
            </tr>
          </table>
        </div>
    
        <div class="section">
          <h2>DNS Configuration</h2>
          <table>
            <tr>
              <th>DNS Servers</th>
            </tr>
            {% for dns in ansible_facts['dns']['nameservers'] %}
            <tr>
              <td>{{ dns }}</td>
            </tr>
            {% endfor %}
          </table>
        </div>
      </body>
    </html>
  6. Crie um playbook de configuração de interface de rede.

    nano configure_network.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Configure network settings
      hosts: webservers
      become: true
      tasks:
        - name: Install NetworkManager if not present
          ansible.builtin.dnf:
            name: NetworkManager
            state: present
    
        - name: Ensure NetworkManager is running
          ansible.builtin.service:
            name: NetworkManager
            state: started
            enabled: yes
    
        - name: Configure hosts file with system information
          ansible.builtin.lineinfile:
            path: /etc/hosts
            line: "{{ ansible_facts['default_ipv4']['address'] }} {{ ansible_facts['hostname'] }}.lab.example.com {{ ansible_facts['hostname'] }}"
            regexp: ".*{{ ansible_facts['hostname'] }}.*"
            backup: yes
    
        - name: Create network monitoring script
          ansible.builtin.copy:
            content: |
              #!/bin/bash
              ## Network monitoring script generated by Ansible
              echo "=== Network Status Report ==="
              echo "Generated at: $(date)"
              echo
              echo "=== Interface Status ==="
              ip addr show
              echo
              echo "=== Routing Table ==="
              ip route show
              echo
              echo "=== DNS Configuration ==="
              cat /etc/resolv.conf
              echo
              echo "=== Network Connectivity Test ==="
              ping -c 3 8.8.8.8
            dest: /usr/local/bin/network-status.sh
            mode: "0755"
    
        - name: Create network information gathering cron job
          ansible.builtin.cron:
            name: Network status monitoring
            job: "/usr/local/bin/network-status.sh >> /var/log/network-status.log 2>&1"
            minute: "*/15"
            user: root
            cron_file: network-monitoring
            state: present
  7. Execute o playbook de coleta de informações de rede.

    ansible-playbook -i inventory.ini network_info.yml

    Isso gerará relatórios abrangentes do sistema e da rede.

  8. Execute o playbook de configuração de rede.

    ansible-playbook -i inventory.ini configure_network.yml

    Isso configurará as configurações de rede e o monitoramento.

  9. Visualize os relatórios gerados.

    ## List generated reports
    ls -la /tmp/system_reports/
    
    ## View the system report (you can also open in a browser)
    cat /tmp/system_reports/system_info_*.html
    
    ## Check the network monitoring script
    cat /usr/local/bin/network-status.sh
    
    ## Test the network monitoring script
    sudo /usr/local/bin/network-status.sh
    
    ## Check the network monitoring cron job
    sudo cat /etc/cron.d/network-monitoring
  10. Crie um playbook final abrangente que combine todos os conceitos aprendidos.

    nano complete_system_setup.yml

    Adicione o seguinte conteúdo:

    ---
    - name: Complete system setup and configuration
      hosts: webservers
      become: true
      vars:
        admin_users:
          - webuser1
          - webuser2
      tasks:
        - name: Ensure all required packages are installed
          ansible.builtin.dnf:
            name:
              - httpd
              - lvm2
              - NetworkManager
              - cronie
            state: present
    
        - name: Ensure all services are running
          ansible.builtin.service:
            name: "{{ item }}"
            state: started
            enabled: yes
          loop:
            - httpd
            - NetworkManager
            - crond
    
        - name: Generate final system status report
          ansible.builtin.template:
            src: system_report.j2
            dest: /tmp/final_system_report.html
            mode: "0644"
    
        - name: Display completion message
          ansible.builtin.debug:
            msg: |
              ============================================
              RHEL System Administration Automation Complete!
              ============================================
    
              Summary of configured components:
              - Software: EPEL repository and packages installed
              - Users: {{ admin_users | length }} administrative users created
              - Services: httpd, NetworkManager, and crond configured
              - Storage: LVM volumes and filesystems configured
              - Network: Interface configuration and monitoring set up
              - Scheduling: Cron jobs and at tasks configured
    
              Reports available at:
              - /tmp/system_reports/
              - /tmp/final_system_report.html
    
              Your RHEL system is now fully automated with Ansible!
  11. Execute a configuração completa do sistema.

    ansible-playbook -i inventory.ini complete_system_setup.yml

Você completou com sucesso uma automação abrangente de tarefas de administração de sistemas RHEL usando Ansible, cobrindo gerenciamento de software, administração de usuários, gerenciamento de serviços, configuração de armazenamento e configuração de rede.

  1. Visualize os relatórios gerados em um navegador web.

    Navegue até o diretório de relatórios:

    cd /tmp/system_reports

    Inicie um servidor web temporário usando Python:

    python -m http.server 8000

    Para visualizar os relatórios em seu navegador:

    1. Clique no botão + na barra de menu superior
    2. Selecione Web Service
    3. Insira o número da porta 8000
    4. Agora você pode visualizar os relatórios HTML gerados online
    Preview the generated reports in a web browser

    O servidor web exibirá uma listagem de diretórios onde você pode clicar nos arquivos HTML para visualizar os relatórios abrangentes do sistema e da rede gerados por seus playbooks Ansible.

    Nota: Pressione Ctrl+C para parar o servidor web quando terminar de visualizar os relatórios.

Resumo

Neste laboratório abrangente, você dominou a automação de tarefas essenciais de administração do Red Hat Enterprise Linux (RHEL) usando Ansible. Você começou com o gerenciamento de pacotes de software, aprendendo a configurar repositórios, gerenciar chaves GPG e instalar pacotes enquanto coletava informações do sistema através de fatos de pacotes. Isso forneceu a base para a implantação consistente de software em sua infraestrutura.

Em seguida, você progrediu para o gerenciamento de usuários e autenticação, onde automatizou a criação de contas de usuário, configurou a autenticação baseada em chave SSH, configurou privilégios sudo e fortaleceu as configurações SSH. Isso estabeleceu políticas de acesso de usuário seguras e padronizadas que são cruciais para ambientes corporativos.

O laboratório continuou com o gerenciamento de serviços e agendamento de tarefas, onde você aprendeu a gerenciar serviços systemd, criar trabalhos cron recorrentes, agendar tarefas únicas com at e configurar destinos de inicialização do sistema. Essas habilidades são essenciais para manter a disponibilidade do serviço e automatizar tarefas de manutenção de rotina.

O gerenciamento de armazenamento foi abordado através da automação abrangente de LVM, incluindo a criação de volumes físicos, gerenciamento de grupos de volumes, provisionamento de volumes lógicos, criação de sistemas de arquivos e configuração de pontos de montagem. Você também aprendeu a expandir volumes de armazenamento dinamicamente, o que é crítico para o gerenciamento de infraestrutura escalável.

Finalmente, você completou a automação da configuração de rede e o monitoramento abrangente do sistema. Você aprendeu a coletar fatos de rede, configurar interfaces, criar relatórios detalhados do sistema usando templates Jinja2 e configurar scripts de monitoramento automatizados. Isso forneceu a imagem completa do gerenciamento e relatórios do estado do sistema.

Ao longo deste laboratório, você aplicou os princípios de Infraestrutura como Código (IaC), garantindo que todas as configurações do sistema sejam reproduzíveis, controladas por versão e implantáveis de forma consistente. Agora você tem as habilidades para automatizar o ciclo de vida completo da administração de sistemas RHEL, desde a implantação inicial até a manutenção e monitoramento contínuos.