I want to include variables from a file (say vars.yml) and use it inside group_vars/all.yml.
How this can be achieved?
tried (in all.yml):
include_vars:
file: ../inventories/dev/cluster-0/group_vars/vars.yml
name: x
ansible_user: "{{ x.username }}"
include_vars is an ansible task, and can only appear in a playbook or task list. A variable file can only contain variables; there's no "include"-style mechanism.
Depending on what exactly you're trying to do, you can turn all.yml into a directory (group_vars/all/) and then place multiple files in that directory:
group_vars/all/file1.yaml
group_vars/all/file2.yaml
Related
I'm trying to separate my vars from the playbook file.
My vars use an alias to make things easier.
Example of my playbook.yaml:
---
- hosts: localhost
name: playbook name
vars:
login: &login
username: "{{ login.user }}"
password: "{{ login.pass }}"
vars_files:
- creds.yaml
tasks:
- name: using creds
some_module:
some_command: true
<<: *login
How can I move the "vars" section to a file outside the playbook and keep the same template inside "tasks"?
Your way to achieve that is to create a proper inventory and use the inventory variables. ansible inventory docs
Create this schema tree:
hosts (directory)
group_vars (directory)
host_vars (directory)
hosts-groups (directory)
hosts-all (file)
Then either you choose to define your hosts individually in the hosts-all
localhost ansible_ssh_host=x.x.x.x {{ potentially any other needed argument/variable }}
Or You group hosts in groups and define new group in hosts/hosts-groups: Create a file with the desired group name, ex: hosts/hosts-groups/local and inside it define your host-group
[local]
localhost
And then, either in the hosts_var or group_vars (depending on your first step), you create a file either with host name or group name, and inside it, you write your variables. Ex (by group): Create hosts/group_vars/local and inside it write your variables
login: user1
pass: pass1
And then automatically, your play will search the right vars for each hosts according to your inventory structure.
In my Ansible scripts, is there a way to reference a path variable when importing a playbook?
I have set up some variables with the path to different files in my Ansible file hierarchy that I would like to reference when importing and including playbook and variable files. The path variables are defined in a file in the group_vars/all/ directory so they are loaded automatically.
When I try to import a playbook and reference one of my path variables, I get an error that the variable is not defined.
Here's an example. I created a simple playbook file that I call include.yml:
---
- name: Include playbook
import_playbook: "{{ base_dir }}/foo.yml"
The playbook imports another playbook called foo.yml in a directory defined in the variable, base_dir.
Here is foo.yml:
---
- name:
hosts: localhost
gather_facts: no
tasks:
- name: Check that group_vars/all variable loaded
debug:
var: test_dir
In the group_vars/all/ directory, I define base_dir and test_dir in a file called dirs.yml:
base_dir: "{{ playbook_dir }}"
test_dir: "{{ base_dir }}/foo"
When I run:
ansible-playbook include.yml
I expect that Ansible will import and run foo.yml, which prints the value of the test_dir variable which references base_dir.
Instead, I get the error:
ERROR! 'base_dir' is undefined
If I run:
ansible-playbook include.yml --extra-vars base_dir="."
then it runs as expected.
It appears that the import occurs before the group_vars variables are loaded.
If true, this is inconvenient because I would like to define my file paths in global variables that can be referenced by multiple playbooks, instead of hardcoding them in all of my playbooks. Is there a way around this issue?
Q: "I would like to define my file paths in global variables that can be referenced by multiple playbooks, instead of hardcoding them in all of my playbooks. Is there a way around this issue?
A: It's a rational expectation that group_vars/all might have been loaded before a playbook is imported. But neither playbook nor inventory related group_vars/all works this way. There are closed issues on this topic (locked and limited conversation to collaborators on Apr 27) for example playbook_vars_root doesn't work for playbook imports #34239.
There is no workaround. The scope of such variables is the play. goup_vars can't be loaded before the hosts is known from the play.
FWIW. An option of running playbooks in a systemic and flexible way is ansible-runner. See Runner Input Directory Hierarchy and Running Playbooks.
I have a task in playbook as shown :
- name: Create configuration.json for every analytics from the template.
template:
src: ./src-zip/{{ item.key }}/configuration_sample.j2
dest: ./src-zip/{{ item.key }}/configuration.json
with_dict: "{{ apps }}"
Now , i have variables in which some are common and some are different defined in file for every run .
Like, there is file var_alerts-manager.yml for one run.
For another run, I have var_abc.yml.
Now i want to use different file for different run. In other words, template will use variables defined in var_alerts-manager.yml in one run and abc.yml in another run and so on.
How can this be achieved in ansible and where should I keep these files so task can include only that specific file for every run?
This is a scenario for which roles mechanism evolved:
Create a my_role role in your playbook dir.
Move your task and template into that role.
Store your variables inside vars directory in the role.
Execute the role with:
- name: Create configuration.json for every analytics from the template.
include_role:
name: my_role
vars_from: "{{ item.key }}" # or whatever key your naming is defined in
loop: "{{ apps|dict2items }}"
You might want to replace item inside the template task with some other variable for clarity, read about loop_control.
I have a playbook that will iterate over a set of hosts in different environments, "dev", and "prod". The environment that a host is in will change the other variables that it has. For example, this is in my vars/main.yml file:
---
folder_list_DEV: ["folder-1", "folder-2", "folder-3"]
folder_list_PROD: ["folder-1", "folder-2"]
The intention in my example is to create a series of folders on the target system, depending on which environment it is in. The code that I would like to work, but does not, looks like this:
- name: Create folders
file:
path: "/{{ item }}"
state: present
with_items: "{{ folder_list_env }}
"env" is set on execution of the playbook (-e "env=DEV").
How can I reference this "folder_list_*" variable based on value of the "env" variable?
"{{ vars['folder_list_' + env] }}"
I have three sets of servers. Depending on the hostname, I want the client to grab the correct file. I tested the playbook on a server with the word "batch" but it picks up both files group_vars/perl and group_vars/batch
pre_tasks:
- include_vars: group_vars/web
when: "'web' in ansible_hostname"
- include_vars: group_vars/batch
when: "'web' not in ansible_hostname"
- include_vars: group_vars/perl
when: "'web' not in ansible_hostname" or "'batch' not in ansible_hostname"
Ansible will handle group_vars for you. For any hosts in the group web, the vars at group_vars/web (or group_vars/web.yml) will be automatically included. See Splitting Out Host and Group Specific Data in the Ansible docs.
To answer your question about conditional variable includes, the examples you gave are the correct syntax. Here's another example, not using group_vars:
- include_vars: vars/{{ ansible_distribution}}_packages.yml
when: install_extra_packages is defined and
install_extra_packages != ''
Note that include_vars accepts expressions, so you can use variables to determine the vars files to pull in dynamically.