Puppet. classes vs Defined resource types

Как то на днях мой коллега озадачил меня вопросом о разнице между классами puppet и defined resources(или defined types). Я задумался, но дать нормального ответа не смог. На первый взгляд эти сущности очень похожи. И class и defined type описывают внутри себя некую логику и набор ресурсов. И class и defined type могут быть параметризованы. Но, есть существенное различие в том как они вызываются.

Defined resources

Описанные однажды могут вызываться множество раз как внутри одного класса так и из разных.
Как известно, puppetserver оперирует понятием ресурсов и компилирует манифесты(каталог ресурсов) для каждого сервера по отдельности. Главное требование при множественном вызове одного и того же defined resource для одного сервера — различающийся $title.

Например у нас есть некий defined resource network::route который добавляет маршруты в таблицу маршрутизации:

network::route {add_route_to_${network}_via_{$gw_ip}:
  dst_net => $network,
  gateway => $gw_ip,
}

Описанным выше способом мы можем вызывать это defined resource множество раз например в цикле передовая на каждой итерации разные значения $network и $gw_ip

Classes

Классы могут вызываться двумя способами — с помощью директивы include и в resource-like нотации.

Include

include some_module::class_name

Такая нотация чаще всего используется в init-классе или в node-структуре для включения тех или иных классов в каталог.
include не позволяет передать или переопределить параметры класса. Но, зато, таким образом можно вызывать класс множество раз, во время компиляции каталога ошибки не возникнет, класс будет включен единожды для конкретного сервера.

Resource like

class { network::route:
  dst_net => $network,
  gateway => $gw_ip,
}

В данном примере, мы представили описываемый выше defined resource в виде класса и при вызове передали ему значения некоторых параметров. На вид практически тоже самое что и defined resource, но, таким образом класс может быть вызван лишь один раз. При попытке позвать этот класс еще раз, например с другими параметрами это приведет к ошибке компиляции каталога на сервере. Дело в том, что для конкретного сервера, конкретный класс может быть вызван только раз. Это принципиальное отличие defined resources и классов.

Различие в способах переопределения параметров

Пока писал эту заметку, вспомнил про еще одно весомое отличие в это раз в пользу классов). Параметры классов могут быть вынесены в hiera и прочитаны из hiera автоматически при компиляции каталога. Передача параметров в defined type напрямую из hiera кажется не возможна, по крайней мере я о таком способе не знаю.

Ресурсы:
https://docs.puppet.com/puppet/4.9/lang_defined_types.html
https://docs.puppet.com/puppet/4.9/lang_classes.html