Hi,
is currently a way in which I can specify a different remote_user for
each host defined ? I'm running a rather non-conventional farm of
servers who have different everything (users, ports, keys, etc) :-S
Thank you
Hi,
is currently a way in which I can specify a different remote_user for
each host defined ? I'm running a rather non-conventional farm of
servers who have different everything (users, ports, keys, etc) :-S
Thank you
You can do this per play in a playbook. It doesn’t make sense to keep it with the host as you may be doing different things on a host from multiple different user IDs (root + some other user + some other OTHER user, etc)
It works And now comes the second question to which I couldn't
find an answer
from the documentation.
I have three hosts: h1.domain.org, h2.domain.org and h3.domain.org .
For each of
these hosts I want to run "apt-get update" and "apt-get -y -u
dist-upgrade". But I
don't have the same user on all three hosts. h1 and h2 has admin, while h3 has
sysadmin . How can I write a playbook with a minimum of redundant information ?
At this moment I have:
You can do this per play in a playbook. It doesn’t make sense to keep it
with the host as you may be doing different things on a host from multiple
different user IDs (root + some other user + some other OTHER user, etc)It works And now comes the second question to which I couldn’t
find an answer
from the documentation.
I have three hosts: h1.domain.org, h2.domain.org and h3.domain.org .
For each of
these hosts I want to run “apt-get update” and “apt-get -y -u
dist-upgrade”. But I
don’t have the same user on all three hosts. h1 and h2 has admin, while h3 has
sysadmin . How can I write a playbook with a minimum of redundant information ?
At this moment I have:
You should be able to pass in user with --extra-vars though like:
user: $user
ansible-playbook playbook.yml --extra-vars user=foo
Haven’t tested recently, but you can do other things like this. If not, we should make it possible, and it’s easy to do so.
Like Michael said, you could do this:
This has been requested before, I looked into it and it is tricky to
implement, when you also have diff passwords to ask for (per user or
user/host?). IIRC it was closed for lack of interest but that might change.
Patches are always welcome.
I had a patch for it but I reverted my push and lost the commit.
https://github.com/ansible/ansible/pull/1743#issuecomment-11222659
My last comment was probably lost from github because of the revert…
…
I gave up, this change without an API update will cause bad code that would likely break under threading conditions with the shared remote_user value being used dynamically.
The issue seems to root from the host file ideology.
I feel if the host file was treated more as a connection list, /a list of connection strings to the resources/, most of these issues would work them self out.
perhaps the connection strings could be in a format more similar to urls…
Added extra is you can parse them with pythons urllib
sftp://user@host:port/?setvarable=value
local://user@host:port/?setvarable=value
it is not only an issue of that, its prompting for the password (user and/or sudo) that is a bigger issue, specially if it is different per host.
The prompting part already works nicely. Both -k, --ask-pass and -K, --ask-sudo-pass prompt for a password.
I think having different users shouldn’t be an issue, simply ask for 1 user password and 1 sudo password and apply them to all hosts using the username in the config. That is, Hosts A,B and C might have users a, b and c but would have the same password or better, have a pre-shared key setup for each user+host combo. The user has control over setting their password on remote hosts through ssh and the passwd command or copying their public key over to the remote host. I think having different PASSWORDS along with different users per host is a use case Ansible should not consider.
how about something like…
ssh://user:pass@hostname:port/?setvar=value&sudo_user=value&sudo_pass=value
in this example the password is not set but is a variable…
when you go to connect to the service or make a system call that requires a value that is unknown /like ‘$1’/
ask the user for it. This will allow the value to be reused between the different connections as the user describes in a connection list.
added extra is you could use this same syntax on usernames and all the other values…
conceptually interesting, but I'm not really wanting to change the way
this works and am pretty happy with the present connection mechanism.
conceptually interesting, but I’m not really wanting to change the way
this works and am pretty happy with the present connection mechanism.
I have a patch that templates the remote_user and sudo_user using the host variables just before the connection is made. One can then very easily define multiple user roles on a host-by-host basis.
I don’t know if I’ve done it in the right way/place, or if more than host variables should be used. E.g. the whole of the “inject” dict from the runner could be a candidate, but since that’s not exposed I left it alone…
Anyway, would you be more amenable to this way of doing it?
If you’re wondering about a use-case, I’m setting up machines in which different users accounts need to fetch resources from a third-server. Ssh agent-forwarding doesn’t seem to work over sudo, but setting the user for a play based on the host means this can work very simply (as long as the local user’s public key is—temporarily—installed for the remote user’s account).
Michael.
I have a patch for multiple users… It seems to work well.
https://github.com/steverweber/ansible/commit/5c84fe4a4ad5832fc0c467acebff663468216443
However it breaks the API.
add user in host file like:
[libapp]
libapp@liba.uaterloo.ca
libdev@libd.uaterloo.ca
libsys@libs.uaterloo.ca
if the project maintainer thinks it would be worth my time to create a new format like my above post:
ssh://user2:$0@hostname:23/?sudo_user=admin&ansible_ssh_key=/bla/key&sudo_pass=$2
Then perhaps this weekend I’ll create a patch for it.
It will be rejected.
thanks.
Hi, I posted on exactly this issue earlier today, and I just found this thread.
The aspects of different user per host are all handled correctly by ssh with a localhost ~/.ssh/config file with a stanza like:
Host remotehost-as-mike
HostName remotehost.com
User mike
IdentityFile mike-remote/id_rsa
where you have added your id_rsa.pub key contents to the end of the robertvernonphillips.com/home/mike/.ssh/authorized_keys file and you have put your matching private key in
localhost:/home/localuser/.ssh/config/mike-remote/id_rsa. The path part ‘mike-remote’ is just some directory you create to hold the private key.
Then, you can do at any bash prompt $ ssh remotehost-as-mike
Now ssh finds the stanza with Host remothost-as-mike and uses its HostName to really connect to and also uses the User in that stanza. Your login goes unchallenged by a password prompt.
You can have as many different stanzas in .ssh/config using as many different made-up Host names, each paired with some combination of HostName (IP Address) and User. Ans ssh to any HostName “JustWorks”.
Now, since ansible has the ansible option --conection=ssh, just getting that option to work correctly should address all of the needs mentioned here. There is no need to modify the supported variable names in the ansible_host file and deal with the issue of how to support multiple host/user combinations in ansible itself.
If I can get some pointers from anyone who has given some thought to THIS approach of making --connecton=ssh work,then I would not be averse to diving into the code and trying to fix this.
Any thoughts?
Please regard my mention of robertvernonphillips.com to mean remotehost.com, and please bear with a few other typos.
In the ansible_hosts file, support of the connection=ssh variable to augment a ‘host name’ seems it would be a nice way to activate this new proposed behavior to use the .ssh/config file Host value to identify its stanza and derive the HostName and User for a connection.
This way the ansible_host file’s line for a host could indicate whether the ‘ssh “Host”’ name defined in a .ssh/config file stanza is the type of name that is indicated on that line. And with that, the ssh “HostName” and “User” values would be defined and derivable by ansible code.
As with a call to ansible, no specification of the connection value on an ansible_host line would default to the way ansible currently works - that is the “host” name specified in the ansible file would be a direct IP address or one that is in the /etc/hosts file or known by DNS.
Does this sound like a satisfactorily non-disruptive and workable design?
This is a very long thread and I'm not sure exactly what you mean to do.
In the ansible_hosts file, support of the connection=ssh variable to augment
a 'host name' seems it would be a nice way to activate this new proposed
behavior to use the .ssh/config file Host value to identify its stanza and
derive the HostName and User for a connection.
Is it that you want to specifying the connection type to be used for
the host in the inventory variable instead of setting the default in
the config file, or in the play?
This way the ansible_host file's line for a host could indicate whether the
'ssh "Host"' name defined in a .ssh/config file stanza is the type of name
that is indicated on that line. And with that, the ssh "HostName" and "User"
values would be defined and derivable by ansible code.
I don't want this.
The user is still something we explicitly set. One inventory record
could be accessed by a *variety* of user accounts sharing the same
inventory file, and using connection=ssh to imply
this behavior overloads the semantics.
As with a call to ansible, no specification of the connection value on an
ansible_host line would default to the way ansible currently works - that is
the "host" name specified in the ansible file would be a direct IP address
or one that is in the /etc/hosts file or known by DNS.Does this sound like a satisfactorily non-disruptive and workable design?
I don't agree with it for the above reasons...
First of all, thank you for helping me work though this.
This is a very long thread and I’m not sure exactly what you mean to do.
In the ansible_hosts file, support of the connection=ssh variable to augment
a ‘host name’ seems it would be a nice way to activate this new proposed
behavior to use the .ssh/config file Host value to identify its stanza and
derive the HostName and User for a connection.Is it that you want to specifying the connection type to be used for
the host in the inventory variable instead of setting the default in
the config file, or in the play?
To clarify what I had meant to propose:
My notion was that I -would- overload the semantics of connection=ssh, to granularize its scope per host, but only to convey that the named ‘host’ value on that particular inventory line would be used to look up a .ssh/config file’s defined Host and use its “User” setting, and failing that lookup, would be used to identify a host and user for the connection exactly as it is today.
My initial (false) assumption was that connect=ssh already worked that way, but working with ansible showed me that it does not.
So, I agree that yesterday’s proposal is not a workable approach for the reasons you gave later in your response.
It would be silly and disruptive to rewrite how the connection=ssh works now.
Since then, I have done some hacking on my ansible git repo and I have some success on implementing what I think is a better design anyway. I would appreciate any comments on it.
I have implemented a new ANSIBLE_TRANSPORT method, connection=use_ssh_hosts (better name suggestions are welcome) that works in a new way, as in the following ansible example:
$ ansible all -a "/bin/echo ‘ssh-user connection works here’ " --connection=use_ssh_hosts
where, ansible_hosts file inventory lines may optionally name Hosts that are in the executing user’s .ssh/config file.
(open issue: what is the best design to indicate a custom .ssh config file name).
This connection method, for each inventory line, first seeks the given ‘host’ value in .ssh/config as a Host value for a stanza there. If not found there, it continues to interpret the host value just like the default paramiko connection. (So maybe I should better use paramiko as some part of the new connection name to avoid confusion)
If a Host is found in .ssh/config , this connection method uses the stanza’s HostName value to use to connect to.
And if it finds a User value in its stanza, and no “-u otheruser” option was given to ansible, then it uses the .ssh/config file’s User value.
So the username priority is (1) -u option, (2) if a .ssh/config host was found with a User defined, use it; or (3) the default executing user.
I have not tested with ansible playbooks yet,but I think the connection option could work with them too, and just always give priority to any playbook’s explicitly defined user.
Similar treatment could be given to the Port in an .ssh/config Host stanza, but I am not addressing Port now. However, this connection method would relieve ansible-playbooks from needing to specify different users there… they would be derived values of the “Host” name.
If for some reason a new username on a host has to be used to perform all playbooks’ commands using that host, then that username would only have to change in one place in the .ssh/config file.
What I have working now suits my purposes, and if there is community interest, I would submit a patch along these lines, also incorporating further comments you may have.