String formatting in Ansible
This post is about configuring ISAM WebSeal using the IBM Security Ansible Collection https://github.com/IBM-Security/isam-ansible-collection, but it is valid for any string related operation in Ansible yaml files.
There are different moving parts in play that impact how your strings will be rendered, and I try to clear that up a bit here.
It can be a Python, Yaml or Jinja syntax thing.
There are a couple of situations where the standard string syntax in Ansible is not enough to pass the configuration data to the IBM Security Ansible Collection.
- “Truthy” values (
!!str
) - Python - Strings containing special characters (“{% raw %}”) - Jinja
- Multiline strings for long strings without spaces - Yaml
Truthy values
The WebSEAL configuration entries can contain multiple values that are Truthy values in Python. (https://www.freecodecamp.org/news/truthy-and-falsy-values-in-python/). Examples of thruthy values in Python are for instance True,False,yes,no,true,false .
If Python handles them as truthy values, they end up in the configuration as Python booleans.
So for example, if I want to set use-filename-for-pkmslogout
to yes, it actually ends up as True in the configuration.
- method: set
stanza_id: actn-mgt
entries:
- ["use-filename-for-pkmslogout", yes]
This is the result:
use-filename-for-pkmslogout = True
This is not going to work in WebSEAL.
So here’s where the Yaml string scalar notation !!str
comes in handy.
It means “handle this next thing as String, even if it’s thruthy in Python”.
This syntax will make sure the result in the webseald.conf file is use-filename-for-pkmslogout=true
- method: set
stanza_id: actn-mgt
entries:
- ["use-filename-for-pkmslogout", !!str yes]
Special characters in string
Specifically the request-log-format
in the webseald.conf file contains characters that can be interpreted incorrectly by the Jinja interpreter in Ansible.
So to pass the String value unchanged, you can use {
% raw %
}{
% endraw %
}
.
The text in between will not be parsed by Jinja and will end up unchanged in the webseald.conf file. See https://jinja.palletsprojects.com/en/3.0.x/templates/ for more information.
- method: set
stanza_id: logging
entries:
- [request-log-format, '{ % raw % }%{%Y-%m-%dT%H:%M:%S}t %h %A %u "%R" %s %F %b
SESS_ID:%{PD-S-SESSION-ID}e %d %{User-Agent}i %{tagvalue_session_index}C{ % endraw % }']
Note: Ironically, I’m struggling to escape raw/endraw correctly here, so I’m writing it with spaces in between the {
and the %
. These spaces should not be there. Since this is Jinja, it also applies to any tools that use Jinja, like this Jekyll-based blog.
Multiline strings for long strings
To keep the Ansible Yaml files readable, it can be useful to split long strings on multiple lines. Yaml has basically 2 syntaxes for multiline strings (and a number of combinations)
- Folded
>
- Literal
|
Combine them with a chomping indicator -
, to remove newlines.
Both are equally useless when you want to split up a long string, for instance a URL with a lot of querystring parameters.
They are useless, because whatever you do, there’s going to be spaces (
) entered between the text on your multiple lines.
You can test the different options here : https://yaml-multiline.info/.
So to split a long URL in Yaml, forget about the Yaml multiline syntax, but just use a string :
my_long_url: "http://www.test.com/uri\
?query=param1\
&query2=param2\
&query3=param3"
The backslash \
escapes the newline character, so the result is a nice long string without extra spaces.