How to add more than one value to a variable in ansible playbook? - variables

I have defined a value to variable in my playbook as :
war_name: abc
and i m calling this war_name in the roles as :
- name: Download war file
get_url:
url=http://url/directory/packages/tomcat/{{ war_name }}.war
Now the problem is I have to assign 2 values to variable war_name in playbook
like
war_name: abc,xyz
How can i do this in my playbook?
If used with_items as :
- name: Download war file
get_url:
url=http://url/directory/packages/tomcat/{{ item }}.war
with_items:
- abc
- xyz
when: "'server' in app_name"
It results in an error as :
TASK [tomcat : Download war file]
********************************************** failed: [10.x.x.x] (item=abc) => {"failed": true, "item": "abc", "msg": "missing required
arguments: dest"} failed: [10.x.x.x] (item=xyz) => {"failed": true,
"item": "xyz", "msg": "missing required arguments: dest"}

You are missing the dest argument that is required for get_url
Here is the modified version of your task:
- name: Download war file
get_url:
url: "http://url/directory/packages/tomcat/{{ item }}.war"
dest: "/path-where-you-want-to-place/{{ item }}"
with_items:
- abc
- xyz
when: "'server' in app_name"
Hope that help you

what you can do is something like this
war_name:
war1: one
war2: two
This is basically a dictionary. Though i am not sure what actually you wanna do here? I guess you want to place 2 wars at a same location with different names, if that is the case you can actually use with_items

Related

Fetch a file from task in same Ansible playbook

How do I transfer a file I have created from a previous task in my Ansible playbook? Here is what I got so far:
- name: Create Yum Report
shell: |
cd /tmp
yum history info > $(hostname -s)_$(date "+%d-%m-%Y").txt
register: after_pir
- name: Transfer PIR
fetch:
src: /tmp/{{ after_pir }}
dest: /tmp/
However, I receive this error message when I run my playbook.
TASK [Transfer PIR] ************************************************************************************************************
failed: [x.x.x.x] (item=after_pir) => {"ansible_loop_var": "item", "changed": false, "item": "after_pir", "msg": "the remote file does not exist, not transferring, ignored"}
I have tried to run different fetch, synchronzie and pull methods but I'm not sure what the issue is.
One way to do that:
- name: Create Yum Report
command: yum history info
register: yum_report
- name: Dump report on local disk for each host
copy:
content: "{{ yum_report.stdout }}"
dest: "/tmp/{{ inventory_hostname_short }}-{{ '%d-%m-%Y' | strftime }}"
delegate_to: localhost

Ansible replace a string in a variable with a variable

debug:
msg: "{{backup_facts | replace(',world',',{{custom}}')}}"
register: replace_csv
in the above code, I am trying to replace a string/word in a variable with a variable.
so in this case these are the vars:
backup_facts = "hello,world"
custom = "prab"
so the end results I would like is: "hello, prab" after the replace. But everytime I run the playbook, I get the following:
"replace_csv": {
"changed": false,
"failed": false,
"msg": "hello,{{custom}}"
}
I have attempted different variation such as putting a quotation around the curly brackets or not putting the curly brackets at all but no results.
Q: "The result is: hello,prab after the replace."
Keep it simple. Put the parameters into variables. This will simplify the code. For example,
- hosts: localhost
vars:
backup_facts: "hello,world"
custom: "prab"
tasks:
- debug:
msg: "{{ backup_facts|replace(old, new) }}"
vars:
old: ",world"
new: ",{{ custom }}"
gives (abridged)
ok: [localhost] =>
msg: hello,prab

How to know in which task an ansible play failed when launched using AWX API?

