Reputation: 317
I am writing an ansible playbook to provision a web server for me. Part of this process involves using the geerlingguy/ansible-role-security role (which I use to change the default ssh port). However, since the port changes, you cannot run the playbook over and over without changing the ansible_ssh_port variable. This seems to go against the whole point of idempotence, since you have to edit the playbook between runs. So I was wondering if there was a way to describe 2 ports for ansible to try. That way it would use port 22 the first time the script runs, but all other times it would use the other port.
I tried searching for ways to try different ports, but I couldn't find anything.
Upvotes: 4
Views: 2828
Reputation: 583
I had similar issue when it got failed in the gather fact step so I
Disabled gather facts in my playbook:
- hosts: all
gather_facts: no
vars:
refused: "port 22: Connection refused"
Added the tasks that checks the connection (default port is 22)
- name: Check ssh port
command: /bin/true
ignore_unreachable: yes
register: result
become: yes
- name: set ansible_port
set_fact:
ansible_port: {{ port }}
when: result.msg is defined and refused in result.msg
Upvotes: 3
Reputation: 3037
I had the similar scenario and found an workaround using wait_for and set_fact modules.
The idea is to set ansible_port
if a port is accessible.
Below is a sample that checks and sets a port specified using port1
variable. It's not necessary to use ignore_errors
or check the result in this sample scenario but could be useful if multiple ports needed to be tested. Also, delegate_to: localhost
may be used if a play is using a remote host.
Extend the implementation further using loops, block, rescue etc. as appropriate.
- name: test1
wait_for:
host: hostname
port: "{{ port1 }}"
timeout: 10
ignore_errors: yes
register: result
delegate_to: localhost
- name: set ansible_port
set_fact:
ansible_port: "{{ port1 }}"
when: not result.failed
Upvotes: 4