Введение
В этом лабораторном занятии (lab) вы познакомитесь с модулем Ansible Command, мощным инструментом для выполнения команд на удаленных хостах. Модуль Command позволяет взаимодействовать с командной строкой непосредственно из ваших Ansible-плейбуков и задач, предоставляя гибкий способ управления удаленными системами. В рамках этого лабораторного занятия вы научитесь использовать модуль Ansible Command для выполнения различных команд, работы с переменными и аргументами, а также для захвата вывода команд.
Создание простого плейбука Ansible
На этом шаге вы создадите свой первый Ansible-плейбук, используя модуль Command для выполнения простой команды.
Сначала перейдите в директорию проекта:
cd ~/project
Теперь создайте новый файл с именем simple_command.yml с помощью текстового редактора по вашему выбору. Например, вы можете использовать редактор nano:
nano simple_command.yml
Добавьте в файл следующее содержимое:
---
- name: Execute a simple command
hosts: localhost
tasks:
- name: Run 'ls' command
command: ls -l
Разберем этот плейбук:
- Строка
hosts: localhostуказывает, что плейбук будет выполняться на локальной машине. - Раздел
tasksсодержит список задач, которые должны быть выполнены. - Строка
command: ls -lиспользует модуль Command для выполнения командыls -l, которая выводит список файлов и директорий в длинном формате.
Сохраните файл и выйдите из редактора (в nano нажмите Ctrl+X, затем Y, а затем Enter).
Теперь запустите плейбук с помощью следующей команды:
ansible-playbook simple_command.yml
Вы должны увидеть вывод, похожий на следующий:
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
Этот вывод показывает, что плейбук был успешно выполнен, и команда ls -l была выполнена на вашей локальной машине.
Использование переменных с модулем Command
На этом шаге вы научитесь использовать переменные с модулем Ansible Command. Переменные позволяют сделать ваши плейбуки более гибкими и повторно используемыми.
Создайте новый файл с именем variable_command.yml:
nano variable_command.yml
Добавьте в файл следующее содержимое:
---
- 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
В этом плейбуке представлены несколько новых концепций:
- Раздел
varsопределяет переменные, которые можно использовать в рамках всего плейбука. - Мы используем синтаксис
{{ variable_name }}для обращения к переменным внутри команды. - Ключевое слово
registerсохраняет вывод команды в переменную с именемcommand_output. - Модуль
debugиспользуется для отображения содержимого переменнойcommand_output.
Сохраните файл и выйдите из редактора.
Теперь запустите плейбук:
ansible-playbook variable_command.yml
Вы должны увидеть вывод, похожий на следующий:
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
Этот вывод показывает последние 5 строк файла /etc/passwd, демонстрируя, как можно использовать переменные с модулем Command.
Захват и обработка вывода команды
На этом шаге вы научитесь захватывать вывод команды и далее обрабатывать его с помощью Ansible.
Создайте новый файл с именем process_output.yml:
nano process_output.yml
Добавьте в файл следующее содержимое:
---
- 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 == ''
Этот плейбук более надежен и обрабатывает случаи, когда корневая раздел (root partition) может быть трудно обнаружена:
- Мы выводим все разделы, чтобы увидеть, какие из них доступны.
- Мы используем более гибкий шаблон для поиска корневой раздела.
- Мы добавляем проверки для обработки случаев, когда корневая раздела не найдена.
- Мы используем фильтр
default(''), чтобы избежать ошибок, когда корневая раздела не найдена.
Сохраните файл и выйдите из редактора.
Теперь запустите плейбук:
ansible-playbook process_output.yml
Вы должны увидеть вывод, похожий на следующий:
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
Этот вывод показывает все разделы, определяет корневую раздел и проверяет ее использование. Точные значения могут отличаться на вашей системе.
Работа с параметрами модуля Command
На этом шаге вы познакомитесь с некоторыми параметрами, доступными в модуле Ansible Command, которые позволяют контролировать его поведение.
Создайте новый файл с именем command_options.yml:
nano command_options.yml
Добавьте в файл следующее содержимое:
---
- 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
В этом плейбуке демонстрируются различные параметры модуля Command:
chdir: Изменяет текущую рабочую директорию перед выполнением команды.environment: Устанавливает переменные окружения для команды.ignore_errors: Продолжает выполнение плейбука, даже если команда завершилась с ошибкой.asyncиpoll: Запускает команду асинхронно с установкой таймаута.
Сохраните файл и выйдите из редактора.
Теперь запустите плейбук:
ansible-playbook command_options.yml
Вы должны увидеть вывод, похожий на следующий:
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
Этот вывод демонстрирует различные поведения параметров модуля Command, которые мы рассмотрели.
Использование модуля Command в сценарии, совместимом с Docker
На этом последнем шаге вы будете использовать модуль Ansible Command в более реалистичном сценарии, совместимом с Docker: проверять статус службы SSH и управлять ею при необходимости.
Создайте новый файл с именем check_service_docker.yml:
nano check_service_docker.yml
Добавьте в файл следующее содержимое:
---
- name: Check and manage SSH service in Docker
hosts: localhost
become: yes ## Это позволяет Ansible использовать 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' }}"
Этот плейбук выполняет следующие действия:
- Проверяет статус службы SSH с использованием команды
service. - Отображает текущий статус службы.
- Запускает службу, если она не запущена.
- Проверяет статус службы после возможного запуска.
- Отображает итоговый статус службы.
- Проверяет, прослушивается ли порт SSH (22).
- Отображает статус порта SSH.
Сохраните файл и выйдите из редактора.
Теперь запустите плейбук с привилегиями sudo:
sudo ansible-playbook check_service_docker.yml
Вы должны увидеть вывод, похожий на следующий:
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
Этот вывод показывает, что служба SSH уже была запущена, поэтому ее не нужно было запускать. Плейбук успешно проверил и подтвердил статус службы, а также убедился, что порт SSH открыт.
Резюме
В этом лабораторном занятии вы познакомились с универсальностью и мощностью модуля Ansible Command. Вы научились:
- Создавать простые плейбуки Ansible с использованием модуля Command для выполнения базовых команд.
- Использовать переменные с модулем Command, чтобы сделать ваши плейбуки более гибкими и повторно используемыми.
- Захватывать и обрабатывать вывод команд, что позволяет принимать решения на основе результатов выполнения команд.
- Работать с различными параметрами модуля Command для управления его поведением, например, изменять директорию, устанавливать переменные окружения и обрабатывать ошибки.
- Применять модуль Command в реальном сценарии, проверяя и управляя системной службой.
Эти навыки составляют прочную основу для использования Ansible для автоматизации задач системного администрирования и эффективного управления удаленными хостами. По мере дальнейшей работы с Ansible вы убедитесь, что модуль Command является универсальным инструментом в вашем арсенале автоматизации.
Не забывайте, что хотя модуль Command мощный, часто лучше использовать специализированные модули Ansible (например, модуль service для управления службами), если они доступны. Эти специализированные модули обеспечивают лучшую идемпотентность и могут обрабатывать более сложные сценарии сразу.
Продолжайте практиковаться и изучать возможности Ansible, чтобы дополнительно улучшить свои навыки автоматизации и упростить свои IT-операции.


