Ansible parses my YML comment and mistake it with k=v - ansible

In this code block running ansible 2.9.6:
// System/group_vars/all/vars.yml
---
# AWS S3
# User Ansible
# Permissions put/get on arn:aws:s3:::snap/backup-db/*
# Plus d'infos: https://console.aws.amazon.com/iam/home?region=eu-west-2#/users/ansible?section=permissions
s3_access_key: {{ lookup('aws_ssm', '/iam/ansible/access-key', region='eu-west-2', aws_access_key=aws_access_key, aws_secret_key=aws_secret_key) }}
Gives the following error:
ERROR! Syntax Error while loading YAML.
found unacceptable key (unhashable type: 'AnsibleMapping')
The error appears to be in 'System/group_vars/all/vars.yml': line 32, column 63, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
# Plus d'infos: https://console.aws.amazon.com/iam/home?region=eu-west-2
^ here
There appears to be both 'k=v' shorthand syntax and YAML in this task. Only one syntax may be used.
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
It thinks that region=eu-west-2 is a key value that is mixed with YML syntax.
What can I do to avoid Ansible throwing this wrongful error since it's in a YML comment ?
Thank you :)

It was a stupid mistake caused by a line right after this one:
# Plus d'infos: https://console.aws.amazon.com/iam/home?region=eu-west-2#/users/ansible?section=permissions
s3_access_key: {{ lookup('aws_ssm', '/iam/ansible/access-key', region='eu-west-2', aws_access_key=aws_access_key, aws_secret_key=aws_secret_key) }}
Should be:
# Plus d'infos: https://console.aws.amazon.com/iam/home?region=eu-west-2#/users/ansible?section=permissions
s3_access_key: "{{ lookup('aws_ssm', '/iam/ansible/access-key', region='eu-west-2', aws_access_key=aws_access_key, aws_secret_key=aws_secret_key) }}"
note the quotes around the "{{ lookup }}". The error message was trying to tell me so at the very last part of the error ("might be an issue with
missing quotes") I just was focused on why my comment was parsed and interpreted as key=value

Related

Ansible Playbook msg var interpolation seems to only work with carrot > in yml file

Found an odd behavior I can't explain;
Running a small Ansible Playbook to just gather and display operating system information from hosts(For example: "Debian GNU/Linux 10")
I randomly stumbled across this solution(using carrot >), but can't find an explanation why it works this way;
---
- name: Show Operating System version information
hosts: all
gather_subset: distribution_version
tasks:
- name: Display operating system facts
debug:
msg: >
{{ ansible_facts.lsb.description }}
Generates successful output;
ok: [orville.lan] => {
"msg": "Ubuntu 19.10"
}
But if changed to this (remove >);
---
- name: Show Operating System version information
hosts: all
gather_subset: distribution_version
tasks:
- name: Display operating system facts
debug:
msg: {{ ansible_facts.lsb.description }}
Then running the playbook generates this error sequence;
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: No JSON object could be decoded
Syntax Error while loading YAML.
found unacceptable key (unhashable type: 'AnsibleMapping')
The error appears to be in '/home/eschin/Repositories/ansible-files/OperatingSystemReport.yml': line 9, column 17, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
debug:
msg: {{ ansible_facts.lsb.description }}
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
I understand that the carrot > treats all following indented lines as a single line, i.e, converts newlines to spaces, but what other "secret sauce" is going on that makes the former work, but not the latter?
SOLUTION:
Simply making the interpolation a string, which the carrot > does for you, makes the second example work. I thought I'd tried this, and was sure it didn't work... but tried it again, and it works now. Coding Imps must have been messing with me 0:)
So this works;
---
- name: Show Operating System version information
hosts: all
gather_subset: distribution_version
tasks:
- name: Display operating system facts
debug:
msg: "{{ ansible_facts.lsb.description }}"
{{}} is used for jinja2 template and to make that work, you need to put the template in a string within quote ' or ". So below should work:
msg: "{{ ansible_facts.lsb.description }}"
# Or, within a string without quote like below (better to use quote because the yaml processor implementation may differ for some special characters),
msg: The description is {{ ansible_facts.lsb.description }}
Now for,
I randomly stumbled across this solution(using carrot >), but can't
find an explanation why it works
> and | represents folded and literal multiline strings in yaml respectively. Since > already put the template within a string, it was working as you indicated on your question.
Have a look at basic YAML syntax too.

