В мире Amazon Web Services (AWS) является довольно распространенной практикой, когда экземпляр службы реляционной базы данных (RDS) работает только в определенные пиковые периоды, а в другое время удобно отключается. Я хотел использовать AWS Lambda, используя Python, чтобы иметь возможность запускать и останавливать экземпляр RDS, и хотел, чтобы имя экземпляра БД было параметризовано как переменная среды. Поэтому, когда я перемещаю код из Dev в QA в Production, я могу изменить имя базы данных в переменной среды без необходимости изменения кода. Я предполагаю, что можно использовать одну и ту же технику для запуска и остановки разных типов экземпляров, таких как MySQL, MariaDB или PostgreSQL.
Итак, начнем.
Лямбда-функция для остановки экземпляра RDS
Шаг 1. Создание роли IAM
Мы создадим соответствующую роль IAM для обеспечения доступа к журналам CloudWatch, а также для запуска и остановки экземпляра RDS. В AWS теперь есть удобный визуальный редактор для выбора политик, если вы выберете его использование.
Сначала я создам политику и затем присоединю ее к роли IAM.
- Войдите в консоль IAM и нажмите
- Политика и создание политики .
- Вставьте следующее в редактор JSON.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:DescribeDBInstances",
"rds:StopDBInstance",
"rds:StartDBInstance"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
-
Дайте имя политики: policy_start_stop_RDS вместе с описанием, затем нажмите « Создать политику» .
- Теперь в консоли IAM нажмите « Роли» и « Создать роли».
- Выберите AWS Services , Lambda в качестве вашего сервиса.
- В строке поиска выполните поиск policy_, и политика, созданная вами ранее, должна выглядеть следующим образом.
-
Укажите описательное имя роли (например), lambda-start-stop-rds и нажмите « Создать роль».
Шаг 2 — Автор функции
- Убедитесь, что вы находитесь в правильном регионе для создания функций Lambda и в том же регионе, в котором был создан ваш экземпляр БД. В моем случае это Н. Вирджиния.
- Получите имя экземпляра RDS и зону доступности от администратора.
- Откройте консоль Lambda и нажмите « Создать функцию и создать автора с нуля».
- Введите следующую информацию в окне
- Имя: RDSInstanceStop
- Время выполнения: Python 2.7
- Роль: выберите существующую роль
-
Имя роли: Lambda-start-stop-rds и нажмите « Создать функцию».
- Будет создана лямбда-функция, которая будет выглядеть следующим образом:
-
В верхнем правом углу теперь есть ресурс ARN, созданный для функции Lambda. Это используется для предоставления разрешений для функции Lambda для доступа к Lambda API GetFunctionConfiguration и доступа к переменным среды.
- Вернитесь к роли: lambda-start-stop-rds и нажмите « Добавить встроенную политику» .
-
Затем перейдите на вкладку JSON и введите:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "lambda:GetFunctionConfiguration",
"Resource": "arn:aws:lambda:<region>:<Account_id>:function:RDSInstanceStop"
}
]
}
- Обязательно измените Ресурс на Lambda ARN, который вы только что создали.
- Присвойте Lambda ARN описательное имя политики, например policy_rds_stop, и нажмите « Сохранить».
- Теперь вернитесь к функции Lambda, и добавленная AWS Lambda должна появиться в качестве ресурса.
Шаг 3 — Обновить код функции
- В разделе кода функции Python вставьте следующее:
import sys
import botocore
import boto3
from botocore.exceptions import ClientError
def lambda_handler(event, context):
rds = boto3.client('rds')
lambdaFunc = boto3.client('lambda')
print 'Trying to get Environment variable'
try:
funcResponse = lambdaFunc.get_function_configuration(
FunctionName='RDSInstanceStop'
)
DBinstance = funcResponse['Environment']['Variables']['DBInstanceName']
print 'Stoping RDS service for DBInstance : ' + DBinstance
except ClientError as e:
print(e)
try:
response = rds.stop_db_instance(
DBInstanceIdentifier=DBinstance
)
print 'Success :: '
return response
except ClientError as e:
print(e)
return
{
'message' : "Script execution completed. See Cloudwatch logs for complete output"
}
- Основная часть линии , которая останавливает экземпляр БД
rds.stop_db_instance
. -
lambdaFunc.get_function_configuration
возвращает словарь свойств функцииRDSInstanceStop
. -
DBInstance
Переменная содержит переменную среды,DBInstanceName
которая является парой ключ-значение, которую можно использовать для разделения сред Dev, QA или Prod.
Шаг 4 — Настройте лямбда-функцию
- Прокрутите вниз до Переменных среды и добавьте два элемента:
- Ключ:
DBInstanceName
- Значение: <
userDB instance name
>. В моем примере я использовал тестовую базу данных.
- Ключ:
- Выберите роль выполнения
lambda-start-stop-rds
и сохраните функцию.
Шаг 5 — Время для тестирования
- В правом верхнем углу экрана выберите « Тестировать и настраивать тестовые события».
- Выберите Создать новое тестовое событие и выберите шаблон события Hello World .
- Когда вы нажимаете «Сохранить», выполнение должно быть успешным. Если ваша БД не запущена, на самом деле останавливать нечего, и поэтому вы получите сообщение, похожее на «Экземпляр <> не доступен».
Поздравляем, вы только что создали функцию Lambda для остановки экземпляра RDS.
Теперь давайте создадим функцию для запуска экземпляра RDS. Поскольку шаги повторяют шаги, описанные в функции «Лямбда-стоп», в инструкциях будут упоминаться только изменения к шагам, указанным выше.
Лямбда-функция для запуска экземпляра RDS
Шаг 1. Создание роли IAM
ПРИМЕЧАНИЕ. Мы определили действия запуска и остановки в более ранней роли IAM « policy_start_stop_RDS », поэтому в этом примере мы будем использовать одну и ту же роль.
Шаг 2 — Автор функции
- Задайте те же настройки, что и выше, за исключением названия функции как « RDSInstanceStart ».
Шаг 3. Обновление роли IAM
-
Мы обновим роль IAM,
lambda_start_stop_RDS
чтобы включить другую встроенную политику -
Перейдите к IAM Roles и выберите lambda-start-stop-rds Role.
- Нажмите « Добавить встроенную политику» и измените JSON, как показано ниже. Обязательно измените идентификатор учетной записи и региона на ARN функции.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "lambda:GetFunctionConfiguration",
"Resource": "arn:aws:lambda:<region>:<Account_id>:function:RDSInstanceStart"
}
]
}
- Сохраните политику как policy_rds_start.
- Роль теперь имеет доступ для запуска и остановки функций, специально определенных вместе с любыми экземплярами RDS.
Шаг 4 — Обновите код функции
-
Обновите лямбда-функцию, как показано ниже:
import sys
import botocore
import boto3
from botocore.exceptions import ClientError
def lambda_handler(event, context):
# TODO implement
rds = boto3.client('rds')
lambdaFunc = boto3.client('lambda')
print 'Trying to get Environment variable'
try:
funcResponse = lambdaFunc.get_function_configuration(
FunctionName='RDSInstanceStart'
)
#print (funcResponse)
DBinstance = funcResponse['Environment']['Variables']['DBInstanceName']
print 'Starting RDS service for DBInstance : ' + DBinstance
except ClientError as e:
print(e)
try:
response = rds.start_db_instance(
DBInstanceIdentifier=DBinstance
)
print 'Success :: '
return response
except ClientError as e:
print(e)
return
{
'message' : "Script execution completed. See Cloudwatch logs for complete output"
}
- Важное направление коды отметить , который начинается с RDS.
rds.start_db_instance
Шаг 5 — Настройте лямбда-функцию
Выполните те же шаги, что и выше, чтобы настроить лямбда-функцию для переменных среды и роли выполнения.
Поздравляем, теперь вы можете запускать и останавливать экземпляр RDS из лямбда-функции.