I have the following playbook that is supposed to create user, group, disable remote password login etc.,
---
- name: Create groups & users
hosts: all
gather_facts: false
become: true
vars:
# Define group and user as variable
user_group: myuserhrp
user_name_1: myuser
tasks:
- name: Create group
group:
name: "{{ user_group }}"
state: present
- name: Create user
user:
name: "{{ item }}"
state: present
password: "{{ default_user_password | password_hash('sha512','A512') }}"
shell: /bin/bash
group: "{{ openelectrons_k3s_group }}"
loop:
- "{{ user_name_1 }}"
- name: Add user to the sudoers
copy:
dest: "/etc/sudoers.d/{{ item }}"
content: "devops ALL=(ALL) NOPASSWD: ALL"
loop:
- "{{ user_name_1 }}"
- name: Deploy SSH Public Key
ansible.posix.authorized_key:
user: "{{ item }}"
state: present
key: "{{ lookup('file', '/home/{{ item }}/.ssh/id_rsa.pub') }}"
loop:
- "{{ user_name_1 }}"
- name: Disable Password Authentication
lineinfile:
dest=/etc/ssh/sshd_config
regexp='^PasswordAuthentication'
line="PasswordAuthentication no"
state=present
backup=yes
- name: Disable Root Login
lineinfile:
dest=/etc/ssh/sshd_config
regexp='^PermitRootLogin'
line="PermitRootLogin no"
state=present
backup=yes
notify:
- restart ssh
handlers:
- name: restart ssh
service:
name=sshd
state=restarted
I would like to know if that playbook is correct before I apply it on my set of hosts. I have the following questions:
- Is my way of looping over user's correct when I create them?
- With which user will this playbook run on my remote hosts? Should those users be created upfront on all my remote hosts? Can I for this purpose, use any default users? For example., I have a set of Ubuntu 22.04 servers which are my hosts and there is a default user called ubuntu. Can I use this user to run this playbook?
CodePudding user response:
Is my way of looping over user's correct when I create them?
Although it is not absolutely wrong, it's definitely not the most efficient as it will not scale when you add more users either because of their number or the needed information to declare them.
As a first step, what I would do in a such a scenario is define a list of usernames in my play vars (or elsewhere as in my host_vars
, group_vars
, extra_vars
, ...)
vars:
users:
- myuser1
- myuser2
You can the easilly extend that list when needed and use it in a loop that you don't have to modify when it grows:
- name: Create user
user:
name: "{{ item }}"
state: present
password: "{{ default_user_password | password_hash('sha512','A512') }}"
shell: /bin/bash
group: "{{ openelectrons_k3s_group }}"
loop: "{{ users }}"
A second step to make this even more scalable is to transform that list to a list of dicts so that you can define more user specific fields. The following is just an example to widen your perspective. Adapt to your real needs. The list could be transformed to:
vars:
default_group: some_default
users:
- name: myuser1
- name: myuser2
primary_group: my_toto_group
password: totopipo # This one should be encrypted with ansible-vault
shell: /bin/zsh
full_sudo: false
key: /custom/path/to/key_id_ed25519.pub
all_groups: "{{ users | selectattr('primary_group', 'defined')
| map(attribute='primary_group') [default_group] }}"
As you can see, the first user does not declare any custom values whereas the second overrides quite a few. The corresponding tasks taking this into account could then be turned to:
- name: make sure all declared primary groups exist on target
ansible.builtin.group:
name: "{{ item }}"
state: present
loop: "{{ all_groups }}"
- name: Create user
ansible.builtin.user:
name: "{{ item.name }}"
state: present
password: "{{ item.password | d(default_user_password) | password_hash('sha512','A512') }}"
shell: "{{ item.shell | d('/bin/bash') }}"
group: "{{ item.primary_group | d(default_group) }}"
loop: "{{ users }}"
- name: Add user to the full sudoers if asked
ansible.builtin.copy:
dest: "/etc/sudoers.d/{{ item.name }}"
content: "{{ item.name }} ALL=(ALL) NOPASSWD: ALL"
loop: "{{ users }}"
when: "{{ item.full_sudo | d(true) | bool }}"
- name: Deploy SSH Public Key
ansible.posix.authorized_key:
user: "{{ item.name }}"
state: present
key: "{{ lookup('file', item.key | d('/home/{{ item.name }}/.ssh/id_rsa.pub')) }}"
loop: "{{ users }}"
With which user will this playbook run on my remote hosts?
With the one you declare. By default it will the one currently running the playbook on the controller. But this can be overridden on the command line, in your play, at task level, in your inventory... As an overview and entry point to the subject, see https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_environment.html