How to properly use when condition in Ansible - ansible

---
- name: test
hosts: localhost
tasks:
- name: Checking project list
shell: |
argocd proj list | grep xcore
register: argoProj
- debug: var=argoProj.stdout
- name: create a project if not exits
shell: |
argocd proj create xcore
# when: argoProj.stdout != "xcore"
when: argoProj.stdout.find('xcore')!=-1
Error:
''
TASK [create a project if not exits] *****************************************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "argocd proj create xcore\n \n# when: argoProj.stdout != \"xcore\"\n", "delta": "0:00:00.807940", "end": "2021-02-04 09:11:24.257123", "msg": "non-zero return code", "rc": 20, "start": "2021-02-04 09:11:23.449183", "stderr": "time=\"2021-02-04T09:11:24Z\" level=fatal msg=\"rpc error: code = InvalidArgument desc = existing project spec is different, use upsert flag to force update\"", "stderr_lines": ["time=\"2021-02-04T09:11:24Z\" level=fatal msg=\"rpc error: code = InvalidArgument desc = existing project spec is different, use upsert flag to force update\""], "stdout": "EE: 0/[]", "stdout_lines": ["EE: 0/[]"]}
NOTE: I want to skip the last task when an xcore project is already created. The last task needs to execute when there is no project with same name.
Actual output of the shell command:
#argocd proj list | grep xcore
xcore gke_ec2nf-256816_us-central1_gke-devops,production <none> <none> <none> <none> disabled

---
- name: test
hosts: localhost
tasks:
- name: Checking project list
shell: argocd proj list | grep xcore
register: argoProj
- debug: var=argoProj.stdout
- name: create a project if not exits
shell: argocd proj create xcore
when: "'xcore' not in argoProj.stdout"

Related

while evaluating conditional (argoProj.stdout.find('xcore') != -1): 'dict object' has no attribute 'stdout'

