С образцом кода Terraform для бессерверного проекта AWS
Обзор
Недавно я прошел через задачу по настройке прокси-сервера RDS для новой бессерверной архитектуры, которую я создавал. С точки зрения IaC (Infrastructure as Code) я обнаружил, что настройка была немного сложной, с довольно большим количеством лишних деталей. Поскольку многие ресурсы, доступные для решения этой задачи, не являются законченными решениями, я подумал, что другим было бы полезно увидеть весь пошаговый процесс. Я использую Terraform в примере кода, но уверен, что он будет вам полезен, если вы используете CloudFormation или любое другое решение IaC.
Что такое прокси-сервер RDS?
Прокси-сервер RDS - это пул подключений к базе данных, предназначенный для обработки и масштабирования множества одновременных подключений. По сути, это бессерверный ответ AWS на то, что Lambda не может использовать стандартный пул соединений, например, доступный в библиотеке mysql2
.
Проблемы без пула подключений
Рассмотрим случай без прокси-сервера RDS: у вас есть интеграция Lambda с API-шлюзом и экземпляром RDS. Мы знаем, что каждый вызов Lambda создает новый экземпляр, если он недоступен, и каждый экземпляр создает новое соединение с базой данных. Вместо того, чтобы повторно использовать доступные соединения из пула, мы неэффективно съедаем ограниченный ресурс. В общем, формула для определения максимального количества подключений для экземпляра MySQL / MariaDB: DBInstanceClassMemory/12582880
. t2.micro имеет 512 МБ доступной памяти или 512000000Б, что означает, что этот экземпляр базы данных может поддерживать максимум примерно 40 подключений.
Выгоды
- Пул соединений и повторное использование соединений сокращают накладные расходы на ЦП и память и улучшают масштабируемость.
- Автоматически регулирует входящие соединения, чтобы избежать сбоев.
- Инфраструктура прокси-сервера RDS отличается высокой доступностью (несколько зон доступности) с вычислительными ресурсами, памятью и хранилищем независимо от экземпляра базы данных или кластера.
- Обрабатывает отработку отказа базы данных, не влияя на текущие соединения.
- Повышенная безопасность за счет подключения к прокси-серверу через TLS / IAM и сохранения учетных данных базы данных в Secrets Manager.
В целом прокси-сервер RDS повышает эффективность бессерверной архитектуры без необходимости масштабирования. В результате использование таких сервисов, как API Gateway, Lambda, Aurora и RDS Proxy, даст вам полностью бессерверное решение.
Образец кода
Если я впервые работаю со службой и мне нужно написать ее как код, я обычно предпочитаю сначала настроить ее через консоль, чтобы лучше понять, как она работает. Это дает мне лучшее представление о том, какие аргументы будут доступны, прежде чем я перейду к документации Terraform. Этот блог / руководство AWS полезно для работы с этим:
Шаг 1. Настройте секрет в диспетчере секретов
Секрет содержит учетные данные нашей базы данных и детали подключения. Обратите внимание: это предполагает, что мы уже создали ресурсaws_db_instance
или аналогичный (модуль rds-aurora популярен для Aurora) с именем database
.
При этом используется ключ KMS, управляемый AWS по умолчанию, с именем aws/secretsmanager
. Я также предполагаю, что мы работаем с MySQL, а не с Postgres (но прокси RDS поддерживает оба).
Шаг 2: Установите необходимые правила безопасности
Самый простой способ настроить это - создать одну группу безопасности для каждого из наших ресурсов (Lambda, RDS Proxy и RDS).
sg_lambda
отправляет запросы наsg_rds_proxy
. Я оставлю это правило исходящего (исходящего) соединения.sg_rds_proxy
принимает только входящий (входящий) трафик отsg_lambda
на порт 3306 / TCP.sg_rds
принимает только входящий трафик отsg_rds_proxy
на порт 3306 / TCP.
Как правило, правила исходящего трафика можно оставить открытыми. Обратите внимание, что это предполагает, что наши лямбда-функции будут находиться внутри vpc и подсети.
Распространенной ошибкой здесь является присвоение прокси-серверу и базе данных одной и той же группы безопасности. Это приведет к недоступности целевого прокси-сервера, поскольку эта группа безопасности не предоставляет доступ к себе.
Шаг 3. Настройте необходимые политики IAM и роль IAM
Затем мы должны убедиться, что прокси-сервер RDS имеет разрешение на получение и расшифровку учетных данных базы данных из диспетчера секретов. В этом примере это достигается за счет принятия на себя роли службы RDS и присоединения к ней необходимых политик. Actionsts.AssumeRole
дает RDS Proxy ту же роль, что и RDS, поэтому он может выполнять те же функции.
Обратите внимание, что я оставил все ресурсы для действия kms:Decrypt
. Это сработает, но, конечно, мы хотим предоставить минимум необходимых привилегий. Если вы использовали CMK (управляемый клиентом ключ) для rds_secret
, используйте выходной arn из этого ресурса. Если вы оставили значение по умолчанию (под управлением AWS), вы можете использовать что-то вроде data aws_kms_key
, чтобы получить arn.
Шаг 4: Настройте фактический прокси вместе с его группой и целью
Целевая группа, связанная с прокси-сервером, управляет настройками, связанными с подключением к базе данных.
Лучше всего держать прокси-сервер RDS в той же подсети, что и база данных. Убедитесь, что все службы (Lambda, Proxy и RDS) настроены с созданными нами группами безопасности. Вот и все, вы можете проверить соединение, запустив образец кода javascript, представленный в блоге AWS, ссылка на который приведена выше.
Шаг 5. Предоставьте Lambda разрешение на доступ к прокси-серверу RDS
И последнее, что следует отметить, это то, что для того, чтобы Lambda имела разрешение на доступ к прокси-серверу RDS, его роль должна быть изменена с помощью правильной политики. Если вы настроили Lambda вручную (например, через Добавить прокси-сервер базы данных) и затем проверите роль, вы увидите, что действие равно rds-db:connect
, а ресурс arn настроен в формате:
`arn:aws:rds-db:${region}:${awsAccountId}:dbuser:${proxyId}/*`
Так, например, если arn вашего прокси-сервера arn:aws:rds:us-east-1:424824108755:db-proxy:prx-1126716789abcdef07
, тогда arn ресурса для политики должен бытьarn:aws:rds-db:us-east-1:424824108755:dbuser:prx-1126716789abcdef07
.
Больше контента на plainenglish.io