Важную роль в деятельности IT-специалистов занимает системное администрирование. Желание упростить все процессы до максимума оставляет лишь один выбор – автоматизация. В этом случае существенно помогают средства «Everything-as-Code».

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

Часто в этом случае используется внешняя DNS-зона, которая хостится на nic.ru. Тогда она ее ограничивалась несколькими доменами, на базе которых размещалось более 3000 записей. Стоит отметить, что преимущественное большинство из этого количества было записями для стендов, предназначенных разработчикам. Их единственное отличие – порядковые номера или какой-нибудь суффикс. 

Количество таких dev<N> достигало 150, в зависимости от временного промежутка. Весь этот процесс осложнял один факт – необходимость периодического изменения, добавления и удаления записей. К примеру, некоторые DEV-стенды должны быть переброшены на другой IP, или же для каждого из стендов необходимо создать персональный CNAME, либо что-то еще в этом роде. 

Все эти действия выполнялись либо специалистами (поправка, добавление единичных записей), либо обвязками скриптов, для которых устанавливались сложные параметры, багги и большие мануалы. Можно сказать, что система далеко не из самых легких. 

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

Затем можно проверить свою теорию, и воспользовался строкой поиска Google, вбив максимально точную фразу «DNS as Code». Далее последовал поиск подходящих инструментов, которые помогли бы всем планам перейти от статуса фантазий к реальности. Прошло буквально 10 минут, прежде чем удастся наткнуться на несколько инструментов – Dnscontrol и Octodns. Они достаточно интересные, поэтому лучшим решением было незамедлительное изучение особенностей и поведения в работе. 

Чтобы внести больше ясности, стоит рассмотреть их подробнее. 

Octodns

OctoDNS – обобщенное название инструмента, основа которого положена на подход «инфраструктура в виде кода». С его помощью осуществляется развертывание и управление DNS-зонами. Для выполнения действий используется ряд стандартных принципов программного обеспечения. Это касается контроля версий, тестирования и автоматического развертывания. Создателем OctoDNS является GitHub, его написали на Python.

С этим вопросом разобраться не тяжело, но из него вытекает немало последующих. Как же действовать после изучения подходящего инструмента? С чего начинать? 

Используя OctoDNS специалисты имеют возможность исключить различные сложности, с которыми связано ручное управление DNS, поскольку для хранения файлов зон используется исключительно структурированный формат (YAML).

Итак, после того, как с раздела системных администраторов мы переходим к девопсам, тактику придется немного изменить. Важно подробно изучить великий и могучий YAML. 

Посмотрим на его возможности:

  • наличие разработанных провайдеров, которые взаимодействуют со многими популярными облачными системами и регистраторами;
  • возможность синхронизации DNS-записи, привязав несколько провайдеров одновременно;
  • возможность встраивания в CI/CD.

Описание DNS-записей в формате YAML выглядит приблизительно так: 

  • ~/octodns/config/config.yaml
  • ~/octodns/config/your-domain.yaml.

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

  • создание циклов и других алгоритмических конструкций для упрощения создания однотипных записей;
  • экспорт зоны в формате Bind.

Из-за этих минусов обесцениваются возможности использования инструментов на базе моего кейса. Продолжаем искать. 

Dnscontrol

DNSControl – достаточно удобный инструмент, в построении которого лежит принцип инфраструктуры в формате кода. С его помощью можно развертывать и управлять зонами DNS. При этом используются стандартные принципы разработки ПО. Это касается контроля версий, тестирования и автоматизированного развертывания. Создателем инструмента DNSControl является Stack Exchange. Его написали на Go.

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

DNSControl использует javascript в качестве основного языка ввода, чтобы обеспечить мощность и гибкость для настройки ваших доменов. Основная цель javascript — создать объект DNSConfig, который будет передаваться туда и обратно.

Здесь я был немного удивлен. Но мы продолжаем изучать принцип работы инструмента. 

Основные файлы конфигурации выглядят следующим образом:

  • dnscontrol.js.

А вот шаблон файлов, в которых описана ваша зона:

  • my-zone.ru.js.

Выглядит так себе, если честно. Если сравнивать с предыдущим вариантом, то YAML явно завоюет больше симпатий. Все еще непонятно, почему разработчики решили встроить JavaScrip для написания такого простенького кода. Повторно обратимся к документации и остановимся на интересной записи:

«Продвинутые темы:

Уловки кода: безопасно используйте макросы и циклы.»

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

«Язык dnsconfig.js — это JavaScript. С другой стороны, это означает, что вы можете использовать циклы, переменные и все, что захотите …

Конечно, вы можете проделать много интересных трюков с if / thens, макросами и циклами. Да, вы понимаете код. Однако подумайте о своих коллегах, которые будут следующими, кто отредактирует файл. Вы настраиваете их на провал?»

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

Если исключить страх, можно перейти к более сложным примерам, по типу: 

  • my-zone.ru.js.

Многие привыкли использовать провайдера Bind. Он выполняет генерирование файлов зон в формате Bind. В дальнейшем они доступны для использования в любом направлении. 

Для того, чтобы применить конфигурацию, воспользуемся командой dnscontrol push:

  • вывод.

Изучив каталог zones, можно заметить появление файлов  зоны формата Bind:

  • myzone.ru.

Далее, когда в исходных файлах появился ряд изменений, выполняется команда dnscontrol preview с перечнем планируемых изменений. Чтобы из применить придется повторно воспользоваться командой dnscontrol push. Это достаточно удобный вариант. 

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

Безусловно, этот инструмент – именно то, что нужно. Займемся построением полного процесса DNS as Code.

Этапы построения

После того, как специалистам удалось определиться с выбором подходящего инструмента, приступаем к построению CI. Принципы Infrastructure as Code требуют применения практических навыков, которые используются во время работы над ПО. Среди них:

  • внедрение системы контроля версий;
  • код ревью;
  • CI/CD;
  • проведение тестирования;

Новичкам будет сложновато разобраться со всеми этими требованиями, по возможности соберем их в пайплайн.

Этот проект реализовывается с использованием Gitlab. Встроенный Container Registry и CI позволяет осуществить выстраивание всего необходимого пеплайна в одном месте. Для этого используем репрезиторий проекта, упростив себе задачу. 

Предварительно займемся определением шагов, которые будут содержать наш пайплайн. Оптимальным вариантом будет такой состав:

  • validate — валидация кода;
  • prepare — подготовка всего необходимого, скачивание текущего состояния зон с сайта NIC.RU;
  • plan — построение плана изменений;
  • build — сборка новых файлов зон;
  • test — тестирование зон на DNS-сервере;
  • deploy — отправка проверенных зон в NIC.RU и их применение.

Далее выбираем оптимальные docker-образы, которые будут использоваться на протяжении каждого шага. Можно остановиться на двух: 

  • stackexchange/dnscontrol — для всех шагов, кроме test;
  • internetsystemsconsortium/bind9 — для шага test.

Придется пересобирать эти образы, поскольку понадобилась настройка корпоративных сертификатов и дополнительных утилит. 

Несколько суток ушло на эксперименты с Gitlab CI, и в итоге получился пайплайн такого формата:

  • .gitlab-ci.yml

Хочется уделить дополнительное внимание шагам plan и test.

На первом из них plan после выводы команды началось перенаправление к файлу и последующее складывание его в артефакты. Этот артефакт был помечен опцией expose_as. Она свидетельствует  о том, что когда контрибьютор создаст Merge Request, ссылка на данный файл и джобу прикрепится в автоматическом порядке. Эта функция удобна для ревьюверов, которые кроме внесенных коррективов в коде смогут изучать и запланированные изменения в результирующей зоне. Выглядит это вот так:

После нажатия на кнопку plan, которая находится снизу надписи Job, можно провалиться в вывод, чтобы ознакомиться с подробным планом: 

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

Некоторые шаги требуют использования shell-скриптовс необходимой логикой. Процесс редактируется в зависимости от необходимостей.

Shell-срипты для CI:

  • nic_auth.sh
  • nic_download.sh
  • nic_upload.sh
  • zones.conf.sh
  • bind_test.sh

На этом, пожалуй, закончим данную тему. Надеемся, она была полезной для вас.