# Properly generate random ports

**URL:** <https://forum.ansible.com/t/properly-generate-random-ports/1872>\
**Category:** Get Help\
**Tags:** playbook\
**Created:** [October 23, 2023, 2:47pm UTC](https://forum.ansible.com/t/properly-generate-random-ports/1872 "2023-10-23T14:47:22Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![su8319](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/su8319/32/1285_2.png) [@su8319](https://forum.ansible.com/u/su8319)\
**Post date:** [October 23, 2023, 2:47pm UTC](https://forum.ansible.com/t/properly-generate-random-ports/1872/1 "2023-10-23T14:47:22Z")

</div>

Hello everyone 🙂

I would like to implement a way to generate multiple random and unique ports that will be registered as facts, and then used in the next playbooks to setup some services.

This is currently the non-elegant solution I’m using :

```auto
---
- name: Define ports for containers
  hosts: debian
  gather_facts: no
  vars:
    port: "{{ 65535 | random(start=1024) }}"
  tasks:
  - name: Generate random ports
    ansible.builtin.set_fact:
      service1_port: "{{ port }}"
      service2_port: "{{ port }}"
      service3_port: "{{ port }}"
      cacheable: yes
    run_once: yes

  - ansible.builtin.debug:
      msg: Your service1 port is "{{ service1_port }}", service2 is "{{service2_port}}" and "{{ service3_port }}"

```

My questions are :

- How to avoid potential collision when generating those (unique) numbers ?
- Since the “random” filter break the idempotent nature of Ansible, should I be worried about it ? I’m planning to deploy this on a single server, so I don’t think it’ll be. Nevertheless, don’t hesitate to suggest if there is a more appropriate method for this.

In advance, thanks for helping a new user 😊

---

<div class="post-metadata">

**Author:** ![IPvSean](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/ipvsean/32/1153_2.png) [@IPvSean](https://forum.ansible.com/u/IPvSean)\
**Post date:** [October 23, 2023, 8:24pm UTC](https://forum.ansible.com/t/properly-generate-random-ports/1872/2 "2023-10-23T20:24:33Z")

</div>

an attempt…

```auto
---
- name: Define ports for containers
  hosts: localhost
  gather_facts: no
  tasks:
    - name: Initialize ports list
      set_fact:
        ports: []

    - name: Generate unique random ports
      set_fact:
        ports: "{{ ports + [1024 + (38927 | random)] }}"
      when: "1024 + (38927 | random) not in ports"
      loop: "{{ range(3) }}"

    - set_fact:
        service1_port: "{{ ports[0] }}"
        service2_port: "{{ ports[1] }}"
        service3_port: "{{ ports[2] }}"
        cacheable: yes

    - debug:
        msg: 
          - "Your service1 port is {{ service1_port }}"
          - "Your service2 port is {{ service2_port }}"
          - "Your service3 port is {{ service3_port }}"

```

Ports in the range `0-1023` are referred to as well-known ports. They’re reserved for standard services, so you generally want to avoid using them for custom applications. That’s why we start with port `1024` . The port `49151` is the upper limit of the registered port range. Ports above `49151` up to `65535` are dynamic or private ports. While you could use them, they might be less predictable in terms of what other software could dynamically allocate and use them. So, the range between `1024` and `49151` is often preferred for manually assigning ports for custom applications.

Feel free to modify… for whatever ports you want?

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [October 24, 2023, 2:05am UTC](https://forum.ansible.com/t/properly-generate-random-ports/1872/3 "2023-10-24T02:05:00Z")

</div>

> [@su8319](#):
>
> Since the “random” filter break[s] the idempotent nature of Ansible, should I be worried about it ? I’m planning to deploy this on a single server, so I don’t think it’ll be. Nevertheless, don’t hesitate to suggest if there is a more appropriate method for this.

You can “idempotentize” randomly generated values on a per-host basis by seeding your random generator with something idempotent about the hosts. For instance, we have a playbook that schedules cron jobs across all our hosts with times picked using such a seeded `random()` in order to spread the jobs out fairly evenly across the work day, like so:

```yaml
    rng_minute: "{{ 59 | random(seed=ansible_hostname) }}"
    rng_hour: "{{ 19 | random(seed=(ansible_machine_id), start=7) }}"

```

Be aware that you need to seed _all_ such “idempotent random” calls because you can’t guarantee order of evaluation etc.

I’m sure something similar could work for your hosts’ ports, especially combined with @IPvSean 's excellent advice with respect to port ranges.

---

<div class="post-metadata">

**Author:** ![su8319](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/su8319/32/1285_2.png) [@su8319](https://forum.ansible.com/u/su8319)\
**Post date:** [October 26, 2023, 9:56am UTC](https://forum.ansible.com/t/properly-generate-random-ports/1872/4 "2023-10-26T09:56:30Z")

</div>

Thanks to both of you for your help 😀

---

<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:** [November 25, 2023, 9:56am UTC](https://forum.ansible.com/t/properly-generate-random-ports/1872/5 "2023-11-25T09:56:35Z")

</div>

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