# Jinja2 template and generating a table with fixed columns

**URL:** <https://forum.ansible.com/t/jinja2-template-and-generating-a-table-with-fixed-columns/45044>\
**Category:** Get Help\
**Created:** [January 1, 2026, 4:14pm UTC](https://forum.ansible.com/t/jinja2-template-and-generating-a-table-with-fixed-columns/45044 "2026-01-01T16:14:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Django](https://avatars.discourse-cdn.com/v4/letter/d/e36b37/32.png) [@Django](https://forum.ansible.com/u/Django)\
**Post date:** [January 1, 2026, 4:14pm UTC](https://forum.ansible.com/t/jinja2-template-and-generating-a-table-with-fixed-columns/45044/1 "2026-01-01T16:14:44Z")

</div>

OK, I want to create a list using a template. This consists of two columns, one for the host portion of the IPV4 address (the fourth number of the IPv4 address) and one for the host name. The host names and IP addresses are listed in the inventory.

Example:

192.168.2.1 with the host name = host1  
192.168.2.35 with the host name = host2  
192.168.2.205 with the host name = host3

Using

```auto
{% for host in groups[‘intra’] %}
{{ (hostvars[host][‘host_ipv4’] | split(‘.’)).3 }} {{ host }}
{% endfor %}

```

I generate the following:

```auto
1 host1
35 host2
205 host3

```

However, I need a list where the first column is filled with spaces so that it becomes a “nice” list, such as this one:

```auto
1 host1
35 host2
205 host3

```

Or, to put it another way: the first column should always be padded with spaces to a fixed column width, regardless of whether it contains “only” a letter or number, or even a long name.

I’ve tried so many things with Jinja filters, but nothing seems to work. It’s probably very simple, but I just have a PEBKEC problem.

Does anyone have any ideas on how to do this in the cleanest way possible?

I am grateful for any information!

---

<div class="post-metadata">

**Author:** ![felixfontein](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/felixfontein/32/7530_2.png) [@felixfontein](https://forum.ansible.com/u/felixfontein)\
**Post date:** [January 1, 2026, 4:47pm UTC](https://forum.ansible.com/t/jinja2-template-and-generating-a-table-with-fixed-columns/45044/2 "2026-01-01T16:47:36Z")

</div>

This is one of the cases where creating / using a filter plugin is likely the best choice. While it is possible to do this with several `set_fact` / `vars` (depending on how inefficient is still fine) and Jinja2 expressions, a dedicated filter plugin will result in a much more maintainable (and likely also reusable!) result (which will also be more efficient).

Depending on how important the exact formatting is, the community.general.to\_prettytable filter could be useful.

---

<div class="post-metadata">

**Author:** ![bvitnik](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bvitnik/32/4132_2.png) [@bvitnik](https://forum.ansible.com/u/bvitnik)\
**Post date:** [January 1, 2026, 6:28pm UTC](https://forum.ansible.com/t/jinja2-template-and-generating-a-table-with-fixed-columns/45044/3 "2026-01-01T18:28:23Z")

</div>

You can use the formating operator `%` like this:

```auto
{% for host in groups[‘intra’] %}
{{ '%-4s' % ((hostvars[host][‘host_ipv4’] | split(‘.’)).3) }} {{ host }}
{% endfor %}

```

You can also use the `format` filter for more modern approach:

> **[Template Designer Documentation — Jinja Documentation (3.1.x)](https://jinja.palletsprojects.com/en/stable/templates/#jinja-filters.format)**
>
> abs()

---

<div class="post-metadata">

**Author:** ![Django](https://avatars.discourse-cdn.com/v4/letter/d/e36b37/32.png) [@Django](https://forum.ansible.com/u/Django)\
**Post date:** [January 1, 2026, 6:29pm UTC](https://forum.ansible.com/t/jinja2-template-and-generating-a-table-with-fixed-columns/45044/4 "2026-01-01T18:29:17Z")

</div>

Damn! I thought it would be easier than this! Why? O.K. let me expalin my thoughts:

The following lines:

```auto
{{'{:31}'.format('hello') }} TEXT
{{'{:31}'.format('community') }} TEXT
{{'{:31}'.format('I wish you a happy new') }} TEXT
{{'{:31}'.format('year → 2026!') }} TEXT

```

produces:

```auto
hello TEXT
community TEXT
I wish you a happy new TEXT
year → 2026! TEXT

```

My naive thinking whispered to me, “Just replace the string in quotation marks with a variable and everything will be fine!”

Well, far from it, because when I add the following line to the jinja2 file:

```auto
{{'{:31}'.format('{{ host }}') }} TEXT

```

I crash and burn spectacularly:

```auto
{{ host }} TEXT

```

Damn it, the variable isn’t being replaced, but rather the name of the variable is being output.

---

<div class="post-metadata">

**Author:** ![Django](https://avatars.discourse-cdn.com/v4/letter/d/e36b37/32.png) [@Django](https://forum.ansible.com/u/Django)\
**Post date:** [January 1, 2026, 6:34pm UTC](https://forum.ansible.com/t/jinja2-template-and-generating-a-table-with-fixed-columns/45044/5 "2026-01-01T18:34:46Z")

</div>

YYMD!

It works and it works fine - muchas gracias!

---

<div class="post-metadata">

**Author:** ![bvitnik](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/bvitnik/32/4132_2.png) [@bvitnik](https://forum.ansible.com/u/bvitnik)\
**Post date:** [January 1, 2026, 6:42pm UTC](https://forum.ansible.com/t/jinja2-template-and-generating-a-table-with-fixed-columns/45044/6 "2026-01-01T18:42:24Z")

</div>

Just do:

```auto
{{'{:31}'.format(host) }} TEXT

```

In other words, in a code enclosed by `{{` and `}}`, variable interpolation is done so you don’t enclose variables with another `{{` and `}}`. Just use variable names as they are.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [January 31, 2026, 6:42pm UTC](https://forum.ansible.com/t/jinja2-template-and-generating-a-table-with-fixed-columns/45044/7 "2026-01-31T18:42:54Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
