0
votes

I've got an ansible playbook for adding over 50 ssh-users for a packer ami build.

Here is how my /playbooks/roles/users/tasks/create_user.yml: looks like.

---
- name: "User {{ item.name }}"
  user:
    comment: "Add {{ item.name }} account"
    name: "{{ item.name }}"
    home: "/data/companies/project/{{ item.name }}"
    state: present
    uid: "{{ item.uid }}"
    group: company
    groups: company
    shell: /sbin/nologin
    state: present
    generate_ssh_key: no
    password: "{{ item.password }}"

- name: "Create home directory for {{ item.name }}"
  file:
    path: "/data/companies/project/{{ item.name }}"
    state: directory
    owner: "{{ item.name }}"
    group: company
    mode: 0700

Here's how /playbooks/roles/users/vars/main.yml file looks like

---
location: UK
users:
  - name: user1
    password: $6$8T8lH2vS$JKIdqkQmHUHR/s75RYMguPyHTisnNrXIPOjJ9IWxMHB4LY9PJX.3rgkmfLCWAHDi5VYZno2ntlYm7Kkdy0iAZ.
    uid: 601
    location: UK
  - name: user2
    password: $6$8T8lH2vS$JKIdqkQmHUHR/s75RYMguPyHTisnNrXIPOjJ9IWxMHB4LY9PJX.3rgkmfLCWAHDi5VYZno2ntlYm7Kkdy0iAZ
    uid: 602
    location: USA

Here's how my "/playbooks/roles/users/tasks/main.yml" looks like

---
 - name: Create users based on location
   include: create_users.yml
   loop: "{{ users | selectattr('location', 'equalto', location) | list }}"

When the corresponding packer build has been run there are no errors but user1,user2 and their attributes are not getting created.

amazon-ebs: TASK [: Create users based on location] ***********************************
    amazon-ebs:
    amazon-ebs: PLAY RECAP *********************************************************************
    amazon-ebs: default                    : ok=10   changed=7    unreachable=0    failed=0
    amazon-ebs:

Please can someone help me understand as to why users are not getting created? Thanks

2
You may want to read about variablesKonstantin Suvorov

2 Answers

3
votes

This is commonly approached through the use of variables and loops. Extract all the variable stuff out into a list variable, containing dictionaries of params, then use a loop to read through and apply. So based on your role approach:

Create a task file containing the two tasks to run - /playbooks/roles/users/tasks/create_user.yml:

---

- name: User "{{ item.name }}"
  user:
    comment "{{ item.name }} company account"
    name: "{{ item.name }}"
    home: "/data/company/{{ item.name }}"
    state: present
    uid: 666
    group: company
    groups: company
    shell: /bin/bash
    state: present
    generate_ssh_key: no
    password: "{{ item.password }}"

- name: "Create home directory for {{ item.name }}"
  file:
    path: "/data/company/{{ item.name }}"
    state: directory
    owner: "{{ item.name }}"
    group: company
    mode: 0700

Create a vars file containing your users - /playbooks/roles/users/vars/main.yml:

---

location: UK   # This will be your default. It can be overridden in a variety of places
users:
  - name: user1
    password: <some password>
    location: US
  - name: user2
    password: <some password>
    location: UK
  - name: user3
    password: <some password>
    location: UK

then in /playbooks/roles/users/tasks/main.yml:

---

- name: Create users based on location
  include: create_user.yml
  loop: "{{ users | selectattr('location', 'equalto', location) | list }}"

Hopefully most of it is self explanatory. Because you are using a role, by placing the users variable in /playbooks/roles/users/vars/main.yml, the variable is automatically made available. The users | selectattr('location', 'equalto', location) expression, takes the user variable and filters the list to only include objects where the 'location' element is equal to the value specified in the 'location' variable.

Variables

Loops

Roles

0
votes

Some additional hints, you can use defaults too. Also, in case you want to protect the encrypted passwords, you can store them in Ansible Vault:

users.yml example:

users:
- name: user1
  uid: 666
  group: group1
  groups: [allusers]
  comment: User One
  home: /home/user1
  shell: /bin/bash

passwords: "{{ vault_passwords }}"

The vault file you crypt with 'ansible-vault' command looks like (decrypted):

passwords:
- name: user1
  password: $6$509875346RH.RAaVNW2iWtf/QJ4zUGaJiEyh.

playbook included tasks file example:

  - name: Set up user accounts
    user:
      name: "{{ item.name }}"
      create_home: '{{ item.createhome | default("no") }}'
      uid: "{{ item.uid }}"
      group: "{{ item.group }}"
      state: '{{ item.state | default("present") }}'
      comment: '{{ item.comment | default("Ansible created comment") }}'
      home: "{{ item.home }}"
      shell: '{{ item.shell | default("/bin/bash") }}'
    with_items: "{{ users }}"

  - name: Set up user account passwords
    user:
      name: "{{ item.name }}"
      password: '{{ item.password | default("*") }}'
    with_items: "{{ passwords }}"