Эта серия блогов посвящена представлению сложных проектов DevOps как простых и доступных с помощью простого языка и множества изображений. Ты можешь это сделать!

Всем привет!

На прошлой неделе я работал над созданием универсального модуля AWS ECS для Terraform, чтобы моя команда могла легко развертывать контейнеры на Fargate, предоставляемой AWS вычислительной мощности для контейнеров.

Как от Hashi, так и от AWS доступно множество ресурсов о том, как развернуть кластер ECS, но в основном они сосредоточены только на ресурсе ECS. Они не помогут вам настроить другие необходимые ресурсы, например:

  • Группа журналов Cloudwatch для хранения журналов
  • Роль IAM «Выполнение», используемая для доступа к ресурсам и этапам выполнения задач.
  • Сгенерируйте политику IAM для доступа к секретам, корзинам S3 и ключам KMS и установите связь с ролью Execution IAM (которую я создаю динамически, используя действительно крутые циклы terraform for и конструкторы политик данных IAM)
  • Определение задачи ECS, которое инструктирует сборщика о том, как запускать, размер и среды.
  • Логический объект кластера ECS
  • Сервис ECS для связывания задач с кластером
  • Целевой объект автомасштабирования приложения, который будет использоваться с действиями автомасштабирования
  • Запланированные действия по использованию cron на стороне AWS для увеличения или уменьшения размеров пула (или перестройки пула с нуля, как я перейду)

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

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

Сначала давайте рассмотрим, как мы назовем этот модуль, а затем вы сравните его с тем, что делает модуль (это много!)

Вызов модуля

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

Поиск секретного KMS CMK ARN

Вот и много сокращений подряд! Мы хотим, чтобы наш процесс выполнения, запускающий наш контейнер, мог получить доступ к любым секретам, а также к KMS CMK (Customer Managed Key), который используется для их шифрования. Для этого нам нужен ARN CMK, который мы можем найти с помощью этого блока данных в сочетании с секретным IAM, о котором я расскажу ниже.

Вызов модуля

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

Во-первых, мы устанавливаем ecs_name, который является обозначением, чтобы разделять ресурсы, и называем их так, как люди узнают. Это позволяет запускать модуль несколько раз (много раз!) В одном аккаунте и регионе.

Затем мы передаем URL-адрес ECR - местоположение нашего изображения для запуска.

Затем мы передаем переменные задачи (несекретные, строки) и переменные секрета задачи (секрет, ARN на секрет в диспетчере секретов).

Затем мы передаем сложный объект с именем execution_iam_access. Он содержит ARN любых ресурсов, которые потребуются нашей исполнительной роли IAM. Я подробно расскажу об этом в разделе модулей ниже.

Затем мы передаем ARN роли задачи, которую должен использовать контейнер.

Наконец, мы передаем подсети и группы безопасности, которые должны использовать наш кластер и контейнер FARGATE.

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

Теперь давайте рассмотрим, что делает модуль, на основе всей информации, которую мы отправили ему выше.

Компоненты модуля

Журналы CloudWatch

Прежде всего, мы создаем группу журналов в CloudWatch для хранения журналов ECS.

Роль выполнения IAM

AWS ECS требует того, что он называет «исполняющей» ролью IAM, то есть ролью IAM, используемой для сбора всех элементов, необходимых для запуска образа контейнера. Например, эта роль обычно собирает разрешения для доступа к ECR для захвата изображения, диспетчеру секретов для извлечения секретов (и передачи их в контейнер) и KMS для получения ключей для расшифровки секретов.

Мы прикрепляем эту роль к встроенной политике AWS под названием «AmazonECSTaskExecutionRolePolicy», которая предоставляет общие права выполнения ECS, такие как доступ к ECR и запись в CloudWatch.

Политики IAM - Предварительная обработка ARN и построение политик

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

Сначала давайте начнем с того, что наши родители передали бы этому модулю. Следующее лаконично и главное: very easy to understand. Пользователям этого модуля не нужно писать политики IAM и знать, какие разрешения нужно предоставить, им просто нужно перечислить несколько ARN в правильных блоках, и модуль построит их политики и присоединит их, все автоматически.

Однако их извлечение - задача не из легких. Сначала нам нужно перебрать эту карту списков и извлечь все нужные списки - это первый for цикл. Затем в этом цикле мы выполняем еще один for цикл, на этот раз захватывая каждый указанный там секрет и добавляя * в конце, как того требует политика IAM, которую мы создадим ниже.

