Как организовано хранение переменных в Ansible?

«Как организовано хранение переменных в Ansible?» — вопрос из категории Ansible, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Ansible предоставляет гибкую систему хранения переменных с четким порядком приоритета (от низшего к высшему):

Иерархия приоритетов (основные источники):

  1. Роли (defaults): Переменные по умолчанию в roles/role_name/defaults/main.yml. Имеют самый низкий приоритет.
  2. Инвентарь: Переменные, определенные в файлах инвентаря (inventory.ini или inventory.yml).
  3. Групповые переменные: Файлы в group_vars/all.yml (для всех) или group_vars/group_name.yml.
  4. Переменные хоста: Файлы в host_vars/hostname.yml.
  5. Плейбук (vars): Секция vars: в плейбуке.
  6. Роли (vars): Переменные в roles/role_name/vars/main.yml.
  7. Задачи (set_fact): Переменные, установленные модулем set_fact во время выполнения задач.
  8. Extra vars: Переменные, переданные через -e в командной строке. Наивысший приоритет.

Практические примеры:

1. Определение в плейбуке:

- hosts: webservers
  vars:
    http_port: 8080
    max_clients: 200
  tasks:
    - name: Print variable
      debug:
        msg: "Server will run on port {{ http_port }}"

2. Использование групповых переменных (group_vars/webservers.yml):

---
# Настройки для группы 'webservers'
nginx_version: "1.20"
server_names:
  - example.com
  - www.example.com

3. Динамические переменные через register и set_fact:

- name: Get system memory
  shell: "awk '/MemTotal/ {print $2}' /proc/meminfo"
  register: mem_result

- name: Set fact based on memory
  set_fact:
    memory_sufficient: "{{ mem_result.stdout | int > 4000000 }}"

- name: Install heavy service only if memory is sufficient
  apt:
    name: my-memory-hungry-app
    state: present
  when: memory_sufficient

4. Использование ansible-vault для секретов: Конфиденциальные переменные (пароли, ключи) хранятся в зашифрованных файлах.

# Создание зашифрованного файла
ansible-vault create secrets.yml

Содержимое secrets.yml:

db_password: "{{ vault_db_password }}"
api_key: "{{ vault_api_key }}"

В плейбуке или group_vars подключаем его:

- hosts: all
  vars_files:
    - secrets.yml
  tasks:
    - debug:
        msg: "Password is {{ db_password }}"

Запуск: ansible-playbook playbook.yml --ask-vault-pass

Рекомендация: Храните переменные, специфичные для окружения (dev, staging, prod), в group_vars/ с соответствующими именами, а секреты — в vault. Это обеспечивает чистоту кода и безопасность.