Terraform: инфраструктура на уровне кода — страница 62 из 65

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

$ SKIP_teardown_db=true \

  SKIP_teardown_app=true \

  SKIP_deploy_db=true \

  go test -timeout 30m -run 'TestHelloWorldAppStageWithStages'

(...)

PASS

ok   terraform-up-and-running   13.824s

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

При внесении изменений не забывайте регулярно фиксировать свой код:

$ git commit -m "Updated Hello, World text"


Подача изменений на рассмотрение

Если все работает так, как вы того ожидали, можно создать запрос на включение внесенных изменений (точно так же, как и в случае с прикладным кодом). Ваши коллеги просмотрят ваши изменения в поиске возможных ошибок, заодно исправляя их в соответствии с рекомендациями по оформлению кода. В ходе командной разработки, независимо от того, какой именно код вы пишете, все должны следовать общим рекомендациям. Одно из моих любимых определений чистого кода было дано в интервью, которое я взял у Ника Делламаггиора для одной из своих предыдущих книг Hello, Startup (http://www.hello-startup.net).

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

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

Ник Делламаггиор, ведущий разработчик инфраструктуры в Coursera

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

• документация;

• автоматические тесты;

• структура каталогов;

• рекомендации по оформлению кода.


Документация

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

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

Письменная документация. Большинство модулей Terraform должны содержать файл README, который объясняет их назначение, причину их существования и то, как их можно модифицировать. Этот файл лучше написать в первую очередь, еще до какого-либо кода Terraform. Так, прежде чем окунуться в детали реализации, вы будете помнить о том, что и зачем вы создаете61. Потратив 20 минут на написание README, вы сможете сэкономить часы, которые ушли бы на создание кода, решающего не ту проблему. Помимо этого файла, также следует позаботиться о практических руководствах, документации к API, вики-страницах и проектных документах, которые более глубоко объясняют принцип работы кода и то, почему он так написан.

• Документация в коде. Внутри самого кода в качестве документации можно добавлять комментарии. Terraform считает комментарием любой текст, который начинается со знака #. Не пытайтесь объяснить в комментариях, что делает ваш код; это его работа. Предоставляйте лишь ту информацию, которую нельзя выразить в коде: например, как его следует использовать или почему было выбрано то или иное архитектурное решение. Terraform также позволяет указывать для каждой входной и выходной переменной параметр description, который отлично подходит для описания того, как эти переменные должны использоваться.

• Примеры кода. Как уже обсуждалось в главе 6, любой модуль Terraform должен включать в себя примеры того, как его следует применять. Это отличная возможность подчеркнуть предполагаемые сценарии использования, позволить пользователям запустить ваш модуль без написания какого-либо кода и, что самое главное, добавить автоматические тесты.


Автоматические тесты

Глава 7 полностью посвящена тестированию кода Terraform, поэтому скажу лишь, что инфраструктурный код без тестов можно считать неисправным. В связи с этим один из важнейших комментариев, которые вы можете оставить при разборе кода, звучит так: «Как вы это протестировали?»


Структура каталогов

Ваша команда должна выработать правила о том, где должен храниться код Terra­form и какой должна быть структура каталогов. Поскольку структура файлов и каталогов определяет то, как Terraform хранит свое состояние, нужно особенно тщательно подумать о влиянии вашей структуры каталогов на возможность предоставления гарантий изоляции, чтобы, например, изменения в среде финального тестирования не вызвали проблем в промышленном окружении. При разборе кода важно следить за соблюдением структуры, описанной в подразделе «Изоляция с помощью описания структуры файлов» на с. 119, которая обеспечивает изоляцию разных окружений (таких как Stage и Prod) и отдельных компонентов (скажем, сетевой топологии для всей среды и отдельного приложения в этой среде).


Рекомендации по оформлению кода

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

У Terraform даже есть встроенная команда fmt, которая может автоматически привести код к единому стилю:

$ terraform fmt

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


Выполнение автоматических тестов

У инфраструктурного кода, как и у прикладного, должны быть хуки, которые запускают автоматические тесты в CI-сервере после каждой фиксации и отображают их результаты на странице запроса на включение внесенных изменений. Вы уже видели в главе 7, как пишутся модульные, интеграционные и сквозные тесты для кода Terraform. Но есть еще одна крайне важная проверка, которую вы должны сделать: terraformplan. Здесь действует простое правило: прежде чем применять изменения, всегда выполняйте команду plan.

Terraform автоматически отображает вывод команды plan, когда вы выполняете apply, поэтому данное правило означает, что вы должны остановиться и прочитать этот вывод! Вы не поверите, какие ошибки можно предотвратить, потратив 30 секунд на анализ расхождений, которые выводит apply. Чтобы поощрять это поведение, команду plan можно интегрировать в процесс разбора кода. Например, открытый инструмент под названием Atlantis (https://www.runatlantis.io/) автоматически выполняет terraformplan при фиксации кода и добавляет вывод plan в виде комментариев к запросам на включение внесенных изменений, как показано на рис. 8.3.

Более того, команда plan позволяет сохранять свой вывод в файл:

$ terraform plan -out=example.plan

Затем для этого файла можно выполнить команду apply, чтобы она применила именно те изменения, которые вы видели в начале:

$ terraform apply example.plan

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


Слияние и выпуск новой версии

После того как члены вашей команды разобрали внесенные изменения и вывод команды plan и все ваши тесты были успешно пройдены, можно объединить свой код с веткой master и выпустить новую версию. Как и с прикладным кодом, для этого подходят теги Git:

$ git tag -a "v0.0.6" -m "Updated hello-world-example text"

$ git push --follow-tags

Рис. 8.3. Atlantis умеет автоматически добавлять вывод команды terraform plan в виде комментариев к запросам на включение внесенных изменений

Отличие в том, что прикладной код часто развертывается в виде отдельного артефакта, такого как образ Docker или ВМ, тогда как Terraform умеет самостоятельно загружать код из Git. Таким образом, репозиторий с заданным тегом сам по себе неизменяемый артефакт с поддержкой версионирования, и именно он будет развертываться.


Развертывание

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

• инструментарий для развертывания;

• стратегии развертывания;

• сервер для развертывания;

• продвижение артефакта по разным окружениям.


Инструментарий для развертывания

Основным средством для развертывания кода Terraform является сам Terraform. Но есть также несколько других инструментов, которые могут пригодиться.

Atlantis. Вы уже видели этот открытый инструмент. Он умеет не только добавлять вывод команды plan в ваши запросы на сохранение внесенных изменений, но и запускать terraformapply в ответ на добавление в ваш запрос специального комментария. За счет этого вы получаете удобный веб-интерфейс для развертывания Terraform. Однако имейте в виду, что он не поддерживает версионирование. Это может затруднить поддержку и отладку крупных проектов.