Using a variable for the hosts in a playbook in v2.5

I have a simple playbook and I want to enter the host interactively. My code looks like:
- hosts: "{{my_hosts}}"
vars_prompt:
- name: "my_hosts"
prompt: "Enter the hosts"
private: no
This code works fine in 2.3 and 2.4, but in 2.5 I get the message below.
I haven't seen anything in the release notes that would explain why it
stopped working. Anyone knows why?
Thanks,
a
ERROR! The field 'hosts' has an invalid value, which includes an undefined variable. The error was: 'scraper_hosts' is undefined
The error appears to have been in 'my-playbook.yml': line 8, column 3, but may be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- hosts: "{{my_hosts}}"
^ here
We could be wrong, but this one looks like it might be an issue with missing quotes. Always quote template expression brackets when they start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
Looks like its not intended behavior, please check reported issue at github.
Fix is on its way according to this linked pull request.

is_file produces a syntax error in Ansible

I use Ansible 2.3.2.0 for my project. In this project, I have a task using is_file test:
- name: Create repository.ini file
template: src="{{ playbook_dir }}/../../../repository.ini" dest="/{{ repository_dir }}/repository.ini"
when: "{{ playbook_dir }}/../../..//repository.ini"|is_file
This task produces the following error:
The offending line appears to be:
template: src="{{ playbook_dir }}/../../../repository.ini" dest="/{{ jse_repository_dir }}/repository.ini"
when: "{{ playbook_dir }}/../../../repository.ini"|is_file
^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
. . . .
I tried everything I could with no avail.
When you start a YAML key value with a quote, you must quote the whole value, so if there are any other strings inside, you should use a different quotation mark (e.g., single quote + double quote).
Ansible expects the value of when to be a Jinja2 statement, so there is no need to use {{ inside.
Because 2. that you need to use Jinja2 syntax for string concatenation variable + 'string'.
Combined, your conditional should be:
when: "(playbook_dir+'/../../../repository.ini')|is_file"

How to resolve a variable inside a variable?

Considering this Ansible task:
- name: Set some kernel parameters
lineinfile:
dest: "/home/cloud-user/{{item}}.hostsubnet.json"
regexp: '^(.*hostIP\".*)\"10.*\"(.*)$'
line: \1"{{hostvars['{{item}}']['ansible_eth0']['ipv4']['address']}}"\2
backrefs: yes
with_items: "{{ groups.nodes }}"
I am trying to loop over the all hosts in group [nodes].
For each node, I would like to fetch an IP from facts, and use that IP
as a substitute string for lineinfile regexp.
But this would not work. Looks like nested variables are not possible.
Is it possible to resolve the nested variable?
I am getting this error with a code:
fatal: [master-0.ocp-36-2.teco.dev.a.tecdomain.net]: FAILED! => {
"failed": true
}
MSG:
the field 'args' has an invalid value, which appears to include a
variable that is undefined. The error was:
'ansible.vars.hostvars.HostVars object' has no attribute '{{item}}'
The error appears to have been in
'/var/lib/ansible/playbooks/hostsubnet.yml': line 27, column 7, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: Set some kernel parameters
^ here
You are trying refer to a key in hostvars using a string {{item}}.
You should use a variable name item instead:
line: \1"{{hostvars[item]['ansible_eth0']['ipv4']['address']}}"\2
You seem also to be confused with the terminology: you try to refer to a variable value inside a Jinja2 expression (i.e. what's wrapped in {{ }}). The answer to such a question is: by using variable name, plain.

Splitting variable not working in Ansible

I am trying to split the variable based on delimiter. How can I achieve it?
some_module: {{item}}.split('#')[1]
with_items:
- git#someversionxxx
- gradle#someversionxxx
I get following error:
list object' has no attribute 'split ansible
I want to consider only first part of variable i.e. before '#'
some_module: "{{ item.split('#')[0] }}"
{{ ... }} is used to indicate Jinja2 expressions and everything you have is a Jinja2 expression
with YAML syntax in Ansible you must quote a string if it starts with { (unless it was a JSON object, here it's not)
the first element of the split result will have an index of 0

Resources