Назад | Перейти на главную страницу

Ленивое вычисление «составной» переменной по умолчанию в зависимой роли Ansible

У меня две роли в Ansible, назовем их postgres и myservice.

В моем postgres роль, я определяю несколько переменных по умолчанию (в postgres/defaults/main.yml):

postgres_db: pgdb
postgres_user: postgres
postgres_systemd_docker_service_name: postgres_{{postgres_db}}

В моем postgres роль, я создаю файл служебной единицы systemd из postgres_systemd_docker_service_name переменная. Идея здесь в том, что если я хочу запустить более одного контейнера докеров postgres для нескольких служб, я могу различать их с помощью postgres_db переменная.

Тогда у меня есть myservice роль, в которой я зависим от postgres роль и переопределить некоторые переменные по умолчанию.

В моем myservice/meta/main.yml:

dependencies:
  - {role: docker}
  - role: postgres
    postgres_user: "myservice_user"
    postgres_password: "myservice_password"
    postgres_db: "myservice"

Однако, когда я запускаю playbook, который использует myservice роль, он создаст мои файлы модулей systemd как postgres_pgdb (значение по умолчанию), а не как postgres_myservice.

Если я использую postgres_systemd_docker_service_name переменная в моем myservice роль, она оценивается как postgres_myservice.

Есть ли у меня способ убедиться, что составная переменная в моем postgres роль оценивается таким образом, что мои myservice роль может переопределить значения по умолчанию?

Попробовав небольшой пример, я обнаружил, что (с использованием Ansible 2.4) составная переменная по умолчанию (т.е. она находится в defaults/main.yml) будет интерполироваться только тогда, когда это значение по умолчанию используется впервые.

Пример с использованием только одной роли:

roles/certs/defaults/main.yml

---
certs_dir: /etc/pki/tls/certs
cert_files:
  - "{{ ssl_domain }}.crt"
  - "{{ ssl_domain }}.key"
  - "{{ ssl_domain }}_ca-bundle.crt"

roles/certs/tasks/main.yml

---
- name: Determine the subdomain for the current host
  command: hostname --domain
  register: domain_result

- name: Set domain name as fact
  set_fact:
    ssl_domain: "{{ domain_result.stdout.strip() }}"

- name: Download certificates
  get_url:
    url: "http://{{ intranet_certificate_host }}/{{ intranet_certificate_path }}/_.{{ ssl_domain }}/{{ item }}"
    dest: "{{ certs_dir }}"
  with_items: "{{ cert_files }}"

Это сработает. Я вижу, что это не связано с «зависимой» ролью, но поскольку факты работают таким же образом в разных ролях, я почти уверен, что это будет работать и в разных ролях. Итак, по крайней мере, в той версии, которую я использовал, ленивая оценка является поведением по умолчанию, вам нужно только объединить ее с set_fact чтобы предоставить значение, которое входит в составное значение по умолчанию.