set ansible-playbook user varialbe dynamically bas

2019-05-25 18:16发布

问题:

I'm creating an ansible playbook that goes through a group of AWS EC2 hosts and install some basic packages. Before the playbook can execute any tasks, the playbook needs to login to each host (2 type of distros AWS Linux or Ubuntu) with correct user: {{ userXXX }} this is the part that I'm not too sure how to pass in the correct user login, it would be either ec2-user or ubuntu.

   - name: setup package agent 
  hosts: ec2_distros_hosts


  user: "{{ ansible_user_id }}"

  roles:
    - role: package_agent_install

I was assuming ansible_user_id would work based of the reserved variable from ansible but that is not the case here. I don't want to create 2 separate playbook for different distros, is there an elegant solution to dynamically lookup user login and used as the user: ?

Here is the failed cmd with unknown user ansible-playbook -i inventory/ec2.py agent.yml

回答1:

You have several ways to accomplish your task:

1. Create ansible user with the same name on every host

If you have one, you can use user: ansible_user in your playbook.

2. Tag every host with suitable login_name

You can create a tag (e.g. login_name) for every ec2 host and specify user in it. For Ubuntu hosts – ubuntu, for AWS Linux hosts – ec2-user. After doing so, you can use user: "{{ec2_tag_login_name}}" in your playbook – this will take username from login_name tag of the host.

3. Patch the ec2.py script for your needs

It seems there is no decent way to get exact platform name from AMI, but you can use something like this:

image_name = getattr(conn.get_image(image_id=getattr(instance,'image_id')),'name')
login_name = 'user'
if 'ubuntu' in image_name:
    login_name = 'ubuntu'
elif 'amzn' in image_name:
    login_name = 'ec2-user'
setattr(instance, 'image_name', image_name)
setattr(instance, 'login_name', login_name)

Paste this code just before self.add_instance(instance, region) in ec2.py with the same indentation. It fetches image name and do some guess work to define login_name. Then you can use user: "{{ec2_login_name}}" in your playbook.



回答2:

You can set variables based on EC2 instance tags. If you tag instances with the distro name then you can set Ansible's ssh username for each distro via group_vars files.

Example group_vars file for Ubuntu relative to your playbook: group_vars/tag_Distro_Ubuntu.yml

---
ansible_user: ubuntu

Any instances tagged Distro: Ubuntu will connect with the ubuntu user. Create a separate group_vars file per distro tag to accommodate other distros.