Transform ansible yml files "with vars templating" to yml files "without templating" - ansible

I have this yml files inside an ansible project with templating and vars :
custom_values:
postgresql:
postgresqlDatabase: "{{ secrets.db_name }}"
postgresqlPassword: "{{ secrets.postgres_password }}"
I search a solution to generate the same yml file without the templating like :
custom_values:
postgresql:
postgresqlDatabase: "mydatabase"
postgresqlPassword: "mypassword"
Do you know an existing software to do that automatically ?

You already have a set of ansible templates, that are rendered by a render engine like Jinja2.
The easiest way to convert them would be to actually use the render engine to render the templates, supplying the correct values to it.
You'll end up with a bunch of templates that have the {{ something }} blocks, replaced with the values you want.
Since this looks to be simple Jinja2 templating, please refer to: https://jinja.palletsprojects.com/en/2.10.x/
You'll end up with something like this:
>>> from jinja2 import Template
>>> template = Template('Hello {{ name }}!')
>>> template.render(name='John Doe')
Please also refer to this stackoverflow post: How to load jinja template directly from filesystem
That explains how to load templates from files

This python code is OK for me :
#import necessary functions from Jinja2 module
from jinja2 import Environment, FileSystemLoader
#Import YAML module
import yaml
#Load data from YAML into Python dictionary
config_data = yaml.load(open('./my_vars.txt'))
#Load Jinja2 template
env = Environment(loader = FileSystemLoader('./templates'), trim_blocks=True, lstrip_blocks=True)
template = env.get_template('my_template.yml')
#Render the template with data and print the output
print(template.render(config_data))
thanks :)

Related

Calling an Ansible script inside of a ansible script and/or within a Loop module

Context:
I am trying to deploy an IDAM solution. In order to do that specific things need to be installed in a certain order.
How I am currently doing it:
I have a variables file that looks like vars/main.yml:
EPM:
list_of_packages:
- package1.msi
- package2.msi
- package3.msi
- package4.msi
Now this method 1 works if I do:
win_package:
path: C:\path\{{ item }}
arguments: /qn /norestart
loop: "{{ EPM['list_of_packages'] }}
The problem is Package1 doesn't properly install. In order to get Package1 installed I needed to create a separate Ansible script that executes a bunch of .SQL scripts. This script, for the sake of this example is called: epm_sql_scripts.yml
This script loops through a bunch of .SQL scripts with the loop module and psiexec module.
It looks similar to method 1 script.
Is there a way I can call the epm_sql_scripts.yml from the method 1 script and/or from the vars/main.yml file?
I understand where you were heading but ansible wont allow you to do that. You cannot nest playbooks like your example.
Other important point is that, if you choose to use import_tasks the playbook imported must contain only tasks.

How to concatenate several strings and variables in Yaml?

I need to do something like this:
domain: &domain example.com
ip: &ip 1.2.3.4
Address4: v=spf1 include:*domain ip4:*ip -all
I tried this but didn't work, it says there's a syntax error:
Address4: 'v=spf1 include:'*domain' ip4:'*ip' -all'
The implementation (I'm using these files in Ansible) seems to support concatenation, for example this works fine:
Address2: http://*domain # actually this doesn't work, I don't remember the exact example
Any ideas?
I don't exactly get why you're trying to concatinate in YAML, since Ansible uses jinja2 as a templating engine:
Defining variables in a vars file for Ansible (in YAML):
domain: example.com
ip: 1.2.3.4
Referencing variables (still in YAML):
Address4: v=spf1 include:{{ domain }} ip4:{{ ip }} -all
When you use the Address4 variable in the template module (I assume), it works the same way.

Conditional check in yaml file to show the proper content

How can I check if / else in yaml file.
like:
if %{attribute}
attributes:
shipping_comment: Shipping comment / Instructions
else
attributes:
shipping_date: Date
YAML is a data serialisation language, so it's not meant to contain if/else style executable statements: that's the responsibility of the programming language you're using.
A simple example in Ruby to determine which config string from a YAML file to output could be defining your YAML config file as follows:
data.yml
attributes:
shipping_comment: Shipping comment / Instructions
shipping_date: Date
Then, in your program, read the file in and run the conditional there:
shipping.rb
#!/usr/bin/env ruby
require 'yaml'
config = YAML.load_file('data.yml')
attribute = true # your attribute to check here
if attribute
puts config['attributes']['shipping_comment']
else
puts config['attributes']['shipping_date']
end
Out of the box .yaml files won't include any conditional logic, as Paul Fioravanti says:
YAML is a data serialisation language, so it's not meant to contain if/else style executable statements: that's the responsibility of the programming language you're using.
However, there are some cases, such as Infrastructure as Code where you might not have the luxury of Paul's solution. In these cases, most decent Infrastructure tools provide an inbuilt way of achieving conditional logic.
Since it appears that infra is not the area you're looking in, I won't go into detail on how to write each tools solution, but for anyone that end's up here like I did, docs such as these helped me and may prove useful for you:
Ansible
CloudFormation
This is a little late for the original poster, but may be of use to others: The Azure implementation of the YAML parser does support conditional checks. For example, the following YAML in an azure-pipeline.yml:
#azure-pipeline.yml
parameters:
- name: testCondition
displayName: 'Use experimental build process?'
type: boolean
default: true
steps:
- ${{ if eq(parameters.testCondition, true) }}:
- bash: echo 'true'
- ${{ if not(eq(parameters.testCondition, true)) }}:
- bash: echo 'false'
will evaluate the value of the testCondition parameter. When run, the bash task will echo "true", something like this:

Using app engine interactive console with jinja2 template

from jinja2 import Template
template = Template('Hello {{ name }}!')
template.render(name='John Doe')
I have entered the above into app engine's interactive console and get no output. How can I get output?
I have tried adding the code I found at the following link to the console, but still no output.
Debug Jinja2 in Google App Engine
Thanks,
Brian in Atlanta
You forgot to add a print. Try this:
from jinja2 import Template
template = Template('Hello {{ name }}!')
print template.render(name='John Doe')

Jekyll Liquid - accessing _config.yml dynamically

For internationalizing my app I need to be able to dynamically access entries in a YAML file.
It is best explained with an example:
Page:
---
layout: default
title: title_homepage
---
This will then allow access to the title_homepage variable in the Default Layout Template:
Default Layout:
page.title = "title_homepage"
Now normally I would access my _config.yml file like this:
{{ site.locales[site.default_locale].variable }}
However, now for this to work, I need to access the _config.yml with the value of page.title. This will not work:
{{ site.locales[site.default_locale].page.title }}
I need the following (pseudo code):
{{ site.locales[site.default_locale].#{value of page.title}}
With the way your vars are set, it would be something alog the lines of
{{ site.locales[site.default_locale][page.title] }}
The thing is, ... I don't really see the point of doing this. Let's say your page is the english page. The locale should then be defined within the page, and so should your title!
---
locale: en
title: My Wonderful Page
---
Which you can retrieve with {{ page.title }} ...
What could be the point of putting the title into the _config.yml file?
(edit) well unless you want to access page.title when in another page/post, in this case you have no choice but to put it into _config.yml.

Resources