mapping AWS 'Username' tag to ansible_user inventory var?

Hi

I'm using the ec2.py dynamic inventory, and this appears to work well.
My deployment consists of several different distros, and so the
ansible_user is different across the instances.
While instantiating from different AMI, I am adding a "Username" tag
to the instances.
I then include a second inventory, to map these:

# Map usernames
[tag_Username_ubuntu:vars]
ansible_user=ubuntu

[tag_Username_admin:vars]
ansible_user=admin

[tag_Username_admin:centos]
ansible_user=centos

This works fine, but I wonder if there is a way to do without this extra file.
Basically I'm looking to populate ansible_user from the last part of
the tag_Username_ubuntu/admin/etc.
Some kind of regex replacement, or...?

thanks :slight_smile:

This last entry should of course read:

[tag_Username_centos:vars]
ansible_user=centos

I had a look at the ec2.py code and I was able to add this as a feature:

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

thx!!

This is one of AWS’ stranger choices, having different default usernames on different distros of the same operating system. Imagine if you got “Administrator” on Windows 7, “Admin” on Windows 8, and “Root” on Windows10…

I can’t help you with the vars, but here are some oter ideas:

If you bake your own AMIs, the simplest solution by far is to set up your own user on the AMIs you bake. The only special things about the default users are that they have the private ssh key in ~/.ssh, they are in the sudoers file, they are able to do passwordless sudo, and they are in a particular set of groups. Setting up a user of your own with a well-known name common to all your instances can be done in userdata quite easily. It’s a security benefit too - especially if you take the default user OUT of the sudoers file. Also, it is rapidly and painfully obvious if an instance has not been based on one of your own AMIs. A related method would be to change the user on one distro to be the same as the user on the other, e.g., change all your “ubuntu” users to be called “ec2-user”. Half the effort :slight_smile:

Assuming you don’t change the usernames, then an alternative that I like because it is dynamic, is to attempt to access an instance using first one, then the other username. Whichever one works is the right one for that instance :slight_smile: I confess though that I have not implemented that in Ansible, just in various utility scripts.

A third alternative, also only possible if you bake your own AMIs, is to make sure that an OS identifier is in the AMI name. Then you can figure out what the OS is dynamically, even on a stopped instance, by getting the instance details and checking the AMI name. I have a script that sets up my ~/.ssh/config file with entries for every instance, and it decides whether to set the user parameter to ubuntu or ec2-user based on AMI info in the instance descriptions.

A fourth alternative - also simple to do in userdata - is to have each instance “phone home” as it launches. For example, if you have a webserver somewhere you could have your new Ubuntu instances use curl to request https://domain?HiIAmUbuntuAt10.10.100.12 or whatever, while your Centos instances request https://domain?HiIAmCentosAt_11.11.102.15. It’ll stand out nicely in your webserver logs. The nice thing about this solution is that you can dump almost unlimited amounts of info out of the instance like that - anything the instance can know, it can communicate.

If you really want to go old-school (not to mention a bit secret squirrel), use ping with the -p option, and send 0x5555 for Ubuntu and 0x4343 for Centos to a listener somewhere. Or send 85-byte packets from Ubuntu and 67-byte packets from Centos :slight_smile:

Regards, K.