Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split an ansible role's `defaults/main.yml` file into multiple files?

In some ansible roles (e.g. roles/my-role/) I've got quite some big default variables files (defaults/main.yml). I'd like to split the main.yml into several smaller files. Is it possible to do that?

I've tried creating the files defaults/1.yml and defaults/2.yml, but they aren't loaded by ansible.

like image 532
myrdd Avatar asked Aug 13 '18 08:08

myrdd


People also ask

What is main yml in Ansible?

yml exists, Ansible adds the tasks in that file to the play. If roles/x/handlers/main. yml exists, Ansible adds the handlers in that file to the play. If roles/x/vars/main. yml exists, Ansible adds the variables in that file to the play.

What is defaults in Ansible roles?

According to Ansible's definition, the difference between defaults and vars is: defaults mean “default variables for the roles” and vars mean “other variables for the role”. The priority of the vars is higher than that of defaults.

What is the file structure of Ansible roles?

Ansible role is a set of tasks to configure a host to serve a certain purpose like configuring a service. Roles are defined using YAML files with a predefined directory structure. A role directory structure contains directories: defaults, vars, tasks, files, templates, meta, handlers.

Can Ansible roles be reused by playbooks in a different directory?

Ansible will look here when we want to use our new role in a playbook later in this tutorial. Within this directory we will define roles that can be reused across multiple playbooks and different servers. Each role that we will create requires its own directory.


2 Answers

The feature I'm describing below has been available since Ansible 2.6, but got a bugfix in v2.6.2 and another (minor) one in v2.7.
To see a solution for older versions, see Paul's answer.


defaults/main/

Instead of creating defaults/main.yml, create a directorydefaults/main/ — and place all YAML files in there.

  • defaults/main.ymldefaults/main/*.yml

Ansible will load any *.yml file inside that directory, so you can name your files like roles/my-role/defaults/main/{1,2}.yml.

Note, the old file — defaults/main.yml — must not exist. See this Github comment.


vars/main/

By the way, the above solution also works for vars/:

  • vars/main.ymlvars/main/*.yml

further details

The feature has been introduced in v2.6 — git commit, Pull Request, main Github issue.

There have been two bugfixes:

  • v2.7 fix: git commit, Pull Request — backported to v2.6.2: commit, Pull Request
  • v2.7 fix: git commit, Pull Request, bug discussion
like image 160
myrdd Avatar answered Oct 17 '22 10:10

myrdd


If you aren't using 2.6 (which you probably should, but I understand that isn't always an option), then you might find include_vars useful.

- name: Include vars of stuff.yaml into the 'stuff' variable (2.2).
  include_vars:
    file: stuff.yaml
    name: stuff

- name: Conditionally decide to load in variables into 'plans' when x is 0, otherwise do not. (2.2)
  include_vars:
    file: contingency_plan.yaml
    name: plans
  when: x == 0

- name: Load a variable file based on the OS type, or a default if not found. Using free-form to specify the file.
  include_vars: "{{ item }}"
  with_first_found:
    - "{{ ansible_distribution }}.yaml"
    - "{{ ansible_os_family }}.yaml"
    - default.yaml

- name: Bare include (free-form)
  include_vars: myvars.yaml

- name: Include all .json and .jsn files in vars/all and all nested directories (2.3)
  include_vars:
    dir: vars/all
    extensions:
        - json
        - jsn

- name: Include all default extension files in vars/all and all nested directories and save the output in test. (2.2)
  include_vars:
    dir: vars/all
    name: test

- name: Include default extension files in vars/services (2.2)
  include_vars:
    dir: vars/services
    depth: 1

- name: Include only files matching bastion.yaml (2.2)
  include_vars:
    dir: vars
    files_matching: bastion.yaml

Note that this is a task directive, though. It isn't as neat as just being able to include it into the defaults file itself.

like image 6
Paul Hodges Avatar answered Oct 17 '22 08:10

Paul Hodges