I need your help since I'm at a complete loss here.
We started checking Ansible as a configuration manager (the AWX Project). We are currently based on a Chef Infra configuration manager.
In chef when you want to control a resource from happening you can use only_if
or not_if
filesystem "Test mount" do
fstype "xfs"
mount "/tmp/test"
device "/dev/sda"
action [:create, :enable]
not_if { File.exists?("/tmp/test") }
end
After checking in Ansible I saw that conditionals are the equivalent for Chef guards.
My problem is this: In my example I'm trying to see if a service exists and if it does, do action A, if not, do action B. This is my playbook:
---
- name: Test of powershell
hosts: all
tasks:
- name: test if ABCD service exists
win_shell: |
$a = Get-Service -Name ABCD -ErrorAction SilentlyContinue
if ($a) {
return $(Write-Host -NoNewline $true)
}
return $(Write-Host -NoNewline $false)
register: ABCDExists
- name: print ABCDExists value
debug:
var: ABCDExists
verbosity: 3
- name: Write service info if service exists
win_shell: |
$a = Get-Service -Name ABCD
New-Item -Path c:\temp\ -Name "text.txt" -ItemType File -Force
Set-Content -Path C:\temp\test.txt -Value "$($a | select-object -property *)"
when: ABCDExists is "True"
- name: Write service doesn't exists
win_shell: |
New-Item -Path c:\temp\ -Name "text.txt" -ItemType File -Force
Set-Content -Path C:\temp\test.txt -Value "Service ABCD doesn't exists"
when: ABCDExists is "False"
As you can see, the latest try for the conditional is ABCDExists is "True"
\ ABCDExists is "False"
.
This if after I tried doing:
ABCDExists == False
ABCDExists == "False"
ABCDExists|string() == "False"
I really at a loss here, I cannot understand where to look in Jinja documentation for the comparison operators or such.
Any help would be greatly appreciated.
UPDATE:
After testing ABCDExists | bool
I managed to skip one of the tasks, but not the one I expected.
These are the logs from the running job (After the change):
ansible-playbook 2.9.10
config file = /etc/ansible/ansible.cfg
configured module search path = ['/var/lib/awx/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible-playbook
python version = 3.6.8 (default, Apr 16 2020, 01:36:27) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
Using /etc/ansible/ansible.cfg as config file
SSH password:
host_list declined parsing /tmp/awx_183_ngdrbth5/tmph5taum3q as it did not pass its verify_file() method
Parsed /tmp/awx_183_ngdrbth5/tmph5taum3q inventory source with script plugin
PLAYBOOK: powershell_test.yml **************************************************
1 plays in powershell_test.yml
PLAY [Test of powershell] ******************************************************
TASK [Gathering Facts] *********************************************************
task path: /tmp/awx_183_ngdrbth5/project/powershell_test.yml:2
Using module file /usr/lib/python3.6/site-packages/ansible/modules/windows/setup.ps1
Pipelining is enabled.
<server01> ESTABLISH WINRM CONNECTION FOR USER: User@Domain.com on PORT 5985 TO server01
EXEC (via pipeline wrapper)
ok: [server01]
META: ran handlers
TASK [test if ABCD service exists] *****************************************
task path: /tmp/awx_183_ngdrbth5/project/powershell_test.yml:5
Using module file /usr/lib/python3.6/site-packages/ansible/modules/windows/win_shell.ps1
Pipelining is enabled.
<server01> ESTABLISH WINRM CONNECTION FOR USER: User@Domain.com on PORT 5985 TO server01
EXEC (via pipeline wrapper)
changed: [server01] => {
"changed": true,
"cmd": "$a = Get-Service -Name ABCD -ErrorAction SilentlyContinue\\nif ($a) {\\n return $(Write-Host -NoNewline $true)\\n}\\nreturn $(Write-Host -NoNewline $false)",
"delta": "0:00:00.484379",
"end": "2020-09-01 01:34:23.412182",
"rc": 0,
"start": "2020-09-01 01:34:22.927802",
"stderr": "",
"stderr_lines": [],
"stdout": "True",
"stdout_lines": [
"True"
]
}
TASK [print ABCDExists value] **********************************************
task path: /tmp/awx_183_ngdrbth5/project/powershell_test.yml:14
ok: [server01] => {
"ABCDExists": {
"changed": true,
"cmd": "$a = Get-Service -Name ABCD -ErrorAction SilentlyContinue\\nif ($a) {\\n return $(Write-Host -NoNewline $true)\\n}\\nreturn $(Write-Host -NoNewline $false)",
"delta": "0:00:00.484379",
"end": "2020-09-01 01:34:23.412182",
"failed": false,
"rc": 0,
"start": "2020-09-01 01:34:22.927802",
"stderr": "",
"stderr_lines": [],
"stdout": "True",
"stdout_lines": [
"True"
]
}
}
TASK [Write service info if service exists] ************************************
task path: /tmp/awx_183_ngdrbth5/project/powershell_test.yml:19
skipping: [server01] => {
"changed": false,
"skip_reason": "Conditional result was False"
}
TASK [Write service doesn't exists] ********************************************
task path: /tmp/awx_183_ngdrbth5/project/powershell_test.yml:26
Using module file /usr/lib/python3.6/site-packages/ansible/modules/windows/win_shell.ps1
Pipelining is enabled.
<server01> ESTABLISH WINRM CONNECTION FOR USER: User@Domain.com on PORT 5985 TO server01
EXEC (via pipeline wrapper)
changed: [server01] => {
"changed": true,
"cmd": "New-Item -Path c:\\\\temp\\\\ -Name \\"text.txt\\" -ItemType File -Force\\nSet-Content -Path C:\\\\temp\\\\test.txt -Value \\"Service ABCD doesn't exists\\"",
"delta": "0:00:00.531259",
"end": "2020-09-01 01:34:26.380055",
"rc": 0,
"start": "2020-09-01 01:34:25.848796",
"stderr": "",
"stderr_lines": [],
"stdout": "\\r\\n\\r\\n Directory: C:\\\\temp\\r\\n\\r\\n\\r\\nMode LastWriteTime Length Name \\r\\n---- ------------- ------ ---- \\r\\n-a---- 9/1/2020 9:34 AM 0 text.txt \\r\\n\\r\\n\\r\\n",
"stdout_lines": [
"",
"",
" Directory: C:\\\\temp",
"",
"",
"Mode LastWriteTime Length Name ",
"---- ------------- ------ ---- ",
"-a---- 9/1/2020 9:34 AM 0 text.txt ",
"",
""
]
}
META: ran handlers
META: ran handlers
PLAY RECAP *********************************************************************
server01 : ok=4 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
From the debug
output for variable ABCDExists
we can see a couple of things which might change depending on the existence of service.
"failed": false,
"stdout": "True",
We can have the tasks with when:
condition as below to compare the boolean value of "failed"
:
- name: Write service info if service exists
win_shell: |
$a = Get-Service -Name ABCD
New-Item -Path c:\temp\ -Name "text.txt" -ItemType File -Force
Set-Content -Path C:\temp\test.txt -Value "$($a | select-object -property *)"
when: not ABCDExists.failed | bool
- name: Write service does not exists
win_shell: |
New-Item -Path c:\temp\ -Name "text.txt" -ItemType File -Force
Set-Content -Path C:\temp\test.txt -Value "Service ABCD doesn't exists"
when: ABCDExists.failed | bool
Another way is to compare the text output in "stdout": "True",
:
- name: Write service info if service exists
win_shell: |
$a = Get-Service -Name ABCD
New-Item -Path c:\temp\ -Name "text.txt" -ItemType File -Force
Set-Content -Path C:\temp\test.txt -Value "$($a | select-object -property *)"
when: ABCDExists.stdout == 'True'
- name: Write service does not exists
win_shell: |
New-Item -Path c:\temp\ -Name "text.txt" -ItemType File -Force
Set-Content -Path C:\temp\test.txt -Value "Service ABCD doesn't exists"
when: not ABCDExists.stdout == 'True'
There are some ways to test conditions.