Управление пользователями в системе, неважно Linux или любой другой, это первичная задача, с которой сталкивается любой администратор. В моей работе речь идет об управлении парком серверов, и для этого конечно используется система управления конфигурацией. На текущем месте работы (OneTwoTrip) это Chef, а до этого был Ansible.

Про другие инструменты DevOps я писал здесь.
На самом деле, неважно какую CM использовать - принцип остается неизменным:
Работая с системой управления конфигурации, ты описываешь состояние системы, каким оно должно быть, а не изменения.
Ну т.е. технически ты конечно же описываешь изменения, но твой финальный скрипт управления должен постоянно поддерживать правильное состояние системы. Пример с пользователями отлично подходит для демонстрации данного принципа, перейду к сути.
Как чаще всего решается задача создания пользователей в системе?
node['users'].each do |name|
user name do
comment 'system user'
system true
end
end
Что произойдет, когда сотрудник уволится? Вы удалите запись из атрибута и данный пользователь не будет создаваться на новых серверах, но на старых он по-прежнему останется, потому что мы написали код для создания пользователей, но не написали код для удаления тех, кого нет в атрибуте (не считая системных и специальных пользователей, конечно же).
Более того, со временем мы заметим странную штуку, что UID/GID одного и того же пользователя на разных серверах будет отличаться. Все это приводит к так называемому Configuration drift, когда конфигурация на серверах начинает различаться, хотя управляется одними и теми же правилами.
В шефе, я предлагаю следующий вариант:
- Делим пользователей на админов и простых смертных
- Жестко контролируем UID/GID
- Автоматически удаляем тех, кого нет в системе
- Создаем тех, кого не хватает в системе
Итак, выделим для админов пул с 500 по 600 UID, а для простых смертных с 1000 и до 65533. Будем проходиться по всем пользователям в системе, и если находим того, кого не существует - удаляем.
node['etc']['passwd'].each do |user, data|
uid = data['uid'] ? data['uid'] : user
if uid.to_i.between?(500, 600)
s = search('users', "groups:admin AND id:#{user}")
if s.empty?
user(user) do
force true
action :remove
end
end
end
if uid.to_i.between?(1000, 65533)
s = search('users', "groups:users AND id:#{user}")
if s.empty?
user(user) do
force true
action :remove
end
end
end
end
node[‘etc’][‘passwd’] атрибут, который Ohai автоматически заполняет при каждом прогоне chef-client
Ресурс user
, используемый в данном коде, который мы берем из официальной кукбуки, работает с дата багом users
. Пользователей нужно перечислять в следующем виде:
{
"id": "ivanivanov",
"uid": 501,
"shell": "/bin/bash",
"groups": [
"admin"
],
"ssh_keys": [
"ssh-rsa xxx"
],
"comment": "devops | Ivan Ivanov"
}
Следовательно, вот такой код:
users_manage 'admin' do
action [:remove, :create]
end
Будет искать всех пользователей, у которых в groups есть admin
. Запись для обычных пользователей почти не отличается:
{
"id": "petya",
"uid": 1001,
"shell": "/bin/bash",
"groups": [
"users"
],
"ssh_keys": [
"ssh-rsa xxx"
],
"comment": "trivial | Petya programmist"
}
Как и код в рецепте:
users_manage 'users' do
action [:remove, :create]
end
Вот так я предлагаю управлять пользователями в Chef и применять данный принцип в других системах управления конфигурацией. Если у вас есть что добавить или исправить, пишите в твиттер или на почту, ссылки слева под аватаркой 😉
#Linux #DevOps #TechAndDev