I'm trying to email a template file that has variable in html such as {{user_name}}, html renders correctly in my mail client, however {{user_name}} doesn't get resolved and displays as string {{user_name}}
- name: Send e-mail to a bunch of users, attaching files
mail:
host: mail.server.com
subtype: html
subject: email template
body: '{{ lookup("file", "roles/binding/templates/email.j2") }}'
to: "{{ user_email }}"
Example output
Hi {{ user_name }} ....
Desired output
Hi John Doe
Any ideas on how I can resolve this issue?
Simply replace the file lookup plugin with the template lookup plugin in the body parameter:
body: '{{ lookup("template", "roles/binding/templates/email.j2") }}'
you can add a template task to process the file, right before the task you have for sending the mail. Example:
- name: prepare mail body from template
template:
src: email.j2
dest: /tmp/email.out
The variable replacement will take place in this task.
Then, you shall send tha mail with the task you have already prepared, but body will have to point to the /tmp/mail.out file.
template module documentation
Related
Within a playbook one can include Jinja Templated like so:
tasks:
name: 'Foo Bar'
template:
src: '~/tmpl/baz.j2'
dest: '/dev/null'
That renders the template and copies it over to the remote host. But is it possible to use a jinja template to generate a value for a module argument?
What I would like to do is:
tasks:
name: 'create server'
a_cloude_server_create:
…
user_data: "{{ render(./tmpl/cloud-init.yml.j2) }}"
…
Can that be done?
Use template lookup, as Ansible documentation is bad recently, check local docs for lookup plugin via ansible-doc -t lookup template.
I wanted to log content of a variable in a file. I did it like this,
- name: write infraID to somefile.log
copy:
content: "{{ infraID.stdout }}"
dest: somefile.log
And it worked. But in the documentation for copy here, I found that they have recommended to use template instead of copy in such cases.
For advanced formatting or if content contains a variable, use the
ansible.builtin.template module.
I went through the examples given at the documentation for template module here. But I was unable to figure out something that works in my scenario. Could you please show me how to do this properly in recommended way ?
Thanks in advance !! Cheers!
The template module does not have a content property.
You have to create a file that contains your template, for example:
templates/infra-id-template
{{ infraID.stdoud }}
playbook
---
- hosts: localhost
tasks:
- name: Get infra ID
shell: echo "my-infra-id"
register: infraID
- name: Template the file
template:
src: infra-id-template
dest: infra-id-file
I'm new to ansible but trying to progress and learn.
I'm running a number of API calls to configure a web proxy tool.
The flow is essentially, make a GET request to see if the object exists, if does not exist, follow up with a POST request to create the object. Pretty standard.
This procedure repeats itself multiple times as the product can have a number of instances of the same type of configuration. So I would like to make the GET/POST routine as generic repeatable as possible, by associating an id.
The playbook is:
set_fact:
'vh_task_id': 01
- name: check virtual host exists
uri:
method: GET
url: "{{ admin_api_url }}/hosts?vHost={{ public_virtual_host|urlencode() }}"
return_content: yes
headers:
X-XSRF-Header: "Access"
user: "{{ admin_user }}"
password: "{{ admin_password }}"
status_code: 200
validate_certs: no
register: response
- name: set fact virtual host task id response '{{ public_virtual_host }}'
set_fact:
'response_{{ vh_task_id }}': "{{ response }}"
This all works fine, up to this point and response_{{ vh_task_id }} correctly contains the response body from the above set_fact, as I can see it, if I output it.
The issue now becomes when I want to query the JSON in response_{{ vh_task_id }} as the variable to query to get the id value.
The set_fact, is setting a literal value ofresponse_01 rather than seeing the concatenation as a registered variable.
Here is an example of how I was trying to do it:
set_fact:
'vh_id': "{{ hostvars[inventory_hostname].response_{{ vh_task_id }} | json_query('json.items[0].id') }}"
Many thanks for any help.
Try this:
set_fact:
'vh_id': "{{ hostvars[inventory_hostname].hostvar | json_query('json.items[0].id') }}"
vars:
hostvar: response_{{ vh_task_id }}
Also you don't need explicit quote ' for plain string as variable name. Like, you can change 'vh_id': to vh_id: if no other reason to keep the name with quotes.
Thanks for your time to come back, I tested this but, in the end, I have since learnt that using the with_items, gives me better results and it more repeatable
I am trying to write the output of a series of show commands to a text file on Ansible. My approach is to reference the registers on my jinja2 template. I am unclear on how to reference these register values if the return type is not a dictionary/list. How do I reference these variables in my template ?
I have tried calling them as msg."register name". This writes to the file, but is haphazard with barely any formatting structure.
Part of my Playbook
register: int_status
- set_fact:
int_status={{ int_status.stdout }}
- name: Print the interface status
debug:
msg: "{{ int_status }}"
My jinja2 file:
Host information:
------------------------------
ip address: {{device_info.ansible_facts['ansible_net_all_ipv4_addresses']}}
Interfaces: {{msg}}
so I'm using this simple playbook as an example:
- name: Show interfaces
junos_command:
commands:
- show interfaces
display: text
register: json_response
And I need to save json_response to a file:
- name: Saving logs to output
copy:
content: "{{ json_response.stdout }}"
dest: "./output.txt"
I know that json_response.stdout_lines has the real organized json, but when I save it, it comes ALL unindented, and if I use "json_response.stdout" it comes "indented" but he doesn't recognize '\n' as a breakline character, so I execute another task to replace \n to breakline. My problem here is, anyway I can save json_response variable in a correctly way? When I execute the playbook the debug var prints perfectly indented on my shell, but doesn't work for my output file.
Thanks.
You can try one of the formatting filters, e.g. like this:
- name: Saving logs to output
copy:
content: "{{ json_response.stdout | to_nice_json(indent=4) }}"
dest: "./output.txt"
More details and examples can be found in the Ansible Documentation.