When condition in ansible - linux

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 ^^

Related

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.

Ansible "nsupdate" module adding zone to record value

I'm trying to use the nsupdate module to update records but I'm having mixed success. While the records do get added, I'm getting the zone appended at the end of the value.
For example:
I want a cname called mycname.domain1.com pointed to shawarmas.domain2.com. After I run the playbook I end up with an entry that looks like this:
mycname.domain1.com. 5 IN CNAME shawarmas.domain2.com.domain1.com
Is there something wrong in my playbook that is causing this?
Playbook:
---
- hosts: myserver
tasks:
- debug:
msg: "{{ value }}"
- name: "Add record to escapia zone"
nsupdate:
key_name: "ddns"
key_secret: "******"
server: "dnsserver"
record: "{{ record }}"
type: "{{ type }}"
value: "{{ value }}"
ttl: 5
Run Command:
ansible-playbook -i inv -e "record=record-test.example.com.
type=CNAME value=test.different.com" exampledns.yml -v
Ansible output:
changed: [myserver] => changed=true
dns_rc: 0
dns_rc_str: NOERROR
record:
record: record-test.example.com.
ttl: 5
type: CNAME
value:
- test.different.com
zone: example.com.
DNS result:
;; ANSWER SECTION:
record-test.example.com. 5 IN CNAME test.different.com.example.com
Usually, you need to append a . to the end of the value to make it full qualified. Without the . it is unqualified and appending the zone.
Try with:
ansible-playbook -i inv -e "record=record-test.example.com. type=CNAME value=test.different.com." exampledns.yml -v

Is there a way to use if..else logic in conditional filters in ansible?

I want to hard code 2 different values based on variable stdout in a single play.If a service is running then i want to hard code value as good else bad.How to use this logic in ansible?
I can able to hard code one value based on status result.
---
- hosts: localhost
connection: local
gather_facts: false
vars:
tasks:
- name: load var from file
include_vars:
file: /tmp/var.json
name: imported_var
- name: Checking mysqld status
shell: service mysqld status
register: mysqld_stat
- name: Checking mysqld status
shell: service httpd status
register: httpd_stat
- name: append more key/values
set_fact:
imported_var: "{{ imported_var| default([]) | combine({ 'mysqld_status': 'good' })}}"
when: mysqld_stat.rc == 0
- name: append more key/values
set_fact:
imported_var: "{{ imported_var| default([]) | combine({ 'httpd_status': 'good' })}}"
when: httpd_stat.rc == 0
- name: write var to file
copy:
content: "{{ imported_var | to_nice_json }}"
dest: /tmp/final.json
I want to hard code mysqld_status : Good if mysqld_stat.rc == 0 or mysqld-status: Bad if mysqld_stat.rc != 0.Is it possible to achieve in single play.(i.e) in single command
There are many of ways of approaching this problem. You could just add a second set_fact that runs when mysqld_stat.rc != 0. In the following example, only one of the two set_fact tasks will run:
- name: append more key/values
set_fact:
imported_var: "{{ imported_var| default({}) | combine({ 'mysqld_status': 'good' })}}"
when: mysqld_stat.rc == 0
- name: append more key/values
set_fact:
imported_var: "{{ imported_var| default({}) | combine({ 'mysqld_status': 'bad' })}}"
when: mysqld_stat.rc != 0
You could instead use Ansible's ternary filter:
- name: append more key/values
set_fact:
imported_var: "{{ imported_var| default({}) | combine({ 'mysqld_status': (mysqld_stat.rc == 0)|ternary('good', 'bad') })}}"

Ansible conditional based on stdout of result?

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

Resources