Inventory-based SSH proxy/bastion host support, ssh_args + docs #9477

Closed
wants to merge 93 commits into
from

Conversation

Projects
None yet
@nitzmahone
Member

nitzmahone commented Nov 4, 2014

Supersedes #9122

First-class inventory var support for proxy/bastion/jump hosts seems to be increasingly requested. I've tried to make it reasonably comprehensive and well-documented, though I intentionally omitted proxy_password support (had some trouble stacking the file descriptors for the two-level-deep sshpass).

(CC @sivel)

@jimsmith

This comment has been minimized.

Show comment
Hide comment
@jimsmith

jimsmith Nov 4, 2014

+1 for this, it's a request that I rarely get asked but it's becoming more frequently.

jimsmith commented Nov 4, 2014

+1 for this, it's a request that I rarely get asked but it's becoming more frequently.

@mpdehaan

This comment has been minimized.

Show comment
Hide comment
@mpdehaan

mpdehaan Nov 5, 2014

Contributor

So this has been discussed a bit recently on the devel list, and I believe there may be some competing implementations, can you stop by ansible-devel to discuss?

Thanks!

Contributor

mpdehaan commented Nov 5, 2014

So this has been discussed a bit recently on the devel list, and I believe there may be some competing implementations, can you stop by ansible-devel to discuss?

Thanks!

@tzz

This comment has been minimized.

Show comment
Hide comment
@tzz

tzz Nov 7, 2014

I've needed this so definitely happy to see an implementation!

tzz commented Nov 7, 2014

I've needed this so definitely happy to see an implementation!

@quinot

This comment has been minimized.

Show comment
Hide comment
@quinot

quinot Nov 9, 2014

Contributor

I'm just starting to use Ansible and was wondering whether this feature existed, or how to implement it if not. Would love to have this merged!

Contributor

quinot commented Nov 9, 2014

I'm just starting to use Ansible and was wondering whether this feature existed, or how to implement it if not. Would love to have this merged!

@rmetzler

This comment has been minimized.

Show comment
Hide comment
@rmetzler

rmetzler Nov 25, 2014

Contributor

I really want this feature in Ansible, but after looking at the code, I would think you shouldn't add that many arguments to connect. Maybe use *args and **kwargs.

Contributor

rmetzler commented Nov 25, 2014

I really want this feature in Ansible, but after looking at the code, I would think you shouldn't add that many arguments to connect. Maybe use *args and **kwargs.

@nitzmahone

This comment has been minimized.

Show comment
Hide comment
@nitzmahone

nitzmahone Nov 26, 2014

Member

Funny, that was my first thought when I looked at it too- "why are they passing all these args positionally?" I looked at the history, and the last couple of args were added later. I assumed there was some reason to do with the abstraction of the Connect stuff, and went for the "when in Rome" approach, but if reviewers feel the same way, I'm happy to convert it to use named args instead. It is much cleaner, IMHO.

Member

nitzmahone commented Nov 26, 2014

Funny, that was my first thought when I looked at it too- "why are they passing all these args positionally?" I looked at the history, and the last couple of args were added later. I assumed there was some reason to do with the abstraction of the Connect stuff, and went for the "when in Rome" approach, but if reviewers feel the same way, I'm happy to convert it to use named args instead. It is much cleaner, IMHO.

@rmetzler

This comment has been minimized.

Show comment
Hide comment
@rmetzler

rmetzler Nov 26, 2014

Contributor

I want to say, I just said this as a user who needs this feature and searched through the different threads / PRs. I really don't have any authority regarding Ansible.

Contributor

rmetzler commented Nov 26, 2014

I want to say, I just said this as a user who needs this feature and searched through the different threads / PRs. I really don't have any authority regarding Ansible.

@igoratencompass

This comment has been minimized.

Show comment
Hide comment
@igoratencompass

igoratencompass Dec 4, 2014

I've been waiting for this kind of module definitely needed for dynamic aws inventory of mixed public and private instances! Can we please have this released asap???

I've been waiting for this kind of module definitely needed for dynamic aws inventory of mixed public and private instances! Can we please have this released asap???

@christophgysin

This comment has been minimized.

Show comment
Hide comment
@christophgysin

