You could try a local_action on the hosts to see if you can connect to the respective ports and register the one that succeeds and set that as a fact. You want to turn off gather facts because otherwise the setup module will fail when it tries to connect with the hosts which have already been reconfigured. Once you've done this play just add others below with gather_facts and all the rest.
- name: determine ssh port
hosts: all
gather_facts: false
vars:
custom_ssh_port: 222
tasks:
- name: test default ssh port
local_action: wait_for port=22 timeout=5 host={{inventory_hostname}}
register: default_ssh
ignore_errors: true
- name: set ansible_ssh_port to default
set_fact: ansible_ssh_port=22
when: default_ssh.elapsed < 5
- name: test ssh on high port
local_action: wait_for port={{custom_ssh_port}} timeout=5 host={{inventory_hostname}}
register: high_ssh
when: default_ssh.elapsed >= 5
ignore_errors: true
- name: set ansible_ssh_port high
set_fact: ansible_ssh_port={{custom_ssh_port}}
when: default_ssh.elapsed >= 5 and high_ssh.elapsed < 5
It was pointed out to me that this will blow out the time for playbooks where you use this. You could also set ansible_ssh_port in the vars section of plays that should only be run on hosts with reconfigured ssh port. e.g.
- name: change ssh ports
tasks:
- name: edit sshd_config
lineinfile ..
notify: restart ssh
handlers:
- name: restart ssh
service: sshd state=restarted
- name: continue setup
vars:
- ansible_ssh_port : 5422
tasks:
...