Обратите внимание, что у нас также есть if, который помогает нам выбрать только список, используемый для хранения secrets, а не s3_buckets или kms cmk keys.

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

Их несколько, и все они составляют списки каждой цели ресурса, которая нам понадобится для наших политик IAM ниже.

Затем мы создаем блок data, чтобы помочь нам создать наш документ политики IAM. Он основан на count, и обратите внимание на этот пустой набор, который мы использовали выше в нашем блоке locals try, если вызывающий абонент не отправил нам никаких секретов.

Обратите внимание, как мы можем просто передавать ресурсы из нашего local.execution_iam_secrets списка ресурсов, который мы подготовили заранее. Это выглядит очень аккуратно и намного проще, чем описанные выше местные команды try / flatten / for / for.

После этого мы создаем политику роли IAM, встроенную политику под ролью выполнения, и связываем ее с созданным нами документом данных.

Существует несколько их наборов, и, исходя из приведенного выше дизайна, это отличная расширяемая модель для любых других типов разрешений, которые вы хотите предоставить роли в любом контексте. Он создает отдельную ролевую политику для каждого типа разрешений, масштабируемость которой не превышает 10 или около того. Однако я не могу найти способ безопасно объединить вместе документы политики. Если вы разобрались с этой проблемой, дайте мне знать!

Определение задачи ECS

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

Обратите внимание, что у нас здесь жестко запрограммировано FARGATE, мой вариант использования не требует сборщиков с поддержкой ec2. Если у вас есть, вам нужно сделать это переменной и добавить другую логику. Обратите внимание на параметры ЦП и памяти Fargate, которые по умолчанию равны 1024 ЦП и 2048 память, но при необходимости их можно изменить и увеличить.

Затем у нас есть определение контейнера, которое почти полностью построено для нас на основе предоставленной нами информации. По умолчанию мы используем тег :latest в ECR, не стесняйтесь игнорировать его в вызывающей программе, если вы хотите управлять версиями более удобным для предприятия способом. Вы также можете переопределить требования контейнера к ЦП и памяти - убедитесь, что им не требуется больше, чем доступно в вашем кластере FARGATE, иначе контейнер не сможет запуститься.

Мы также передаем информацию о среде (строки) и секретной среде (ссылки на диспетчер секретов). Процесс выполнения ECS будет собирать всю эту информацию на пути к запуску контейнера.

Затем мы добавляем информацию о регистрации в конце.

Кластер ECS

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

Определение службы ECS

Затем мы определяем сервис ECS. Эта служба работает постоянно и может запускать и автоматически восстанавливать наши задачи, если / когда они умирают или прекращают работу.

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

Цель автоматического масштабирования приложения ECS

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

Но сами они ничего подобного не делают. Для этого нам понадобится еще один ресурс.

Планирование ECS AutoScale

Сначала мы предопределяем все это для переменной enable_scaling, так что вы можете с радостью отключить это, если хотите. Затем мы устанавливаем часовой пояс (PST, Los_Angeles в Америке) и устанавливаем cron на 5 часов утра по тихоокеанскому времени с понедельника по пятницу.

Доступны 3 из них для выполнения следующих действий:

  • Масштабирование в 5 часов утра в начале каждого буднего дня.
  • Уменьшите масштаб в 8 часов вечера. в конце каждого буднего дня
  • Масштабируйте до 0 каждую ночь в полночь - это позволяет нам гарантировать, что ни один хост не работал дольше 24 часов, что (если мы построили этот контейнер в течение последних 24 часов) означает, что он всегда будет запускать новую версию.
  • Масштабируйте до 1 каждую ночь через 5 минут после полуночи - это позволяет нам иметь минимальное покрытие в ночное время.

Вывод

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

Найдите здесь код:



Удачи!
Кайлер

Присоединяйтесь к FAUN: Веб-сайт 💻 | Подкаст 🎙️ | Twitter 🐦 | Facebook 👥 | Instagram 📷 | Группа Facebook 🗣️ | Группа Linkedin 💬 | Slack 📱 | Cloud Native Новости 📰 | Еще .

Если этот пост был полезен, нажмите несколько раз кнопку хлопка 👏 ниже, чтобы выразить поддержку автору 👇