Ansible playbook to install different packages dep

2019-07-24 04:35发布

I have an Ansible playbook (using ansible 1.9.3) that sets up and updates a bunch of servers. One of those steps is to install packages (using the 'apt' plugin). Until recently all of my servers have been uniform (same version of Ubuntu server). I'm introducing a newer Ubuntu server and some of package names have changed.

Here's what my tasks file looks like:

- name: install needed packages
  apt: name={{ item }} state=present update_cache=yes
  with_items: packages

(and I have a list of packages in a vars file).

I could define a variable in my inventory file for the hosts with a different Ubuntu version.

How do I change this task to use one list of packages for my current hosts, and another list of packages for my newer hosts?

标签: ansible
2条回答
Melony?
2楼-- · 2019-07-24 05:12

Use a when clause. Here's an example that will only run on ubuntu 12.04

when: "'{{ ansible_distribution}}' == 'Ubuntu' and '{{ ansible_distribution_release }}' == 'precise'"

You could alternatively use:

when: "'{{ ansible_distribution }}' == 'Ubuntu' and '{{ ansible_distribution_version }}': '12.04'"

Edit: Later versions of Ansible (e.g. 2.7.1) would print a warning for this statement:

[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: '{{ansible_distribution}}' == 'Ubuntu' and '{{ ansible_distribution_release }}' == 'bionic'

Ansible now expects another syntax for conditional statements, as stated in the docs.

For Ansible 2.5 you could try this:

when: "ansible_distribution|string == 'Ubuntu' and ansible_distribution_release|string == 'bionic'"

or even:

when: 
  - ansible_distribution|string == 'Ubuntu'
  - ansible_distribution_release|string == 'bionic'

The latest version of the docs suggests to use access the ansible_facts like this:

when:
  - ansible_facts['distribution'] == "CentOS"
  - ansible_facts['distribution_major_version'] == "6"
查看更多
唯我独甜
3楼-- · 2019-07-24 05:22

To keep your playbooks cleaner, you could do this within the roles, for example, you could have a single tasks/main.yml the one based on the OS it will include the tasks matching the condition used with when, for example, if using ansible_os_family the contents of main.yml could be something like:

---
- include_tasks: freebsd.yml
  when: ansible_os_family == "FreeBSD"
  tags:
    - unbound

- include_tasks: debian.yml
  when: ansible_os_family == "Debian"
  tags:
    - unbound

- include_tasks: redhat.yml
  when: ansible_os_family == "RedHat"
  tags:
    - unbound

The advantage of this approach is that besides only having a set of task per OS, you can also tag the full tasks.

查看更多
登录 后发表回答