Skip to content

Ansible

Ansible — система управления конфигурациями, написанная на Python, с использованием декларативного языка разметки для описания конфигураций. Используется для автоматизации настройки и развертывания программного обеспечения. Обычно используется для управления Linux-узлами, но Windows также поддерживается. Поддерживает работу с сетевыми устройствами, на которых установлен Python версии 2.4 и выше по SSH или WinRM соединению.

https://www.altlinux.org/Ansible

https://docs.ansible.com/projects/ansible/latest/collections/index.html

Быстрый старт

Установка на сервер:

bash
apt-get install ansible

Установка на клиенты:

bash
apt-get install python python-module-yaml python-module-jinja2 python-modules-json python-modules-distutils

На клиенте должен быть настроен ключевой (безпарольный) доступ по ssh к пользователю root на клиенте пользователем, который будет работать с ansible на сервере (не root).

Все дальнейшие действия производим на сервере.

Редактируем файл /etc/ansible/hosts - это файл, который содержит списки хостов и группы этих хостов:

[all:vars]
ansible_user=root
ansible_python_interpreter=/usr/bin/python3

ниже указываем хосты

Пример файла hosts:

[all:vars]
ansible_user=root
ansible_python_interpreter=/usr/bin/python3

[group1]
192.168.100.101
192.168.100.102
192.168.100.103

[servers]
altsrv1.courses.alt
altsrv2.courses.alt

[wks]
altwks1 ansible_ssh_port=2221 ansible_ssh_host=192.168.100.201
altwks2 ansible_ssh_port=2221 ansible_ssh_host=192.168.100.202

[alt:children]
servers
wks

Использование ad-hoc команд в Ansible

Проверяем связь с клиентом с помощью модуля ping в интерактивном режиме:

bash
$ ansible -m ping servers
altsrv1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
altsrv2 | SUCCESS => {
"changed": false,
"ping": "pong"
}

где servers - это группа хостов из файла /etc/ansible/hosts

Пример. Выполнение команды на управляемых узлах

bash
$ ansible -i hosts -m shell -a 'uname -a' servers
altsrv2 | CHANGED | rc=0 >>
Linux altsrv2 5.10.82-std-def-alt1 #1 SMP Fri Dec 3 14:49:25 UTC 2021 x86_64
GNU/Linux
altsrv1 | CHANGED | rc=0 >>
Linux altsrv1 5.10.82-std-def-alt1 #1 SMP Fri Dec 3 14:49:25 UTC 2021 x86_64
GNU/Linux

Пример. Удаление файла

bash
$ ansible -m file -a "name=/etc/nologin state=absent" all

Создание хеша пароля:

bash
mkpasswd <password>

Получаем строку.

Далее используем ansible-vault:

bash
$ ansible-vault encrypt_string 'ранее полученный хэш'
New Vault password:
Confirm New Vault password:
!vault |
    $ANSIBLE_VAULT;1.1;AES256
    65366666616436396133363165346432623166616161383037613833393438363039336438386265
    6633613030303565316431336531313261366532376336640a623861316166643730323833666263
    65333534303663363066323832376231616261363636616330366634616334663234666330623934
    3764343932663632350a393563366331376630666239386163656531343936616438316434343738
    36636533366433353939666333313538633539383365643766663563616534623863396166356530
    63306638373134303961353364333131386361653064306364346265313334353436303239373838
    62346136656161653430383730663661393830313430343539366663383431626365633465376436

И теперь весь этот блок, начиная с !vault | необходимо использовать в ансибле

Полезные рецепты с Альтвики

Рецепты применяются командой:

ansible-playbook <имя файла>

Прописывание репозитория

Файл: /etc/ansible/playbooks/repo.yml

- hosts: local
  remote_user: root
  tasks: 
  - name: Remove all repositories
    shell: apt-repo rm all
  - name: Add official mirror
    shell: apt-repo add http://10.10.3.77/repo/p8
  - name: Add official mirror with arepo
    shell: apt-repo add 'rpm http://10.10.3.77/repo/p8 x86_64-i586 classic'
  - name: Add extra repository 
    shell: apt-repo add 'rpm http://10.10.3.77/repo/extra x86_64 extra'

Примечание: Используется модуль shell и программа apt-repo.

Установка пакета

Файл: /etc/ansible/playbooks/install-ifcplugin.yml

- hosts: local
  remote_user: root
  tasks:
  - name: Update cache and install ifcplugin
    apt_rpm:
      name: ifcplugin
      state: present
      update_cache: yes

Обновление системы

С версии ansible-2.9.27-alt2 и ansible-core-2.14.2-alt1:

