How to replicate local user account to remote system?

I feel like this probably comes up a lot and is a solved problem, but my Google-fu is failing me.

I’m using Ansible with vagrant to create development virtual machines.

The one thing that bugs me a little (and this was true with our previous Chef-based solution as well to be fair) is that I have to log into this system as a user called “vagrant” and I don’t have my preferred dotfiles and what-not. So this means my vim isn’t the way I like it and if I do a git commit it’s going to show up in the log as “vagrant”.

This is of course all solvable by copying my dotfiles over; I could even create an account with my name. I haven’t bothered to do this, because I’m lazy to do this manually. Like most developers, I refuse to do a few minutes of manual work if I can spend a couple of hours and make it automated :wink: And of course this is Ansible, so it should totally be possible to do this – I’m just missing a bit of knowledge to make it happen.

So if my user on the local system that I’m running ansible on is “marca” – how do I get at this information? I couldn’t find a built-in variable for this. Reading ansible_env.USER is going to get me the USER on the remote system; not what I want.

My current, possibly hacky solution is to invoke ansible-playbook with --extra-vars=“invoking_user=$USER” and then my playbook can do:

  • name: Create user for invoking user
    sudo: true
    user: name={{ invoking_user }} comment=“John Doe” uid=1040 group=admin password=xxx
    tags:

  • user

  • name: Set authorized_key for invoking user
    sudo: true
    authorized_key: user={{ invoking_user }} key=“{{ lookup(‘file’, “/Users/marca/.ssh/id_rsa.pub”) }}”
    tags:

This is pretty crude, as ideally I wouldn’t have to pass the --extra-vars and ideally there would be some existing solution that sets the user, comment, uid, group, etc. all automatically using the local values. Note that I also want to copy my ssh key but I can’t figure out how to replace “marca” with {{ invoking_user }} – that doesn’t work, because it would nest the double curly brace syntax so it won’t get expanded. Actually it would be even better to use $HOME but it’s the same problem.

I guess the ideal would be some kind of module that replicates my local user to the remote system, including uid and ssh key.

If there wasn’t such a role/playbook available, I might write it, if I knew how.

Would be grateful for any tips to point me in the right direction.

Marc

“This is of course all solvable by copying my dotfiles over; I could even create an account with my name. I haven’t bothered to do this, because I’m lazy to do this manually”

Write a playbook? :slight_smile:

Most people would keep their dotfiles as a repo, managed centrally, rather than trying to discover them.

It’s more explicit, and translates over to Ansible easier than trying to discover them from some arbitrary remote system, copy them back, move them to the other, etc.

“This is of course all solvable by copying my dotfiles over; I could even create an account with my name. I haven’t bothered to do this, because I’m lazy to do this manually”

Write a playbook? :slight_smile:

Yes. I would like to do this. I kinda sorta have the beginnings of something, but it’s perhaps a little clunky. My playbook has:

vars_files:

  • group_vars/user.yml

and then group_vars/user.yml has my local settings:

invoking_user:
name: marca
full_name: Marc Abramowitz
uid: 502
home: /Users/marca
ssh_public_key: /Users/marca/.ssh/id_rsa.pub

and then I do this in my playbook:

tasks:

  • name: Create user for invoking user
    sudo: true

debug: var=invoking_user

user:
name: “{{ invoking_user.name }}”
comment: “{{ invoking_user.full_name }}”
uid: “{{ invoking_user.uid }}”
tags:

  • user

  • name: Set authorized_key for invoking user
    sudo: true
    authorized_key:
    user: “{{ invoking_user.name }}”
    key: “{{ lookup(‘file’, invoking_user.ssh_public_key) }}”
    tags:

  • user

I would’ve preferred something more automatic, but I guess I could always have a simple Python configure.py script that generates group_vars/user.yml

Most people would keep their dotfiles as a repo, managed centrally, rather than trying to discover them.

It’s more explicit, and translates over to Ansible easier than trying to discover them from some arbitrary remote system, copy them back, move them to the other, etc.

Yeah that’s a good point. And in fact I do have my dotfiles in a git repo, so maybe checking them out is better. The alternative is to rsync them from the host running ansible.