Módulo Command do Ansible

AnsibleBeginner
Pratique Agora

Introdução

Neste laboratório, você explorará o módulo Command do Ansible, uma ferramenta poderosa para executar comandos em hosts remotos. O módulo Command permite que você interaja com a linha de comando diretamente de seus playbooks e tarefas do Ansible, fornecendo uma maneira versátil de gerenciar sistemas remotos. Ao longo deste laboratório, você aprenderá como usar o módulo Command do Ansible para executar vários comandos, trabalhar com variáveis e argumentos e capturar a saída de comandos.

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 99%. Recebeu uma taxa de avaliações positivas de 100% dos estudantes.

Criar um Playbook Ansible Simples

Nesta etapa, você criará seu primeiro playbook Ansible usando o módulo Command para executar um comando simples.

Primeiro, navegue até o diretório do projeto:

cd ~/project

Agora, crie um novo arquivo chamado simple_command.yml usando um editor de texto de sua escolha. Por exemplo, você pode usar o editor nano:

nano simple_command.yml

Adicione o seguinte conteúdo ao arquivo:

---
- name: Execute a simple command
  hosts: localhost
  tasks:
    - name: Run 'ls' command
      command: ls -l

Vamos analisar este playbook:

  • A linha hosts: localhost especifica que o playbook será executado na máquina local.
  • A seção tasks contém uma lista de tarefas a serem executadas.
  • A linha command: ls -l usa o módulo Command para executar o comando ls -l, que lista arquivos e diretórios em formato longo.

Salve o arquivo e saia do editor (no nano, pressione Ctrl+X, depois Y, depois Enter).

Agora, execute o playbook com o seguinte comando:

ansible-playbook simple_command.yml

Você deve ver uma saída semelhante a esta:

PLAY [Execute a simple command] ************************************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Run 'ls' command] ********************************************************
changed: [localhost]

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Esta saída indica que o playbook foi executado com sucesso, executando o comando ls -l em sua máquina local.

Usar Variáveis com o Módulo Command

Nesta etapa, você aprenderá como usar variáveis com o módulo Command do Ansible. As variáveis permitem que você torne seus playbooks mais flexíveis e reutilizáveis.

Crie um novo arquivo chamado variable_command.yml:

nano variable_command.yml

Adicione o seguinte conteúdo ao arquivo:

---
- name: Use variables with the Command module
  hosts: localhost
  vars:
    file_path: /etc/passwd
    line_count: 5
  tasks:
    - name: Display the last few lines of a file
      command: "tail -n {{ line_count }} {{ file_path }}"
      register: command_output

    - name: Show the command output
      debug:
        var: command_output.stdout_lines

Este playbook introduz vários novos conceitos:

  • A seção vars define variáveis que podem ser usadas em todo o playbook.
  • Usamos a sintaxe {{ variable_name }} para referenciar variáveis dentro do comando.
  • A palavra-chave register salva a saída do comando em uma variável chamada command_output.
  • O módulo debug é usado para exibir o conteúdo da variável command_output.

Salve o arquivo e saia do editor.

Agora, execute o playbook:

ansible-playbook variable_command.yml

Você deve ver uma saída semelhante a esta:

PLAY [Use variables with the Command module] ***********************************

TASK [Gathering Facts] *********************************************************
ok: [localhost]

TASK [Display the last few lines of a file] ************************************
changed: [localhost]

TASK [Show the command output] *************************************************
ok: [localhost] => {
    "command_output.stdout_lines": [
        "games:x:5:60:games:/usr/games:/usr/sbin/nologin",
        "man:x:6:12:man:/var/cache/man:/usr/sbin/nologin",
        "lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin",
        "mail:x:8:8:mail:/var/mail:/usr/sbin/nologin",
        "news:x:9:9:news:/var/spool/news:/usr/sbin/nologin"
    ]
}

PLAY RECAP *********************************************************************
localhost                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Esta saída mostra as últimas 5 linhas do arquivo /etc/passwd, demonstrando como as variáveis podem ser usadas com o módulo Command.

Capturar e Processar a Saída de Comandos

Nesta etapa, você aprenderá como capturar a saída de um comando e processá-la ainda mais usando o Ansible.

Crie um novo arquivo chamado process_output.yml:

nano process_output.yml

Adicione o seguinte conteúdo ao arquivo:

---
- name: Capture and process command output
  hosts: localhost
  tasks:
    - name: Get disk usage information
      command: df -h
      register: df_output

    - name: Display all partitions
      debug:
        msg: "{{ df_output.stdout_lines }}"

    - name: Find root partition
      set_fact:
        root_partition: "{{ df_output.stdout_lines | select('match', '\\s+/$') | first | default('') }}"

    - name: Display root partition information
      debug:
        msg: "Root partition: {{ root_partition }}"
      when: root_partition != ''

    - name: Extract usage percentage
      set_fact:
        root_usage: "{{ root_partition.split()[-2].rstrip('%') | int }}"
      when: root_partition != ''

    - name: Display root partition usage
      debug:
        msg: "Root partition is {{ root_usage }}% full"
      when: root_partition != ''

    - name: Check if root partition is over 80% full
      fail:
        msg: "Warning: Root partition is over 80% full!"
      when: root_partition != '' and root_usage > 80

    - name: Display message if root partition not found
      debug:
        msg: "Root partition (/) not found in df output"
      when: root_partition == ''

