Более пристальный взгляд на самую большую тенденцию в DevOps

Часть 2 Декларативных микрофреймворков DevOps

Декларативное программирование - не новое понятие, но его использование для описания инструментов DevOps в последнее время резко возросло. Это может показаться еще одним модным модным словечком, но декларативное программирование имеет некоторые уникальные преимущества для DevOps, которые гарантируют, что оно останется.

Что такое декларативное программирование?

Декларативное программирование часто объединяют с функциональным программированием, но это несколько иначе. Самый простой способ понять декларативную парадигму - противопоставить ее нормальному императивному коду.

Что такое императивное программирование?

Если вы задаете этот вопрос, хорошим примером императивного кода является ваша текущая кодовая база. Императивный код определяет логику как последовательность шагов. Каждый шаг ожидает завершения предыдущего шага перед продолжением, и каждый шаг изменяет состояние вашей системы. «Состояние» - это все, что имеет динамическое значение, например:

  • переменная в памяти
  • какой-то ресурс на диске, например файл или параметр реестра
  • какой-то внешний ресурс, например виртуальная машина в облаке

Что плохого в императивном программировании?

Состояние сложно отлаживать. Если у вас есть состояние, хранящееся в переменных, вам может потребоваться отладчик для проверки состояния вашей программы. Если у вас есть состояние, хранящееся на диске или в облаке, вам, возможно, придется запустить сценарий или открыть проводник для просмотра состояния. Хуже того, состояние является синонимом побочных эффектов, которые гораздо сложнее поддаются модульному тестированию, чем чистая функция. Чистые функции - функции, которые гарантируют отсутствие побочных эффектов - необходимо только модульно тестировать с точки зрения их входных и выходных данных, тогда как функции с побочными эффектами также требуют тестирования на отсутствие или наличие побочного действия.

Там должен быть лучший способ!

Альтернативой императивному программированию является декларативное программирование. В декларативном программировании вы «объявляете» свои структуры данных и «запрашиваете» их состояние. Например, SQL - чисто декларативный язык, потому что вы «объявляете» свои структуры данных (базы данных, таблицы и их взаимосвязи), а затем «запрашиваете» полученное значение. Тот же аргумент можно привести и для других чисто декларативных языков, таких как Haskell, где вы «объявляете» свои структуры данных как деревья и «запрашиваете» подстановки в этих структурах данных.

В декларативном программировании вы «объявляете» свои структуры данных и «запрашиваете» их состояние.

Не волнуйтесь, если вас смущает абстрактный язык - могут потребоваться недели, чтобы интуитивно понять, как работают чисто декларативные языки. Все, что вам нужно помнить, это то, что декларативный код избегает мутирующего состояния в вашей программе, что впоследствии позволяет избежать побочных эффектов, поэтому он автоматически идемпотентен и его легче отлаживать.

Написание декларативного кода

Вы не используете чисто декларативный язык для своих приложений и скриптов, но вы все равно можете применять декларативные концепции к своему коду. Эти рекомендации сделают ваш код более декларативным:

  • «Запрашивайте» ваши данные, добавляя как можно больше логики в выражения, которые ссылаются на ваши ранее определенные константы.
  • «Объявите» свои данные, привязав эти выражения запроса к неизменной переменной.

Этот пример фрагмента PowerShell для агрегирования журналов запросов к серверу демонстрирует эти рекомендации, никогда не изменяя состояние и максимально используя выражения.

Поскольку мы «запрашиваем», а не «выполняем последовательность шагов», наши вычисления по своей сути не имеют состояния и не имеют побочных эффектов, поэтому мы можем разбить проблему на все более мелкие и более мелкие тестируемые компоненты без необходимости запускать отладчик. .

Декларативный DevOps

Декларативный DevOps - это частный случай декларативного программирования. С помощью декларативного DevOps мы определяем желаемое состояние нашей конфигурации, а затем позволяем платформе установить желаемое состояние или «сделать это так».

В декларативном DevOps вы «объявляете» желаемое состояние вашей конфигурации, а затем позволяете платформе «сделать это».

Пропустить промежуточные состояния

В то время как большинство скриптов должны учитывать любое количество начальных и промежуточных состояний, в декларативных конфигурациях мы определяем только конечное «желаемое» состояние. Поскольку нам не нужно учитывать эти другие состояния в нашей программе, у нас значительно меньше кода для отладки.

Поскольку нам не нужно беспокоиться о промежуточных состояниях, мы можем гарантировать, что наш код будет идемпотентным: у него не будет разных результатов (например, выдачи ошибки), если вы запустите его несколько раз. С Declarative DevOps вам больше никогда не придется вручную перестраивать вашу конфигурацию, если ваш сценарий развертывания выйдет из строя на полпути - вы просто перезапустите свой декларативный сценарий. Поскольку нам не нужно самостоятельно реализовывать идемпотентность, наш код также будет чище, потому что у нас не будет операторов WET if во всем коде или использования -Force и -ErrorAction Ignore для подавления всех ошибок, даже если некоторые из ошибок могут ( даже в редких случаях).

Объявите свои абстрактные типы данных

Декларативные программы DevOps принимают на вход сериализованный абстрактный тип данных - обычно набор ресурсов, определяющих систему, - который мы называем конфигурацией. Поскольку они абстрактны, они обладают высокой расширяемостью, а поскольку они представляют собой схематизированные типы данных, их можно статически проверять путем проверки конфигурации по схеме, что имеет решающее значение для защитного кода DevOps.

Одна из распространенных ошибок при попытке создания декларативных программ - использование Составного типа данных в качестве входных данных вместо абстрактного типа данных. Составные типы - это просто глобальные константы с пространством имен, а не расширяемые структуры данных. Хотя конфигурации составного типа данных полезны для скомпилированных программ, поэтому вы можете изменять входные данные без перекомпиляции программы, эти конфигурации могут фактически добавить ненужную абстракцию в сценарии DevOps (которые не требуют перекомпиляции после изменений кода) и внести небольшие изменения кода, требующие нескольких кодов. изменения.

Как вы можете видеть в сравнении выше, наша конфигурация абстрактного типа данных справа строго использует списки и карты, в то время как конфигурация слева не так универсальна.

Популярные декларативные системы DevOps

Это одни из самых популярных инструментов DevOps для определения желаемых состояний инфраструктуры и платформ.

  • Диаграммы Kubernetes / Helm - диаграммы Helm позволяют определять желаемое состояние ресурсов Kubernetes: Pod, ServiceAccounts, Containers и т. д.
  • Шаблоны ARM и CloudFormation - шаблоны ARM для Azure и шаблоны CloudFormation для AWS позволяют определять желаемое состояние облачных ресурсов: виртуальных машин, учетных записей хранения, балансировщиков нагрузки и т. д.
  • Конфигурации желаемого состояния PowerShell - DSC позволяют определять желаемое состояние ресурсов в контексте вычислений (физический сервер, виртуальная машина или контейнер Docker): файл, параметр реестра, список контроля доступа и т. Д.

Следующие шаги

Начните использовать декларативную систему DevOps и проверяйте конфигурации на git, чтобы вы могли достичь Инфраструктура как код.

Узнайте больше о масштабировании PowerShell

Эта статья является частью серии статей Declarative DevOps Microframeworks по масштабному управлению кодовыми базами PowerShell. Прочтите остальную часть серии, чтобы узнать больше о разработке и написании меньшего количества кода для больших баз кода DevOps.