Я расскажу вам, как быстро написать и развернуть код terraform с помощью localstack и как протестировать ваш код с помощью terratest. Вы можете найти код на моем github

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

Я твердо верю в важность тестирования и, более того, мне очень нравится подход TDD (Test Driven Development). Когда я начал использовать terraform, это было весело, вы повторяете свой код, пытаетесь развернуть, видите его в своей облачной консоли и продвигаетесь вперед. К сожалению, довольно скоро я понял, что этот способ написания и развертывания модуля/кода довольно трудоемкий и вы теряете много времени. Чаще всего я тестировал сервис в консоли вручную, так как вы не можете быть уверены, что то, что вы развернули, работает так, как вы ожидаете.

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

Обратите внимание, что я привел примеры интеграции localstack и terratest с действиями gitlab-ci и github на своем github.

Представляем Terratest.

Terratest — это библиотека Go, которая упрощает написание автоматических тестов для кода вашей инфраструктуры. Он предоставляет множество вспомогательных функций для общих задач тестирования инфраструктуры, таких как тестирование кода terraform и его развертывание, но предоставляет гораздо больше.

Представляем Localstack.

Localstack предоставляет простую в использовании среду тестирования/мока для разработки облачных приложений. Он запускает тестовую среду на вашем локальном компьютере, которая предоставляет те же функции и API, что и реальная облачная среда AWS, такая как AWS. Вы можете использовать localstack в своем CICD или локально.

Практика.

Как выполнить локальное развертывание с помощью terraform и localstack.

В этой статье мы будем использовать docker-compose.

После создания файла docker-compose.yml выполните docker-compose up на терминале, чтобы запустить localstack. Теперь вы можете развертывать ресурсы локально, но сначала вам нужно настроить provider.tf для использования конечных точек localstack с terraform, а не с AWS. Вот пример.

В этом провайдере нам еще нужно указать фиктивные учетные данные для AWS с доступом и секретным ключом. Чтобы избежать проблем с маршрутизацией и аутентификацией, мы добавляем эти четыре параметра s3_force_path_style , skip_credentials_validation , skip_metadata_api_check и skip_requesting_account_id. Все параметры говорят сами за себя, за исключением, может быть, s3_force_path_style. Этот параметр указывает, следует ли разрешить запросу использовать адресацию в стиле пути, т. е. https://s3.amazonaws.com/BUCKET/KEY. По умолчанию клиент S3 будет использовать адресацию виртуального размещенного корзины, https://BUCKET.s3.amazonaws.com/KEY, когда это возможно. Специфично для сервиса Amazon S3. https://registry.terraform.io/providers/hashicorp/aws/latest/docs#s3_use_path_style

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

Модульный тест

Все тесты с использованием Terratest написаны на Golang. Это довольно удобно, потому что, как вы знаете, terraform разрабатывается с помощью go, как и большинство инструментов DevOps.

Вот пример, показывающий, как легко проверить свою разработку. Этот фрагмент кода запустит terraform init, terraform apply --auto-approve, извлечет открытые outputs, утвердит их и terraform destroy --auto-approve.

Как видите, в terraformOptions мы указываем каталог, в который мы записали экземпляр нашего модуля terraform для целей тестирования. Мы также предоставляем имя файла для передачи значений переменных. У вас есть много других вариантов, таких как OutputMaxLineSize, MaxRetries и т. д.

После этого вам нужно определить действие terraform destroy. Указав ключевое слово defer, вы даете указание уничтожить ресурсы, созданные тестом после apply, и выполнить любое дополнительное тестирование независимо от того, пройден тест или нет.

И последнее, но не менее важное: вы на самом деле используете свои terraform init и terraform apply. Если инициализация или apply не пройдены, тест считается неудачным. В противном случае испытание считается успешным.

Что ж, теперь, когда у нас есть наша установка, нам нужно провести некоторое тестирование, иначе этого недостаточно!

Я добавил два утверждения для ID и ARN, которые выводит наш модуль. До этого функция ничего не тестировала, кроме создания ресурсов. Но на самом деле, даже без тестов очень полезно иметь возможность протестировать свой модуль локально. На мой взгляд, это позволяет ускорить разработку, если вы можете развернуть свою инфраструктуру локально.

Ради этой статьи я создал очень простой модуль ведра terraform aws s3, чтобы легко активировать управление версиями. Как видите, для каждого сегмента я тестирую оба выхода: ID и ARN моего сегмента.

Вы можете найти полный код на моем github

Дополнительные тесты с golang.

В этот момент я был очень взволнован возможностями объединения terratest с локальным стеком. Итак, как насчет дополнительного тестирования, чтобы проверить, правильно ли активировано управление версиями, и некоторого функционального тестирования для размещения, получения, удаления и утверждения значения put с извлеченным значением из get.

Проверьте правильность активации управления версиями

Сначала, чтобы выполнить больше тестов, я создал функцию, которая не дублирует объявление terraform.Options .

Для этого и следующих тестов мне понадобится сеанс s3 из aws gloang sdk, чтобы выполнять вызовы API в корзине развертывания в среде localstack. Для этого я объявил глобальную переменную с функцией инициализации, которая дает мне повторно используемый сеанс s3.

Вы можете увидеть два необычных ввода в экземпляре сеанса s3. Здесь важны как endpoint, так и s3ForcePAthStyle. s3ForcePAthStyle указывает SDK использовать URL-адрес hostname/bucket вместо bucket.hostname, что позволяет SDK запрашивать корзину localstack. Без этих двух входных данных SDK всегда будет пытаться попасть в AWS.

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

Функциональное тестирование

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

Как мы инициировали сеанс s3 для предыдущего теста, нам не нужно делать это снова.

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

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

Последнее, что я хотел бы представить вам, это gotestsum. Этот инструмент выполняет команду go test, но дает более читаемый вывод, например pytest.

Весь мой код вы можете найти на github.

Я также привожу примеры того, как интегрировать localstack и terratest с gitlab-ci, действиями github и circle-ci.

Спасибо за прочтение,

Не стесняйтесь оставлять свои мысли в разделе комментариев!