- hosts: local
  remote_user: root
  gather_facts: no
  tasks:
  - name: Update cache
    apt_rpm:
      update_cache: true
  - name: Upgrade system
    apt_rpm:
      dist_upgrade: true
  - name: Upgrade kernel
    apt_rpm:
      update_kernel: true
  - name: Clean package cache
    apt_rpm:
      clean: true

Или всё в одном:

- hosts: local
  remote_user: root
  gather_facts: no
  tasks:
  - name: Upgrade system
    apt_rpm:
      update_cache: true
      dist_upgrade: true
      update_kernel: true
      clean: true

Примечание: Используется модуль apt_rpm.

Ссылки


использование плагина nmap в связке с плагином constructed. При запуске он опрашивает указанные подсети и формирует список хостов для применения плейбуков или ролей, а потом делает свои грязные делишки на отобранные по правилам хосты.

Использование ANSIBLE VAULT Назначение:

  • Шифрование данных
  • Хранение шифрованных данных
  • Расшифровка данных только в момент использования этих данных Работа с ansible-vault в интерактивном режиме:
bash
$ ansible-vault
- create
- decrypt
- edit
- view
- encrypt
- encrypt_string
- rekey

Шифрование отдельных строк:

bash
$ ansible-vault encrypt_string 'password'
New Vault password:
Confirm New Vault password:
!vault |
$ANSIBLE_VAULT;1.1;AES256
    36616364663239636230386638643139383237326533363236323339666162323163376565313138
    3333636130646636363639363530643364656534336338370a383131306136353337303261366430
    61366633656262373236333434353539633631366533623630373032366461346630636635313235
    6631393939646632360a656430626338336533376437646232323161653939383739353564353934
    6338

Применение полученного результата, создадим плейбук в котором используются зашифрованная строка:

yaml
play1.yml:
---
- name: Получим пароль
hosts: localhost
gather_facts: no
vars:
password: !vault |
$ANSIBLE_VAULT;1.1;AES256
    36616364663239636230386638643139383237326533363236323339666162323163376565313138
    3333636130646636363639363530643364656534336338370a383131306136353337303261366430
    61366633656262373236333434353539633631366533623630373032366461346630636635313235
    6631393939646632360a656430626338336533376437646232323161653939383739353564353934
    6338
tasks:
- name: debug
debug:
msg: "Пароль: {{ password }} "

Выполним полученный плейбук:

bash
$ ansible-play play1.yml
# Получим ошибку, т.к. не указан пароль для расшифровки
$ ansible-playbook play1.yml --ask-vault-password
PLAY [Получим пароль]
******************************************************************************
TASK [debug]
***************************************************************************************
ok: [localhost] => {
"msg": "Пароль: password "
}
PLAY RECAP
*****************************************************************************************
localhost : ok=1 changed=0 unreachable=0
failed=0 skipped=0 rescued=0 ignored=0
Создание строки пригодной для встраивание в плейбуки:
$ ansible-vault encrypt_string 'password' --name 'user_password'
user_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
    63366162373537346533316265303361303766393938333439633965613866623130376330616531
    3664323366666234363636656264333133653562396135310a633237613966343065643736363733
    34313737643732616662356539383130373962356363333366353834366163313030663563623037
    3633663230373636330a326262353464323334363632323639313633313531333164343664376438
    3433

Создание хранилища в виде файла:

bash
$ ansible-vault create /tmp/vault1.yml
New Vault password:
Confirm New Vault password:

Запускается редактор по-умолчанию для редактирование файла (vim). Просмотр результата:

bash
$ cat /tmp/vault1.yml
$ANSIBLE_VAULT;1.1;AES256
    31306565313730343431623364613939373162323163643238613137323261653139623062646438
    3764383630306665666439663530613538363035386232640a643265356263303133623037363234
    33326336386338613064383732663664396436643864303137653966376139643465353566313330
    3662323665636463630a653637376438326164306536313638653633333930626262636362353962
    36613462333261346633323464646437316464343034353830316437373431643765

Просмотр дешифрованного содержимого файла:

bash
$ ansible-vault view /tmp/vault1.yml
Vault password:
user_password: netlab123

Использование шифрованных файлов в плейбуке: play1.yml:

yaml
---
- name: Получим пароль
hosts: localhost
vars_files: "/tmp/vault1.yml"
gather_facts: no
tasks:
- name: debug
debug:
msg: "Пароль: {{ user_password }}"

Результат:

bash
$ ansible-playbook play1.yml --ask-vault-password
Vault password:
PLAY [Получим пароль]
******************************************************************************
TASK [debug]
***************************************************************************************
ok: [localhost] => {
"msg": "Пароль: netlab123"
}
PLAY RECAP
*****************************************************************************************
localhost : ok=1 changed=0 unreachable=0
failed=0 skipped=0 rescued=0 ignored=0