christophgysin Dec 11, 2014

I'm also looking forward to this!

I'm also looking forward to this!

+ proxy_args += ["-o", "User="+self.proxy_user]
+ proxy_args += ["-o", "ConnectTimeout=%d" % self.runner.timeout]
+
+ self.common_args += ["-o", "ProxyCommand=ssh {proxy_host} {proxy_args} -W %h:%p".format(proxy_host=self.proxy_host, proxy_args=" ".join(proxy_args))]

This comment has been minimized.

@christophgysin

christophgysin Dec 12, 2014

ssh -W asumes openssh-5.4 or later. Older versions of openssh need netcat to achieve this.

@christophgysin

christophgysin Dec 12, 2014

ssh -W asumes openssh-5.4 or later. Older versions of openssh need netcat to achieve this.

This comment has been minimized.

@nitzmahone

nitzmahone Dec 12, 2014

Member

Yeah, I considered using netcat as a lowest-common-denominator approach. However, I saw some complaints around the openssh community about instability with various versions of netcat that the -W mode attempts to address (don't have a reference to share off the top of my head- it was several months ago). If a bastion host can't be upgraded to a reasonably recent version of openssh, the ssh_args escape hatch is still there- I think that beats the alternatives of:

  • forcing everyone to use a potentially unstable approach that has another dependency (netcat)
  • adding yet another mode-changing variable (ansible_ssh_proxy_mode=netcat or some such blah)
  • version-sniffing ssh (rife with issues)
@nitzmahone

nitzmahone Dec 12, 2014

Member

Yeah, I considered using netcat as a lowest-common-denominator approach. However, I saw some complaints around the openssh community about instability with various versions of netcat that the -W mode attempts to address (don't have a reference to share off the top of my head- it was several months ago). If a bastion host can't be upgraded to a reasonably recent version of openssh, the ssh_args escape hatch is still there- I think that beats the alternatives of:

  • forcing everyone to use a potentially unstable approach that has another dependency (netcat)
  • adding yet another mode-changing variable (ansible_ssh_proxy_mode=netcat or some such blah)
  • version-sniffing ssh (rife with issues)
@anthcourtney

This comment has been minimized.

Show comment
Hide comment
@anthcourtney

anthcourtney Jan 16, 2015

Is there a timeline for this feature progressing / being integrated?

Is there a timeline for this feature progressing / being integrated?

@rmetzler

This comment has been minimized.

Show comment
Hide comment
@rmetzler

rmetzler Jan 16, 2015

Contributor

For everyone needing a workaround fast, this is a great tutorial: http://alexbilbie.com/2014/07/using-ansible-with-a-bastion-host/

But I also would prefer first class support in Ansible.

Contributor

rmetzler commented Jan 16, 2015

For everyone needing a workaround fast, this is a great tutorial: http://alexbilbie.com/2014/07/using-ansible-with-a-bastion-host/

But I also would prefer first class support in Ansible.

@mpeters

This comment has been minimized.

Show comment
Hide comment
@mpeters

mpeters Jan 16, 2015

Contributor

That approach only works when you have a single bastion server for all your environments. This won't work if you have a separate bastion for say production, staging and integration.

Contributor

mpeters commented Jan 16, 2015

That approach only works when you have a single bastion server for all your environments. This won't work if you have a separate bastion for say production, staging and integration.

@bcoca

This comment has been minimized.

Show comment
Hide comment
@bcoca

bcoca Jan 17, 2015

Member

@mpeters it does, you just need to specify the diff bastions per host or host pattern (this is where naming conventions can help a lot).

Member

bcoca commented Jan 17, 2015

@mpeters it does, you just need to specify the diff bastions per host or host pattern (this is where naming conventions can help a lot).

@mpeters

This comment has been minimized.

Show comment
Hide comment
@mpeters

mpeters Jan 17, 2015

Contributor

That's assuming you are naming your servers. How would you handle just IP addresses (since these are livestock, not pets) in different VPCs? The IPs can be repeated for a different environment.

Also, how would you hook this up with Tower? (You'd need multiple Tower installs right?) Multiple Tower installs?

What about a single environment that uses multiple VPCs for PCI, etc?

Contributor

mpeters commented Jan 17, 2015

That's assuming you are naming your servers. How would you handle just IP addresses (since these are livestock, not pets) in different VPCs? The IPs can be repeated for a different environment.

Also, how would you hook this up with Tower? (You'd need multiple Tower installs right?) Multiple Tower installs?

What about a single environment that uses multiple VPCs for PCI, etc?

@bcoca

This comment has been minimized.

Show comment
Hide comment
@bcoca

bcoca Jan 17, 2015

Member

no need for multiple ansible/tower installs, one thing you can do is set ssh args per group/host/inventory, passing specific ssh config for each.

In any case, this is a workaround, the patch is a good step into a more integrated solution.

Member

bcoca commented Jan 17, 2015

no need for multiple ansible/tower installs, one thing you can do is set ssh args per group/host/inventory, passing specific ssh config for each.

In any case, this is a workaround, the patch is a good step into a more integrated solution.

@mpeters

This comment has been minimized.

Show comment
Hide comment
@mpeters

mpeters Feb 3, 2015

Contributor

Can you really set ansible_ssh_args per group/host/inventory (that would be great)? The documentation doesn't list it with the rest of the ansible_ssh_* args (http://docs.ansible.com/intro_inventory.html#list-of-behavioral-inventory-parameters) and the only place I see you can set it is in the ansible config file, which is global.

Contributor

mpeters commented Feb 3, 2015

Can you really set ansible_ssh_args per group/host/inventory (that would be great)? The documentation doesn't list it with the rest of the ansible_ssh_* args (http://docs.ansible.com/intro_inventory.html#list-of-behavioral-inventory-parameters) and the only place I see you can set it is in the ansible config file, which is global.

@rmetzler

This comment has been minimized.

Show comment
Hide comment
@rmetzler

rmetzler Feb 4, 2015

Contributor

I had a quick look into the source and it seems like ssh_args is respected in 1.8.2. Not sure since when, though.

https://github.com/ansible/ansible/blob/v1.8.2/lib/ansible/constants.py#L165
https://github.com/ansible/ansible/blob/v1.8.2/lib/ansible/runner/connection_plugins/ssh.py#L55-L64

Contributor

rmetzler commented Feb 4, 2015

I had a quick look into the source and it seems like ssh_args is respected in 1.8.2. Not sure since when, though.

https://github.com/ansible/ansible/blob/v1.8.2/lib/ansible/constants.py#L165
https://github.com/ansible/ansible/blob/v1.8.2/lib/ansible/runner/connection_plugins/ssh.py#L55-L64

@mpeters

This comment has been minimized.

Show comment
Hide comment
@mpeters

mpeters Feb 4, 2015

Contributor

But that just shows that it's configurable globally from the ansible configuration file. Not that it's possible to specify per group/host/inventory, right?

Contributor

mpeters commented Feb 4, 2015

But that just shows that it's configurable globally from the ansible configuration file. Not that it's possible to specify per group/host/inventory, right?

@snackycracky

This comment has been minimized.

Show comment
Hide comment
@snackycracky

snackycracky Feb 7, 2015

I also need the 'Ansible EC2 external inventory script' to detect the internal hosts. http://docs.ansible.com/intro_dynamic_inventory.html#example-aws-ec2-external-inventory-script
it only finds the jump-hosts for each environment but not the internal servers.

I also need the 'Ansible EC2 external inventory script' to detect the internal hosts. http://docs.ansible.com/intro_dynamic_inventory.html#example-aws-ec2-external-inventory-script
it only finds the jump-hosts for each environment but not the internal servers.

jimi-c and others added some commits Mar 10, 2015

preliminary privlege escalation unification + pbrun
- become constants inherit existing sudo/su ones
- become command line options, marked sudo/su as deprecated and moved sudo/su passwords to runas group
- changed method signatures as privlege escalation is collapsed to become
- added tests for su and become, diabled su for lack of support in local.py
- updated playbook,play and task objects to become
- added become to runner
- added whoami test for become/sudo/su
- added home override dir for plugins
- removed useless method from ask pass
- forced become pass to always be string also uses to_bytes
- fixed fakerunner for tests
- corrected reference in synchronize action plugin
- added pfexec (needs testing)
- removed unused sudo/su in runner init
- removed deprecated info
- updated pe tests to allow to run under sudo and not need root
- normalized become options into a funciton to avoid duplication and inconsistencies
- pushed suppored list to connection classs property
- updated all connection plugins to latest 'become' pe

- includes fixes from feedback (including typos)
- added draft docs
- stub of become_exe, leaving for future v2 fixes
fixed traceback when x_user implicitly sets the become method
Fixes #10430

Also removed redundant resolution of sudo/su for backwards compatibility which
confused the conflict detection code.
fixes password error detection for ssh connection plugin
removes sycnronize test that does not work with current sudo setup
Fixes #10434
@terbolous

This comment has been minimized.

Show comment
Hide comment
@terbolous

terbolous Mar 24, 2015

Thanks @nitzmahone, I'm testing this, but I seem to have trouble getting Ansible to wait for the proxycommand to finish.
I get this error message blazingly fast: "fatal: [r-4-VM] => SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh"
but if I try the same SSH command manually it works just fine..

Thanks @nitzmahone, I'm testing this, but I seem to have trouble getting Ansible to wait for the proxycommand to finish.
I get this error message blazingly fast: "fatal: [r-4-VM] => SSH Error: data could not be sent to the remote host. Make sure this host can be reached over ssh"
but if I try the same SSH command manually it works just fine..

bcoca and others added some commits Mar 24, 2015

Make run_command() work when we get byte str with non-ascii character…
…s (instead of unicode type like we were expecting)

Fix and test.

Fixes #10536
Update README.md
I think since ansible and the ansible-modules have been splitted --recursive should be added
now ansible ignores tempate errors on passwords
they could be caused by random character combinations, fixes #10468
Made ansible_ssh_args runtime-settable, added proxy_host, port, user,…
… and private_key_file support + docs

Only works in OpenSSH, added warning to paramiko if these values are encountered there.
@bcoca

This comment has been minimized.

Show comment
Hide comment
@bcoca

bcoca Jun 1, 2015

Member

I was thinking about integrating this soon now that v2 is almost 'there', but needs massive rebase, should probably wait till v2 is in place in devel

Member

bcoca commented Jun 1, 2015

I was thinking about integrating this soon now that v2 is almost 'there', but needs massive rebase, should probably wait till v2 is in place in devel

@bcoca

This comment has been minimized.

Show comment
Hide comment
@bcoca

bcoca Jun 1, 2015

Member

the other thing I wanted to do is move away from having ansiible_ssh and go for ansible_connection (or at least conn) as the variable naming, so we can actually use the same vars for other protocols w/o asking 'why does winrm use ansible_ssh_user?'

Member

bcoca commented Jun 1, 2015

the other thing I wanted to do is move away from having ansiible_ssh and go for ansible_connection (or at least conn) as the variable naming, so we can actually use the same vars for other protocols w/o asking 'why does winrm use ansible_ssh_user?'

@nitzmahone

This comment has been minimized.

Show comment
Hide comment
@nitzmahone

nitzmahone Jun 1, 2015

Member

Yeah, this will probably just end up being a whole new PR for v2 (adding support for proxy chaining, new arg naming, etc), but now that I know cchurch's trick for smuggling vars in v1, I might backport the chaining stuff to this one as a standalone connection plugin. Let's leave this one open for now, and I'll try to prioritize the v2 work and backport.

Member

nitzmahone commented Jun 1, 2015

Yeah, this will probably just end up being a whole new PR for v2 (adding support for proxy chaining, new arg naming, etc), but now that I know cchurch's trick for smuggling vars in v1, I might backport the chaining stuff to this one as a standalone connection plugin. Let's leave this one open for now, and I'll try to prioritize the v2 work and backport.

@sivel

This comment has been minimized.

Show comment
Hide comment
@sivel

sivel Oct 1, 2015

Member

This PR was superseded by the already merged #11908

Member

sivel commented Oct 1, 2015

This PR was superseded by the already merged #11908

@sivel sivel closed this Oct 1, 2015

@ansibot ansibot added feature and removed feature_pull_request labels Mar 4, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment