I'm trying to only execute a task if some host var has a value greater than 0
host-file
---
os:
version_nr: 8
version_name: jessie
dotdeb:
priority: 100
task.yml
- name: setup dotdeb preferences
lineinfile: dest=/etc/apt/preferences
create=yes
line="{{ item }}"
with_items:
- "Package: *"
- "Pin: release o=packages.dotdeb.org"
- "Pin-Priority: {{ dotdeb.priority }}"
when: dotted.priority > 0
But it seems that Ansible can't access the host variable for the 'preference'
task.
Ansible is saying:
error while evaluating conditional: dotdeb.priority > 0
I tried different quoting but nothing seems to work.
The host variables are working though, because 'os.version_name' is replaced properly in some task earlier.
Any suggestions?
Cheers Sebastian
It looks like there is a problem with the variable and the tag named equally.
I changed the var to
dotdeb_repo:
priority: 0
and the tasks to
- name: setup dotdeb preferences
lineinfile: dest=/etc/apt/preferences
create=yes
line="{{ item }}"
with_items:
- "Package: *"
- "Pin: release o=packages.dotdeb.org"
- "Pin-Priority: {{ dotdeb_repo.priority }}"
when: dotdeb_repo.priority > 0
Now everything works as expected
Related
I have been creating a role in Ansible and when I run my gitci pipeline, i get a warning message as
"no-changed-when: Commands should not change things if nothing needs doing"
I have tried to use changed_when: false on the task file. When I try to deploy the image build, I get the permission error or status doesn't show properly.
In the example below, I am just copying the files from one directory to another.
Let me know how to use the shell module here.
E.g.
- name: Copy the configuration files to the Helm Directory
shell: "cp {{ files_dir_path }}/*.xml {{ roles_dir_path }}/{{ image.docker_tag }}/files/helm- chart/"
I am a little late to the party, but for those, that stumble upon this:
Ansible wants to be idempotent, so it needs to be able to verify if a change is necessary. In your example Ansible has to blindly run a command, without being able to check if that is even necessary. This is what the warning wants to tell you.
You can solve this, by giving Ansible a file, that will be present, only after the command ran. That way Ansible will skip the task the next time around.
- name: Copy the configuration files to the Helm Directory
shell: "cp {{ files_dir_path }}/*.xml {{ roles_dir_path }}/{{ image.docker_tag }}/files/helm- chart/"
args:
creates: "{{ roles_dir_path }}/{{ image.docker_tag }}/files/helm- chart/*.xml"
See e.g., the command module documentation for further reference.
I have few playbooks and inventories and I need to run them from 2 different locations.
One that requires a jumphost and one that doesn't.
I have defined the jumphost in my inventory but when trying to run the playbook on the local one (no jumphost required) will fail.
Is there a way to load the SSH related vars based on ansible hostname?
If you just need to run things on the local host.. you can do that with specific tasks:
try local_action.. e.g.:
- name: copy file
local_action:
module: copy
src: stfile
dest: /path/to/testfile
or you can use delegate_to:
- name: copy a file
delegate_to: localhost
copy:
src: testfile
dest: /path/to/testfile
Edit: OK it seems I misread your question. Your question seems to be that you are running playbooks off two different hosts, one works and one fails, and so you need some logic that will select different variables for you based on the host?
You can include logic in the tasks using the when conditional like so :
- name: get ansible hostname
local_action:
module: shell
cmd: hostname
register: hostname_output
- shell: echo '{{variablefornonjumpbox}}'
when: hostname_output.stdout.find('jumpbox') != -1"
If you need to change the SSH target and details based on the hostname, you can use special variables like the ones at the bottom of this page:
https://docs.ansible.com/ansible/latest/reference_appendices/special_variables.html
Hopefully that helps.. If not I will need some clarification on the variables you are using and the errors you see.
I want to dynamically include var files in ansible. Dynamically means, that the user can provide a list as an extra-var, that list will be transformed into an array and defines the files to load. This is possible so far. What makes it hard is the fact that those files shall result in a single object holding the information.
This works and loads all the files in the folder and creates a variable (projects) out of the values specified there:
- name: Load project-specific Configuration
include_vars:
name: projects
dir: "{{project_vars_dir}}"
extensions:
- yml
To reach my goal and give the ability to specify which files to load, I tried the following:
- name: Load project-specific Configuration (requested projects only)
include_vars:
name: projects
file: "{{project_vars_dir}}/{{item}}.yml"
with_items: "{{projectlist.split(',') | list}}"
I can now call my playbook and specify --extra-vars like so: --extra-vars projectlist=projectA,projectB
Loading these files works, but the last file always overwrites the projects variable. How can I combine it?
Many thanks in advance
This is a somewhat complex loop so you'll need 2 files and the include_tasks module:
In tasks.yml you put:
- include_vars:
name: file_vars
file: "{{ item }}"
- set_fact:
all_vars: "{{ file_vars | combine(all_vars | default({})) }}"
In playbook.yml you put:
- hosts: all
tasks:
- include_tasks: tasks.yaml
loop: "{{projectlist.split(',') | list}}"
Ansible is not meant to be used as a programming language so complex loops are hard to write elegantly. Ideally you should look for built-in modules which handle your use case (which isn't the case here, as far as I know), write your own custom module or look into prepackaged roles written by someone else.
Please see my playbook below. I call 2 executions on different hosts in 1 playbook.
The first execution changes some variables in a vars file which would be used in next execution (create new backup folder and update its name to another vars file)
The second execution try to use 2 vars file to do backup tasks (using roles). The issue I met here is the vars file value were loaded with old value not the updated. Seem all defined vars files were loaded before tasks executed on all hosts, and update during running task doesn't effect.
I can separate this playbook into 2 playbooks and all work well as expected but I'm trying to combine 1 playbook. Do anyone can show me how to reload vars file in correctly executing tasks/roles ? I exactly want the second execution load the updated vars file before running roles.
## backup playbook
---
- hosts: ftpserver01
gather_facts: no
ignore_errors: yes
vars_files:
- ./vars_files/lab1.yml
- ./vars_files/global_vars.yml
roles:
- create_define_backup_folder
# this role will create new backup folder and update its name in ./vars_files/global_vars.yml
- hosts: terminal02
become: yes
become_method: su
gather_facts: no
ignore_errors: yes
vars_files:
- ./vars_files/lab1.yml
- ./vars_files/global_vars.yml
roles:
- backup_feature01
- backup_feature02
Expect: using updated global_vars.yml while running tasks on hosts terminal02
Actual result: all tasks on terminal02 using old value not the updated value of global_vars.yml vars_files
Use include_vars and include_role in the 2nd play
- hosts: terminal02
become: yes
become_method: su
gather_facts: no
ignore_errors: yes
tasks:
- include_vars:
file: ./vars_files/lab1.yml
- include_vars:
file: ./vars_files/global_vars.yml
- include_role:
name: backup_feature01
- include_role:
name: backup_feature02
I want to list all sub-directories in a parent directory then use each directory name a seperate variable in ansible for further action.
Keep in mind, that it is in general not possible to use file names as Ansible variables. A file name can contain characters, which are illegal in a variable name.
Also keep in mind, that a file could have the same name as an already defined variable. It is better to prefix the variable to avoid collisions.
The following example filters for valid file names and prefixes the variable names.
---
- hosts: test1
tasks:
- find:
path: /etc
file_type: file
use_regex: yes
patterns: "^[a-zA-Z0-9_]+$"
recurse: no
register: files
- set_fact:
"my_{{ item | basename }}": "{{ item }}"
with_items: "{{ files.files | map(attribute='path') | list }}"
- debug: var=my_passwd
- debug: var=my_hosts