Reputation: 179
My Task: Generate jinja2 templates
Challenge: i wanted to make my playbook/roles independent, and usable in any server irrespective of their HOME directory name, So i have stored the $HOME path into a variable and use that directory location variable to access jinja2 source files.. $HOME stored variable works fine in all tasks, but i am getting error while i use it inside template
module"
my role structure..
roles/
└── my_role
├── defaults
│ ├── main
│ │ └── input.yml
│ └── main.yml
├── files
│ ├── conf
│ │ └── test.yml
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ ├── data-input.yml
│ ├── main.yml
├── templates
│ ├── DIR1
│ │ ├── PATH1
│ │ │ ├── file1
├── tests
│ ├── inventory
│ └── test.yml
└── vars
├── main
│ └── input.yml
└── main.yml
and my task for generating jinja2 templates..
---
- include_vars: vars/main/input.yml
- name: Generate templates
template:
src: {{ home }}/roles/my_role/templates/DIR1/PATH1/file1
dest: {{ home }}/roles/my_role/templates/DIR1/PATH1/file2
{{ home }}
stands for /home/ansible
that i have stored it to name home
using $HOME linux variable.
Getting Error:
ERROR! Syntax Error while loading YAML.
did not find expected key
The error appears to be in '/home/ansible/roles/my_role/tasks/data_input.yml': line 6, column 24, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
template:
src: {{ home }}/roles/my_role/templates/DIR1/PATH1/file1
^ here
i have even tried templates/DIR1/PATH1/file1
directory only. but no luck.
It works fine when i specify full directory path /home/ansible/roles/my_role/templates/DIR1/PATH1/file1
in both src
and dest
..
please help.
thanks in advance..
Upvotes: 2
Views: 11688
Reputation: 68104
Use env plugin to "read the value of environment variables". For example
- set_fact:
my_home: "{{ lookup('env','HOME') }}"
- template:
src: "{{ my_home }}/roles/my_role/templates/DIR1/PATH1/file1"
1) It's possible to use role_path special variable
"The path to the dir of the currently running role"
For example
src: '{{ role_path }}/templates/DIR1/PATH1/file1'
2) But, this shouldn't be necessary because of The magic of ‘local’ paths
"Relative paths get attempted first with a ‘files|templates|vars’ appended (if not already present), depending on the action being taken, ‘files’ is the default. (i.e include_vars will use vars/). The paths will be searched from most specific to most general (i.e role before play).|
Hence, the path below show work by default
src: 'DIR1/PATH1/file1'
For example the role
$ tree roles/test14/
roles/test14/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── README.md
├── tasks
│ └── main.yml
├── templates
│ └── DIR1
│ └── PATH1
│ └── file1
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
$ cat roles/test14/tasks/main.yml
- template:
src: 'DIR1/PATH1/file1'
dest: '/scratch/tmp/test14'
$ cat roles/test14/templates/DIR1/PATH1/file1
{{ inventory_hostname }}
with the playbook
$ cat test14.yml
- hosts: localhost
roles:
- test14
works as expected
PLAY RECAP localhost: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ cat /scratch/tmp/test14
localhost
Upvotes: 3
Reputation: 44675
Rule: In an ansible yaml files (included, in roles, your playbook....), values containing jinja2 template expressions and starting with "{{" MUST be enclosed in quotes.
Good practice: Enclose any string containing jinja2 template expression in quotes.
=>
src: "{{ home }}/roles/my_role/templates/DIR1/PATH1/file1"
dest: "{{ home }}/roles/my_role/templates/DIR1/PATH1/file2"
Upvotes: 4