Вы применили инфраструктуру как код (IoC) и кропотливо создали Terraform или CloudFormation для моделирования ваших инстансов EC2, групп AutoScaling, кластеров ECS и всего остального. Команда разработчиков и разработчиков обязалась изменять и создавать инфраструктуру только с использованием выбранных вами инструментов IoC, но, как ни странно, некоторые люди просто не подчиняются. Может быть, кто-то станет ленивым во время разработки функции или примет ярлык во время реагирования на инциденты. Возможно, вы передали на аутсорсинг поддержку первого уровня и еще не полностью доверяете этой группе. Какой бы ни была причина, вы хотели бы знать, когда пользователь входит на веб-сайт Консоли AWS и вручную что-то меняет.

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

В этой статье мы собираемся создать систему для мониторинга вашей инфраструктуры AWS и отправки уведомлений всякий раз, когда пользователь вносит изменения непосредственно из консоли AWS. Мы будем использовать CloudTrail для записи событий и записи их в S3. Триггер S3 вызовет функцию Lamba. Эта функция отфильтрует события и опубликует соответствующие в теме соцсети, на которую ваша команда может подписаться. Если это звучит устрашающе, не волнуйтесь; AWS берет на себя тяжелую работу, и нам просто нужно соединить части. Каждый шаг подробно описан ниже - приступим.

Включить CloudTrail

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

CloudTrail часто используется для исследований безопасности, соблюдения нормативных требований и аудита. и вы можете использовать его веб-интерфейс для поиска событий, которые он регистрирует. Вам нужно знать, кто запустил этот дорогостоящий экземпляр, который простаивает? Проверьте журналы CloudTrail. Определите, кто изменил конфигурацию запуска, чтобы узнать почему? CloudTrail. Базовые функции поиска CloudTrail доступны прямо в его веб-интерфейсе AWS, и вы также можете использовать AWS Athena для выполнения запросов в стиле SQL к журналам событий.

По умолчанию CloudTrail ведет журнал событий за последние 90 дней активности в вашей учетной записи. Но эти журналы недоступны в S3; для этого нам нужно создать новый след. AWS позволяет бесплатно создать одну трассу событий управления.

Перейдите в консоль CloudTrail и выберите «Создать трейл». Введите имя и выберите «Только для записи» для фильтра событий, потому что это все, что нас интересует.

Прокрутите вниз до раздела «Место хранения» и выберите или создайте корзину S3 для хранения журналов.

Теперь, чтобы проверить это, внесите некоторые изменения в свою среду AWS - запустите микро-экземпляр t.2, создайте пустую функцию Lambda, все будет работать. Затем взгляните на корзину S3, которая должна содержать наши журналы CloudTrail:

Если вы загрузите файл журнала из этого сегмента, вы увидите массив («Записи») событий. К каждому событию прикреплено множество метаданных - вот пример события (сокращенный), которое генерируется при запуске нового экземпляра EC2:

Создайте лямбда-выражение для обработки журналов CloudTrail

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

Перейдите в консоль Lambda и создайте новую функцию. Выберите пустую функцию и Python 3.8 в качестве среды выполнения.

Для функции требуется разрешение на чтение из S3 и публикацию уведомлений в SNS. Выберите «Создать новую роль из шаблонов политик AWS» и выберите «Объект S3 только для чтения» и «Публикация в SNS» в раскрывающемся списке «Шаблон политики». Укажите имя для своей роли, а затем выберите «Создать функцию».

После создания функции прокрутите вниз, чтобы найти встроенный редактор кода и очень простую функцию Python.

Скопируйте весь приведенный ниже код и вставьте его в редактор, заменив весь существующий код:

Давайте рассмотрим код. Прокрутите вниз и найдите lambda_handler - это точка входа в наше приложение. Поскольку лямбда-функция вызывается триггером S3, параметр «событие» содержит список событий S3. Каждое событие содержит ключ для объекта, который был создан в корзине S3, в которую записываются наши журналы CloudTrail. Мы просматриваем список и для каждого события загружаем указанный файл из S3 и распаковываем его.

В каждом файле у нас есть список событий CloudTrail в формате JSON. Мы не хотим получать уведомления о каждом событии CloudTrail; цель этого упражнения - уловить только события, инициированные пользователями через Консоль AWS. Amazon не предоставляет простой способ отличить изменения, внесенные вручную пользователем, от изменений, вызываемых SDK или командной строкой. Аркадий Тетельма написал фантастический блог здесь, в котором работает над решением той же проблемы. Мы собираемся фильтровать события CloudTrail таким образом, который Аркадий описывает в нашей Lamda.

