Я пытаюсь понять, насколько Ansible является процедурным, а Terraform - нет. Все блоги, кажется, предлагают пример - если вы создадите 2 экземпляра EC2 в Ansible и измените счетчик на 4, у вас будет еще 4; но в Terraform у вас будет всего 4, а не еще 4 экземпляра EC2, когда вы измените счетчик.
Но я считаю, что это не совсем пример процедурного / декларативного?
Есть ли лучший пример, чтобы объяснить, почему Ansible является процедурным, а Terraform - декларативным?
Эти широкие классификации полезны только в той степени, в которой мы знаем, что мы подразумеваем под ними, и, к сожалению (но неизбежно) каждый имеет собственное представление о том, что означает «декларативный», и поэтому я думаю, что не очень полезно делать общие утверждения вроде « Terraform декларативен ».
Вместо этого, я думаю, стоит копнуть глубже и поговорить о некоторых характеристиках этих систем, которые относятся к идеям декларативное программирование. В частности, я собираюсь сосредоточиться на идее явного и неявного потока управления, как описано в начале этой статьи в Википедии, когда я пишу это, но я скажу заранее, что (как мы можем видеть в этой Википедии page) существуют различные другие определения декларативного программирования, которые не фокусируются на потоке управления и, таким образом, предположительно могут привести к другому анализу.
(Раскрытие информации: я работаю над Terraform в HashiCorp, и я разработал самую последнюю версию языка Terraform. Поэтому, хотя я намерен сделать все возможное, чтобы объективно описать обе системы, я знаю Terraform намного лучше, чем Ansible, и поэтому мои утверждения о Ansible исходит с моей точки зрения как пользователя, в то время как мои утверждения о Terraform также окрашены моими знаниями о его реализации.)
О языке Terraform мы можем сказать одно: информация, которую мы там пишем, говорит: что должно существовать, не описывая серию шагов, чтобы это стало правдой. Когда мы бежим terraform plan
(или когда Terraform запускает его неявно как часть terraform apply
) Terraform принимает конфигурацию, которая, в общем, состоит из существительные (экземпляр EC2, определение облачного запуска, виртуальная сеть) и Сам Терраформ превращает это в набор глаголы (Создайте экземпляр EC2, Обновить определение облачного режима, Удалить виртуальная сеть).
Другой аспект Terraform, связанный с динамическим программированием, заключается в том, что обычно нет явных заявлений о заказ операций в конфигурации Terraform. Так же, как Terraform сам производит запланированный набор действий, Terraform также сам определяет порядок этих действий, а также те из них, которые потенциально могут быть предприняты одновременно. Можно сказать, что Terraform использует поток данных (способ передачи значений от одного ресурса к другому посредством выражений), чтобы сделать вывод поток управления.
В частности, отмечу, что нельзя сказать, что Terraform не имеет потока управления. вообще: есть еще идея правильной последовательности операций, которая требуется для получения желаемого результата. Но этот поток управления подразумевает распространение данных между объектами, которое явно не описано автором.
Хотя пользователи часто используют слово «циклы» для описания таких повторяющихся конструкций Terraform, как for
выражения, ресурс for_each
, и dynamic
блоки, они больше похожи на комбинаторы функционального программирования, такие как карта, где мы описываем преобразование одного значения в другое, а не последовательность выполняемых операций. Terraform может реализовать это преобразование, используя различные пути управления, если конечный результат соответствует тому, что пользователь описал с помощью выражений.
В provisioner
Концепция Terraform в целом делает Terraform чем-то вроде гибрида: провайдеры - это определяемая пользователем последовательность обязательных шагов, которые должны быть выполнены как часть шага «создать» или «уничтожить». Terraform содержит средства обеспечения в качестве меры прагматизма, потому что для объектов с отслеживанием состояния, таких как виртуальные машины, мы часто должны использовать императивные методы, чтобы гарантировать, что побочные эффекты появляются в определенном порядке, который Terraform, естественно, не сможет вывести. С учетом сказанного, Поставщики Terraform задокументированы как последнее средство конкретно так как они уходят от обычной модели и оставляют Terraform неспособной полностью смоделировать набор выполняемых действий. В Terraform также отсутствуют конструкции для написания динамического потока управления. в пределах языка с использованием провайдеров: нет механизма для записи циклов и условных переходов, и вместо этого провайдеры (с точки зрения Terraform) представляют собой просто плоскую фиксированную последовательность операций.
В список задач в Ansible playbook - это упорядоченная последовательность глаголов, определяющая действие, которое необходимо предпринять. Многие из этих типов задач представлены как «Убедитесь, что ...», например «Убедитесь, что /etc/foo
существует и содержит это содержимое », поэтому я думаю, что будет справедливо сказать, что эти задачи являются декларативными утверждениями, представленными в форме контрольного списка: если файл уже существует и уже имеет это содержимое, то с точки зрения внешнего наблюдателя эта задача будет вообще не предпринимать никаких действий.
Некоторые задачи Ansible - это те вещи, которые Terraform мог бы делегировать провайдерам, например, «запускать эту отдельную программу для ее побочных эффектов». В этом случае, как и в Terraform с инициаторами, ответственность за понимание побочных эффектов и обеспечение того, чтобы шаги выполнялись в правильном порядке, чтобы эти побочные эффекты имели смысл, ложатся на автора.
Поток управления - это область, в которой модели Terraform и Ansible расходятся более значительно. Как я отмечал ранее, список задач - это упорядоченная последовательность, поэтому автор должен явно указать соответствующий порядок действий, описанных в этом списке задач. Ansible не выводит автоматически поток управления из потока данных, как это делает Terraform.
Ansible имеет петли это больше похоже на их тезку императивного программирования. В общих случаях они в принципе похожи на комбинаторы функционального программирования, но для циклов задач, в частности, тот факт, что сами задачи могут иметь побочные эффекты, означает, что порядок выполнения цикла имеет значение, и поэтому циклы Ansible являются явным потоком управления.
Исходя из вышеперечисленных характеристик, я считаю, что и Terraform, и Ansible можно использовать как декларативно, так и процедурно. Однако язык Terraform предназначен для расставлять приоритеты решения проблем в стиле декларативного программирования и ограничивают / препятствуют процедурным подходам, в то время как Ansible отдает приоритет процедурным подходам, хотя, возможно, позволяет автору выберите использовать декларативный подход.