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

Одна проблема, с которой я столкнулся, заключается в том, что когда я делаю некоторые изменения, связанные с ресурсами, которые я определил в pulumi, и их конфигурациями, запуска pulumi preview недостаточно, чтобы убедиться, что все работает правильно. Возможно, я правильно определил свои ресурсы, и команда preview сообщит мне об этом, но мои конфигурации, такие как порты, которые были определены в балансировщике нагрузки приложения, или конфигурация групп безопасности не были установлены правильно. Таким образом, после того, как я слил ветку фичи с одной из веток, например development, только позже я обнаружил бы, что не все было установлено правильно при попытке попасть в одну из конечных точек. Помните, что одна из самых важных вещей, о которых следует помнить, когда речь заходит о DevOps, заключается в том, что нам нужно быстро ошибаться, и мне нужно жить с этим.

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

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

Начнем со структуры проекта, с которым мы будем работать.

Каталог infra/ содержит весь код, связанный с пулуми и инфраструктурой, такой как определение ресурсов и их конфигурации. Внутри infra/ я создал новую папку с именем automation, в которой есть код API автоматизации, который позволит нам автоматически создавать стек после каждого PR. Этот код будет запускаться через файл рабочего процесса Github Action, о котором я расскажу чуть позже. Одна важная вещь заключается в том, что у нас уже есть определенный стек, который представляет собой стек development, как вы можете видеть из файла Pulumi.development.yaml, это важно, по крайней мере, в моем случае, так как это будет стек, из которого я скопирую всю конфигурацию, например секреты и переменные среды, которые я передам различным ресурсам, которые будут созданы, т.е. экземпляру ECS.

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

  1. PR на Github создан для ветки development.
  2. Действия Github начнут срабатывать, и рабочие процессы начнут запускаться.
  3. Один рабочий процесс pull_request будет иметь шаги, которые будут cd в папке automation и запускать node index.js, который запустит наш код API автоматизации, который создаст для нас стек и развернет ресурсы.
  4. Ресурсы созданы, рецензент доволен нашим PR, он сливает изменения в целевую ветку
  5. Последнее действие Github запустится destroy_pulumi_on_merge и уничтожит стек PR, созданный с помощью его ресурсов.

Скрипт API автоматизации Pulumi

Давайте начнем с нашего API-скрипта автоматизации, который создаст новый стек, получит конфигурации, определенные нашим стеком development, а затем развернет ресурсы.

Сценарий довольно прямолинейный, я думаю. Сначала мы определяем наши аргументы, такие как имя стека (которое мы берем из переменной env PR_STACK_NAME) и workDir, указывающее на каталог, в котором находится наш Pulumi.yaml. Позже мы создаем новый стек, используя имя, которое установлено как PR_STACK_NAME. значение и скопируйте все секреты и значения конфигурации из уже существующих настроек стека, которые в этом примере Pulumi.development.yaml.

Единственное изменение, которое я делаю в этих конфигурациях, — это регион AWS. Это связано с тем, что существует ограничение в 5 эластичных IP-адресов на регион AWS, и чтобы обойти это ограничение, я развертываю ресурсы PR в другом регионе, отличном от того, который я изначально использовал для разных этапов приложения development, staging и production.

В конце мы прогоняем код pulumi up.

Действия на гитхабе

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

Рабочий процесс запроса на вытягивание

Прежде всего, это определение рабочего процесса запроса на вытягивание.

В моем случае я развертываю свои ресурсы на AWS, а также создаю кластер MongoDB, поэтому я передаю эти переменные среды.

Наиболее интересными частями этого файла рабочего процесса являются последние два шага. На предпоследнем шаге мы создаем переменную среды для стека, который мы будем создавать для PR. Это то, в чем я не уверен на 100% по нескольким причинам. Одним из них является то, что имя стека будет <target_branch_name>_<first_15_characters_of_the_branch_to_merge>. Итак, если вы создали PR, который должен объединить fix_aws_resources с веткой development, стек будет называться dev-fix-aws-resourc, что я бы не назвал лучшим именем. Это сделано потому, что, когда мы позже действительно объединяем PR, мы хотим снова получить это имя и иметь возможность сослаться на него, чтобы мы могли уничтожить стек.

К сожалению, это лучшая комбинация, которую я смог найти, которая не меняется между коммитами, например, SHA, который может меняться между коммитами и слияниями. Одна проблема, которую я имел в виду, — это ограничение символов для имен ресурсов AWS, поэтому я старался сделать его коротким, но в то же время достаточным, чтобы иметь возможность просмотреть PR на github и понять, к какому из них относится это развертывание. к.

На последнем шаге мы передаем только что созданное имя стека, которое я объяснил выше, и оно используется в скрипте infra/automation/index.js, который делает за нас всю магию.

Рабочий процесс запроса на слияние

Это самая простая часть, если вы поняли последний файл рабочего процесса и код, единственное отличие этого рабочего процесса в том, что он срабатывает при закрытии запроса на вытягивание. Единственная разница в том, что мы передаем destroy нашему сценарию автоматизации, который вы можете увидеть на последнем шаге node index.js destroy.

Спасибо

Я надеюсь, что это было полезно. У меня все еще есть некоторые сомнения, что нужно улучшить это решение, и я обязательно это сделаю. Если будут какие-либо изменения, я обязательно обновлю эту статью, и если у вас есть предложения и улучшения, я был бы очень признателен.