Чтобы выполнить этот фильтр, мы используем анализ списка Python для запуска filter_user_events для каждого элемента в журнале и создания output_dict, содержащего только совпадения.

Функция filter_user_events проверяет соответствующие поля в событии на соответствие указанным нами фильтрам. Сначала он просматривает userAgent и пытается сопоставить ряд регулярных выражений, имитирующих URL-адреса консоли AWS. Затем он просматривает события, доступные только для чтения, например те, которые начинаются с «Получить» или «Описать». Третья проверка - это набор конкретных имен событий, которые мы игнорируем (например, вход в консоль AWS). Последняя проверка заключается в том, было ли событие вызвано «внутренним AWS».

После того, как у нас есть подмножество интересующих нас событий, мы хотим отправить фактическое уведомление. Мы будем использовать Amazon Simple Notification Service (SNS), который представляет собой очень простой сервис, который позволяет вам создать тему, а затем опубликовать / подписаться на нее. Код для публикации в теме SNS находится в нашей функции sns_publish, и есть два метода оболочки (post_to_sns публикует только userName и eventName, а post_to_sns_details публикует все событие JSON.)

Обратите внимание на указанную здесь переменную sns_arn, определенную в верхней части файла; вам нужно будет заменить его на ARN темы соцсети, в которой вы хотите опубликовать. Нажмите «Сохранить» в правом верхнем углу экрана, чтобы обновить вашу лямбда-функцию кодом, который вы вставили; это изменение вступит в силу немедленно. Затем перейдите в раздел SNS консоли AWS, выберите «Темы» и «Создать тему».

Назовите тему соответствующим образом и используйте настройки по умолчанию для всех остальных разделов. При желании вы можете изменить настройки политики доступа; политика по умолчанию - разрешить только владельцу темы публиковать эту тему и подписываться на нее. Это нормально для этой демонстрации, но если вы хотите использовать это в более крупной организации, вам нужно адаптировать эту политику по своему вкусу. Выберите «Создать тему», чтобы завершить процесс настройки.

На этом экране вы можете скопировать ARN вашей темы и вернуться в Lambda, чтобы обновить код (заменив значение переменной sns_arn). Вы также заметите, что на тему нет подписок. ; выберите «Создать подписку», выберите «Электронная почта» в качестве протокола, введите свой адрес электронной почты и снова выберите «Создать подписку».

Убедитесь, что вы проверили свою электронную почту и подтвердили подписку, иначе вы не получите ни одного сообщения, опубликованного в теме.

Запускать лямбду по событиям S3

Итак - краткое резюме. Ведение журнала CloudTrail включено, тема SNS существует, и мы подписались на нее, наша функция Lambda активна (и переменная sns_arn обновлена). Все, что осталось сделать, это создать триггер для вызова нашей функции Lambda всякий раз, когда создается новый журнал CloudTrail. создан в ведре S3.

Вернитесь к консоли Lambda, перейдите к сведениям о своей функции и выберите опцию «Добавить триггер» в верхней части окна дизайнера.

Выберите корзину S3, в которую записываются журналы CloudTrail. Для типа события выберите «все события создания объекта», чтобы вызывать нашу функцию всякий раз, когда в этом сегменте создаются новые объекты. Убедитесь, что выбрано «Включить триггер», чтобы активировать этот триггер немедленно, а затем нажмите «Добавить».

Вы должны увидеть триггер в представлении конструктора после его создания.

Проверить это

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

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

Исправление проблем

  • Проверьте ведро CloudTrail S3; ведутся журналы?
  • Проверьте журналы Cloudwatch на наличие функции Lambda. Журналы должны существовать каждый раз, когда вы ожидаете срабатывания лямбды. Ищите пишите сообщения в логах.
  • Проверьте триггер S3 на наличие лямбда-функции; это отслеживает правильное ведро?
  • Проверьте роль IAM, назначенную лямбде; есть ли у него соответствующие разрешения на чтение из S3 и публикацию в SNS?
  • Соответствует ли переменная sns_arn в коде Lambda Python вашей теме в социальных сетях?
  • Вы подписались на тему соцсети со своим адресом электронной почты и подтвердили подписку?
  • Если ничего не помогает, вы можете раскомментировать и запустить модульный тест в коде Python на вашем локальном компьютере. Вы также можете добавить в код более подробное ведение журнала print () и просматривать журналы Cloudwatch, чтобы лучше понять, что происходит во время выполнения вашей функции.

Ресурсы

Обнаружение ручных действий консоли AWS - Аркадий Тетельман

Репозиторий PyCloudTrailProcessor на GitHub