Syntax highlighting of 8252cb3 ~( devops/ansible)

= Ansible =

<<TableOfContents(2)>>

== Вложенные материалы ==

<<ItemList(display=”ChildName”)>>

== Полезные ссылки ==

[[https://www.ansible.com|Ansible|class=" moin-https"]]

[[https://docs.ansible.com|Documentation|class=" moin-https"]]

[[https://docs.ansible.com/ansible/latest/collections/index_module.html|Index of all Modules|class=" moin-https"]]

[[http://onreader.mdl.ru/MasteringAnsible2nd/content/index.html|Полное руководство Ansible|class=" moin-http"]]

[[https://galaxy.ansible.com/|Ansible Galaxy|class=" moin-https"]]

[[https://docs.ansible.com/ansible-lint/|Проверка синтаксиса playbook|class=" moin-https"]]

== Установка ==

[[https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#latest-releases-via-apt-ubuntu|source|class=" moin-https"]]

=== Бинарник (v2.x) ===

{{{#!highlight bash
sudo apt-get update
sudo apt-get install software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible
sudo apt-get install ansible
ansible --version

}}}

=== Pip-пакет ===

{{{#!highlight bash
sudo python3 -m pip install ansible
# --- консоль необходимо перезапустить
ansible --version

}}}

== Ad Hoc ==

{{{#!highlight bash
#
# --- modules
#
# --- ping
# пигуем все серверы
ansible all -m ping
# пингуем один сервер
ansible ds4ci -m ping
# пингуем один сервер из заданного инвентаря с выводом отладочной информации
ansible ds4ci -i /path/to/hosts -m ping -vvvv

# --- setup
# получение "фактов" о хосте (значительный вывод)
ansible ds4staging -m setup
# получение "фактов" с фильтрацией вывода
ansible ds4staging -m setup -a 'filter=ansible_ens*'

# --- command
# выполнение произвольной команды на сервере (uptime)
ansible ds4ci -m command -a uptime
# то же, -m command выполняется по умолчанию
ansible ds4ci -a uptime
# выполнение команды с пробелами на сервере
ansible ds4ci -a "tail /var/log/dmesg"

# --- reboot
# reboot all hosts
ansible -i inventory/hosts.yml all -m reboot -b

# --- apt
ansible all -m apt -a "upgrade=yes update_cache=yes" --become
ansible all -m apt -a "upgrade=yes update_cache=yes autoremove=yes" --become

#
# --- debug
#
ansible registry -a uptime -e @secrets.yml.enc --ask-vault-pass
# отладочный вывод с подключением зашифрованного файла с секретами
ansible registry -m debug -a 'var=hostvars[inventory_hostname]' -e @secrets.yml.enc --ask-vault-pass
ansible registry -a uptime

# получение справки по модулю `service`
ansible-doc service

}}}

== Inventory ==

{{{#!highlight ini
[group]
ds4ci   ansible_host=10.0.100.232 ansible_user=adminwaltix \
    ansible_port=10022 ansible_private_key_file=/path/to/idrsa

[group1]
host1 ...

[group2]
host2 ...

[parent_group:children]
group1
group2

}}}

Поведенческие параметры

||Имя||Знач. по умолчанию||Описание||
=====
||`ansible_host`||-||Имя хоста или IP-адрес||
||`ansible`||22||Порт для подключения по SSH||
||`ansible_user`||`root`||Пользователь для подключения по SSH||
||`ansible_password`||-||Пароль для подключения по SSH||
||`ansible_private_key_file`||-||Приватный SSH-ключ для аутентификации по SSH||
||`ansible_shell_type`||`sh`||Командная оболочка||

Определение переменных групп в реестре

{{{#!highlight ini
[all:vars]
ntp_server=ntp.ubuntu.com
[production:vars]
db_host=
db_name=
...
[staging:vars]
db_host=
db_name=

}}}

Определение переменных групп и хостов в отдельных файлах:

''host_vars/'' - директория для переменных хостов
''host_vars/example.com'' - файл с переменными хоста ''example.com''''group_vars/'' - директория для переменных групп
''group_vars/production'' - файл с переменными группы ''production''

Формат файла:

{{{#!highlight yaml
db:
  user: dbuser
  password: dbpassword
  primary:
    host: db1.example.com
    port: 5432
  replica:
    host: db2.example.com
    port: 6543

}}}

Доступ к переменным из сценария: `{{ db.primary.host }}`

== Vault ==

Утилита командной строки `ansible-vault` позволяет создавать и редактировать  зашифрованный файл, который `ansible-playbook` будет автоматически распознавать  и расшифровывать с помощью пароля.

{{{#!highlight bash
# зашифровать имеющийся файл
ansible-vault encrypt secrets.yml
# создать новый зашифрованный файл
ansible-vault create secrets.yml.enc
# изменить пароль зашифронного файла
ansible-vault rekey secrets.yml.enc
# открыть зашифрованный файл для редактирования
ansible-vault edit secrets.yml.enc
# вызов сценария с запросом пароля расшифрования
ansible-playbook some-playbook.yml --ask-vault-pass
# вызов сценария с указанием расположения файла с паролем
ansible-playbook some-playbook.yml --vault-password-file ~/password.txt

}}}

== Recipes ==

=== Alt Linux ===

Для возможности управления Alt Linux с использование Ansible необходимо установить на Alt следующие пакеты:

{{{#!highlight bash
# --- python 2
su
apt-get install python-module-pip
pip install simplejson 
# --- python 3
su
apt-get install python3 python3-module-pip
ln -fs /usr/bin/python3 /usr/bin/python
ln -fs /usr/bin/pip3 /usr/bin/pip

}}}

=== Кэширование переменных ===

Выявлено, что если в переменных хоста прописать следующую конструкцию

{{{#!highlight yaml
ansible_password: "{{ registry.ansible_password }}"
registry: ""

}}}

а в ''secrets.yml.enc'' 

{{{#!highlight yaml
registry:
  ansible_password: 'secret'

}}}

то при выполнении команды

{{{#!highlight bash
ansible registry -a uptime -e @secrets.yml.enc --ask-vault-pass

}}}

мы ожидаемо получаем корректный ответ.

Но если мы сразу повторим команду без ''secrets.yml.enc'', то она также выполнится корректно

{{{#!highlight bash
ansible registry -a uptime

}}}

Т.е. в течении некоторого времени (до 5 минут) пароль где-то хранится... 

Данное поведение наблюдается только при наличии пустой переменной `registry: ""```

== Troubleshooting ==

=== localhost in Alert URL ===

В уведомлениях приходит URL  localhost.
Необходимо добавить переменную окружения `GF_SERVER_ROOT_URL` с адресом сервера.
https://community.grafana.com/t/how-can-i-update-the-grafana-dashboard-url-in-the-slack-notification/15075/2

=== "AnsibleError: template error while templating string: unexpected '.' ===

При выполнении модуля template, может случится так, что в файле-шаблоне уже используются `{{ }}`. 

Напр, `oauth2_proxy` предполагает конфигурация логов через фигурные скобки.

{{{
#standard_logging_format = "[{{.Timestamp}}] [{{.File}}] {{.Message}}"

}}}

Подобная запись будет интерпретироваться Ansible-ом и будет выдана ошибка

{{{
"AnsibleError: template error while templating string: unexpected '.'

}}}

'''Решение'''
Чтобы ''Ansible'' пропускал определенные записи файла-шаблона необходимо воспользоваться `{% raw %}`и `{% endraw %}`, например

{{{
{% raw %}
#standard_logging_format = "[{{.Timestamp}}] [{{.File}}] {{.Message}}"
{% endraw %}

}}}