My ansible playbook accepts two run-time variables
run_on_host
section
I want to pass multiple hosts to above variables. I can do this on jenkins pipeline by looping and feeding the data:
example:
hosts = [ "Server1", "Server2", "Server3" ] for(host in hosts) {
ansiblePlaybook inventory: '/etc/ansible/inventory_test', extras: "-e 'configFile=/nps/data/ansible/config_test.ini hosts=$host
section=$host' -playbook: '/nps/data/ansible/commonscripts/test.yml'
I want to do similar on AWX and I have tried passing variables in my job template as:
run_on_host:
- Server1
- Server2
section:
- Server1
- Server2
but the section variable is combined and passed into the playbook which fails.
Error:
An unhandled exception occurred while templating '{{ lookup('ini', 'TOMCATS section={{ section }} file={{ configFile }}').split(',') }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while running the lookup plugin 'ini'. Error was a <class 'configparser.NoSectionError'>, original message: No section: \"['Server1', 'Server2 ']\""}
How can I achieve a loop-like logic similar to Jenkins for ansible AWX?
Thanks for the help.
Related
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
[SOLVED - answer in comments]
I am looking for a help. Maybe someone had this problem already or just have a idea what is going on and can advise? Much appreciated!
In Rundeck I've defined project with Ansible (via ansible plugin) set as a executor.
Within a project I've two resource models:
Ansible Resource Model Source (with Satellite set as dynamic inventory - all works as expected)
resourceyaml (which is not working)
Configuration for both resources is listed at the end of this post.
As said, I am struggling with nodes defined in yaml resource model -
node is visible in Nodes section, but whenever I am trying to execute a command or job against it, error is being throwed:
[WARNING]: Could not match supplied host pattern, ignoring: template
ERROR! Specified hosts and/or --limit does not match any hosts
Failed: AnsibleError: ERROR: Ansible execution returned with non zero code.
Execution failed: 116 in project Linux-Ansible: [Workflow result: , step failures: {1=Dispatch failed on 1 nodes: [template: AnsibleError: ERROR: Ansible execution returned with non zero code. + {dataContext=MultiDataContextImpl(map={}, base=null)} ]}, Node failures: {template=[AnsibleError: ERROR: Ansible execution returned with non zero code. + {dataContext=MultiDataContextImpl(map={}, base=null)} ]}, status: failed]
When I am executing ansible via cli with resourceyaml file set as inventory, I can see these warnings:
ansible -i /etc/ansible/hosts-rundeck-static.yml all --limit node001#domain.com -m shell -a id
[WARNING]: Skipping key (username) in group (template) as it is not a mapping, it is a <class 'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: Skipping key (description) in group (template) as it is not a mapping, it is a <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: Skipping key (tags) in group (template) as it is not a mapping, it is a <class 'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: Skipping key (hostname) in group (template) as it is not a mapping, it is a <class 'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: Skipping key (ssh-keypath) in group (template) as it is not a mapping, it is a <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: Skipping key (nodename) in group (template) as it is not a mapping, it is a <class 'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: node001#domain.com
Conf. for resource models:
YAML:
Format: resourceyaml
File Path:/etc/ansible/hosts-rundeck-static.yml
Writeable: yes
Content of hosts-rundeck-static.yml:
---
template:
nodename: node001#domain.com
hostname: 1.2.3.4
username: admin#domain.com
ssh-keypath: keys/ssh_key/key1
description: this is a template node
tags: template
Ansible inventory:
ansible inventory File path:/etc/ansible/foreman.yml
Ansible config file path:/etc/ansible
Gather Facts: yes
Ignore Host Discovery Errors: yes
SSH Authentication: privateKey
SSH User:admin#domain.com
SSH Key File path:/rundeck/id_ecdsa
Privilege escalation method.: sudo
Ansible conf:
[defaults]
strategy_plugins = /opt/mitogen/ansible_mitogen/plugins/strategy
collections_paths = /etc/ansible/collections
inventory = /etc/ansible/foreman.yml
timeout = 30
[inventory]
enable_plugins = host_list, yaml, script, ini, foreman
[privilege_escalation]
[paramiko_connection]
[ssh_connection]
pipelining = True
[persistent_connection]
[accelerate]
[selinux]
[colors]
[diff]
Rundeck version: 3.3.6-20201111, with Ansible plugin version: 3.1.1
Can anyone help me with that? Thank you!
For the record answer: following this guide and defining correctly the ansible.cfg / inventory path on the Node Executor section (with filename at the end) solves this issue.
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 running a simple ansible playbook and getting an error:
ERROR: parse error: playbooks must be formatted as a YAML list, got type 'str'
---
- hosts: all
tasks:
- name: Get server availability by pinging it
ping:
- name: Get server hostname
command: hostname
Not sure where the problem is. Ansible v1.9.6
Answer from comment: missing -i flag in ansible-playbook hostname.yml inventory.
In my playbook I have a conditional include statement to include a task:
tasks:
# Install Java if not present
- name: Execute Java
shell: java -version
register: result
ignore_errors: True
- include: tasks/java.yml
when: result | failed
...
When I execute playbook it give out an error:
user1#localhost:~ ansible-playbook tomcat.yml
ERROR: tasks is not a legal parameter in an Ansible task or handler
However when I replace this include statement with shell or something else, playbook runs as expected....
Ansible docs tells that task can be conditionally included, so why I am getting error here?
Solution: You should leave out the "tasks:" part in the included file.
Why it fails:
When you include, you are already in the tasks section so to Ansible it looks like:
- tasks:
tasks:
- name: https://www.digitalocean.com/pricing/
...
This happens when you define "tasks" within "tasks"
Tasks definitions within tasks definitions can happen if you try to include another playbook that has a tasks definition in it.