У меня около 200 более-менее одинаковых виртуальных машин Linux. Есть класс для всех распространенных конфигураций:
class my_packages {
class { "::ntp":
servers => [ "de.pool.ntp.org" ],
}
....
}
который я включаю в каждый узел в site.pp.
Теперь я хочу запустить свой собственный локальный сервер времени, что довольно просто, используя пакет puppetlabs / ntp. Мне просто нужно заменить запись серверов в my_packages на IP-адрес новой виртуальной машины сервера времени, и теперь эта виртуальная машина имеет ту же запись класса ntp, которая ранее использовалась в my_packages.
node 'mytime' {
# include my_packages
class { '::ntp':
servers => [
'de.pool.ntp.org',
'ptbtime1.ptb.de',
'ptbtime2.ptb.de',
'ptbtime3.ptb.de',
],
}
...
}
Однако, поскольку запись класса «:: ntp» теперь определена в узле, я не могу включить my_packages в запись узла для моей новой виртуальной машины сервера времени, потому что в этом случае я получаю ошибку «Повторяющееся объявление».
Аналогичная проблема возникла при использовании локального сервера имен. Каждая виртуальная машина имеет файл /etc/resolv.conf, указывающий на локальный сервер имен, поэтому в my_packages есть файловый ресурс для этого. Но сам локальный сервер имен должен иметь другой файл /etc/resolv.conf - он не может указывать на себя, пока его установка не будет завершена, чего не происходит во время установки.
Как лучше всего использовать общий набор ресурсов, но допускать случайные исключения?
Если вы используете Puppet 3 или более позднюю версию, лучший способ приблизиться к этому - использовать hiera для выполнения автоматический поиск параметров. Вкратце, он позволяет вам объявлять классы, используя синтаксис include, а не синтаксис в стиле ресурсов, что означает, что вы можете иметь несколько объявлений для класса. Обратите внимание, что вы не можете смешивать для класса объявления включаемых и ресурсных стилей.
Обычно, если вы использовали синтаксис include для объявления класса, он не работал бы, если бы у него были какие-либо обязательные параметры. Когда вы используете автоматический поиск параметров, puppet попытается найти значения для параметров через hiera.
Hiera назван так потому, что он пытается искать значения в иерархии источников данных. Вы можете указать эту иерархию в hiera.yaml, и она может сопоставляться с различными фактами (имя хоста, настраиваемые факты и т. Д.) Или проверять жестко заданные файлы.
Вот краткий пример, который может сработать в вашем случае:
Определение класса:
class my_packages {
include ::ntp
...
}
mytime.yaml:
----
ntp::servers:
- 'de.pool.ntp.org'
- 'ptbtime1.ptb.de'
- 'ptbtime2.ptb.de'
- 'ptbtime3.ptb.de'
common.yaml:
---
ntp::servers: ['de.pool.ntp.org']
hiera.yaml:
...
:hierarchy:
- "${::fqdn}"
- common
...
В этом случае hiera попытается найти значение параметра server в классе ntp, используя ключ ntp :: servers. Сначала он будет искать этот ключ в любых файлах yaml, соответствующих имени хоста, а затем искать в common.yaml.
В большинстве случаев он будет использовать ключ из common.yaml, но в случае узла mytime он найдет значение выше по иерархии и перестанет искать там.
Вот ссылка на полный пример, который, кстати, покрывает модуль ntp.