How to fix this formatting issue? - ansible

I am attempting to template a system properties file using Jinja2. I'm using a list, a for loop and an if loop to cycle through various hostnames and to produce them in a list as a variables property. However, when I then deploy this code using ansible, the formatting comes out wrong and the next line is attached to the first line with no line break.
I have tried numerous different ways of layout, but none of them seem to work.
database.url = {%- set list1 = application_host.split(',') -%} {%- for list in list1 -%} {{ list }}:{{ db_port }}{%- if not loop.last -%},{%- endif -%}{%- endfor -%}
database.name = {{application_db_name }}
This is how it actually looks in the file:
database.url =db-cluster-router-1:4526,db-cluster-router-2:4526solr.database.name = DATABASENAME
I am expecting a line break between the two variables. E.g.:
database.url = db-cluster-router-1:4526,db-cluster-router-2:4526
database.name = DATABASENAME

Related

Access yaml key name with liquid

Is it possible to access the key names along with key values from a yaml file using liquid?
For example from a .yaml file that looks like this:
- type: a
id: b
author: c
website: d
Have liquid code that looks something like this:
{%- for item in YAMLFILE -%}
{{ item.??? }} = {{ item.??? }}
{%- endfor -%}
with the following output:
type = a
id = b
author = c
website = d
I am trying to do this this way because my yaml file has different key names along with values and it would be a pain having to embed a bunch of different if else statements to account for every possible key name.
Thank you all so much!
Assuming your yaml file is in _data/test, you can use:
{% for list in site.data.test %}
{% for item in list %}
{{ item[0] }} = {{ item[1] }}
{% endfor %}
{% endfor %}
item[0] is the key and item[1] is the value. It will work with different number of keys and names in each list.
Also be aware that four spaces in Markdown formats the content of the second for loop as a code block. Simply do not indent if putting this code in a Markdown file.

migrating Jekyll 3.8.6 to 4.0 captured variables from import no longer expand

I have a Jekyll site with articles about products. At the top of each post.md I include a file with {%- include vars -%}. vars is an include file that contains {%- include varfiles/product.html id=page.product -%}. It automatically grabs the product number into the page, and then passes it to product.html in the varfiles folder. The following is product.html
{%- assign product = site.data.products | where:"id",include.id | first -%}
<!-- product name -->
{%- if product.name -%}
{%- capture product-name -%}
{{ product.name }}
{%- endcapture -%}
{%- endif -%}
plus a lot more similar to the code above
The file is essentially many types of variable name creators based on the product properties pulled from the products data file, which is a list of products. The result is when I add the {%- include vars -%} at the top of any post.md it will automatically generate easier to remember/use variables names based on the product id number in the frontmatter. Then I can include the variable names throughout the article like {{ product-name }} and it automatically resolves from the variables that were created from the vars include.
THE PROBLEM: Whne I upgrade jekyll to use 4.0 all of the variables are empty. When putting {{ product-name }} somewhere in post.md under the vars include it would automatically convert it to the products name. On 4.0 it becomes empty. The only change I'm making is updating to Jekyll 4.0. If I downgrade all the variables work fine.
The workaround that seems to work is to change
{%- assign product = site.data.products | where:"id",include.id | first -%}
to
{%- assign product = site.data.products[include.id] -%}
no clue why that works.

Translating multiple default variables from Chef to Ansible

How would a node attribute being set by a case in Chef be translated to a variable in Ansible?
Example:
case node['custom_attribute']
when 'security_standard_1'
security_standard = 'ss1'
when 'security_standard_2'
security_standard = 'ss2'
else
security_standard = 'off'
end
I've only seen things that have two possible values being set with jinja.
security_standard: "{{ security_standard_1 | security_standard_2 }}"
Is this thought process even doable in Ansible?
You can define variables using jinja template with if-else conditions to suit your needs.
Here's an example:
security_standard: "{%- if (security_standard_1 is defined) -%}ss1
{%- elif (security_standard_2 is defined) -%}ss2
{%- else -%}off
{%- endif -%}"

How can one generate a dict in Jinja/Ansible as a var?

I need to dynamically generate a dict and assign it to an Ansible var so that the same data is available to every host and does not need to be regenerated on each one. This will be looped over by a task and template. It is possible to build lists by nesting Jinja in a var definition like so:
var_list: >
[
{% set data = [] %}
{% for host in groups['all'] %}
{{ data.append(host) }}
{% endfor %}
{{ data }}
]
However, I am not able to do so with dicts:
var_dict: >
{
{% set data = dict() %}
{% for host in groups['all'] %}
{{ data | combine({host: []}) }}
{% endfor %}
{{ data }}
}
This results in a giant, garbled string: {u'host.subdom.dom.tld': []} {}...
What I am expecting is a var set to a true dict object that can have its components referenced individually (like {{ var_dict.host1[0] }}), with a structure similar to the following JSON:
{
"host1": [],
"host2": []
}
Is there a way to cause this to expand into a proper dict when assigned to the variable? Or is there perhaps another way to generate a dict from a loop without that awful set_fact hackery?
Either of your templates is broken (the first one produces nested lists, the second one prints data in loop with this expression {{ data | combine({host: []}) }}, the value of data remains empty until the end).
Jinja2 is a templating engine, you don't really need to create data structures to print them later. You can form your output directly.
For the list:
var_list: >
[ {% for host in groups['all'] %}'{{ host }}',{% endfor %} ]
For the dictionary:
var_dict: >
{ {% for host in groups['all'] %}'{{ host }}': [],{% endfor %} }
As you expect the values to be interpreted by Ansible, you don't need to pay attention to the trailing coma, otherwise there is loop.last.

Shopify Liquid Syntax - What is the difference between {%- assign [some_var] = [some_val] -%} and {% assign [some_var] = [some_val] %}

When coding in Shopify's Liquid language I notice some variables being assigned using the following syntax:
{%- assign variable = value -%}
and other variables being assigned using the following syntax:
{% assign variable = value %}
Could someone explain the difference, if there is any?
When yo use {% assign variable = value %} you keep any white space if there is any.
But if you use {%- assign variable = value -%} the white space is stripped.
That's the main difference.
PS: This is true for any liquid operation{%- if -%}, {%- capture -%} etc.. even if you like to output something like so {{- -}}.
In Liquid, you can include a hyphen in your tag syntax {{-, -}}, {%-, and -%} to strip whitespace from the left or right side of a rendered tag.
If you don't want any of your tags to output whitespace, as a general rule you can add hyphens to both sides of all your tags ({%- and -%})

Resources