Редактирование зашифрованного содержимого файла:

bash
$ EDITOR=nano ansible-vault edit /tmp/vault1.yml
# Данные в виде словаря
passwords:
user1:
password: netlab123
user2:
password: netlab123
Изменённый плейбук:
play1.yml:
---
- name: Получим пароль
hosts: localhost
vars_files: "/tmp/vault1.yml"
gather_facts: no
tasks:
- name: debug
debug:
msg: "Пароль пользователя {{ item.key }} :
{{ item.value.password }}"
loop: "{{ passwords | dict2items }}"
bash
$ ansible-playbook play1.yml --ask-vault-password
Vault password:

Шифрованние/дешифрование готового файла:

bash
$ vim user-passwords.yml # создаём файл
$ ansible-vault encrypt user-passwords.yml # шифрование файла
$ cat user-passwords.yml # просмотр результата
$ ansible-vault view user-passwords.yml # просмотр
$ ansible-vault decrypt user-passwords.yml # шифрование файла
$ ansible-vault encrypt user-passwords.yml # зашифруем снова

Шифрование (+ хранение) файла:

bash
$ cp ~/.ssh/id_rsa id_rsa.encrypted
$ ansible-vault encrypt id_rsa.encrypted
yaml
Создадим плейбук для копирования зашифрованного файла:
copy-file.yml:
---
- name: Соединяемся с другим узлом
hosts: remotehost
gather_facts: no
become: false
tasks:
- name: Копирование файла на удалённый сервер
copy:
src: id_rsa.encrypted
dest: ~/.ssh/remote_key
mode: '0600'
Пример использования:
use-user.yml:
---
- name: Соединяемся с другим узлом
hosts: remotehost
vars_files: "user-passwords.yml"
gather_facts: no
tasks:
- name: Установим учётную запись и пароль для соединения
set_fact:
ansible_user: "{{ item.key }}"
ansible_password: "{{ item.value.password }}"
with_items: "{{ passwords | dict2items }}"
when:
- item.key == "user1"
- name: Посмотрим в какие группы входит пользователь
shell: /usr/bin/id
register: result
- name: Посмотрим результат
debug:
msg: "Пользователь {{ ansible_user }} входит в группы
{{result.stdout}}"

Потребуется sshpass:

bash
# apt-get install sshpass
$ ansible-playbook use-user.yml --ask-vault-password
Vault password:
- no_log:

Использование ansible-vault без введения пароля:

bash
ANSIBLE_VAULT_PASSWORD_FILE=
--vault-password-file=
$ ansible-playbook use-user.yml --vault-password-file=
$ chmod +x <vault-password-file>

say_password:

bash
#!/bin/sh
echo U2FsdGVkX1+7Gd8IBqVzGfDmsrbRcT2K0SNZSq8158o= | openssl aes-
256-cbc -d -a -pass pass:somepassword 2>/dev/null
Использование ansible-vault в ролях:
$ cd r1/vars
- открытая часть:
- закрытая часть:
passwords.yml:
---
# vars file for r1
passwords:
user1:
password: "netlab123"

Шифруем файл «закрытой части»:

bash
$ ansible-vault encrypt passwords.yml
New Vault password:
Confirm New Vault password:
Encryption successful
Изменяем файл с задачами:
$ cd ../tasks/
yaml
main.yml:
---
# tasks file for r1
- name: Создаём пользователя без пароля
user:
name: "{{ item.key }}"
append: "{{ item.value.append }}"
groups: "{{ item.value.groups }}"
loop: "{{ users | dict2items }}"
- name: Добавим файл с паролем
include_vars: passwords.yml
- name: Создаём пароль для пользователя
user:
name: "{{ item.key }}"
password: "{{ item.value.password |
password_hash('sha512') }}"
loop: "{{ passwords | dict2items }}"
no_log: true
bash
$ ansible-playbook r1task.yml --vault-password-file=say_password

Использование нескольких хранилищ:

bash
$ cat ~/.ansible/inventory.ini
$ EDITOR=nano ansible-vault create --vault-id become105@prompt

/home/sysadmin/.ansible/192.168.100.105.yml

yaml
- @
- prompt
bash
$ cat /home/sysadmin/.ansible/192.168.100.105.yml
$ANSIBLE_VAULT;1.2;AES256;become105
$ vim become105
r1task.yml:
vars_files: "/home/sysadmin/.ansible/192.168.100.105.yml"
$ ansible-playbook r1task.yml --vault-password-file=say_password
--vault-id=become105
--vault-password-file=
--vault-id=

TIP

