owner: роль причёсана под конвенции eget и secrets
- валидация аргументов через assert вместо пары fail с одинаковым именем - with_items/with_dict заменены на loop, имена задач без точки на конце - добавлены meta/main.yml и README с таблицей переменных - задача ansible-owner-role-cleanup удалена из беклога
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# owner
|
||||
|
||||
Заводит системного пользователя и группу под одно приложение: фиксированные
|
||||
uid/gid, ssh-ключи и переменные окружения в `~/.env`.
|
||||
|
||||
Один сервис — один пользователь: контейнеры приложения работают от его uid/gid,
|
||||
и файлы в `base_dir` принадлежат ему же. Роль вызывается первой задачей почти
|
||||
каждого `playbook-<app>.yml`.
|
||||
|
||||
## Что делает
|
||||
|
||||
1. **Группа и пользователь.** Создаёт группу `owner_group` с `owner_gid` и
|
||||
пользователя `owner_name` с `owner_uid` и шеллом `/bin/bash`. Номера задаёт
|
||||
плейбук приложения (соглашение по нумерации — в `AGENTS.md`).
|
||||
2. **SSH-ключи.** Прописывает `owner_ssh_keys` в `authorized_keys`.
|
||||
3. **Переменные окружения.** Рендерит `~/.env` из `owner_env` плюс `USER_UID` и
|
||||
`USER_GID` — их подставляют docker-compose шаблоны приложений. В `.bashrc`
|
||||
добавляет строку, подгружающую `~/.env` целиком, и вычищает старые построчные
|
||||
`export`-ы, оставшиеся от прежней схемы.
|
||||
|
||||
## Результат для плейбука
|
||||
|
||||
Роль регистрирует `owner_create_result` — результат модуля `user`. Плейбуки и
|
||||
compose-шаблоны берут оттуда `owner_create_result.uid` и
|
||||
`owner_create_result.group` (это gid) для `user:` в docker-compose.
|
||||
|
||||
## Переменные
|
||||
|
||||
Полный список и значения по умолчанию — в `defaults/main.yml`.
|
||||
|
||||
| Переменная | Обязательная | Описание |
|
||||
| --------------------- | ------------ | --------------------------------------------------- |
|
||||
| `owner_name` | да | Имя пользователя; по умолчанию оно же имя группы |
|
||||
| `owner_uid` | да | Uid пользователя |
|
||||
| `owner_group` | нет | Имя группы, по умолчанию `owner_name` |
|
||||
| `owner_gid` | нет | Gid группы, по умолчанию `owner_uid` |
|
||||
| `owner_extra_groups` | нет | Дополнительные группы (обычно `["docker"]`) |
|
||||
| `owner_ssh_keys` | нет | Список публичных ключей для `authorized_keys` |
|
||||
| `owner_env` | нет | Словарь переменных окружения, попадающих в `~/.env` |
|
||||
|
||||
## Пример использования
|
||||
|
||||
```yaml
|
||||
- name: "Create user and environment"
|
||||
ansible.builtin.import_role:
|
||||
name: owner
|
||||
vars:
|
||||
owner_name: "{{ app_user }}"
|
||||
owner_uid: "{{ app_owner_uid }}"
|
||||
owner_gid: "{{ app_owner_gid }}"
|
||||
owner_extra_groups: ["docker"]
|
||||
```
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
galaxy_info:
|
||||
role_name: owner
|
||||
author: "Anton Vakhrushev"
|
||||
description: "Системный пользователь приложения: группа, uid/gid, ssh-ключи и переменные окружения"
|
||||
license: "MIT"
|
||||
min_ansible_version: "2.14"
|
||||
platforms:
|
||||
- name: Ubuntu
|
||||
versions:
|
||||
- all
|
||||
- name: Debian
|
||||
versions:
|
||||
- all
|
||||
galaxy_tags:
|
||||
- users
|
||||
- system
|
||||
- environment
|
||||
|
||||
dependencies: []
|
||||
+28
-20
@@ -1,21 +1,24 @@
|
||||
---
|
||||
- name: 'Check app requirements for user "{{ owner_name }}".'
|
||||
ansible.builtin.fail:
|
||||
msg: You must set owner name.
|
||||
when: not owner_name
|
||||
# tasks file for owner
|
||||
|
||||
- name: 'Check app requirements for user "{{ owner_name }}".'
|
||||
ansible.builtin.fail:
|
||||
msg: You must set owner uid.
|
||||
when: not owner_uid
|
||||
- name: "Validate owner role arguments"
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- owner_name is string and owner_name | length > 0
|
||||
- owner_uid | int > 0
|
||||
- owner_gid | int > 0
|
||||
fail_msg: >-
|
||||
Роль owner требует непустой owner_name и положительные owner_uid/owner_gid
|
||||
(owner_name={{ owner_name }}, owner_uid={{ owner_uid }}, owner_gid={{ owner_gid }})
|
||||
quiet: true
|
||||
|
||||
- name: 'Create group "{{ owner_group }}".'
|
||||
- name: "Create group {{ owner_group }}"
|
||||
ansible.builtin.group:
|
||||
name: "{{ owner_group }}"
|
||||
gid: "{{ owner_gid }}"
|
||||
state: present
|
||||
|
||||
- name: 'Create user "{{ owner_name }}".'
|
||||
- name: "Create user {{ owner_name }}"
|
||||
ansible.builtin.user:
|
||||
name: "{{ owner_name }}"
|
||||
group: "{{ owner_group }}"
|
||||
@@ -24,20 +27,21 @@
|
||||
shell: /bin/bash
|
||||
register: owner_create_result
|
||||
|
||||
- name: 'Set up user ssh keys for user "{{ owner_name }}".'
|
||||
- name: "Set up ssh keys for user {{ owner_name }}"
|
||||
ansible.posix.authorized_key:
|
||||
user: "{{ owner_name }}"
|
||||
key: "{{ item }}"
|
||||
state: present
|
||||
with_items: "{{ owner_ssh_keys }}"
|
||||
when: owner_ssh_keys | length > 0
|
||||
loop: "{{ owner_ssh_keys }}"
|
||||
|
||||
- name: "Prepare env variables."
|
||||
# USER_UID/USER_GID кладём в окружение всегда: их подставляют docker-compose
|
||||
# шаблоны приложений, чтобы контейнер работал от того же пользователя.
|
||||
- name: "Prepare env variables"
|
||||
ansible.builtin.set_fact:
|
||||
# yamllint disable-line rule:line-length
|
||||
owner_env_dict: '{{ owner_env | combine({"USER_UID": owner_create_result.uid, "USER_GID": owner_create_result.group}) }}'
|
||||
owner_env_dict: >-
|
||||
{{ owner_env | combine({"USER_UID": owner_create_result.uid, "USER_GID": owner_create_result.group}) }}
|
||||
|
||||
- name: 'Set up environment variables for user "{{ owner_name }}".'
|
||||
- name: "Set up environment variables for user {{ owner_name }}"
|
||||
ansible.builtin.template:
|
||||
src: env.template
|
||||
dest: "/home/{{ owner_name }}/.env"
|
||||
@@ -45,14 +49,18 @@
|
||||
group: "{{ owner_group }}"
|
||||
mode: "0640"
|
||||
|
||||
- name: 'Remove from bashrc absent environment variables for user "{{ owner_name }}".'
|
||||
# Раньше переменные писались в .bashrc построчно; теперь источник истины —
|
||||
# ~/.env, поэтому старые строки вычищаем.
|
||||
- name: "Remove from bashrc absent environment variables for user {{ owner_name }}"
|
||||
ansible.builtin.lineinfile:
|
||||
path: "/home/{{ owner_name }}/.bashrc"
|
||||
regexp: "^export {{ item.key }}="
|
||||
state: absent
|
||||
with_dict: "{{ owner_env_dict }}"
|
||||
loop: "{{ owner_env_dict | dict2items }}"
|
||||
loop_control:
|
||||
label: "{{ item.key }}"
|
||||
|
||||
- name: 'Include in bashrc environment variables for user "{{ owner_name }}".'
|
||||
- name: "Include in bashrc environment variables for user {{ owner_name }}"
|
||||
ansible.builtin.lineinfile:
|
||||
path: "/home/{{ owner_name }}/.bashrc"
|
||||
regexp: "^export \\$\\(grep -v"
|
||||
|
||||
Reference in New Issue
Block a user