Changing ssh port with Ansible

Nope (and also, do not want this), you'll have to update your
inventory file to reference the new ports.

Michael DeHaan wrote:

Nope (and also, do not want this), you'll have to update your
inventory file to reference the new ports.

You can do this on your own by creating an action_plugin that returns a
dict containing {'ansible_facts': {'ansible_ssh_port': int(module_args)}}
for instance.

Daniel

Though why would you? Go write a plugin when you can edit a file?

-- Michael

Here are a few things that I have tried, which all failed:

  1. Use the ‘port’ play attribute with a variable:
  • hosts: all
    port: $ssh_port

The same approach works with hosts, e.g. hosts: $hosts, but not with port, which gives me:
ValueError: invalid literal for int() with base 10: ‘${ssh_port}’

This would have been nice, especially if it could be overridden using the --extra-vars CLI option.

  1. Use the --remote-port CLI option. Found out the option was removed, although --user is available.

Like the OP, I want to set arbitrary ports for my hosts while still being able to bootstrap them when they are first deployed using the default ssh port. I want ssh tasks to still work using the new port so it can keep checking that everything is in place and sshd_config hasn’t changed since initial deployment. After all, ansible’s ability to bootstrap machines is one of its most attractive features. Inflexible ssh port setting is an annoyance.
Editing the inventory every time an initial deployment is done is just annoying.

I think a --port option would complement the --user option nicely and keep the playbooks intact. It should override any ports set in the inventory.

Any other solutions that do not involve editing the inventory?

It means the value was not templated, and because of that it was not an integer. I'll look into creating two patches, one for templating and the other for making sure the exception is properly handled as well.

Pull-requests:

  - #1649 (https://github.com/ansible/ansible/pull/1649)
  - #1650 (https://github.com/ansible/ansible/pull/1650)

Kind regards,

Thanks Dag.
Will check it out.

I tried a fresh checkout which includes this patch:

(Allow the remote port to be templated per play)

I still get the message:

site-packages/ansible/runner/init.py", line 384, in _executor_internal_inner
actual_port = int(actual_port)
ValueError: invalid literal for int() with base 10: ‘${ssh_port}’

Right, at this point only variables defined in the playbook are taken into account. I made a new patch moving the templating down to the runner.

     https://github.com/ansible/ansible/pull/1651

And this time I tested it with host variables, not just playbook variables.

Thanks for the feedback,

Ok, the official word is that using #1649 you can now do -e 'ssh_port=22', or you can use ansible_ssh_port variable. The change in #1651 will not be merged. (Plenty of options, no need to create another one)

Thanks Dag..

I commented on the pull request, explaining my use case. Here it is again
for people following this thread:

The use case that I still cannot implement with current options is: by
default use a non-standard ssh port, but allow resetting it back to port 22
from the command line.

Can I do this without this patch?

I was hoping I can use every host's or group's ssh_port as set in their
host_vars or group_vars, then override them from the command line using -e
ssh_port=22.

Thanks Dag…

I commented on the pull request, explaining my use case. Here it is again for people following this thread:

The use case that I still cannot implement with current options is: by default use a non-standard ssh port, but allow resetting it back to port 22 from the command line.

Can I do this without this patch?

I was hoping I can use every host’s or group’s ssh_port as set in their host_vars or group_vars, then override them from the command line using -e ssh_port=22.

For future reference, I’d just like to point it that there is a way around this now.

You can set your default ports in the inventory, and override them from the command line using the --extra-vars option:
ansible-playbook […] -e ansible_ssh_port=22

This used not to affect GATHERING FACTS (which may appear as though it did not affect anything since the failure would abort execution), but not it does, thanks to daniel_hozac.

FYI -- It's ansible_ssh_port, not ssh_port

Well, ssh_port is defined in my group_vars, and I was trying to use it, but
'port: $ssh_port' in the playbook doesn't work.
I now do not have 'port:' in the playbook. Instead, I set my non-standard
default port in the inventory and override it using -e ansible_ssh_port,
which used not to work (GATHERING FACTS ignored it) but now it does work.

Banana_tree_firetruck as a variable also does not work.

– Michael

It's ansible_ssh_port, not Banana_tree_firetruck.

What are you getting at?

You left off the ansible_ which matters

– Michael

I left it off initially because I was trying to use my own variable,
ssh_port, which I define in the group_vars file tree, and use in the
sshd_config template. I was hoping I could reuse the same variable to
specify the ssh connection port.

I am not trying to do that anymore, and am satisfied with ansible_ssh_port,
although my attempts uncovered an issue with ansible_ssh_port, where it is
not used for the GATHERING FACTS task, which happens to be the first task,
so when it fails, execution aborts, and it *looks* like ansible_ssh_port is
not being recognized at all. With that issue fixed (ansible_ssh_port is
used for GATHERING FACTS now), ansible_ssh_port does what I want, and
ssh_port (my own variable) is only used for templating.

I also realize now that using the same template variable for connections
will not work: if a remote machine is initially using a different port,
trying to change it by setting my template variable to a different port
will cause the connection to fail (if it uses the same variable to connect).

I hope I clarified things. Again, I was not expecting ssh_port to do what
ansible_ssh_port does. I was trying to over-use my own variable for things
it shouldn't be doing.

I’ve found I can’t override ansible_ssh_port at all. My hosts file defines ansible_ssh_port at the top, set to my custom port.

I’ve tried overriding it to set it 22 for new hosts on the new host’s line in the hosts file, and also on the command line using -e ansible_ssh_port=22, and neither of these changes seem to have an effect. It always connects to the ansible_ssh_port defined at the top of the hosts file.