Ansible практика – урок №14: defaults для хранения констант.

Предыдущий урок: Ansible практика – урок №13: Использование условия if в шаблонах.

Мы уже умеем пользоваться переменными и знаем, зачем они нужны. Одно из применений – задание констант. Если одно и тоже значение повторяется в плейбуке несколько раз, это повод вынести это значение в defaults.

Что выносить в defaults?

В defaults удобно выносить названия файлов, пути к файлам конфигураций, название скриптов, имена пользователей, пароли и прочие значения, которые часто повторяются в плейбуке. Так, в случае изменения данного значения, достаточно будет заменить его в defaults, а не менять по всему плейбуку.

defaults для хранения констант

В прошлый раз мы модифицировали роль nginx, после чего в ней осталось пару значений, которым самое место в defaults.

Шаг 1: Выносим значения в defaults

Создадим поддиректорию defaults в директории роли nginx:

[root@Control-Node ansible]# mkdir roles/nginx/defaults
[root@Control-Node ansible]#

Добавим файл со следующим содержанием:

---
default_nginx_conf_file: "/etc/nginx/nginx.conf"
default_htpasswd_file: "/usr/share/nginx/.htpasswd"
default_basic_auth_user: "ba_user"
default_basic_auth_password: "secret_password" 

Мы выделили в дефолтные переменные пару файлов, и вынесли пару пользователь/пароль. Держать пароли непосредственно в тасках плохая практика.

Шаг 2: Редактируем плейбук

Поправим плейбук, заменив значения их переменными. Файл roles/nginx/templates/nginx.conf.j2  примет вид:

worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80;
        listen       [::]:80;
        server_name  {{ domain_name }};
        root         /usr/share/nginx/html;

        include /etc/nginx/default.d/*.conf;
{% if basic_auth is defined and basic_auth is true -%}
        auth_basic          "Restricted area";
        auth_basic_user_file {{ default_htpasswd_file }};
{% endif -%}

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
}

А модифицированный файл roles/nginx/tasks/main.yml:

---
- name: "Role: NGINX | Block: Installation"
  tags:
    - installation
    - nginx
  block:
    - name: "Install NGINX on CentOS"
      ansible.builtin.dnf:
        name: nginx
        state: latest
      when: ansible_distribution == "CentOS"

    - name: "Install NGINX on Ubuntu"
      ansible.builtin.apt:
        name: nginx
        state: latest
      when: ansible_distribution == "Ubuntu"

- name: "Ensure NGINX is started and enabled"
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: true
  tags:
    - start
    - nginx

- name: "Role: NGINX | Block: Configuration"
  notify: restart_nginx
  tags:
    - nginx
  block:
    - name: "Deploy nginx.conf from template"
      ansible.builtin.template:
        src: nginx.conf.j2
        dest: "{{ default_nginx_conf_file }}"
        mode: '0644'
        owner: root
        group: root

    - name: "Set user/password for Basic Auth"
      ansible.builtin.shell: "htpasswd -cb {{ default_htpasswd_file }} {{ default_basic_auth_user }} {{ default_basic_auth_password }}"
      when: basic_auth is defined and basic_auth is true

Не забудьте про использование кавычек с именами переменных в задачах.

Шаг 3: Проверяем плейбук

Запустим Ansible и проверим, правильно ли работают наши изменения:

[root@Control-Node ansible]# ansible-playbook install_lemp.yml --tags nginx --skip-tags installation,start

PLAY [all] ******************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************
ok: [Managed-Node-1]
ok: [Managed-Node-2]
ok: [Managed-Node-3]

TASK [nginx : Deploy nginx.conf from template] ******************************************************************************************************************************************************
ok: [Managed-Node-2]
ok: [Managed-Node-3]
ok: [Managed-Node-1]

TASK [nginx : Set user/password for Basic Auth] *****************************************************************************************************************************************************
skipping: [Managed-Node-2]
skipping: [Managed-Node-3]
changed: [Managed-Node-1]

RUNNING HANDLER [nginx : restart_nginx] *************************************************************************************************************************************************************
changed: [Managed-Node-1]

PLAY RECAP ******************************************************************************************************************************************************************************************
Managed-Node-1             : ok=4    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Managed-Node-2             : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0
Managed-Node-3             : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

[root@Control-Node ansible]#

Раскатка плейбука прошла успешно, в процессе Ansible взял необходимые значения из defaults.

Итоги:

Мы научились использовать defaults. Теперь если нам нужно будет изменить общий пароль Basic Auth или файл, хранящий пару пользователь/пароль, нам не нужно будет искать эти значения в плейбуке и менять их там. Все делается в отдельном файле.

Следующий урок: Ansible практика – урок №15: Использование vault для хранения секретов.