HiveBrain v1.2.0
Get Started
← Back to all entries
snippetMinor

How to deterministic and reproducibly assign increasing port numbers in Ansible?

Submitted by: @import:stackexchange-devops··
0
Viewed 0 times
numbersreproduciblydeterministicincreasinghowandportansibleassign

Problem

I am new to Ansible, but I have to maintain a set of playbooks, which correspond to services to be setup in a given environment. They need to be assigned a port, certificates, etc. This results in many files with lists of essentially always the same names and an assignment to them.

In many cases I think I can easily reuse the service_name as variable, but when mapping to IPs, ports or other numeric identifiers I have not yet figured out a way to deterministically assign them different numbers in a way that is reproducible, and preferably remains the same even when new services are added. I have considered using a SQLite database to store the services from and to generate the values from their ids, but I have no idea how to integrate that with Ansible.

I assume that assigning increasing port numbers is not something entirely new; it is something a lot of sysadmins to on a day-to-day basis so there has to be some way to do that.

Edit: We directly add the port numbers etc. in group_vars/all.yml like this:

ports:
    service1:1024
    service2:1025
    service3:1026


The inventory is generated automatically, since we create additional jails (BSD) and depends on the roles that will be executed.

Solution

Disclaimer: I'm not using Ansible.

What I would do is use a random "predictable" number.
According to Ansible doc you can seed the random number generator:


As of Ansible version 2.3, it’s also possible to initialize the random
number generator from a seed. This way, you can create
random-but-idempotent numbers:


"{{ 59 |random(seed=inventory_hostname) }} root
/script/from/cron"

So in your case for a port number (I assume unpriviledged) I would go for a variable with something like:

port="{{ 32767 |random(start=1024,seed=service_name) }}"


Max at 32767 to avoid clashing with any client initiated port (See Ephemeral port for the reason).

Code Snippets

port="{{ 32767 |random(start=1024,seed=service_name) }}"

Context

StackExchange DevOps Q#208, answer score: 5

Revisions (0)

No revisions yet.