Mike A
Mike A

Reputation: 510

Adding multiple users to a linux system with Ansible

I've build a lovely set of Ansible playbooks that are used by packer to build our Linux images for software builds in AWS. They're so nice that now a bunch of other teams want to use them too.

The current setup is a playbook that calls a lot of roles. Some of those roles do system level config and others create the user defined by the var jenkins_user and set up various programs for it (conan, npm, jfrog)

Since my roles are already set up to act on a single variable, it should not be too difficult to modify them to act on an array of usernames. I'm trying to decide on the best approach of defining the multiple users.

I'll need a small number of vars for each user:

I'm trying to decide the best way to store all this. My first thought is a hash of users and data:

build_users:
  user1:
    password: "{{vault_user1_pass}}"
    private_key_file:  "{{vault_user1_key}}"
    auth_keys_file:  "{{auth_keys_file}}"

  user2:
    password: "{{vault_user2_pass}}"
    private_key_file:  "{{vault_user2_key}}"
    auth_keys_file:  "{{user2_auth_keys_file}}"

This would have me gatekeeping user data, which isn't necessarily a bad thing.

The second thing I thought of was just to have a directory with each user in their own file: user1.yml contains

user1:
  password: "{{vault_user1_pass}}"
  private_key_file:  "{{vault_user1_key}}"
  auth_keys_file:  "{{auth_keys_file}}"

then user2.yml contains

user2:
  password: "{{vault_user2_pass}}"
  private_key_file:  "{{vault_user2_key}}"
  auth_keys_file:  "{{user2_auth_keys_file}}"

However, it seems that if I try to add additional files to the buildusers variable, include_vars overwrites it instead of adding:

- name: load buildusers files
  include_vars:
    dir: buildusers
    name: buildusers

This results in the buildusers variable only having the last files data in it.

Upvotes: 0

Views: 3112

Answers (1)

Romain
Romain

Reputation: 21948

include_vars will overwrite the content of the buildusers variables with the values of the variables located in all the files of the buildusers folder.

If you want to merge variables defined in a central file (the playbook or a variable file) with the values defined in a list of files in a folder you have to combine manually the two variables.

- name: Combine variables
  hosts: localhost
  connection: local
  gather_facts: no
  vars:
    buildusers_default:
      user3:
        password: "pass"
        private_key_file:  "priv"
        auth_keys_file:  "auth"

  tasks:
   - name: load buildusers files
     include_vars:
      dir: buildusers
      name: buildusers_files
   - name: combine variables
     set_fact:
       buildusers: "{{ buildusers_default | combine(buildusers_files) }}"
   - name: debug
     debug: 
      var: buildusers

# ok: [127.0.0.1] => 
#   buildusers:
#     user1:
#       auth_keys_file: auth
#       password: pass
#       private_key_file: priv
#     user2:
#       auth_keys_file: auth
#       password: pass
#       private_key_file: priv
#     user3:
#       auth_keys_file: auth
#       password: pass
#       private_key_file: priv

The content of the folder buildusersbeing.

$ tree buildusers 
buildusers
├── user1.yml
└── user2.yml

Hope it helps.

Note

You can also check what's going on in the variable loading from files by registering a variable during the load and checking its value through the variable ansible_included_var_files.

  tasks:
   - name: load buildusers files
     include_vars:
      dir: buildusers
      name: buildusers_files
     register: check_load
   - name: debug
     debug:
       var: check_load.ansible_included_var_files

#  check_load.ansible_included_var_files:
#  - /home/romain/ansible/user1.yml
#  - /home/romain/ansible/user2.yml

Upvotes: 1

Related Questions