I intend to launch ansible jobs on AWX using AWX api and get a call back from the ansible playbook to be informed about the result of the play.
To do so I'm using the /api/v2/job_templates/<job-template-id>/launch/ with some extra_vars in the body to pass parameters to my play.
{
"extra_vars": {
"target": "w.x.y.z", (put here a real IP)
"directory_name_1": "dir1",
"directory_name_2": "dir2",
"file_name": "file1" (or "subdir/file1" to make it fails)
}
}
I've also configured a webhook notification in the job-template with the default customization: {{ job_metadata }}
I've put here the play I'm using which is super simple, it creates 2 directories and one file in the first directory.
- hosts: "{{ target }}"
name: fbplay
tasks:
- name: Create dummy directory 1
file:
path: "{{directory_name_1}}"
state: directory
- name: Create dummy directory 2
file:
path: "{{directory_name_2}}"
state: directory
- name: Create dummy file in directory
file:
path: "{{directory_name_1}}/{{file_name}}"
state: touch
mode: u=rw,g=r,o=r
All of this work great and in case of error 4 tasks will be executed on the target machine:
TASK [Gathering Facts] *********************************************************
TASK [Create dummy directory 1] ************************************************
TASK [Create dummy directory 2] ************************************************
TASK [Create dummy file in directory] ******************************************
...but here is my question with regard to error handling: How can I indicate in the call back which task failed in case of error ?
In fact I can know if the play failed or not getting, in case of success:
"hosts": {
"w.x.y.z": {
"failed": false,
"changed": 1,
"dark": 0,
"failures": 0,
"ok": 4,
"processed": 1,
"skipped": 0,
"rescued": 0,
"ignored": 0
}
}
and in case of failure:
"hosts": {
"w.x.y.z": {
"failed": true,
"changed": 0,
"dark": 0,
"failures": 1,
"ok": 3,
"processed": 1,
"skipped": 0,
"rescued": 0,
"ignored": 0
}
}
But I cannot get the exact task that failed (in this case the last one by passing a filename containing a sub-directory that does not exist for example).
I'm a newbie on AWX & ansible and I'm fighting with what I thought would be a relatively simple point... so any hints or ideas is welcome.
Thx beforehand.
in case it helps someone, I actually confirm that ARA does what I was looking for above which is to display if using its web client (or provide through an API) exactly which task failed in each playbook you ran.
ARA does an excellent job for analyzing awx-runs, but it has to be set up on the AWX-server (the host running the AWX instance), if I understand correctly.
A workaroud would be to use the awx commandline interface ( see https://docs.ansible.com/ansible-tower/latest/html/towercli/index.html and * ):
watch --color 'awx --conf.host https://awx.site --conf.username my.user --conf.password "my_super_secret" -k -f human job_events list --job 3232445 --event "runner_on_failed" --filter "stdout"'
One could also sroll the API for different "?event=runner_on_failed", like:
https://your.awx.site/api/v2/jobs/3232445/job_events/?event=runner_on_failed
Or other "filters" like:
awx --conf.host https://awx.site --conf.username my.user --conf.password "my_supersecret" -k -f human job_events list --job 3232445 --event "runner_on_unreachable" --filter "*" >/tmp/tmp
https://docs.ansible.com/ansible-tower/latest/html/towercli/output.html#human-readable-tabular-formatting
https://docs.ansible.com/ansible-tower/latest/html/towercli/reference.html#awx-job-events-list
* (not to confuse with awx-cli/tower-cli - I think they are different)

Create Ansible local facts from variables

I am trying to create local facts from variables.
My fact is:
datadog_http_checks:
- name : {{ env }} ResourceManager
url : http://{{ inventory_hostname }}:
threshold : 5
window : 5
timeout : 10
My task is:
- include_vars: clouderamanager.yml
- lineinfile: dest=/etc/ansible/facts.d/datadog_http_checks.fact line={{ datadog_http_checks }} create=yes
Which doesn't create the local facts, it fails with following error
TASK [hadoop : lineinfile] *****************************************************
fatal: [hmn001.dev.abc.cc]: FAILED! => {"changed": false, "failed": true, "module_stderr": "", "module_stdout": "Traceback (most recent call last):\r\n File \"/home/xyz/.ansible/tmp/ansible-tmp-1460581285.88-252089462921262/lineinfile\", line 2540, in <module>\r\n main()\r\n File \"/home/abc/.ansible/tmp/ansible-tmp-1460581285.88-252089462921262/lineinfile\", line 371, in main\r\n ins_aft, ins_bef, create, backup, backrefs)\r\n File \"/home/abc/.ansible/tmp/ansible-tmp-1460581285.88-252089462921262/lineinfile\", line 266, in present\r\n lines.append(line + os.linesep)\r\nTypeError: can only concatenate list (not \"str\") to list\r\n", "msg": "MODULE FAILURE", "parsed": false}
Lineinfile does exactly what it says it does: it changes a single line in a file.
If you want to create a local fact that looks like:
datadog_http_checks:
- name : {{ env }} ResourceManager
url : http://{{ inventory_hostname }}:
threshold : 5
window : 5
timeout : 10
Then you need to create a file that looks like this:
[datadog_http_checks]
name={{ env }} ResourceManager
url=http://{{ inventory_hostname }}:
threshold=5
window=5
timeout=10
You can do this with the template module if, like in your example, you have variables in it that you want to dynamically build.
In this exact scenario though I'm confused as to what the benefit of this is rather than having a variable set up as you have in your question and using that rather than templating out a local fact file and then re-reading it later.

Ansible - variable changing it's value even though the condition is not met

I have a role that I need to use for more values. For each task within the role I register a variable: checkdeps (it's the same for all tasks within this role - during a run it always has at least one value/output - I need it like this because the path differs "/opt/play/apps/default-ace", "default-device" etc.) and in the end I do an echo to view the output of checkdeps.stdout.
Below I've put one task that will output ok and one that will intentionally will be skipped.
If I use the parameter dep: APK_PARSER in the playbook what it does is: first checkdeps registers the output and in the second task the value of checkdeps is replaced with nothing! Even though the task is skipped due to no matching dep parameter.
Why does the value of checkdeps is replaced if the condition is not met ?
- name: "output ok"
shell: "cd /opt/play/apps/default-ace && play deps {{ dep }}"
register: checkdeps
when: "dep == \"APK_PARSER\""
- name: "example to skip"
shell: "cd /opt/play/apps/default-device && play deps {{ dep }}"
register: checkdeps
when: "dep == \"I\" or dep == \"II\""
- name: "echo ok if Done!"
shell: "echo \"OK - {{ dep }} Dependencies {{ checkdeps.stdout }}\""
And it gives me error:
One or more undefined variables: 'dict' object has no attribute 'stdout'
I've modified the last line without the stdout:
shell: "echo \"OK - {{ dep }} Dependencies {{ checkdeps }}\""
and it ran without error but gave the wrong output:
stdout:
OK - APK_PARSER Dependencies {u'skipped': True, u'changed': False}
did the variable checkdeps register the "skipping: [...]" ? Why it is changing it's value if the condition is not met ?
ansible stores the "log of ansible task execution", NOT the 'output of command executed'. This log which is a dict and one of the keys is stdout, which contains everything the executed command printed on stdout (output of command).
tasks:
- debug: msg='one'
register: o1
when: True
- debug: msg='two'
register: o2
when: False
- debug: msg='o1={{o1}}'
- debug: msg='o2={{o2}}'
It prints the following. 'skipped' & 'changed' are the two keys that would be present in the "log" when the task is not executed.
TASK: [debug msg='one'] *******************************************************
ok: [localhost] => {
"msg": "one"
}
TASK: [debug msg='two'] *******************************************************
skipping: [localhost]
TASK: [debug msg='o1={{o1}}'] *************************************************
ok: [localhost] => {
"msg": "o1={'msg': u'one', 'verbose_always': True, 'invocation': {'module_name': u'debug', 'module_args': u\"msg='one'\"}}"
}
TASK: [debug msg='o2={{o2}}'] *************************************************
ok: [localhost] => {
"msg": "o2={u'skipped': True, u'changed': False}"
}
* term "task execution log" is invented by me for explanation and not ansible standard terminology.
Or simply tell ansible to not register the variable if the task is skipped with set_when_task_skipped=false:
- name: "example to skip"
shell: "cd /opt/play/apps/default-device && play deps {{ dep }}"
register: checkdeps set_when_task_skipped=false
when: "dep == \"I\" or dep == \"II\""