On Azure I've got a resource group with 1 vnet containing 2 servers; master and worker. Only master has a public IP.
Using "plain" Ansible I can manage both servers by defining worker's private IP as ansible_host
in the hosts
file and creating a group_vars
file with a ssh ProxyCommand arguments to apply for worker's group as described for a jump host here (note there are older methods too which involve direct ssh config but the group_vars approach is preferable I think as it is more portable to other users).
However this approach needs IPs to be hardcoded which isn't great on Azure. There's an azure_rm
inventory script or plugin (depending on Ansible version) which will provide dynamic inventory, avoiding the need for a hosts file, but how I can I do the equivalent of the ProxyCommand setup in this case?
This situation must be pretty common so I feel like I must be missing something.
To use a proxy / bastion host / jump host with Ansible, you need to specify ansible_ssh_common_args
in the ansible.cfg
.
ANSIBLE_SSH_COMMON_ARGS
, but this is missing due to this Ansible issue - not yet fixed as of Ansible 2.9.3.You can set this in a static inventory at the all
group level to experiment with this (easier to try this first without dynamic inventory) - see this blog for more details.
[all:vars]
ansible_ssh_common_args='-o ProxyCommand="ssh -W %h:%p my-bastion.example.com"'
Once you have this working, you can use dynamic inventory - create a file group_vars/all.yml
(test with static inventory first), converting the above INI format inventory to YAML (change the =
to :
).
ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p my-bastion.example.com"'
To ensure that ansible_host
in inventory output uses the private IP, you must use export AZURE_USE_PRIVATE_IP=true
(with the classic azure_rm.py
inventory script, haven't tried yet with plugin inventory).
ansible_host
may be null or set to a public IP / domain nameBe sure to test that the dynamic inventory is generating the right JSON data before you start using it for playbooks.
To check specific inventory values are mapping to the right hosts, try:
$ AZURE_USE_PRIVATE_IP=true ansible -i azure_rm.py mygroup -m debug -a var=ansible_host
test01 | SUCCESS => {
"ansible_host": "10.0.0.1"
}
You can also check Ansible SSH is working like this, with -vvvvv
when debugging:
$ AZURE_USE_PRIVATE_IP=true ansible -i azure_rm.py mygroup -m debug -a var=ansible_host
test01 | SUCCESS => {
"changed": false,
"ping": "pong"
}
I used the older 'classic' azure_rm.py
dynamic inventory here - the same approach works with the current plugin-based dynamic inventory (since Ansible 2.4, includes inventory caching).
To see dynamic inventory JSON output in either mode:
AZURE_USE_PRIVATE_IP=true python azure_rm.py | jq .
ansible-inventory -i azure.yml --graph
Use of jq is optional, it just formats the output for readability.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With