I have a file defining ansible variables in role1/vars/main.yml, to use in a playbook:
app_name: "amazing"
And later on I would like to add a suffix to it in another file role1/vars/over-write-main.yml:
app_name: "{{ app_name }} app"
This is part of more a complex project, where app_name is defined and then used in a template, to witch I have no access. So the idea was to simply add the suffix to the variable. But I can add a new task, or a new variable file.
However I get a long repetitive error from ansible
"AnsibleError: An unhandled exception occurred while templating '{{ app_name}} *.feedzai.live'.
Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ app_name}} *.feedzai.live'.
Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '
...
Error was a <class 'ansible.errors.AnsibleError'>, original message: recursive loop detected in template string: {{ app_name }} app"
I found a lot of explanations on how to do this to a list, but not to a single variable. Do I need to convert it to a list and then convert it back?
I also tried without success: app_name: "{{ app_name + 'app'}"
Re-creating the variable using set_fact seems to work just fine:
- hosts: localhost
gather_facts: false
vars:
app_name: amazing
tasks:
- set_fact:
app_name: "{{ app_name }} app"
- debug:
var: app_name
Related
---
- hosts: localhost
gather_facts: no
vars:
var_folder_path: /home/play
tasks:
- name: Include all yaml files in directories
include_vars:
dir: "{{ var_folder_path }}/vars"
extensions:
- 'yaml'
- name: "Print Variable Name"
shell: echo "{{ item }}"
loop:
- "{{ global.globalname.property.Name }}"
- "{{ S3.secret }}"
My var files under /home/play/vars
example_1.yaml
global:
globalname:
property:
cipher: DEFAULT
client:
type: dynamic
Name: test-run
example_2.yaml
gcp:
keyname: sample-run
S3:
secret: run
Resources: false
celery:
resources:
limits:
cpu: 5
When I execute the playbook I get the below error. Not sure why the values are not loading
fatal: [localhost]: FAILED! => {"msg": "'dict object' has no attribute 'globalname'"}
To debug a playbook when an error occurs, it is very often a good idea to insert a debug task.
In your case insert a debug task before the shell task and get the whole variable global output:
- debug:
var: global
As mentioned in my comment above, there are no issues with the playbooks you shared, except for the "S3" variable definition in example_2.yaml, which should be "s3" (in lower case).
One possible cause for the error you reported is that there are more than one "global" var definition in the var files at /home/play/vars, and is overriding the global var definition in example_1.yaml.
Default Ansible merge is in ASCII order, i.e., the last group loaded overwrites the previous groups. See how-variables-are-merged from Ansible official documentation for more details on how variables are merged in Ansible and update your var files accordingly.
As mentioned by user #phanaz in the other answer, its a good practice to use "debug" module for printing the vars to validate, in such scenarios.
in an Ansible playbook, I'm trying to read the default public key into a variable to be used later.
Here's my yml:
- hosts: hostsGroup
become: false
vars:
publicKey: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
The script breaks with the following error:
fatal: [redacted-ip]: FAILED! =>
{"msg": "An unhandled exception occurred while templating '{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}'. Error was a <class 'ansible.errors.AnsibleError'>,
original message: An unhandled exception occurred while running the lookup plugin 'file'. Error was a <class 'ansible.errors.AnsibleError'>,
original message: could not locate file in lookup: /root/.ssh/id_rsa.pub"}
The file is confirmed to exist in that location.
Is there a better way? or What am I doing wrong?
Quoting the documentation:
Lookups occur on the local computer, not on the remote computer.
To get the content of the remote file, you can use a task like this:
- name: get remote file contents
command: "cat {{ ansible_env.HOME }}/.ssh/id_rsa.pub"
register: key
You can then access the contents like this:
- name: show key contents
debug:
var: key.stdout
But! Note that here I'm using ansible_env.HOME. This is populated by Ansible when gathering facts, and it will represent the value of the HOME environment variable from the perspective of whatever user Ansible used to authenticate. If you're using things like become_user, the value will not change to reflect the new user.
As explained in Lookup plugins documentation
Like all templating, these plugins are evaluated on the Ansible
control machine, not on the target/remote.
You can use slurp module to get the content of your remote key.
You mentioned become: false. meaning you want to force the ansible_user lookup in /home/ directory.
However the playbook was looking for the key in a root location: could not locate file in lookup: /root/.ssh/id_rsa.pub
Assuming you want the get publick key for the ansible_user, your playbook is escalating to the root user every time it connects to the remote server + lookup searches in local machine not the remote ones.
I'm trying to run the Ansible modules junos_cli and junos_rollback and I get the following error:
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to have been in '/home/quake/network-ansible/roles/junos-rollback/tasks/main.yml': line 2, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
---
- name: I've made a huge mistake
^ here
This is the role in question:
---
- name: I've made a huge mistake
junos_rollback:
host={{ inventory_hostname }}
user=ansible
comment={{ comment }}
confirm={{ confirm }}
rollback={{ rollback }}
logfile={{ playbook_dir }}/library/logs/rollback.log
diffs_file={{ playbook_dir }}/configs/{{ inventory_hostname }}
Here is the Juniper page:
http://junos-ansible-modules.readthedocs.io/en/1.3.1/junos_rollback.html
Their example's syntax is a little odd. host uses a colon while the rest uses = signs. I've tried mixing both and only using one or the other. I keep getting errors.
I also confirmed that my junos-eznc version is higher than 1.2.2 (I have 2.0.1)
I've been able to use junos_cli before, I don't know if a version mismatch happened. On the official Ansible documentation, there is no mention of junos_cli or junos_rollback. Perhaps they're not supported anymore?
http://docs.ansible.com/ansible/list_of_network_modules.html#junos
Thanks,
junos_cli & junos_rollback are part of Galaxy and not core modules. You can find them at
https://galaxy.ansible.com/Juniper/junos/
Is the content posted here has whole content of your playbook? if yes, You need to define other items too in your playbook such as roles, connection, local. For example
refer https://github.com/Juniper/ansible-junos-stdlib#example-playbook
```
---
- name: rollback example
hosts: all
roles:
- Juniper.junos
connection: local
gather_facts: no
tasks:
- name: I've made a huge mistake
junos_rollback:
host = {{inventory_hostname}}
----
----
```
Where have you saved the content of juniper.junos modules?. Can you post the content of your playbook and the output of the tree command to see your file structure? That could help.
I had a similar problem where Ansible was not finding my modules and what I did was to copy the juniper.junos folder to my roles folder and then added a tasks folder within it to execute the main.yaml from there.
Something like this:
/Users/macuared/Ansible_projects/roles/Juniper.junos/tasks
---
- name: "TEST 1 - Gather Facts"
junos_get_facts:
host: "{{ inventory_hostname}}"
user: "uuuuu"
passwd: "yyyyyy"
savedir: "/Users/macuared/Ansible_projects/Ouput/Facts"
ignore_errors: True
register: junos
- name: Checking Device Version
debug: msg="{{ junos.facts.serialnumber }}"
Additionally, I would add "" to the string values in your YAML. Something like this:
---
- name: I've made a huge mistake
junos_rollback:
host="{{ inventory_hostname }}"
user=ansible
comment="{{ comment }}"
confirm={{ confirm }}
rollback={{ rollback }}
logfile="{{ playbook_dir }}/library/logs/rollback.log"
diffs_file="{{ playbook_dir }}/configs/{{ inventory_hostname }}"
Regarding this "I've tried mixing both and only using one or the other. I keep getting errors."
I've used just colon and mine works fine even when in the documentation suggests = signs. See junos_get_facts
I have problem using parametrized ansible include.
I have created following file, named tasks/haproxy.xml
- name: "change node state to {{state}} in haproxy"
tags:
- "haproxy-{{state}}"
become: yes
become_user: root
haproxy:
state: "{{ state }}"
wait: yes
host: "{{ inventory_hostname }}"
backend: app
socket: /var/container_data/haproxy/run/haproxy.sock
delegate_to: "{{ item }}"
with_items: "{{ groups.haproxy }}"
I am including this file in my playbook.yml, passing value of state parameter
- include: tasks/haproxy.yml state=enabled
I am getting following error
TASK [include] *****************************************************************
included: /home/bb/tasks/haproxy.yml for 172.16.224.68, 172.16.224.69
ERROR! 'state' is undefined
state is my parameter, passed when doing include (as described in http://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse)
Whats wrong?
I am using Ansible 2.0.2.0.
edit:
using alternative syntax for passing paramteres
- include: tasks/haproxy.yml
vars:
state: enabled
gives exactly same error message.
Resolved by removing single leading space (!!) when using alternative syntax (vars).
So correct parametrized include is
- include: tasks/haproxy.yml
vars:
state: enabled
vars keyword must be at the same level as include keyword.
Otherwise it does not work, with message ERROR! 'state' is undefined.
Shortened syntax (- include: tasks/haproxy.yml state=enabled) still does not work.
I have a json file in the same directory where my ansible script is. Following is the content of json file:
{ "resources":[
{"name":"package1", "downloadURL":"path-to-file1" },
{"name":"package2", "downloadURL": "path-to-file2"}
]
}
I am trying to to download these packages using get_url. Following is the approach:
---
- hosts: localhost
vars:
package_dir: "/var/opt/"
version_file: "{{lookup('file','/home/shasha/devOps/tests/packageFile.json')}}"
tasks:
- name: Printing the file.
debug: msg="{{version_file}}"
- name: Downloading the packages.
get_url: url="{{item.downloadURL}}" dest="{{package_dir}}" mode=0777
with_items: version_file.resources
The first task is printing the content of the file correctly but in the second task, I am getting the following error:
[DEPRECATION WARNING]: Skipping task due to undefined attribute, in the future this
will be a fatal error.. This feature will be removed in a future release. Deprecation
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
You have to add a from_json jinja2 filter after the lookup:
version_file: "{{ lookup('file','/home/shasha/devOps/tests/packageFile.json') | from_json }}"
In case if you need to read a JSON formatted text and store it as a variable, it can be also handled by include_vars .
- hosts: localhost
tasks:
- include_vars:
file: variable-file.json
name: variable
- debug: var=variable
for future visitors , if you are looking for a remote json file read. this won't work
as ansible lookups are executed in the local
you should use a module like Slurp