Можно ли запустить лямбду при создании из шаблона CloudFormation
Я попытался создать набор лямбд с помощью облачной информации. Я хочу, чтобы лямбды запускались после их создания. Я видел в различных блогах, чтобы создать триггер s3
или же sns
но ни один из них не может быть опцией lambda
как только он был создан. Есть варианты?
7 ответов
Да, это возможно. Вот несколько вариантов:
Вручную создайте тему SNS. Добавить
AWS::SNS::Subscription
в ваш стек с лямбда-функцией в качествеEndpoint
и тема SNS какTopicArn
, При создании / обновлении стека настройте уведомления о событиях стека для отправки в этот раздел SNS.- (См. Настройка параметров стека AWS CloudFormation для получения документации о том, как это сделать при использовании консоли AWS для создания стека, или используйте эквивалентную опцию, например
--notification-arns
если вы создаете / обновляете свой стек с помощью интерфейса командной строки AWS или другого пакета AWS SDK.)
- (См. Настройка параметров стека AWS CloudFormation для получения документации о том, как это сделать при использовании консоли AWS для создания стека, или используйте эквивалентную опцию, например
Добавьте пользовательский ресурс, ссылающийся на функцию Lambda, которая будет вызываться при создании.
- Если вам нужно, чтобы лямбда-функция вызывалась после создания определенного ресурса, добавьте
DependsOn
Атрибут в пользовательском ресурсе, ссылающийся на ресурс, который вы хотите удостовериться, сначала создается перед вызовом функции. - Чтобы пользовательский ресурс успешно создавался (и не вызывал сбой / откат в вашем стеке), вам нужно будет адаптировать свою функцию Lambda для поддержки формата запроса / ответа CloudFormation (см. Ссылку на пользовательский ресурс).
- Эта опция будет вызывать функцию Lambda, пока статус стека все еще
CREATE_IN_PROGRESS
потому что пользовательский ресурс является частью самого стека. - Лямбда-функция также будет вызываться снова при удалении стека (и соответствующего пользовательского ресурса). Это должно быть правильно обработано вашей лямбда-функцией, иначе ваш стек может застрять в
DELETE_FAILED
государство.
- Если вам нужно, чтобы лямбда-функция вызывалась после создания определенного ресурса, добавьте
Добавьте ссылку на функцию Lambda в вывод стека, затем напишите простой скрипт, который выполняет создание стека, а затем вручную вызывает функцию Lambda.
Пользователя yl.
Следующее просто отлично работает!
Он вызывает лямбду как часть развертывания:
LambdaFunction2:
Type: AWS::Lambda::Function
Properties:
FunctionName: caller
Code:
ZipFile: |
import boto3, json
import cfnresponse
def handler(event, context):
print('EVENT:[{}]'.format(event))
lambda_client = boto3.client('lambda')
test_event = '{"name":"test1"}'
lambda_client.invoke(
FunctionName='target1',
InvocationType='Event',
Payload=test_event,
)
responseValue = 120
responseData = {}
responseData['Data'] = responseValue
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData)
Handler: index.handler
Role:
arn:aws:iam::11111111111:role/mylambda-role
Runtime: python3.7
Timeout: 60
Primerinvoke:
Type: AWS::CloudFormation::CustomResource
DependsOn: LambdaFunction2
Version: "1.0"
Properties:
ServiceToken: !GetAtt LambdaFunction2.Arn
Для тех, кто ищет подобный обходной путь.
CloudWatch может захватывать вызовы API CloudFormation, которые представляют собой "CreateStack", "UpdateStack" и "DeleteStack", состояния стека, такие как "Create_complete" или "Complete_Rollback", не могут быть захвачены, что означает, что такие изменения состояния не могут вызвать лямбду.
Обходной путь - SNS, стеки могут отправлять уведомления в SNS (в предварительных настройках при создании стека), а SNS может выбрать для запуска лямбда, однако вы не можете выбрать конкретные состояния. Итак, лямбда-функция берет на себя задачу выяснить, в каком состоянии находится "Сообщение" содержимого события. Все, только кодирование.
Следующий шаблон должен вызывать лямбду:
"InvokeLambda" : {
"Type": "Custom::InvokeLambda",
"Version" : "1.0",
"Properties" : {
"ServiceToken": {
"Fn::GetAtt": ["InitFunction","Arn"]
}
}
},
Я знаю, что это немного устарело, но решением также может быть использование CommandRunner в качестве типа ресурса в вашем шаблоне.
https://aws.amazon.com/blogs/mt/running-bash-commands-in-aws-cloudformation-templates/.
Вы можете запустить практически любую команду оболочки. Добавьте атрибут DependsOn к вашему типу CommandRunner и запустите сценарий оболочки:
aws lambda invoke --function-name my-function --invocation-type RequestRespone --payload '{ "name": "Bob" }'
Улучшение ответа Кира, потому что в нем отсутствуют две важные вещи:
- как передать параметры лямбде, которую вы вызываете
- как обрабатывать UPDATE и DELETE в вашем стеке (его решение приведет к сбою CloudFormation при удалении)
Вот переработанный и улучшенный код:
LambdaInvoker:
DependsOn: ## important, add stuff here you need to existe BEFORE the lambda is called
Type: AWS::Lambda::Function
Properties:
FunctionName: YourLambdaName
Description: 'Lambda invoke wrapper for Custom CFN actions'
Code:
ZipFile: !Sub |
import boto3, json
import cfnresponse
def handler(event, context):
print('EVENT:')
print(event)
if event['RequestType'] == "Create":
lambda_client = boto3.client('lambda')
cfn_event = {
"param1" : "${Param1}",
"param2" : "${Param2}"
}
lambda_client.invoke(
FunctionName='scm-custom-cfn-actions',
InvocationType='Event',
Payload=json.dumps(cfn_event)
)
responseValue = 120
responseData = {}
responseData['Data'] = responseValue
cfnresponse.send(event, context, cfnresponse.SUCCESS,
responseData, 'scm-cfn-customresource-id')
Handler: index.handler
Role: YourLambdaRoleARN
Runtime: python3.7
Timeout: 5
У вас есть возможность уведомить тему SNS, и вы можете создать лямбду, которая слушает тему, поэтому рабочий процесс будет следующим: Запуск Cloudformation -> Тема SNS -> Lambda.