Workflow:
got stdout from the first task using register variable
used the same values to check whether it contains "xcore" or not
if not, another task to create a new project on Argo CD using Ansible roles.
---
- name: Create a new Argo CD project
hosts: localhost
remote_user: root
tasks:
- name: Checking project list {{proj_name}}
shell: |
argocd proj list | grep -i xcore
register: argoProj
- name: checking xcore value present if not create a project
shell: |
argocd proj create xcore
when: argoProj.stdout.find('xcore') != -1
Getting below error.
output:
argocd proj list | grep -i xcore
xcore 2 destinations 18 repos <none> <none> <none> disabled
Please help me to resolve the issue.
Thanks
I got correct output from registered variable used in debug
- name: Create a new Argo CD project
hosts: localhost
remote_user: root
tasks:
- name: Checking project list {{proj_name}}
shell: |
argocd proj list | grep -i testpjct
register: argoProj
- debug: var=argoProj
ok: [localhost] => { "argoProj": { "changed": true, "cmd": "argocd
proj list | grep -i testpjct\n", "delta": "0:00:00.787347", "end": "2021-02-03 08:32:04.982026", "failed": false, "rc": 0, "start": "2021-02-03 08:32:04.194679", "stderr": "", "stderr_lines": [], "stdout": "testpjct

Ansible run a task based on something in output

I'm new in Ansible and I try to do some practice playbook. I write a playbook to deploy a Docker container as follows. I write a task in the block section if an error happened, run a task in the rescue section based on Failed message content. For example, I want to run a specific task to delete an existing container if the Failed message is something like this:
failed: [192.168.1.140] (item=stderr_lines) => {"changed": true, "cmd": ["docker", "run", "-itd", "--name", "h1", "-p", "80:80", "httpd"], "delta": "0:00:00.016385", "end": "2021-01-04 03:00:55.403364", "failed_when_result": true, "item": "stderr_lines", "msg": "non-zero return code", "rc": 125, "start": "2021-01-04 03:00:55.386979", "stderr": "/usr/bin/docker-current: Error response from daemon: Conflict. The container name "/h1" is already in use by container bc5cc803a5f4321358992d06097ce271f3a63b8eba19900cfc0d23e321a4e243. You have to remove (or rename) that container to be able to reuse that name..\nSee '/usr/bin/docker-current run --help'.", "stderr_lines": ["/usr/bin/docker-current: Error response from daemon: Conflict. The container name "/h1" is already in use by container bc5cc803a5f4321358992d06097ce271f3a63b8eba19900cfc0d23e321a4e243. You have to remove (or rename) that container to be able to reuse that name..", "See '/usr/bin/docker-current run --help'."], "stdout": "", "stdout_lines": []}"
My playbook is as follows but it didn't work correctly. Sometimes an error in reading dictionary or "Unexpected templating type error occurred on". Can somebody guide me on what should I write?
- name: run a container
vars:
- run_container: docker run -itd --name h1 -p 80:80 httpd
- rm_container: docker stop h1 && docker rm h1
hosts: 192.168.x.x
tasks:
- name: check docker container
block:
- name: run a container httpd
command: "{{run_container}}"
register: rss
with_items:
- "stderr_lines"
failed_when: "'Error' in rss.stderr"
rescue:
- name: iterate over list
debug:
msg: "{{item.value}}"
loop: "{{rss | dict2items}}"
- name: remove the exited container
command: "{{rm_container}}"
register: rs
with_items:
- "{{rss | dict2items}}"
when: item.value is search("The container name .* is already in use")

Ansible mount module to just check state and not report status

Team,
I am writing a validation task that is supposed to just check if a mount exists or not and report its state from output. so my task is below but it fails and am not sure how to handle it. any hint what adjustments do i need to make?
- name: "Verify LVP Mounts on CPU Nodes for mount_device"
shell: "mount | grep sdd"
register: lvp_mount
delegate_to: "{{ item }}"
with_items: "{{ groups['kube-cpu-node'] }}"
#failed_when: lvp_mount.rc != 0
#ignore_errors: yes
# - debug:
# var: lvp_mount
- name: "Report status of mounts"
fail:
msg: |
Mounts sdd not found
Output of `mount | grep sdd`:
{{ lvp_mount.stdout }}
{{ lvp_mount.stderr }}
when: lvp_mount | failed
changed: [localhost -> ] => (item=hostA)
[WARNING]: Consider using the mount module rather than running 'mount'. If you
need to use command because mount is insufficient you can add 'warn: false' to
this command task or set 'command_warnings=False' in ansible.cfg to get rid of
this message.
failed: [localhost -> hostA.test.net] (item=hostA) => {"ansible_loop_var": "item", "changed": true, "cmd": "mount | grep sdd", "delta": "0:00:00.009284", "end": "2019-11-06 18:22:56.138007", "failed_when_result": true, "item": "hostA", "msg": "non-zero return code", "rc": 1, "start": "2019-11-06 18:22:56.128723", "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}
...ignoring
TASK [services-pre-install-checks : Report status of mounts] ************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'stdout'\n\nThe error appears to be in '/home/run_ansible_playbook/k8s/baremetal/roles/services-pre-install-checks/tasks/main.yml': line 265, column 9, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - name: \"Report status of mounts\"\n ^ here\n"}
Your task "Verify LVP Mounts on CPU Nodes for mount_device" is a loop so the register behavior is modified as specified in the documentation.
You can access the various outputs with lvp_mount.results.X.stdout where X is the index.
There is a cleaner way to write your script however. More specifically using:
delegate_to: "{{ item }}"
with_items: "{{ groups['kube-cpu-node'] }}"
is bad practice. You can accomplish your desired outcome at the play level.
For example:
- hosts: kube-cpu-node # allows you to iterate over all hosts in kube-cpu-node group
tasks:
- name: "Verify LVP Mounts on CPU Nodes for mount_device"
shell: "mount | grep sdd"
register: lvp_mount
ignore_errors: yes
# notice there is no loop here
- name: "Report status of mounts"
fail:
msg: |
Mounts sdd not found
Output of `mount | grep sdd`:
{{ lvp_mount.stdout }} # no loop so you can use lvp_mount.stdout
{{ lvp_mount.stderr }} # no loop so you can use lvp_mount.stderr
when: lvp_mount | failed

Ansible: Use of Diff command using Ansible

I am trying to one simple task which is find out the difference between the two files and store it in notepad. I am not able to do it with command as well as shell. Please suggest where i am going wrong-
---
- hosts: myserver
tasks:
- name: get the difference
command: diff hosts.new hosts.mod
register: diff
- debug: var=diff.cmd
Error -
fatal: [zlp12037]: FAILED! => {"changed": true, "cmd": ["diff", "hosts.new", "hosts.mod"], "delta": "0:00:00.003102", "end": "2017-03-29 10:17:34.448063", "failed": true, "rc": 1, "start": "2017-03-29 10:17:34.444961", "stderr": "", "stdout":
I'm not quite sure what your input play looks like with your formatting. But the following should be a solution:
- name: "Get difference from two files"
command: diff filea fileb
args:
chdir: "/home/user/"
failed_when: "diff.rc > 1"
register: diff
- name: debug output
debug: msg="{{ diff.stdout }}"
Some explanation:
If something fails with the diff command, the return code is > 1. We evaluate this by the "failed_when".
To get the output of the command, we print the ".stdout" element.
To make sure we're in the folder where the files are, we use "chdir".
I would move the hosts.new or hosts.mod to the ansible control machine.
Run the copy module with the src as hosts.new and the dest as hosts.mod with --check and --diff. I find this method most useful to spot differences in files across a large enterprise.
Run:
ansible all -m copy -a "src=hosts.new dest=/tmp/hosts.mod" --check --diff -i hosts
Output:
--- before: /tmp/hosts.mod
+++ after: /home/ansible/hosts.new
## -1,5 +1,5 ##
host1
+host2
host3
host4
-host6
-host99
+host5
test10 | SUCCESS => {
"changed": true,
"failed": false
}

Ansible : Trouble accessing Register VAlue

I am writing an ansible playbook that will :
log into a windows box
check if the version of the application i am deploying exists already
downloads the application from git
extracts the app's zip file
moves it to the correct directory
I am having a bunch of trouble on a section of the code where i need to find the extracted directory. I am extracting a GIT zip, and of course, through Github the zip file contains the git hash directory. What I do is i look for this directory through a simple find-like command in windows. The problem is that during debug, i can see the results in stdout_lines ... but in practice, it doesn't seem to work.
Here is the code:
---
# Register our work path to do work in
- name: Registering {{apm_work_path}} as our working path
tags: install
win_stat: path={{apm_work_path}}
register: my_apmworkpath
# First check to see if an agent is already installed in our
# destination. We want to make sure we dont install multiple
# agents
- name: Checking if {{apm_root_path}} path exists on our remote server
tags: install
win_stat: path={{apm_root_path}}
register: my_apmrootpath
# Check if the apm agent is installed in the root path
- name: Checking if {{apm_root_path}}\\{{apm_install_path}} path exists
tags: install
win_stat: path={{apm_root_path}}/{{apm_install_path}}
register: my_apminstallpath
# Check if the apm version is installed in the root path
- name: Checking if {{apm_version}} path exists
tags: install
win_stat: path={{apm_root_path}}\\{{apm_install_path}}\\{{apm_version}}
register: my_apmversionpath
# We also want to make sure that we keep track of the path
# that we want our agent to be placed
- name: An agent already exists on server
tags: install
debug: msg="APM {{apm_version}} is already installed under {{apm_install_path}}"
when: my_apminstallpath.stat.exists == true
# Create our work directory
- name: Creating Work directory
tags: install
win_file: path={{apm_work_path}} state=directory mode=0755
when: my_apmworkpath.stat.exists == false
# Create our application directory
- name: Creating APM Agent directory
tags: install
win_file: path={{apm_root_path}}\\{{apm_install_path}} state=directory mode=0755
when: my_apminstallpath.stat.exists == false
# Create our versioning directory
- name: Create APM version directory
tags: install
win_file: path={{apm_root_path}}\\{{apm_install_path}}\\{{apm_version}} state=directory mode=0775
when: my_apmversionpath.stat.exists == false
# Export our agent from our version control repo (GIT)
- name: Exporting Agent from GIT
tags: install
win_get_url:
url: http://git.sys.a.com/APM/apm-agent-{{apm_version}}-base-win/repository/archive.zip?ref=master
dest: "{{apm_work_path}}\\agent.zip"
when: my_apmversionpath.stat.exists == false
# Make sure we succesfully got our agent downloaded
- name: Checking our agent download
tags: install
win_stat: path={{apm_work_path}}\\agent.zip
register: my_agentarchive
# Create the base-nix directory
- name: Creating base-nix directory
tags: install
win_file: path={{apm_root_path}}\\{{apm_install_path}}\\{{apm_version}}\\base-win state=directory mode=0755
when:
- my_apmversionpath.stat.exists == false
- my_agentarchive.stat.exists == true
# Extract our GIT tarball to our new directory
- name: Extracting Agent
tags: install
win_unzip:
src: "{{apm_work_path}}\\agent.zip"
dest: "{{apm_work_path}}"
rm: True
when:
- my_apmversionpath.stat.exists == false
- my_agentarchive.stat.exists == true
###############################################################
##### THIS SECTION ############################################
# Get the extract directory
- name: Locate the Extracted Directory
tags: install
win_shell: for /d %d in (*apm-agent*) do echo %d
args:
executable: cmd
chdir: "{{apm_work_path}}"
register: extout
###### UNABLE TO SEE RESULTS HERE ############
- debug: msg={{ item }}
with_items: extout.stdout_lines
# Copy data from our work directory to the base-win directory
- name: Migrate Agent Files
tags: install
win_copy:
src: "{{apm_work_path}}\\{{ item }}\\"
dest: "{{apm_root_path}}\\{{apm_install_path}}\\{{apm_version}}\\base-win"
with_items:
extout.stdout_lines
ignore_errors: no
when:
- my_apmversionpath.stat.exists == false
- my_agentarchive.stat.exists == true
# Now create a symbolic link for the agent path
- name: Creating Symlink
tags: install
win_file: src={{apm_root_path}}\\{{apm_install_path}}\\{{apm_version}}\\base-win dest={{apm_root_path}}\\{{apm_install_path}}\\base-win state=link
when:
- my_apmversionpath.stat.exists == false
- my_agentarchive.stat.exists == true
# And cleanup after ourselves
#- name: Removing downloaded files
# tags: install
# win_file: path={{apm_work_path}} state=absent
# when:
# - my_apmversionpath.stat.exists == false
# - my_agentarchive.stat.exists == true
Relevant Section
###############################################################
##### THIS SECTION ############################################
# Get the extract directory
- name: Locate the Extracted Directory
tags: install
win_shell: for /d %d in (*apm-agent*) do echo %d
args:
executable: cmd
chdir: "{{apm_work_path}}"
register: extout
###### UNABLE TO SEE RESULTS HERE ############
- debug: msg={{ item }}
with_items: extout.stdout_lines
I can see the values of my register
changed: [ciwsdbxd8559.silver.com] => {
"changed": true,
"cmd": "for /d %d in (*apm-agent*) do echo %d",
"delta": "0:00:00.062173",
"end": "2016-11-06 07:56:51.816995",
"invocation": {
"module_name": "win_shell"
},
"rc": 0,
"start": "2016-11-06 07:56:51.754822",
"stderr": "",
"stdout": "\r\nE:\\SA\\tmp\\apm>echo apm-agent-10.3.0.15-base-win-master-541edbf478cc5e960c33e90b394a9b9cd822def3 \r\napm-agent-10.3.0.15-base-win-master-541edbf478cc5e960c33e90b394a9b9cd822def3\r\n",
"stdout_lines": [
"",
"E:\\SA\\tmp\\apm>echo apm-agent-10.3.0.15-base-win-master-541edbf478cc5e960c33e90b394a9b9cd822def3 ",
"apm-agent-10.3.0.15-base-win-master-541edbf478cc5e960c33e90b394a9b9cd822def3"
],
"warnings": []
}
However the following debug command gives me the following:
TASK [../roles/apm_windows : debug] ********************************************
task path: /home/SILVER/c53259/ansible/apm_deployment/roles/apm_windows/tasks/agent.yml:95
ok: [ciwsdbxd8559.silver.com] => (item=extout.stdout) => {
"invocation": {
"module_args": {
"msg": "extout.stdout"
},
"module_name": "debug"
},
"item": "extout.stdout",
"msg": "extout.stdout"
}
Any thoughts on what is going on?
Using Ansible 2.2
Python 2.7
Are you sure this works without an error? Because mesg is not a valid option in debug. Did you mean msg?
- debug: mesg={{ item }}
Anyway, the problem is you are using a wrong parameter. Use var instead since you are printing the value of a variable.
- debug: var={{ item }}
with_items: extout.stdout_lines

Resources