Ansible conditional based on stdout of result? - linux

How do I use the when statement based on the standard output of register: result? If standard output exists I want somecommand to run if no standard output exists I want someothercommand to run.
- hosts: myhosts
tasks:
- name: echo hello
command: echo hello
register: result
- command: somecommand {{ result.stdout }}
when: result|success
- command: someothercommand
when: result|failed

Try checking to see it if equals a blank string or not?
- hosts: myhosts
tasks:
- name: echo hello
command: echo hello
register: result
- command: somecommand {{ result.stdout }}
when: result.stdout != ""
- command: someothercommand
when: result.stdout == ""

As of 2018, the recommended way to test if output is empty is just:
when: result.stdout | length > 0
That is the pythonic way of evaluating truth, null, empty strings, empty lists all evaluate as false.
Other older alternatives not recommended or even not working:
result.stdout != "" would not pass ansible-lint check!
result.stdout | bool will NOT work as most strings will evaluate as False, only cases where it would return true is if stdout happens to be one of the true, yes,... kind of strings.
result.stdout used to work but now triggers:
[DEPRECATION WARNING]: evaluating as a bare variable, this
behaviour will go away and you might need to add |bool to the
expression in the future. Also see CONDITIONAL_BARE_VARS configuration
toggle.. This feature will be removed in version 2.12. Deprecation
warnings can be disabled by setting deprecation_warnings=False in
ansible.cfg.`

To expand on this answer and address the comment regarding potential problems if stdout isn't defined, the following when statement can be used to ensure stdout is defined before trying to check its length:
when: result.stdout is defined and result.stdout | length > 0

Related

Ansible - Find files via a list with their name and delete them

im currently running into an issue with deleting certain files from our thumbor cache with ansible. After alot of snipping I receive a list with the file names and im running following ansible task to find and delete them:
shell: find . -name {{ item }} -exec rm "{}" \;
args:
chdir: "{{ thumbor_data_path }}"
ignore_errors: true
loop:
- deletion_hash
when: file_url is defined and deletion_hash | length > 0
the list is definitly filled with the correct names of files I know exist and the task itself marks himself as changed, but the files are not getting deleted. The names of the files are sha1 hashes, and are two directories deep.
Is there something wrong with the shell script?
Example of the deletion_hash list:
"msg": [
"115b744b9f6b23bbad3b6181c858cb953136",
"f52f17b2cca937e5586751ff2e938979890b",
"1c39661a0925b3cdb3b524983aaf6cccd6ee",
"1afc79a9e0e3c07ff0e95e1af3b5cb7ae54c",
"424e9159fe652f47c8e01d0aa85a86fbefed",
"11e4994789f24537d6feea085d2bf39c355b",
"a1d2fe0e122d37555df4062d4c0a5d10b651",
"aef976fc897a87091be5a8d5a11698e19591",
"e79f3ee1e6ccb3caff288b0028e031d75d77",
"9448e5e49679c908263922debdffff68eecb",
"a3933be52277a341906751c3da2dfb07ccd8",
"bef3370862a7504f7857be396d5a3139f5c0",
"8cc0cbe847234af96c0463d49c258c85d50f",
"1e7bf6110dcf994d1270682939e14416fc6e",
"d21dae2c047895129e7c462f6ddc4e512a58",
"c107b29b3185171ec46b479352fab6c97ad2"
]
You can try using the file module; this comes with an assumption that the thumbor_data_path variable does not end with a /; if it does, you need to modify this a bit.
- name: Remove file (delete file)
ansible.builtin.file:
path: "{{ thumbor_data_path }}/{{ item }}"
state: absent
loop: deletion_hash
when: file_url is defined and deletion_hash | length > 0

I am getting error like ERROR! unexpected parameter type in action: <class 'ansible.parsing.yaml.objects.AnsibleSequence'>, when running ansible

When i am trying to run this code in ansible, i am getting error like
ERROR! unexpected parameter type in action: <class 'ansible.parsing.yaml.objects.AnsibleSequence'
The error appears to be in '/home/c22377/icoms1.yml': line 15, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
handlers:
- name: starting one time job
^ here
I need to use handlers, can you correct me?
---
- hosts: catl
name: "checking file ran or not"
tasks:
- shell: tail -1 test/test.log|awk '{print $8,$9,$10}'
register: result
- shell: date | awk '{print $1,$2,$3}'
name: checking todays date
register: time
- debug:
msg: "{{ result.stdout }}"
when: result.stdout == time.stdout
notify: starting one time job
handlers:
- name: starting one time job
tasks:
- shell: date
Change from:
handlers:
- name: starting one time job
tasks:
- shell: date
to:
handlers:
- name: starting one time job
shell: date

How to skip the template if the variable is not equal expected value in azure pipeline yaml?

I have a .yaml file
variables:
- name: command1
value: none
- scripts: |
echo '##vso[task.setvariable variable=command1]new_value'
- ${{ if ne(variables['command1'], 'none') }}:
- template: templates/run.yml#temp1 # Template reference
parameters:
COMMAND: '$(command1)'
I have created the variable for two reason ,
to be global
I dont want it to be displayed in the variable list for the users
I want the template only to be executed if variable value of 'command1' is not 'none'
Currently it is not skipping , it keeps executing it even if the value inside the variable is not none.
The other if conditions format I have used is
- ${{ if ne(variables['taskName.command1'], 'none') }}:
- ${{ if ne('$(command1)', 'none') }}:
None of the above worked
Please help in resolving this issue.
As it is written here:
The difference between runtime and compile time expression syntaxes is primarily what context is available. In a compile-time expression (${{ }}), you have access to parameters and statically defined variables. In a runtime expression ($[ ]), you have access to more variables but no parameters.
variables:
staticVar: 'my value' # static variable
compileVar: ${{ variables.staticVar }} # compile time expression
isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')] # runtime expression
steps:
- script: |
echo ${{variables.staticVar}} # outputs my value
echo $(compileVar) # outputs my value
echo $(isMain) # outputs True
So it could work for your YAML value:
variables:
- name: command1
value: none
steps:
- scripts: |
echo '##vso[task.setvariable variable=command1]new_value'
- ${{ if ne(variables.command1, 'none') }}:
- template: templates/run.yml#temp1 # Template reference
parameters:
COMMAND: '$(command1)'
However, it will pick this value:
variables:
- name: command1
value: none
There is no chance that it will take this:
- scripts: |
echo '##vso[task.setvariable variable=command1]new_value'
It is because ${{}} expressions are compile time and echo '##vso[task.setvariable variable=command1]new_value' is runtime.

When condition in ansible

I have written the following playbook and it's working fine but when I am doing the same thing with roles, when condition of the fail module is messing up. Irrespective of the values defined, when I am giving > in when, in fail module, it's skipping and when giving < , it's failing.
Please don't mind the syntax and '-' s, it's messing up here.
- hosts: localhost
vars:
vmcpu_list:
- vmcpu: 2
- vmcpu: 1
- vmcpu: 1
vcpu_value: 0
tasks:
- set_fact:
vcpu_value: "{{ vcpu_value }} + vmcpu_list[{{item}}].vmcpu"
with_sequence: start=0 end="{{ vmcpu_list | length -1 }}"
- debug:
var: "{{ vcpu_value }}"
- fail:
msg: " provided vcpu are more"
when: vcpu_value|int > 5
NOTE: Sorry earlier I have given vcpu_value|int > 5 above but it should be vcpu_value|int > 3
- fail:
msg: " provided vcpu are more"
when: vcpu_value|int > 5
you have set vcpu_value: 0
condition assessement vcpu_value < 5 it dosn't match your condition ==> ansible will skip the task
- fail:
msg: " provided vcpu are more"
when: vcpu_value|int < 5
you have set vcpu_value: 0
condition assessement vcpu_value < 5 OK ==> ansible will get execute the task
There is no problem your code works fine no strange behavior ^^

Run an Ansible task only when the variable contains a specific string

I have multiple tasks depend from the value of variable1. I want to check if the value is in {{ variable1 }} but I get an error:
- name: do something when the value in variable1
command: <command>
when: "'value' in {{ variable1 }}"
I'm using ansible 2.0.2
If variable1 is a string, and you are searching for a substring in it, this should work:
when: '"value" in variable1'
if variable1 is an array or dict instead, in will search for the exact string as one of its items.
None of the above answers worked for me in ansible 2.3.0.0, but the following does:
when: variable1 | search("value")
In ansible 2.9 this is deprecated in favor of using ~ concatenation for variable replacement:
when: "variable1.find('v=' ~ value) == -1"
http://jinja.pocoo.org/docs/dev/templates/#other-operators
Other options:
when: "inventory_hostname in groups[sync_source]"
From Ansible 2.5
when: variable1 is search("value")
For negative scenarios
when: not variable1 is search("value")
Some of the answers no longer work as explained.
Currently here is something that works for me in ansible 2.6.x
when: register_var.stdout is search('some_string')
This works for me in Ansible 2.9:
variable1 = www.example.com.
variable2 = www.example.org.
when: ".com" in variable1
and for not:
when: not ".com" in variable2
This example uses regex_search to perform a substring search.
- name: make conditional variable
command: "file -s /dev/xvdf"
register: fsm_out
- name: makefs
command: touch "/tmp/condition_satisfied"
when: fsm_out.stdout | regex_search(' data')
ansible version: 2.4.3.0
In Ansible version 2.9.2:
If your variable variable1 is declared:
when: "'value' in variable1"
If you registered variable1 then:
when: "'value' in variable1.stdout"
use this
when: "{{ 'value' in variable1}}"
instead of
when: "'value' in {{variable1}}"
Also for string comparison you can use
when: "{{ variable1 == 'value' }}"
I used
failed_when: not(promtool_version.stdout.find('1.5.2') != -1)
means - failed only when the previously registered variable "promtool_version" doesn't contains string '1.5.2'.

Resources