У меня есть лямбда-функция, которая принимает имя набора данных и создает новую лямбда-функцию специально для этого набора данных. Вот код, который это устанавливает:
lambda_response = lambda_client.create_function(
FunctionName=job_name,
Runtime='python3.6',
Role=role_name,
Handler='streaming_data_lambda.lambda_handler',
Code = {
'S3Bucket': code_bucket,
'S3Key': 'streaming_data_lambda.py.zip'
},
Timeout=30,
)
Кажется, это правильно создает лямбду и работает, когда я запускаю ее вручную. Я хочу, чтобы созданная лямбда-функция запускалась один раз в час, поэтому исходный лямбда-скрипт создает следующие правила и цели:
rule_response = event_client.put_rule(
Name=rule_name,
ScheduleExpression=schedule_expression
)
event_client.put_targets(
Rule=rule_name,
Targets=[
{
'Id': lambda_response['FunctionName'],
'Arn': lambda_response['FunctionArn'],
'Input': json.dumps(input_string)
}
]
)
где input_string - это что-то вроде {"datasetName": "name"}. Я вижу правило в пользовательском интерфейсе правил CloudWatch и вижу, что оно связано с правильной лямбдой и присутствует вводимый текст. Он также срабатывает правильно каждый час, но не может вызвать лямбда-функцию. Если я посмотрю на лямбду в пользовательском интерфейсе и добавлю правило события CloudWatch, которое я создал в качестве триггера в разделе конструктора, то оно правильно запускает лямбду, но есть ли способ настроить это в Python, поэтому я не нужно сделать этот последний шаг в пользовательском интерфейсе?






Вам может потребоваться добавить
event_client.enable_rule(Name=rule_name)
После put_rule
В этом бите, возможно, есть дополнительная конфигурация, которую добавляет пользовательский интерфейс.
event_client.put_rule(
Name=rule_name,
ScheduleExpression=schedule_expression)
попробуйте использовать «DescribeRule» для этого правила после того, как оно будет включено и работает, а затем продублируйте любые отсутствующие поля (например, RoleArn) в питоне.
Для тех, кто может искать ответ на этот вопрос в будущем - вам необходимо добавить разрешение для событий cloudwatch для вызова вашей лямбда-функции, например:
lambda_client.add_permission(
FunctionName=lambda_response['FunctionName'],
StatementId=some_random_number,
Action='lambda:InvokeFunction',
Principal='events.amazonaws.com',
SourceArn=rule_response['RuleArn']
)
Ответ, упомянутый @meowseph_furbalin, будет работать, но проблема с этим ответом заключается в том, что для каждого правила он будет добавлять новую политику ресурсов в лямбда. AWS ограничивает максимальный размер политик ресурсов примерно 2 КБ, поэтому после достижения этого ограничения цель не сработает. Одним из способов решения этой проблемы является добавление сопоставления с подстановочными знаками к лямбда-выражению, чтобы оно могло соответствовать каждому правилу из одной политики ресурсов.
aws lambda add-permission --function-name lambda_name\
--action 'lambda:InvokeFunction' --principal events.amazonaws.com \
--statement-id '1' \
--source-arn arn:aws:events:us-west-2:356280712205:rule/*
После добавления этой команды вам не нужно динамически добавлять разрешения к лямбде, и вы примете все правила облачного наблюдения с единой политикой ресурсов.
Нерентабельное решение, если вы хотите иметь (много) динамически создаваемых правил, поскольку вы достигнете пределов лямбда-политики (20 КБ).