I'm playing with ansible dynamics inventories using servicenow.servicenow.now plugin. The main idea, is to tell ansible to use winrm kerberos connection type to all host I pull from it. So i'm using the compose option to do that, but, it seems the string are not parsed as expected. It says in the doc that it should be jinja2 expression. In my case I just want to set a string with mixed number and letters. For some reason it only works with numbers?
here is the plugin configuration:
# Simple Inventory Plugin example
plugin: servicenow.servicenow.now
instance: myamazingcompany
username: username
password: 'amazingpassword'
filter_results: 'install_status=5'
fields: [name,support_group]
table: computers
use_extra_vars: yes
keyed_groups:
- key: sn_support_group | lower
prefix: ''
separator: ''
compose:
ansible_user: "my_windows_user"
ansible_password: "4567"
connection: "winrm"
ansible_winrm_transport: "kerberos"
ansible_winrm_server_cert_validation: "ignore"
Here is the result I get from servicenow
[...]
"windows_server_1": {
"ansible_password": "4567",
"sn_name": "windows_server_1",
"sn_support_group": "windows_support"
},
"windows_server_2": {
"ansible_password": "4567",
"sn_name": "windows_server_2",
"sn_support_group": "windows_support"
},
[...]
Why do I only get the ansible_password variable set to my hosts ? I have tried using simple quote, no quote at all and it does not work. I'm confused as the plugin documentation does not explain anything.
Thanks for your help
Yeah, this comes up a lot and your experience is made worse by them just silently swallowing jinja2 errors during that compose:
step
So, first, the answer to your question, and then a suggestion how one can side-step this silliness in the future
The answer is because because each of those compose values are implicitly wrapped in {{ }}
which is why they talk about "jinja2 expressions" and is the reason why this works at all in their docs:
compose:
sn_tags: sn_sys_tags.replace(" ", "").split(',')
ansible_host: sn_ip_address
one can see that both of those are python jinja2 and for sure not keys in the resulting json; thus, what's actually going on here is:
compose:
sn_tags: '{{ sn_sys_tags.replace(" ", "").split(",") }}'
ansible_host: '{{ sn_ip_address }}'
but I guess including the mustaches in the .yaml file would lead a user to think they can use mustaches anywhere which is for sure untrue
Thus, in your circumstance, you have to make those keys into expressions that produce those literals, like so:
compose:
ansible_user: '"my_windows_user"'
ansible_password: '"4567"'
connection: '"winrm"'
ansible_winrm_transport: '"kerberos"'
ansible_winrm_server_cert_validation: '"ignore"'
since {{ winrm }}
is a jinja2 error if there is no such symbol in scope, but {{ "winrm" }}
is the string winrm
; the outer '"
is to escape those "
from yaml
The reason why your password: "1234"
worked is because {{ 1234 }}
resolves to itself, in ways that {{ foobar }}
does not, although pedantically ansible_password:
was then int
and not str
but I guess it didn't get far enough for that explosion to manifest :-)
Now, I was trying to answer the question you asked, but in the future, what you're really after are group_vars
since every one of those keys you provided do not vary based on the inventory response, and thus they belong in a group_vars/${whatever}.yaml
file, even if the filename ends up being all.yaml
because it applies equally to every single host in the inventory