Este playbook é mais robusto e lida com casos em que a partição raiz pode não ser facilmente detectável:

  • Exibimos todas as partições para ver o que está disponível.
  • Usamos um padrão mais flexível para encontrar a partição raiz.
  • Adicionamos verificações para lidar com casos em que a partição raiz não é encontrada.
  • Usamos o filtro default('') para evitar erros quando a partição raiz não é encontrada.

Salve o arquivo e saia do editor.

Agora, execute o playbook:

ansible-playbook process_output.yml

Você deve ver uma saída semelhante a esta:

PLAY [Capture and process command output] ************************************************

TASK [Gathering Facts] *******************************************************************
ok: [localhost]

TASK [Get disk usage information] ********************************************************
changed: [localhost]

TASK [Display all partitions] ************************************************************
ok: [localhost] => {
    "msg": [
        "Filesystem      Size  Used Avail Use% Mounted on",
        "overlay          20G  618M   20G   4% /",
        "tmpfs            64M     0   64M   0% /dev",
        "tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup",
        "shm              64M  128K   64M   1% /dev/shm",
        "/dev/vdb        100G   17G   84G  17% /etc/hosts"
    ]
}

TASK [Find root partition] ***************************************************************
ok: [localhost]

TASK [Display root partition information] ************************************************
skipping: [localhost]

TASK [Extract usage percentage] **********************************************************
skipping: [localhost]

TASK [Display root partition usage] ******************************************************
skipping: [localhost]

TASK [Check if root partition is over 80% full] ******************************************
skipping: [localhost]

TASK [Display message if root partition not found] ***************************************
ok: [localhost] => {
    "msg": "Root partition (/) not found in df output"
}

PLAY RECAP *******************************************************************************
localhost                  : ok=7    changed=1    unreachable=0    failed=1    skipped=1    rescued=0    ignored=0

Esta saída mostra todas as partições, identifica a partição raiz e verifica seu uso. Os valores exatos podem diferir em seu sistema.

Trabalhando com Opções do Módulo Command

Nesta etapa, você explorará algumas das opções disponíveis com o módulo Command do Ansible para controlar seu comportamento.

Crie um novo arquivo chamado command_options.yml:

nano command_options.yml

Adicione o seguinte conteúdo ao arquivo:

---
- name: Explore Command module options
  hosts: localhost
  tasks:
    - name: Run a command with a specific working directory
      command: pwd
      args:
        chdir: /tmp

    - name: Run a command with environment variables
      command: echo $MY_VAR
      environment:
        MY_VAR: "Hello from Ansible"

    - name: Run a command and ignore errors
      command: ls /nonexistent_directory
      ignore_errors: yes

    - name: Run a command with a timeout
      command: sleep 2
      async: 5
      poll: 0
      register: sleep_result

    - name: Check sleep command status
      async_status:
        jid: "{{ sleep_result.ansible_job_id }}"
      register: job_result
      until: job_result.finished
      retries: 5
      delay: 1

Este playbook demonstra várias opções do módulo Command:

  • chdir: Altera o diretório de trabalho antes de executar o comando.
  • environment: Define variáveis de ambiente para o comando.
  • ignore_errors: Continua a execução do playbook mesmo que o comando falhe.
  • async e poll: Executa o comando de forma assíncrona com um tempo limite.

Salve o arquivo e saia do editor.

Agora, execute o playbook:

ansible-playbook command_options.yml

Você deve ver uma saída semelhante a esta:

PPLAY [Explore Command module options]

TASK [Gathering Facts]
ok: [localhost]

TASK [Run a command with a specific working directory]
changed: [localhost]

TASK [Run a command with environment variables]
changed: [localhost]

