В октябре этого года я выступил с докладом на конференции HashiConf 2018, где рассказал о 5 ключевых уроках, которые я и мои коллеги из Gruntwork усвоили в процессе создания и поддержки библиотеки из более чем 300 000 строк инфраструктурного кода, используемой в производственных системах сотнями компаний. В этой публикации я поделюсь видео и слайдами с выступления, а также сокращенной текстовой версией описания 5 основных уроков. Несмотря на то, что индустрия полна модных прогрессивных слов: Kubernetes, микросервисы, сервисные сетки, неизменяемая инфраструктура, большие данные, озера данных и т. д., — реальность такова, что, когда ты с головой погружен в создание инфраструктуры, ты не чувствуешь себя таким уж модным и прогрессивным. Лично мне DevOps больше больше напоминает вот что:     Создавать инфраструктуру производственного уровня сложно. Это настоящий стресс. И кушает много времени. Очень много времени. Здесь показано, сколько примерно времени понадобится, чтобы реализовать следующий инфраструктурный проект. Мы опирались на эмпирические данные, которые собрали в ходе работы с сотнями различных компаний:  Проекты DevOps всегда занимают больше времени, чем вы ожидаете. Всегда. Почему так?
Первая причина — это "стрижка яка". Ниже — яркая иллюстрация этого феномена, (это отрывок из сериала “Малкольм в центре внимания”) Вторая причина — в том, что процесс создания инфраструктуры производственного уровня (например, инфраструктуры, на которую вы поставили бы свою компанию) состоит из тысячи мелких деталей. Подавляющее большинство разработчиков об этих деталях не осведомлены, поэтому, оценивая проект, вы обычно забываете о многих критических (и трудоемких) задачах.
Чтобы этого избежать, каждый раз, приступая к работе над новым участком инфраструктуры, используйте такой вот чеклист:  Не все элементы списка понадобятся для каждого отдельного участка инфраструктуры, но вы должны осознанно и явно документировать, какие элементы вы реализовали, а какие решили пропустить и почему. Перечислим основные инструменты, которые мы в Gruntwork используем для создания и управления инфраструктурой (по состоянию на 2018 год):  Все эти инструменты полезны, но урок не в этом. Нужно понимать, что одних инструментов недостаточно. Необходимо изменить еще и поведение команды. В частности, даже самые лучшие инструменты в мире не помогут вашей команде, если она не хочет их использовать или у нее недостаточно времени, чтобы научиться их использовать. Таким образом, ключевой вывод — в том, что использование «инфраструктуры как кода» — это инвестиции, то есть от вас потребуются определенные первоначальные затраты. Если инвестируете с умом, то получите большие дивиденды в долгосрочной перспективе. Новички в деле применения «инфраструктуры как кода» часто определяют всю свою инфраструктуру для всех своих сред (среда разработки, промежуточная среда, производственная среда и т. д.) в одном файле или наборе файлов, которые развертываются как единое целое. Зря. Вот лишь некоторые из недостатков такого подхода: Короче говоря, вы должны формировать свой код из небольших автономных и многократно используемых составных модулей. Это не новость и не открытие. Вы слышали это тысячу раз, хотя и в несколько иных ситуациях: Если ваш инфраструктурный код не имеет автоматических тестов, он работает неправильно. Вы просто еще не знаете об этом. Но тестировать инфраструктурный код сложно. У вас нет ни «локального хоста» (например, вы не можете развернуть виртуальное частное облако AWS VPC у себя на ноутбуке), ни реальных «модульных тестов» (например, вы не можете изолировать код Terraform от «внешнего» мира, поскольку он как раз и предназначен для общения с внешним миром). Поэтому чтобы правильно протестировать инфраструктурный код, обычно приходится развертывать его в реальной среде, запускать реальную инфраструктуру, проверять работоспособность кода, а затем разбивать его (описание этого стиля тестирования: см. Terratest, это библиотека с открытым исходным кодом, включающая инструменты для тестирования кода Terraform, Packer и Docker, работы с API-интерфейсами AWS, GCP и Kubernetes, выполнения команд оболочки локально и на удаленных серверах через SSH, а также многие другие возможности). Таким образом, тестируя инфраструктуру, надо слегка переопределить условия:  Модульные тесты развертывают и тестируют один или несколько тесно связанных модулей инфраструктуры одного типа (например, модули для одной базы данных). Интеграционные тесты развертывают и тестируют несколько модулей инфраструктуры различных типов, чтобы проверить правильность их совместной работы (например, модули базы данных и модули веб-службы). Сквозные тесты (e2e) развертывают и тестируют всю архитектуру.
Обратите внимание на то, что диаграмма представляет собой пирамиду: у нас много модульных тестов, поменьше интеграционных тестов и совсем мало e2e-тестов. Почему? Это зависит от длительности выполнения каждого типа тестов:  Инфраструктурные тесты занимают много времени, особенно на верхних уровнях пирамиды, и, естественно, вы захотите найти и исправить как можно больше ошибок еще в самом низу. Для этого нужно: Подытожим все вышесказанное. Вот как вы теперь будете создавать инфраструктуру и управлять ею: