Unclear ansible variable formatting - ansible

When formatting variables in ansible playbooks which format should be followed?
I cannot for the life of me find a straight answer for this?
environment:
- http_proxy: "{{ {{ proxy }} if {{ proxy }} != '' else {{ ansible_local.proxy_facts.proxy }} }}"
- http_proxy: "{{ proxys if proxy != '' else ansible_local.proxy_facts.proxy }}"

Use ternary filter. For example
- set_fact:
http_proxy: "{{ (proxy|length > 0)|
ternary(proxy, ansible_local.proxy_facts.proxy) }}"
Don't compare to empty string

Related

Add a command flag based on a condition in Ansible

I have a command written like below in Ansible,
- set_fact:
user_arg: true
some_arg: "--with some-ver=1.0.0 if {{ user_arg is defined else '' }}"
path: "path/to/file"
- command: "some-command {{ some_arg }} {{ path }}"
Please note, I am adding argument name (--with) and its value (some-var=1.0.0) if user argument is defined.
I want to use args and switch it to look something like
- set_fact:
user_arg: true
some_arg: "--with some-ver=1.0.0 if {{ user_arg is defined else '' }}"
path: "path/to/file"
- command: "some-command {{ path }}"
args:
some_arg: "{{ some_arg }}"
But this adds some_arg with empty value, I do not want it to be added at all if user_arg is undefined. Could any one help me with this.
You cannot use set_fact to set a variable and use it in the same set_fact.
You have to break them up:
- set_fact:
user_arg: true
path: "path/to/file"
- set_fact:
some_arg: "{% if user_arg is defined %}--with some-ver=1.0.0{% endif %}"
Now, what I think you actually want is to set some_arg if user_arg is set and true. If so...
- set_fact:
some_arg: "{% if user_arg is defined and user_arg %}--with some-ver=1.0.0{% endif %}"
You should use the default filter with the omit variable for that.
This will set the argument some_arg if user_arg is defined, otherwise, no argument at all will be sent to the command.
- command: "some-command {{ path }}"
vars:
path: "path/to/file"
args:
some_arg: "{{ user_arg|default(omit) if user_arg is not defined else '--with some-ver=1.0.0' }}"

Ansible change default value according to a condition

I need to help with Ansible and make variable base on condition with another user defined variable.
I wrote something like this, but I am pretty sure this is wrong script.
So "{{ vcpu_size }}" has to be define base on user defined "{{ vm_size }}" and I don't know how to do it
Thanks for help
---
- name: Deploy VM on XenServer
hosts: XEN_Server
become: true
tasks:
- name: Load VPS specs for chosen type
set_fact:
vcpu_size: "{{ '2' if ({{ vm_size }} == 'S') }}"
vcpu_size: "{{ '4' if ({{ vm_size }} == 'M') }}"
vcpu_size: "{{ '6' if ({{ vm_size }} == 'L') }}"
vcpu_size: "{{ '8' if ({{ vm_size }} == 'XL') }}"
- debug:
msg: "Write {{ vcpu_size }} and to be sure {{ vm_size }}"
You can define the sizes in group_vars/all, or somewhere else (such as vars for the role, or in the playbook itself):
sizes:
S: 2
M: 4
L: 6
XL: 8
Then use it like this:
set_fact:
vcpu_size: "{{ sizes[vm_size] }}"
You can use Jinja expression like this :
vcpu_size: "{% if vm_size == 'S' %}2{% elif vm_size == 'M' %}4{% else %}some_def_value_here{% endif %}"

Ansible condition on dictionary item

I have one dictionary list defined:
members_list:
any:
name: any
username: any
anyone:
name:
username: anyone
In my Ansible playbook, I am running multiple docker containers:
docker_container:
name: "{{ item.key }}"
when: "{{ item.key }} != any"
with_dict: "{{ members_list }}"
But I am getting following error:
The conditional check '{{ item.key }} != any' failed. The
error was: error while evaluating conditional ({{ item.key
}} != any): 'any' is undefined
When I run the playbook without when conditional operator it works fine.
Thanks in advance.
You need to quote the word any, because otherwise it is interpreted as a variable reference. Also, you don't need Jinja templating markers in a when expression (the expression is already evaluated as a jinja expression):
- docker_container:
name: "{{ item.key }}"
when: "item.key != 'any'"
with_dict: "{{ members_list }}"
I find nested quotes like this can be confusing, and often opt for one
of YAMLs alternative quoting mechanisms, e.g.:
- docker_container:
name: "{{ item.key }}"
when: >-
item.key != 'any'
with_dict: "{{ members_list }}"
This is identical to the previous version; I just find it easier to
read and understand.

Conditional ansible to set variable

Tried all luck but doesnot work. I would require to set the environment variable check with a condition and then run a play or task on the main.yml while doing includes and using 2 tasks.
main.yml
- include: createnonprod.yml
when: "{{ environment }}" == 'dev' or "{{ environment }}" == 'qa' or "
{{ environment }}" == 'preprod'
- include: createprod.yml
when: "{{ environment }}" == 'prod'
The environment is set on groups_vars variable file "all"
environment:
"{{ lookup('env','ENVIRONMENT') }}"
But this logic to check fails
(Or)
I need to run this logic so that it calls the task with a condition to check the variable
create.yml
- name: Install all users from IAM of the AWS Account.
shell: "{{ scriptdir }}/install.sh -i {{ iamgroup }},{{ sudogroup }} -s {{ sudogroup }}"
when: "{{ environment }}" == 'dev' or "{{ environment }}" == 'qa' or "{{ environment }}" == 'preprod'
- name: Install all users from IAM of the AWS Account.
shell: "{{ scriptdir }}/install.sh -i {{ iamgroup }},{{ sudogroup }} -s {{ sudogroup }}"
when: "{{ environment }}" == 'prod'
Please help me with a logic that works. I get this error:
fatal: [localhost]: FAILED! => {"failed": true, "reason": "ERROR!
Syntax Error while loading YAML.\n\n\nThe error appears to have been in
'/tmp/ansible/roles/provision/users/tasks/create.yml': line 18, column
22, but may\nbe elsewhere in the file depending on the exact syntax
problem.\n\nThe offending line appears to be:\n\n when:\n - {{
env_type }} == 'dev'\n ^ here\nWe could be wrong,
but this one looks like it might be an issue with\nmissing quotes.
Always quote template expression brackets when they\nstart a value. For
instance:\n\n with_items:\n - {{ foo }}\n\nShould be written
as:\n\n with_items:\n - \"{{ foo }}\"\n"}
The When Statement
The when clause, which contains a raw Jinja2 expression without
double curly braces
when: environment == 'dev' or environment == 'qa' or environment == 'preprod'
when: environment == 'prod'
What if you try this way.
Define a variable to handle the lookup of your environment:
vars:
env_value: "{{ lookup('env', 'ENVIRONMENT') }}"
and then use this variable in the when condition:
when: env_value == "dev"
Simple example:
- hosts: "localhost"
vars:
env_value: "{{ lookup('env', 'ENVIRONMENT') }}"
tasks:
- shell: echo "I've got {{ env_value }} and am not afraid to use it!"
when: env_value == "prd"
Example in your code:
- name: Install all users from IAM of the AWS Account.
shell: "{{ scriptdir }}/install.sh -i {{ iamgroup }},{{ sudogroup }} -s {{ sudogroup }}"
when: env_value == 'dev' or env_value == 'qa' or env_value == 'preprod'
Please, also look at this link about Ansible environment variable name being reserved.

Ansible: Save registered variables to file

How could I save a registered variables to a file using Ansible?
Goal:
I would like to gather detailed information about all PCI buses and devices in the system and save the result somewhere (Ex. using lspci. Ideally, I should have results of command in my local machine for further analysis).
Save results also somewhere with the given criterion.
My playbook looks like this:
tasks:
- name: lspci Debian
command: /usr/bin/lspci
when: ansible_os_family == "Debian"
register: lspcideb
- name: lspci RedHat
command: /usr/sbin/lspci
when: ansible_os_family == "RedHat"
register: lspciredhat
- name: copy content
local_action: copy content="{{ item }}" dest="/path/to/destination/file-{{ item }}-{{ ansible_date_time.date }}-{{ ansible_hostname }}.log"
with_items:
- lspcideb
- aptlist
- lspciredhat
But saves only item_name
Good Q&A with saving 1 variable there - Ansible - Save registered variable to file.
- local_action: copy content={{ foo_result }} dest=/path/to/destination/file
My question:
How can I save multiple variables and transfer stdout to my local machine?
- name: copy content
local_action: copy content="{{ vars[item] }}" dest="/path/to/destination/file-{{ item }}-{{ ansible_date_time.date }}-{{ ansible_hostname }}.log"
with_items:
- lspcideb
- aptlist
- lspciredhat
Explanation:
You must embed variable names in Jinja2 expressions to refer to their values, otherwise you are passing strings. So:
with_items:
- "{{ lspcideb }}"
- "{{ aptlist }}"
- "{{ lspciredhat }}"
It's a universal rule in Ansible. For the same reason you used {{ item }} not item, and {{ foo_result }} not foo_result.
But you use {{ item }} also for the file name and this will likely cause a mess.
So you can refer to the variable value with: {{ vars[item] }}.
Another method would be to define a dictionary:
- name: copy content
local_action: copy content="{{ item.value }}" dest="/path/to/destination/file-{{ item.variable }}-{{ ansible_date_time.date }}-{{ ansible_hostname }}.log"
with_items:
- variable: lspcideb
value: "{{ lspcideb }}"
- variable: aptlist
value: "{{ aptlist }}"
- variable: lspciredhat
value: "{{ lspciredhat }}"

Resources