Когда под твоим управление находится сотня-другая unix подобных машин, остро встает вопрос об управлении всем этим парком. Скрипты, это конечно хорошо, но есть и более правильные решения, в частности системы централизованного управления конфигурациями, одной из которой является Puppet.
Достаточная гибкость , включает и свои особенности. В частности мне так и не удалось через стандартные средства видоизменять конфигурацию пакета в зависимости от установленной версии.
Особенно это стало актуально, когда в одной из версий SSH произошла смена названия параметра AuthorizedKeysCommandRunAs на AuthorizedKeysCommandUser и он стал обязательным, что привело к отключению ssh на нескольких машинах.
# diff sshd_config sshd_config_6_4 < #AuthorizedKeysCommandRunAs nobody < # --- > AuthorizedKeysCommandUser nobody >
То есть, в зависимости от версии пакета OpenSSH, нам необходимо подсовывать разные конфигурации. Как была решена данная проблема описано ниже.
- Шаг первый: включаем facter на клиентах
Будем использовать facter, поэтому необходимо убедиться, что система плагинов включена на всех puppet клиентах.
Модифицируем стандартный puppet.conf добавив в него 2 параметра:
# Синхронизировать плагины FACTERLIB=$vardir/lib/facter pluginsync = true
т.е. итоговый конфигурационный файл стал выглядеть следующим образом
# cat /etc/puppet/modules/puppet/files/puppet.conf|egrep -v "^.*?#"|grep -v "^$" [main] logdir = /var/log/puppet rundir = /var/run/puppet ssldir = $vardir/ssl FACTERLIB=$vardir/lib/facter pluginsync = true [agent] classfile = $vardir/classes.txt localconfig = $vardir/localconfig report = true
- Создаем «манифест» для развертывания конфигурации по машинам.
Здесь следует быть очень аккуратным, и исключить серверную машину из применения данного манифеста. т.к. серверный и клиентский конфиг отличается.
cat /etc/puppet/modules/puppet/manifests/init.pp class puppet { filebucket { 'server': path => false, } package{ 'facter': ensure => latest, } package{ 'puppet': ensure => latest, } Package['facter'] -> Package['puppet'] file{ '/etc/puppet/puppet.conf': owner => 'root', group => 'root', mode => 0644, source => 'puppet:///modules/puppet/puppet.conf', } service { 'puppet': ensure => running, name => "puppet", enable => true, hasrestart => true, hasstatus => true, } }
- Шаг второй: создаем ssh_version фактор
Создаем в /etc/puppet/modules/ssh/lib/facter файл «ssh_version.rb» со следующим листингом:
#cat /etc/puppet/modules/ssh/lib/facter/ssh_version.rb require 'facter' result = %x{/bin/rpm -q --queryformat "%{VERSION}" openssh} Facter.add('ssh_version') do setcode do result end end
По сути ничего сложного нет, на клиенте мы выполняем команду
/bin/rpm -q --queryformat "%{VERSION}" openssh
результат возвращаем.
- Шаг третий: применяем фактор в манифесте
Достаточно стандартный манифест для развертывания OpenSSH за исключением того, что в коде мы применяем фактор: «if $::ssh_version == ‘6.4p1‘» и в зависимости от версии установленного пакета применяем нужную нам конфигурацию. В общем-то это нам и требовалось.
#cat /etc/puppet/modules/ssh/manifests/init.pp class ssh { package{ 'openssh-server': ensure => latest, } service{ 'sshd': enable => true, ensure => running, hasrestart => true, } if $::ssh_version == '6.4p1' { file{ '/etc/ssh/sshd_config': owner => 'root', group => 'root', mode => 0600, source => 'puppet:///modules/ssh/sshd_config_6_4', } } else { file{ '/etc/ssh/sshd_config': owner => 'root', group => 'root', mode => 0600, source => 'puppet:///modules/ssh/sshd_config', } } }