TASK [Run a command and ignore errors]
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["ls", "/nonexistent_directory"], "delta": "0:00:00.006113", "end": "2024-09-06 09:40:43.373350", "msg": "non-zero return code", "rc": 2, "start": "2024-09-06 09:40:43.367237", "stderr": "ls: cannot access '/nonexistent_directory': No such file or directory", "stderr_lines": ["ls: cannot access '/nonexistent_directory': No such file or directory"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [Run a command with a timeout]
changed: [localhost]

TASK [Check sleep command status]
FAILED - RETRYING: Check sleep command status (10 retries left).
FAILED - RETRYING: Check sleep command status (9 retries left).
FAILED - RETRYING: Check sleep command status (8 retries left).
FAILED - RETRYING: Check sleep command status (7 retries left).
FAILED - RETRYING: Check sleep command status (6 retries left).
FAILED - RETRYING: Check sleep command status (5 retries left).
FAILED - RETRYING: Check sleep command status (4 retries left).
FAILED - RETRYING: Check sleep command status (3 retries left).
FAILED - RETRYING: Check sleep command status (2 retries left).
FAILED - RETRYING: Check sleep command status (1 retries left).
fatal: [localhost]: FAILED! => {"ansible_job_id": "5877920468.2517", "attempts": 10, "changed": false, "finished": 0, "started": 1}

PLAY RECAP

Esta saída demonstra os diferentes comportamentos das opções do módulo Command que exploramos.

Usando o Módulo Command em um Cenário Docker-friendly

Nesta etapa final, você usará o módulo Command do Ansible em um cenário mais realista e amigável ao Docker: verificar o status do serviço SSH e gerenciá-lo, se necessário.

Crie um novo arquivo chamado check_service_docker.yml:

nano check_service_docker.yml

Adicione o seguinte conteúdo ao arquivo:

---
- name: Check and manage SSH service in Docker
  hosts: localhost
  become: yes ## This allows Ansible to use sudo
  tasks:
    - name: Check SSH service status
      command: service ssh status
      register: ssh_status
      ignore_errors: yes

    - name: Display SSH service status
      debug:
        msg: "SSH service status: {{ ssh_status.stdout }}"

    - name: Start SSH service if not running
      command: service ssh start
      when: ssh_status.rc != 0

    - name: Verify SSH service is running
      command: service ssh status
      register: ssh_status_after

    - name: Display final SSH service status
      debug:
        msg: "SSH service status is now: {{ ssh_status_after.stdout }}"

    - name: Check if SSH port is listening
      command: netstat -tuln | grep :22
      register: ssh_port_check
      ignore_errors: yes

    - name: Display SSH port status
      debug:
        msg: "SSH port 22 is {{ 'open' if ssh_port_check.rc == 0 else 'closed' }}"

Este playbook realiza as seguintes ações:

  1. Verifica o status do serviço SSH usando o comando service.
  2. Exibe o status atual do serviço.
  3. Inicia o serviço se ele não estiver em execução.
  4. Verifica o status do serviço após a potencial inicialização.
  5. Exibe o status final do serviço.
  6. Verifica se a porta SSH (22) está escutando.
  7. Exibe o status da porta SSH.

Salve o arquivo e saia do editor.

Agora, execute o playbook com privilégios sudo:

sudo ansible-playbook check_service_docker.yml

Você deve ver uma saída semelhante a esta:

PLAY [Check and manage SSH service in Docker] *****************************************

TASK [Gathering Facts] ****************************************************************
ok: [localhost]

TASK [Check SSH service status] *******************************************************
changed: [localhost]

TASK [Display SSH service status] *****************************************************
ok: [localhost] => {
    "msg": "SSH service status: * sshd is running"
}

TASK [Start SSH service if not running] ***********************************************
skipping: [localhost]

TASK [Verify SSH service is running] **************************************************
changed: [localhost]

TASK [Display final SSH service status] ***********************************************
ok: [localhost] => {
    "msg": "SSH service status is now: * sshd is running"
}

TASK [Check if SSH port is listening] *************************************************
changed: [localhost]

TASK [Display SSH port status] ********************************************************
ok: [localhost] => {
    "msg": "SSH port 22 is open"
}

PLAY RECAP ****************************************************************************
localhost                  : ok=6    changed=3    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

Esta saída mostra que o serviço SSH já estava em execução, então não precisou ser iniciado. O playbook verificou e validou com sucesso o status do serviço e também confirmou que a porta SSH está aberta.

Resumo

Neste laboratório, você explorou a versatilidade e o poder do módulo Command do Ansible. Você aprendeu a:

  1. Criar playbooks Ansible simples usando o módulo Command para executar comandos básicos.
  2. Usar variáveis com o módulo Command para tornar seus playbooks mais flexíveis e reutilizáveis.
  3. Capturar e processar a saída de comandos, permitindo que você tome decisões com base nos resultados dos comandos.
  4. Trabalhar com várias opções do módulo Command para controlar seu comportamento, como alterar diretórios, definir variáveis de ambiente e lidar com erros.
  5. Aplicar o módulo Command em um cenário do mundo real, verificando e gerenciando um serviço do sistema.

Essas habilidades formam uma base sólida para usar o Ansible para automatizar tarefas de administração de sistemas e gerenciar hosts remotos de forma eficiente. À medida que você continua a trabalhar com o Ansible, você descobrirá que o módulo Command é uma ferramenta versátil em seu kit de ferramentas de automação.

Lembre-se de que, embora o módulo Command seja poderoso, é frequentemente melhor usar módulos Ansible especializados (como o módulo service para gerenciar serviços) quando disponíveis. Esses módulos especializados fornecem melhor idempotência e podem lidar com cenários mais complexos de forma imediata.

Continue praticando e explorando as capacidades do Ansible para aprimorar ainda mais suas habilidades de automação e otimizar suas operações de TI.