在Ansible中有条件地定义变量

时间:2015-07-09 07:22:20

标签: ansible ansible-playbook

我想在Ansible剧本中有条件地定义一个变量,如下所示:my_var: "{{ 'foo' if my_condition}}"。如果条件没有解析为真,我希望变量保持未定义。

如果我尝试这样做,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变量,但我想要一个解决方案而不必更改"界面"这个角色。

有什么想法吗?

4 个答案:

答案 0 :(得分:30)

您可以使用以下内容:my_var: "{{ 'foo' if my_condition else '' }}"。如果条件不匹配,则会发生'else',在这种情况下,将为变量设置一个空值。我认为这是一个简短,易读且优雅的解决方案。

答案 1 :(得分:19)

此代码可帮助您定义带条件的变量。

- 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

所以这里只有条件为真时才会显示“存在”。

答案 2 :(得分:3)

我相信你是在default(omit)过滤器之后。

http://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#omitting-parameters

根据示例,模式的行为类似于循环中前两个项目的设置。

- 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"

答案 3 :(得分:0)

我的示例,在https://stackoverflow.com/a/43403229/5025060之后:

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

由于Ubuntu与其他平台使用了不同的sudo约定,因此我告诉Ansible如果平台是Ubuntu,则将名为sudoGroup的变量设置为sudo,否则将其设置为{{1 }}。

稍后,在我的剧本中,我将变量与Ansible的wheel模块结合在一起,以根据运行的操作系统Ansible将usersudo添加到帐户的辅助组中:

wheel

注释:

    上面的- name: Add or update bob account user: name: bob uid: 3205 groups: "{{ sudoGroup }}" append: yes 定义中,必须在{{ variable }}周围加上
  • 双引号
  • 一旦我在剧本的全局user: groups:部分中定义了sudoGroup,Ansible就会在运行时(基于vars:)为我在{{1}中定义的每个目标配置它}部分。