Подтвердить что ты не робот

Условно определить переменную в Ansible

Я хочу условно определить переменную в Ansible playbook следующим образом:

my_var: "{{ 'foo' if my_condition}}"

Я хотел бы, чтобы переменная оставалась неопределенной, если условие не переходит в true.

Ansible выдает следующую ошибку, если я пытаюсь выполнить код:

fatal: [foo.local] => {'msg': 'AnsibleUndefinedVariable: One or more undefined
                       variables: the inline if-expression on line 1 evaluated
                       to false and no else section was defined.', 'failed': True}

Почему это ошибка в любом случае?

Полный случай выглядит так:

{role: foo, my_var: "foo"}

Если my_var определен, роль делает что-то особенное. В некоторых случаях я не хочу, чтобы роль делала это. Я мог бы использовать when: condition, но тогда мне пришлось бы скопировать весь ролевой блок. Я также мог бы использовать дополнительную переменную bool, но я хотел бы найти решение, не меняя "интерфейс" на роль.

Есть идеи?

4b9b3361

Ответ 1

Вы можете использовать что-то вроде этого:

my_var: "{{ 'foo' if my_condition else '' }}"

"Else" произойдет, если условие не совпадает, и в этом случае будет установлено пустое значение для переменной. Я думаю, что это краткое, удобочитаемое и элегантное решение.

Ответ 2

Этот код может помочь вам определить переменную с условием.

- hosts: node1
  gather_facts: yes
  tasks:
   - name: Check File
     shell: ls -ld /etc/postfix/post-install
     register: result
     ignore_errors: yes

   - name: Define Variable
     set_fact:
         exists: "{{ result.stdout }}"
     when: result|success

   - name: Display Variable
     debug: msg="{{ exists }}"
     ignore_errors: yes

Так что здесь exists будет отображаться, только если условие true.

Ответ 3

Я полагаю, что вы после фильтра по default(omit). (Ссылка).

В соответствии с примером, mode будет вести себя так, как будто он не был установлен для первых двух элементов в цикле.

- name: touch files with an optional mode
  file:
    dest: "{{item.path}}"
    state: touch
    mode: "{{item.mode|default(omit)}}"
  loop:
    - path: /tmp/foo
    - path: /tmp/bar
    - path: /tmp/baz
      mode: "0444"

Ответ 4

Мой пример, после fooobar.com/info/416078/...:

vars:
    sudoGroup: "{{ 'sudo' if ansible_distribution == 'Ubuntu' else 'wheel' }}"

Из-за различных соглашений sudo, используемых Ubuntu по сравнению с другими платформами, здесь я говорю Ansible установить переменную с именем sudoGroup в sudo если платформой является Ubuntu, в противном случае установите ее в wheel.

Позже в моей книге игр я объединю переменную с user модулем Ansible, чтобы добавить sudo или wheel в дополнительные группы учетной записи в зависимости от того, на какой ОС Ansible работает:

- name: Add or update bob account
  user:
    name: bob
    uid: 3205
    groups: "{{ sudoGroup }}"
    append: yes

ЗАМЕТКИ:

  • Двойные кавычки вокруг {{ variable }} требуются в определении user: groups: выше.
  • После того, как я определил sudoGroup как указано выше, в моем разделе глобальных vars: playbook, Ansible настраивает его во время выполнения (на основе ansible_distribution) для каждой цели, которую я определяю в разделе hosts:.