Система управления конфигурациями
Ansible
Основы Ansible
Об Ansible
• Ansible
• Декларативный синтаксис
• Отличительные особенности Ansible
◦ не требует агентского ПО
◦ декларативный синтаксис
◦ push-модель управления
◦ паралельное выполнение изменений
Назначение
• Настройка
• Множество управляемых узлов
• Параметризация
• Сборка фактов
Архитектура
• Управляющий хост
• Управляемые хосты (targets)
• Сетевое взаимодействие
• Модули
• Задание (tasks)
Архитектура Ansible

Установка в ОС Альт
Управляющий узел
$ apt-get install ansible
/etc/ansible/ansible.cfg
~/.ansible.cfg
Подключение к управлемым узлам
• ssh root@host
$ ssh-keygen
$ ssh-copy-id root@<host>
• ssh user@host
Управляемые узлы
$ apt-get install python3 python3-module-yaml python3-module-jinja2 python3-
module-jsonlib
Файл инвентаризации (Inventory)
/etc/ansible/hosts
$ ansible -i ./hosts
$ ANSIBLE_HOSTS=./hosts
Структура файлов инвентаризации
[all:vars]
ansible_user=root
ansible_python_interpreter=/usr/bin/python3
mail.domain.alt
[webservers]
www.domain.alt
private-web.domain.alt
[dbases]
db[1:3].domain.alt
all:
hosts:
mail.domain.alt
children:
webservers:
host:
www.domain.alt
private-web.domain.alt
dbases:
hosts:
db[1:3].domain.alt
Хосты в файле инвенторизации
Группы файла инвентаризации
Переменные файла инвентаризации
Пример файла инвентаризации
[all:vars]
ansible_user=root
ansible_python_interpreter=/usr/bin/python3
[group1]
192.168.100.101
192.168.100.102
192.168.100.103
[servers]
altsrv1.courses.alt
altsrv2.courses.alt
[wks]
altwks1 ansible_ssh_port=2221 ansible_ssh_host=192.168.100.201
altwks2 ansible_ssh_port=2221 ansible_ssh_host=192.168.100.202
[alt:children]
servers
wks
Динамическая инвентаризация
Дополнительное чтение
• https://habr.com/ru/post/509938/
Использование ad-hoc команд в Ansible
Ad-hoc команды
• Типичное применение
◦ управление службами и процессами
◦ проверка содержимого файлов журналов
◦ проверка установленного ПО
◦ проверка системных параметров и данных производительности
◦ знакомство с новыми модулями
Синтаксис команды ansible
$ ansible [-i inventory ] \
[-m module] [-a "params"] \
[ -b ] \
[all|group|host]
• -i inventory-file
• -m module
• -a “param1=val param2=val”
• -b
• all|group|host
Пример. ping средствами Ansible
$ ansible -i hosts -m ping servers
altsrv1 | SUCCESS => {
"changed": false,
"ping": "pong"
}
altsrv2 | SUCCESS => {
"changed": false,
"ping": "pong"
}
$ ansible -m ping all
Пример. Выполнение команды на управляемых узлах
$ ansible -i hosts -m shell -a 'uname -a' servers
altsrv2 | CHANGED | rc=0 >>
Linux altsrv2 5.10.82-std-def-alt1 #1 SMP Fri Dec 3 14:49:25 UTC 2021 x86_64
GNU/Linux
altsrv1 | CHANGED | rc=0 >>
Linux altsrv1 5.10.82-std-def-alt1 #1 SMP Fri Dec 3 14:49:25 UTC 2021 x86_64
GNU/Linux
Пример. Удаление файла
$ ansible -m file -a "name=/etc/nologin state=absent" all
Цветовой вывод ansible
• зеленый
• желтый
• красный
Модули Ansible
О модулях
• Модули Ansible
$ ansible -m module -a "name1=value1 name2=value2"
$ ansible -i hosts -m copy -a 'src=/etc/hosts dst=/etc' all
• https://docs.ansible.com
Часто используемые модули
Модуль Назначение
ping Проверка доступности узла
setup Сбор фактов с управляемых узлов
apt_rpm Установка/обновление ПО
service Управление службами
systemd Управление службами средствами systemd
copy Копирование файлов
file создание, удаление, изменение атрибутов
файлов
template Тиражирование шаблонных файлов
replace Замена строк в файлах на основе регулярных
выражений
Модуль Назначение
lineinfile Вставка, замена, удаление строк в файлах
user Управление пользовательскими УЗ
group Управление УЗ групп
command, shell Выполнение произвольных внешних команд
окружения
debug Вывод отладочной информации
Рецепты (плейбуки) ansible
О рецептах
Правила написания YAML-плейбуков
1. Отступы пробелами
2. Списки play, tasks
3. Равенство отступов
Структура плейбука
play1
task1
task2
. . .
play2
task1
task2
. . .
. . .
• Play (hosts->tasks)

Контакты: bystrovno@basealt.ru