When creating multiple users with Ansible Playbook, it is normal to set the user name, UID, group name, etc. in the list variable in advance and create them all at once with the user module + loop.
However, if you create too many users, it is tedious to prepare the list variable.
I wish I had a playbook that could quickly create users with serial numbers, but I finally made a decent one, so I will leave it as a memorial.
Create a large number of serial number users, for example for developers.
VirtualBox (+ vagrant) CentOS 7.7 ansible 2.9.6
Playbook
Again, to make the article easier to understand, I'll list it all in one Playbook ʻusercreate.yml`. (It's not that I don't know best practices. Just in case.)
First, prepare various variables at the beginning. In this example, we will create users with serial numbers from 01 to 20. See comments for a detailed explanation.
usercreate.yml
---
- name: Create many user
hosts: localhost
vars:
#Create a character string by connecting 1 to 20 with commas. The end ends with a comma, but I'll do something about it later.
user_num_data: "{% for n in range(20) %}{{n+1}},{% endfor %}"
#Divide the variable created above with a comma and register it in the list variable. The last element is empty, but we'll do something about it later.
user_num: "{{ user_num_data.split(',') }}"
#The initial password for the user to create
initialpw: zaq12wsx
# UID/GID prefix. I will use the 5000 series.
pre_id: 50
#Username prefix.
pre_name: devuser
#It is a common group that registers all the users to be created.
common_group: devgroup
Next is the task definition. First, create a common group. Create with 0, GID = 5000, which is not used by the user.
usercreate.yml
tasks:
- name: Common group is created
group:
name: '{{ common_group }}'
gid: '{{ pre_id }}00'
state: present
Next, create a group for each user to be created. Exclude the last empty element by setting the looping list variable to '{{user_num [: -1]}}'
. Then, when using a serial number for a user name, etc., use ʻitem.zfill (2)` to align it to two digits.
usercreate.yml
- name: Groups are created
group:
name: '{{ pre_name }}{{ item.zfill(2) }}'
gid: '{{ pre_id }}{{ item.zfill(2) }}'
state: present
with_items:
- '{{ user_num[:-1] }}'
Finally create a user.
usercreate.yml
- name: Users are created
user:
name: '{{ pre_name }}{{ item.zfill(2) }}'
group: '{{ pre_name }}{{ item.zfill(2) }}'
groups: '{{ pre_name }}{{ item.zfill(2) }}, {{ common_group }}'
uid: '{{ pre_id }}{{ item.zfill(2) }}'
state: present
password: "{{ initialpw | password_hash('sha512') }}"
update_password: on_create
with_items:
- '{{ user_num[:-1] }}'
register: usercreated
As a bonus, disable the password to prompt you to change the initial password. In the previous task, specify a condition with when to execute only when the user was created. Also, specify the label of loop_control to suppress the output when ansible-playbook is executed.
usercreate.yml
- name: Passwords are expired
shell: |
passwd -e '{{ item.invocation.module_args.name }}'
with_items:
- '{{ usercreated.results }}'
when:
- item.changed
- item.invocation.module_args.state == "present"
loop_control:
label: "{{ item.invocation.module_args.name }}"
It is a normal execution result.
$ ansible-playbook -i inventories/test usercreate.yml
PLAY [Create many user] ************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************
ok: [localhost]
TASK [Common group is created] *****************************************************************************************
changed: [localhost]
TASK [Groups are created] **********************************************************************************************
changed: [localhost] => (item=1)
changed: [localhost] => (item=2)
changed: [localhost] => (item=3)
changed: [localhost] => (item=4)
changed: [localhost] => (item=5)
changed: [localhost] => (item=6)
changed: [localhost] => (item=7)
changed: [localhost] => (item=8)
changed: [localhost] => (item=9)
changed: [localhost] => (item=10)
changed: [localhost] => (item=11)
changed: [localhost] => (item=12)
changed: [localhost] => (item=13)
changed: [localhost] => (item=14)
changed: [localhost] => (item=15)
changed: [localhost] => (item=16)
changed: [localhost] => (item=17)
changed: [localhost] => (item=18)
changed: [localhost] => (item=19)
changed: [localhost] => (item=20)
TASK [Users are created] ***********************************************************************************************
changed: [localhost] => (item=1)
changed: [localhost] => (item=2)
changed: [localhost] => (item=3)
changed: [localhost] => (item=4)
changed: [localhost] => (item=5)
changed: [localhost] => (item=6)
changed: [localhost] => (item=7)
changed: [localhost] => (item=8)
changed: [localhost] => (item=9)
changed: [localhost] => (item=10)
changed: [localhost] => (item=11)
changed: [localhost] => (item=12)
changed: [localhost] => (item=13)
changed: [localhost] => (item=14)
changed: [localhost] => (item=15)
changed: [localhost] => (item=16)
changed: [localhost] => (item=17)
changed: [localhost] => (item=18)
changed: [localhost] => (item=19)
changed: [localhost] => (item=20)
TASK [Passwords are expired] *******************************************************************************************
changed: [localhost] => (item=devuser01)
changed: [localhost] => (item=devuser02)
changed: [localhost] => (item=devuser03)
changed: [localhost] => (item=devuser04)
changed: [localhost] => (item=devuser05)
changed: [localhost] => (item=devuser06)
changed: [localhost] => (item=devuser07)
changed: [localhost] => (item=devuser08)
changed: [localhost] => (item=devuser09)
changed: [localhost] => (item=devuser10)
changed: [localhost] => (item=devuser11)
changed: [localhost] => (item=devuser12)
changed: [localhost] => (item=devuser13)
changed: [localhost] => (item=devuser14)
changed: [localhost] => (item=devuser15)
changed: [localhost] => (item=devuser16)
changed: [localhost] => (item=devuser17)
changed: [localhost] => (item=devuser18)
changed: [localhost] => (item=devuser19)
changed: [localhost] => (item=devuser20)
PLAY RECAP *************************************************************************************************************
localhost : ok=5 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
If you look at / etc / passwd, it is beautifully created with serial numbers.
$ grep devuser /etc/passwd
devuser01:x:5001:5001::/home/devuser01:/bin/bash
devuser02:x:5002:5002::/home/devuser02:/bin/bash
devuser03:x:5003:5003::/home/devuser03:/bin/bash
devuser04:x:5004:5004::/home/devuser04:/bin/bash
devuser05:x:5005:5005::/home/devuser05:/bin/bash
devuser06:x:5006:5006::/home/devuser06:/bin/bash
devuser07:x:5007:5007::/home/devuser07:/bin/bash
devuser08:x:5008:5008::/home/devuser08:/bin/bash
devuser09:x:5009:5009::/home/devuser09:/bin/bash
devuser10:x:5010:5010::/home/devuser10:/bin/bash
devuser11:x:5011:5011::/home/devuser11:/bin/bash
devuser12:x:5012:5012::/home/devuser12:/bin/bash
devuser13:x:5013:5013::/home/devuser13:/bin/bash
devuser14:x:5014:5014::/home/devuser14:/bin/bash
devuser15:x:5015:5015::/home/devuser15:/bin/bash
devuser16:x:5016:5016::/home/devuser16:/bin/bash
devuser17:x:5017:5017::/home/devuser17:/bin/bash
devuser18:x:5018:5018::/home/devuser18:/bin/bash
devuser19:x:5019:5019::/home/devuser19:/bin/bash
devuser20:x:5020:5020::/home/devuser20:/bin/bash
The same applies to / etc / group.
$ grep dev /etc/group
devgroup:x:5000:devuser01,devuser02,devuser03,devuser04,devuser05,devuser06,devuser07,devuser08,devuser09,devuser10,devuser11,devuser12,devuser13,devuser14,devuser15,devuser16,devuser17,devuser18,devuser19,devuser20
devuser01:x:5001:devuser01
devuser02:x:5002:devuser02
devuser03:x:5003:devuser03
devuser04:x:5004:devuser04
devuser05:x:5005:devuser05
devuser06:x:5006:devuser06
devuser07:x:5007:devuser07
devuser08:x:5008:devuser08
devuser09:x:5009:devuser09
devuser10:x:5010:devuser10
devuser11:x:5011:devuser11
devuser12:x:5012:devuser12
devuser13:x:5013:devuser13
devuser14:x:5014:devuser14
devuser15:x:5015:devuser15
devuser16:x:5016:devuser16
devuser17:x:5017:devuser17
devuser18:x:5018:devuser18
devuser19:x:5019:devuser19
devuser20:x:5020:devuser20
The password is also expired.
$ sudo chage -l devuser01
Last password change : password must be changed
Password expires : password must be changed
Password inactive : password must be changed
Account expires : never
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7
If there are not enough users, you can re-execute the playbook by changing the following range (20)
to range (40)
etc., and the created users will not be affected and only the additional parts will be created. ..
user_num_data: "{% for n in range(20) %}{{n+1}},{% endfor %}"
With this, even if multiple teams with dozens of members are set up, don't miss it! is.
Recommended Posts