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

Допустим, я хотел бы запустить следующую задачу из ansible:

    - name: dns-cloudflare | Request certificate
      ansible.builtin.shell:
        cmd: certbot certonly \
              --dns-cloudflare \
              --dns-cloudflare-credentials {{ certbot_cloudflare_credentials_file }} \
              --non-interactive \
              --agree-tos \
              --expand \
              --email {{ certbot_email }} \
              --domain {{ __domains }}
      args:
        executable: /bin/bash
        creates: "{{ certbot_directory }}/{{ item.name }}/{{ item.name }}/cert.pem"

Я строю его из такого блока:

certbot_cert:
  - name: test1.example.com
    cn:
      - test2-cn.example.com
    post-hook: systemctl restart apache2
  - name: test3.example.com

Я хочу добавить аргумент --post-hook к моей команде certbot в зависимости от того, item.post-hook. И содержимое этого крючка не статично: все, что я туда ввожу, должно попасть в команду моего certbot, например --post-hook 'systemctl restart apache2'

Но когда я не определяю эту переменную, не должно быть пустого пост-хука, его вообще не должно быть в команде certbot.

Как я могу этого добиться?

Я поигрался с переменными и фильтрами, прочитал документацию, но не нашел подходящего способа обработки. Дублировать эту задачу несколько раз для каждого возможного необязательного аргумента не следует.

Поскольку в команде оболочки могут быть пустые строки, если вы избегаете перевода строки, у вас может быть строка: {{ "--post-hook '" ~ item['post-hook'] ~ "'" if item['post-hook'] is defined }} \. Тем не менее, я был бы удивлен, если бы не существовало существующего модуля, который обеспечил бы вам интеграцию с cerbot, где вы, вероятно, могли бы сделать более простой post_hook: "{{ item['post-hook'] | default(omit) } }".

β.εηοιτ.βε 17.04.2024 21:48

^-- github.com/geerlingguy/ansible-role-certbot

β.εηοιτ.βε 17.04.2024 21:52
Введение в Ansible Roles
Введение в Ansible Roles
Ansible - это отличный инструмент управления конфигурацией, который можно использовать для автоматизации настройки или развертывания на большом...
1
2
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

То, как вы написали значение cmd, не сохраняет символы новой строки - это то, что вы хотите, поскольку это означает, что (а) вам не нужно экранировать (\) конец строк, как вы это сделали в своем примере и (б) вы можете удобно использовать условные выражения jinja для подавления некоторых строк.

Так:

- hosts: localhost
  gather_facts: false
  vars:
    certbot_cloudflare_credentials_file: creds.conf
    certbot_email: [email protected]
    __domains: example.com
    certbot_directory: certs
    certbot_cert:
    - name: test1.example.com
      cn:
        - test2-cn.example.com
      post-hook: systemctl restart apache2
    - name: test3.example.com
  tasks:
    - name: dns-cloudflare | Request certificate
      loop: "{{ certbot_cert }}"
      ansible.builtin.shell:
        cmd: certbot certonly
          --dns-cloudflare
          --dns-cloudflare-credentials "{{ certbot_cloudflare_credentials_file }}"
          --non-interactive
          --agree-tos
          --expand
          --email "{{ certbot_email }}"
          --domain "{{ __domains }}"
          {% if 'post-hook' in item %}
          --post-hook "{{ item["post-hook"] }}"
          {% endif %}
      args:
        executable: /bin/bash
        creates: "{{ certbot_directory }}/{{ item.name }}/{{ item.name }}/cert.pem"

Для первого элемента в certbot_cert это будет выполняться:

certbot certonly --dns-cloudflare --dns-cloudflare-credentials creds.conf --non-interactive --agree-tos --expand --email [email protected] --domain example.com --post-hook systemctl restart apache2

А для второй строки будет работать:

certbot certonly --dns-cloudflare --dns-cloudflare-credentials creds.conf --non-interactive --agree-tos --expand --email [email protected] --domain example.com

Наконец-то у меня появилось время протестировать всю роль, но когда я ее использую, я получаю следующую ошибку ` msg: |- Задача включает параметр с неопределенной переменной. Ошибка была: «объект dict» не имеет атрибута «post». Ошибка находится в «/opt/pscloud/ansible/roles/certbot/tasks/dns-cloudflare-wit‌​hout-cn.yaml»: строка 8, столбец 7, но может находиться и в другом месте файла в зависимости от конкретной синтаксической проблемы. Нарушающая строка выглядит так: - name: dns-cloudflare | Запросить сертификат ^ здесь` Можно ли использовать тире в имени переменной?

patrick_s 27.05.2024 22:18

Тире не допускается в имени переменной, но оно вполне допустимо в ключе словаря. Показанный здесь сборник пьес работает так, как написано, без каких-либо ошибок в моей системе с Python 3.12.3 и Ansible 2.16.7.

larsks 28.05.2024 01:35

Другие вопросы по теме