0
votes

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:

  • username
  • password
  • private key
  • authorized keys file

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.

1
Can you confirm what you mean by "if I try to add additional files to the buildusers variable"? What you've got here should load the contents of the 2 files into buildusers resulting in user1 and users2 members of the buildusers hash, and similarly any other users that are included. They will collide if you don't have unique values in the top level of each file, though.gaige
Nope. When include_vars runs it reads the first file, creates a hash buildusers with user1 as the only element, then reads the second file which recreates the hash buildusers with user2 as the only element, and so on. The end result is if I have multiple files, only the last one will be in the array.Mike A

1 Answers

1
votes

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