
В этой статье я хотел бы рассказать про то, как мы используем Puppet и Hiera для конфигурирования железных и виртуальных серверов. В основном, в ней будет идти речь об архитектуре и придуманной нами иерархии, облегчающей и систематизирующей конфигурацию серверов.
Написать эту статью меня побудило то, что в интернете я особо не находил хороших, реально рабочих примеров того, как можно работать с hiera и для чего она нужна. В основном, это туториалы с примерами для того, чтобы въехать в тему. Но реальное практическое применение hiera там не написано. Возможно, я плохо искал, но вот вам реальный пример, который, возможно, вам поможет расставить все точки над i, как и мне когда-то.
Для кого была бы полезна данная статья
Если:
- Вы знаете, что такое Puppet и Hiera, но особо не использует их в связке, потому что непонятно, как это делать и зачем
- У вас в компании есть множество команд и вам надо как-то разграничивать конфигурацию серверов на уровне команд
- Вы используете паппет, и нодные файлы у вас разрослись до неимоверных размеров
- Вам нравится читать конфигурацию серверов в божественном yaml формате :)
- Вы в принципе интересуетесь темой Configuration Management и системным администрированием
Эта статья для вас.
Прежде, чем начать
Предупрежу сразу, статья получилась длинной, но, я надеюсь, полезной. Кроме того, подразумевается, что у вас уже подключена hiera в puppet, и вы хоть как-то, но знакомы с puppet. Если hiera не подключена, это не сложно сделать.
- Подробнее о том, что такое Puppet, можно почитать тут: Puppet for beginners.
- Как работает Hiera — Introducing in Hiera.
Вводные данные
- У нас в SEMrush есть около 30 команд разработки, каждая из которых имеет свои сервера
- Каждая команда работает со своим набором технологий (ЯП, СУБД и т.д.)
- Команды могут и должны (в идеале) использовать общую конфигурацию для каких-то конкретных проектов (code reuse)
- Команды сами управляют деплоем приложений на свои сервера (это делается не через паппет)
Немного истории
Изначально у нас все было в паппете версии 3, потом решили внедрить 4-й паппет, и все новые сервера начали размещать в нем, а старые потихоньку портировать в 4й.
В третьем паппете у нас раньше использовалась классическая система нодных файлов и модулей. Модули создавали в специальной группе проектов в Gitlab, клонировали их на паппет-сервер (с помощью r10k), дальше паппет агенты приходили к мастеру и получали каталог, чтобы применить его на сервере.
Потом начали стараться так не делать и не использовать локальные модули, а помещать ссылки на нужные модули и их репозитории в Puppetfile. Почему? Потому что те модули постоянно поддерживаются и улучшаются (ну, в идеале) сообществом и разработчиками, а наши локальные — нет. Позже внедрили hiera и перешли полностью на нее, а нодные файлы (типа nodes.pp) канули в лету.
В четвертом паппете мы постарались полностью отказаться от локальных модулей и использовать только remote модули. К сожалению, тут снова следует вставить оговорку, так как “полностью” не получилось, иногда все равно приходится что-то склонировать и доделать самим. Конечно, здесь только hiera и никаких нодных файлов.
Когда у вас 30 команд с зоопарком технологий, проблема того, как содержать этот зверинец с >1000 серверов становится особенно остро. Дальше я расскажу, как в этом нам помогает hiera.
Иерархия
У hiera (собственно, от чего она и получила свое название) настраивается иерархия. У нас она выглядит следующим образом:
--- :hierarchy: - "nodes/%{::fqdn}" - "teams/%{::team}_team/nodes/%{::fqdn}" - "teams/%{::team}_team/projects/%{::project}/tiers/%{::tier}" - "teams/%{::team}_team/projects/%{::project}/%{::role}" - "teams/%{::team}_team/projects/%{::project}" - "teams/%{::team}_team/roles/%{::role}" - "teams/%{::team}_team/%{::team}" - "projects/%{::project}/tiers/%{::tier}/%{::role}" - "projects/%{::project}/tiers/%{::tier}" - "projects/%{::project}/%{::role}" - "projects/%{::project}" - "tiers/%{::tier}" - "virtual/%{::virtual}" - "os/%{::operatingsystem}/%{::operatingsystemmajrelease}" - "os/%{::operatingsystem}" - users - common
Сначала разберемся с непонятными переменными (фактами).
Каждый сервер в SEMrush в идеале должен иметь 4 выставленных, специальных факта, описывающих его принадлежность:
- факт
team— к какой команде он относится - факт
project— к какому проекту он относится - факт
role— какую роль в этом проекте имеет - факт
tier— какой у него стейджинг (prod, test, dev)
Как это работает? Паппет агент приходит к паппет мастеру и на основе данных фактов ищет файлы для себя, проходясь по папкам в соответствии с нашей иерархией. Не нужно указывать принадлежность конфигурационых файлов к серверам. Вместо этого сервера сами знают, какие файлы относятся к ним, смотря только лишь на их путь и свои факты.
При сетапе сервера админы связываются с разработчиками и уточняют данные параметры (часто даже наоборот, знающие люди сами связываются с админами), чтобы в дальнейшем построить иерархию в hiera, на основе которой потом описать конфигурацию сервера. Такая система помогает повторно использовать код и быть более гибким в плане конфигурации серверов.
Например, есть у нас проект special. В этом проекте может быть какой-то фронтенд-сервер с nginx, backend-сервер с python, db-кластер с mysql, redis-сервера для кэширования. Все эти сервера следует поместить в один проект под названием special, а дальше назначать серверам роли.
В проектном файле мы описываем общие для всего проекта параметры. Первое, что приходит на ум, это создание на всех серверах пользователя для деплоя с выдачей ему нужных прав и раскаткой его ssh-ключей.
В роли для каждого сервера обычно описывается и кастомизируется конкретно сервис — для чего данный сервер предназначен (nginx, python, mysql и т.д.) Tier в данном случае нам обязательно понадобится, если нам также нужно разворачивать копию продакшн окружения на dev-площадке, но что-то в ней изменить (пароли, например). В таком случае, dev-сервера и prod-сервера будут лишь отличаться выставленным фактом tier в нужное “положение” (prod или dev). А дальше немного магии и hiera сделает свое дело.
Если же нам нужно развернуть два идентичных сервера в одинаковой роли, но что-то в них должно отличаться, например, какие-то строки в конфигурации, то на помощь придет другая часть иерархии. Помещаем файлы с названием формата {fqdn сервера}.yaml в нужное место (например, nodes/myserver.domain.net), выставляем нужные значения переменных на уровне конкретного сервера, и паппет применит на оба сервера одинаковую конфигурацию для роли, и уникальную для каждого из серверов.
Пример: два бэкэнда с php-кодом находятся в одной роли и полностью идентичные. Понятно, что мы не хотим бэкапить оба сервера — нет смысла. Мы можем создать роль, в которой описать одинаковую конфигурацию для обоих серверов, а потом создать еще файл nodes/backend1.semrush.net, в который поместить конфигурацию для бэкапа.
В командном файле teams/team-name.yaml указывается конфигурация для всех серверов, принадлежащих команде. Чаще всего там описываются пользователи, которые могут взаимодействовать с этими серверами, а также их права доступа.
На основе этих переменных у нас построена данная иерархия. Чем выше найденный файл по иерархии, тем выше приоритет конфигурации, указанной в нем.
Отсюда следует, что переменные могут оверрайдиться исходя из данной иерархии. То есть переменная в файле роли "projects/%{::project}/%{::role}" имеет больший приоритет, чем переменная в файле проекта "projects/%{::project}". Также переменные могут мерджиться на всех уровнях иерархии, если у вас модуль и/или профиль/роль написаны так, что позволяют это делать. Указав общую часть конфига mysql для всех серверов проекта, можно добавить в ту же переменную на других уровнях иерархии специальные части, имеющие вес для данной роли (для слейва будет дополнительная секция в конфиге).
Получается, самый высокий приоритет имеет файл конкретной ноды, расположенный по пути — "hieradata/nodes/%{::fqdn}". Дальше следует файл ноды, но уже на уровне команды. Ниже всего находится блок, описывающий другие, более общие факты:
- "virtual/%{::virtual}" - "os/%{::operatingsystem}/%{::operatingsystemmajrelease}" - "os/%{::operatingsystem}" - users - common
Соответственно, в файле common.yaml у нас содержится конфигурация, которая точно должна приезжать на все сервера, в файле users.yaml описаны все юзеры (но не все они создаются на серверах, конечно же), в os/%{::operatingsystem} общая конфигурация, свойственная серверам с определенной ОС (используется факт ::operatingsystem) и так далее.
Думаю, взглянув на данную иерархию, становится все понятно. Ниже я рассмотрю пример использования такой иерархии. Но сначала следует рассказать о профилях.
Профили
Важным моментом в конфигурировании серверов с помощью модулей является использование профилей. Они располагаются по пути site/profiles и являются точками входа в модули. Благодаря им можно более тонко настраивать навешиваемые модули на сервера и создавать нужные ресурсы.
Рассмотрим простой пример. Есть модуль, устанавливающий и настраивающий redis. И мы хотим также при подключении данного модуля установить sysctl параметр vm.overcommit_memory в значение 1, потому что вот. Тогда пишем небольшой профиль, обеспечивающий этот функционал:
# standalone redis server class profiles::db::redis ( Hash $config = {}, String $output_buffer_limit_slave = '256mb 64mb 60', ) { # https://redis.io/topics/faq#background-saving-fails-with-a-fork-error-under-linux-even-if-i-have-a-lot-of-free-ram sysctl { 'vm.overcommit_memory': ensure => present, value => '1', } class { '::redis': * => $config, } }
Как было сказано выше, профили являются инструментом, позволяющим менять/улучшать поведение модуля, а также уменьшать количество конфигурации в hiera. Если вы используете удаленные модули, то часто можете столкнуться с проблемой, что "одобренные" модули часто не обладают нужным вам функционалом, или имеют какие-то баги/недоработки. Тогда в принципе можно склонировать этот модуль и поправить/добавить функционал. Но правильным решением будет, если это возможно, написать хороший профиль, который способен “приготовить” модуль нужным вам образом. Ниже будут представлены несколько примеров профилей, и можно будет лучше понять, для чего они нужны.
Сокрытие секретов в hiera
Одним из важных преимуществ hiera по сравнению с “голым” паппетом является ее способность хранить sensitive data в конфигурационных файлах в зашифрованном виде в репозитории. Ваши пароли будут в безопасности.
Вкратце, вы с помощью публичного ключа шифруете нужную информацию и помещаете ее такой строкой в файл hiera. На паппет мастере хранится приватная часть ключа, которая позволяет эти данные дешифровать. Более подробно с этим можно ознакомиться на странице проекта.
На клиенте (рабочем компьютере) тулза ставится просто, можно через gem install hiera-eyaml. Дальше с помощью команды вида eyaml encrypt --pkcs7-public-key=/path/to/public_key.pkcs7.pem -s 'hello' можно шифровать данные и вставлять в файл с расширением eyaml или просто yaml в зависимости от того, как вы настроите, а дальше паппет сам разберется. Получится что-то вроде:
roles::postrgresql::password: 'ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAbIz1ihQlThMWa9T+Lq194Y6QdElMD1XTev5y+VPSHtkPTu6Al6TJaSrXF+7phJIjue+NF4ZVtJCLkHxUR6nJJqks0fcGS1vF2+6mmM9cy69sIU1A3HqpOHZLuqHAc7jUqljYxpwWSIGOK6I2FygdAp5FfOTewqfcVVmXj97EJdcv3DKrbAlSrIMO2iZRYwQvyv+qnptnZ7pilR2veOCPW2UMm6zagDLutX9Ft5vERbdaiCiEfTOpVa9Qx0GqveNRVJLV/5lfcL5ajdNBJXkvKqDbx8d3ZBtEVAAqeKlw0LqzScgmCbWQx2kUzukX5LSxbTpT0Th984Vp1sl7iPk7UTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCp5GcwidcEMA+0wjAMblkKgBCR/f9KGXUgLh3/Ok60OIT5]'
Или многострочной строкой:
roles::postgresql::password: > ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEw DQYJKoZIhvcNAQEBBQAEggEAbIz1ihQlThMWa9T+Lq194Y6QdElMD1XTev5y +VPSHtkPTu6Al6TJaSrXF+7phJIjue+NF4ZVtJCLkHxUR6nJJqks0fcGS1vF 2+6mmM9cy69sIU1A3HqpOHZLuqHAc7jUqljYxpwWSIGOK6I2FygdAp5FfOTe wqfcVVmXj97EJdcv3DKrbAlSrIMO2iZRYwQvyv+qnptnZ7pilR2veOCPW2UM m6zagDLutX9Ft5vERbdaiCiEfTOpVa9Qx0GqveNRVJLV/5lfcL5ajdNBJXkv KqDbx8d3ZBtEVAAqeKlw0LqzScgmCbWQx2kUzukX5LSxbTpT0Th984Vp1sl7 iPk7UTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBCp5GcwidcEMA+0wjAM blkKgBCR/f9KGXUgLh3/Ok60OIT5]
Кажется, с подготовкой закончили, теперь можно рассмотреть пример.
Пример на пальцах
Спойлер: дальше будет много конфигураций, так что тем, кому эта статья представляла чисто теоретический интерес, можно пропускать этот раздел и переходить в конец.
Давайте теперь рассмотрим пример, как можно конфигурировать сервера с помощью hiera в puppet4. Я не буду публиковать код всех профилей, потому что иначе пост получится довольно больших размеров. Основной акцент я сделаю на иерархии и конфигурации hiera.
Задача такая: нам нужно развернуть:
- Два идентичных бд-сервера, на которых развернут postgresql
- Еще два сервера — frontend с nginx
- Пятый и шестой сервера — бэкэнды на python в докере
- Все то же самое и на dev-окружении, за исключением некоторой конфигурации серверов
Будем создавать нашу иерархию по порядку и начнем мы с проектного файла.
Проект
Создаем файл проекта projects/kicker.yaml. Поместим в него то, что общее у всех серверов: нам нужны некоторые репозитории и папки для деплоя, а также сам пользователь deploy.
--- classes: - apt::debian::semrush files: "/srv/data": ensure: 'directory' owner: 'deploy' group: 'www-data' mode: '0755' '/srv/data/shared_temp': ensure: 'directory' owner: 'deploy' group: 'www-data' mode: '0775' user_management::present: - deploy
Роль db
Создаем файл роли для БД-серверов projects/kicker/db.yaml. Пока что обойдемся без разделения серверов на окружения:
--- classes: - profiles::db::postgresql profiles::db::postgresql::globals: manage_package_repo: true version: '10' profiles::db::postgresql::db_configs: 'listen_addresses': value: '*' profiles::db::postgresql::databases: kicker: {} profiles::db::postgresql::hba_rules: 'local connect to kicker': type: 'local' database: 'kicker' user: 'kicker' auth_method: 'md5' order: '001' 'allow connect from 192.168.1.100': type: 'host' database: 'kicker' user: 'kicker' auth_method: 'md5' address: '192.168.1.100/32' order: '002'
Здесь мы подключаем один профиль, написанный для общего использования всеми, кто захочет установить postgres себе на сервера. Профиль конфигурируем и позволяет гибко настроить модуль перед его применением.
Для самых любопытных ниже под катом код этого профиля:
class profiles::db::postgresql ( Hash $globals = {}, Hash $params = {}, Hash $recovery = {}, Hash[String, Hash[String, Variant[String, Boolean, Integer]]] $roles = {}, Hash[String, Hash[String, Variant[String, Boolean]]] $db_configs = {}, Hash[String, Hash[String, Variant[String, Boolean]]] $databases = {}, Hash[String, String] $db_grants = {}, Hash[String, Hash[String, String]] $extensions = {}, Hash[String, String] $table_grants = {}, Hash[String, Hash[String, String]] $hba_rules = {}, Hash[String, String] $indent_rules = {}, Optional[String] $role = undef, # 'master', 'slave' Optional[String] $master_host = undef, Optional[String] $replication_password = undef, Integer $master_port = 5432, String $replication_user = 'repl', String $trigger_file = '/tmp/pg_trigger.file', ){ case $role { 'slave': { $_params = { manage_recovery_conf => true, } if $globals['datadir'] { file { "${globals['datadir']}/recovery.done": ensure => absent, } } $_recovery = { 'recovery config' => { standby_mode => 'on', primary_conninfo => "host=${master_host} port=${master_port} user=${replication_user} password=${replication_password}", trigger_file => $trigger_file, } } $_conf = { 'hot_standby' => { value => 'on', }, } file { $trigger_file: ensure => absent, } } 'master': { $_conf = { 'wal_level' => { value => 'replica', }, 'max_wal_senders' => { value => 5, }, 'wal_keep_segments' => { value => 32, }, } file { $trigger_file: ensure => present, } } default: { $_params = {} $_recovery = {} $_conf = {} } } class { '::postgresql::globals': * => $globals, } class { '::postgresql::server': * => deep_merge($_params, $params), } create_resources('::postgresql::server::config_entry', deep_merge($_conf, $db_configs)) create_resources('::postgresql::server::role', $roles) create_resources('::postgresql::server::database', $databases) create_resources('::postgresql::server::database_grant', $db_grants) create_resources('::postgresql::server::extension', $extensions) create_resources('::postgresql::server::table_grant', $table_grants) create_resources('::postgresql::server::pg_hba_rule', $hba_rules) create_resources('::postgresql::server::pg_indent_rule', $indent_rules) create_resources('::postgresql::server::recovery', deep_merge($_recovery, $recovery)) }
Таким образом, мы одним махом устанавливаем Postgresql 10, настраиваем конфиг (listen), создаем БД kicker, а также записываем в pg_hba.conf два правила для доступа к этой базе. Круто!
Роль frontend
Беремся за frontend. Создаем файл projects/kicker/frontend.yaml следующего содержания:
--- classes: - profiles::webserver::nginx profiles::webserver::nginx::servers: 'kicker.semrush.com': use_default_location: false listen_port: 80 server_name: - 'kicker.semrush.com' profiles::webserver::nginx::locations: 'kicker-root': location: '/' server: 'kicker.semrush.com' proxy: 'http://kicker-backend.semrush.com:8080' proxy_set_header: - 'X-Real-IP $remote_addr' - 'X-Forwarded-for $remote_addr' - 'Host kicker.semrush.com' location_cfg_append: 'proxy_next_upstream': 'error timeout invalid_header http_500 http_502 http_503 http_504' proxy_connect_timeout: '5'
Здесь все просто. Мы подключаем профиль profiles::webserver::nginx, который подготавливает вход в модуль nginx, а также определяем переменные, а конкретно server и location для этого сайта.
Внимательный читатель заметит, что правильнее будет поместить описание сайта выше по иерархии, ведь у нас будет еще dev-окружение, и там будут использоваться другие переменные (server_name, proxy), но это не слишком важно. Описывая роль таким образом, мы сможем увидеть, как переопределяются эти переменные только лишь иерархией.
Роль docker
Осталась роль docker projects/kicker/docker.yaml:
--- classes: - profiles::docker profiles::docker::params: version: '17.05.0~ce-0~debian-stretch' packages: 'python3-pip': provider: apt 'Fabric3': provider: pip3 ensure: 1.12.post1 user_management::users: deploy: groups: - docker
Профиль profiles/docker.pp очень прост и изящен. Приведу его код:
class profiles::docker ( Hash $params = {}, Boolean $install_kernel = false, ){ class { 'docker': * => $params, } if ($install_kernel) { include profiles::docker::kernel } }
Все готово. Этого уже достаточно, чтобы развернуть нужный нам продукт на множестве серверов, просто назначив им определенные проект и роль (например, положив файлик в нужном формате в директорию facts.d, местоположение которой зависит от способа установки puppet).
Сейчас мы имеем следующую структуру файлов:
. ├── kicker │ ├── db.yaml │ ├── docker.yaml │ └── frontend.yaml └── kicker.yaml 1 directory, 4 files
Разберемся теперь с окружениями и определением конфигурации, уникальной для роли на конкретной площадке.
Окружения и override
Создадим общую конфигурацию для всего прода. Файл projects/kicker/tiers/prod.yaml содержит указание, что нам нужно подключить класс с файрволом на это окружение (ну, прод же все-таки), а также некий класс, обеспечивающий повышенный уровень безопасности:
--- classes: - semrush_firewall - strict_security_level
Для dev-окружения, если нам нужно описать что-то специфичное, создается такой же файл, и в него вносится нужная конфигурация.
Далее нужно все-таки переопределить переменные для nginx-конфига роли frontend в dev-окружении. Для этого понадобится создать файл projects/kicker/tiers/dev/frontend.yaml. Обратите внимание на новый уровень иерархии.
--- profiles::webserver::nginx::servers: 'kicker-dev.semrush.com': use_default_location: false listen_port: 80 server_name: - 'kicker-dev.semrush.com' profiles::webserver::nginx::locations: 'kicker-root': location: '/' server: ‘kicker-dev.semrush.com' proxy: 'http://kicker-backend-dev.semrush.com:8080' proxy_set_header: - 'X-Real-IP $remote_addr' - 'X-Forwarded-for $remote_addr' - 'Host kicker-dev.semrush.com' location_cfg_append: 'proxy_next_upstream': 'error timeout invalid_header http_500 http_502 http_503 http_504' proxy_connect_timeout: '5'
Класс указывать уже не надо, он наследуется с предыдущих уровней иерархии. Здесь мы изменили server_name и proxy_pass. Сервер, у которого будут факты role=frontend и tier=dev, сначала найдет для себя файл projects/kicker/frontend.yaml, но потом переменные из этого файла будут переопределены файлом с бОльшим приоритетом projects/kicker/tiers/dev/frontend.yaml.
Сокрытие пароля для PostgreSQL
И таким образом у нас остается последний пункт на повестке дня — это задать пароли для PostgreSQL.
Пароли должны различаться в окружениях. Будем использовать eyaml для безопасного хранения паролей. Создадим пароли:
eyaml encrypt -s 'verysecretpassword' eyaml encrypt -s 'testpassword'
Вставляем полученные строки в файлы **projects/kicker/tiers/prod/db.yaml** и **projects/kicker/tiers/dev/db.yaml** (или можно использовать расширение eyaml, это настраиваемо) соответст��енно. Вот пример:
--- profiles::db::postgresql::roles: 'kicker': password_hash: > 'ENC[PKCS7,MIIBeQYJKoZIhvcNAQcDoIIBajCCAWYCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAsdpb2P0axUJzyWr2duRKAjh0WooGYUmoQ5gw0nO9Ym5ftv6uZXv25DRMKh7vsbzrrOR5/lLesx/pAVmcs2qbhd/y0Vr1oc2ohHlZBBKtCSEYwem5VN+kTMhWPvlt93x/S9ERoBp8LrrsIvicSYZByNfpS2DXCFbogSXCfEPxTTmCOtlOnxdjidIc9Q1vfAXv7FRQanYIspr2UytScm56H/ueeAc/8RYK51/nXDMtdPOiAP5VARioUKyTDSk8FqNvdUZRqA3cl+hA+xD5PiBHn5T09pnH8HyE/39q09gE0pXRe5+mOnU/4qfqFPc/EvAgAq5mVawlCR6c/cCKln5wJTA8BgkqhkiG9w0BBwEwHQYJYIZIAWUDBAEqBBDNKijGHBLPCth0sfwAjfl/gBAaPsfvzZQ/Umgjy1n+im0s]'
Далее пароль для роли kicker приедет, расшифруется и применится на БД-сервере в PostgreSQL.
На этом, собственно, и все. Да, пример получился массивным, но, надеюсь, функциональным, не оставляющим вопросов, понятным и полезным. Итоговая иерархия в hiera получилась такая:
. ├── db.yaml ├── docker.yaml ├── frontend.yaml └── tiers ├── dev │ ├── db.yaml │ └── frontend.yaml ├── prod │ └── db.yaml └── prod.yaml 3 directories, 7 files
Вы можете посмотреть эти файлы "вживую", склонировав специально созданный репозиторий
Заключение
Puppet хорош и удобен в связке с hiera. Я бы не назвал его идеальным инструментом конфигурации в современном мире, вовсе нет, но он заслуживает внимания. С некоторыми задачами он справляется очень хорошо, а его “философия” поддержки постоянно одинакового состояния ресурсов и конфигурации может играть немаловажную роль в обеспечении безопасности и единообразия конфигураций.
Современный мир постепенно синергирует и развивается. Мало кто сейчас использует только одну систему конфигурации, часто в арсенале девопсов и админов сразу несколько систем. И это хорошо, так как есть из чего выбрать. Главное, чтобы все было логично и понятно, как и где это можно сконфигурировать.
Наша цель как админов в итоге — ничего не конфигурировать самим. Все это в идеале должны делать сами команды. А мы им должны дать инструмент или продукт, позволяющий это делать безопасно, легко и, главное, с точным результатом. Ну, и помогать решать архитектурные и более серьезные задачи, чем "Нужно установить PostgreSQL на сервер и создать пользователя". Камон, 2018-й год на дворе! Поэтому выкидывайте puppet и ansible и двигайтесь в serverless future.
C развитием облаков, контейнеризации и систем оркестраций контейнеров, системы управления конфигураций потихоньку отступают и отходят на задний план для пользователей и клиентов. Можно же в облаке поднять отказоустойчивый кластер контейнеров и держать свои приложения в контейнерах с авто-скелингом, бэкапированием, реплицированием, авто-дискавери и т.д, не написав ни строчки для ansible, puppet, chef etc. Ни о чем заботиться не надо (ну почти). С другой стороны, железных серверов из-за облаков меньше не стало. Просто вам их больше не нужно конфигурировать, это действие находится в ответственности облачного провайдера. Но вряд ли они пользуются теми же системами, что и простые смертные.
Credits
Спасибо:
- Дмитрию Тупицину, Дмитрию Логинову, Степану Федорову и всей команде системных администраторов за помощь в подготовке этой статьи
- Владимиру Легкоступову за картинку
- Яне Табаковой за организацию этого всего и помощь в прохождении всех pre-publishing этапов
- Никите Захарову за помощь в делах лицензирования
