I have this usecase where I need to trigger a lambda every time my cloudformation stack updates/deletes. Cloudformation does not emit any cloudwatch metrics. Is there a way to get the cloudformation events to trigger a lambda. Any existing examples I can refer to.
What you can do is add reference your lambda function within the cloudformation script as a custom resource. You can then have the custom resource run (which executes your Lambda) on every update of the stack.
Basic syntax is:
MyCustomResource:
Type: "Custom::TestLambdaCrossStackRef"
Properties:
ServiceToken:
!Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaFunctionName}
StackName:
Ref: "NetworkStackName"
More information here:
AWS Documentation
Configure an SNS Topic as a Notification Option in the CFT via https://docs.aws.amazon.com/en_pv/AWSCloudFormation/latest/UserGuide/cfn-console-add-tags.html. Have your lambda be a subscriber to that topic.
Related
I describe existing AWS Lambda function in CloudFormation template and I face with the next issue. In our Lambda we configured few test events which helps us to verify some usecases (I mean functionality from the screenshot below).
But I don't see any abilities to add these test events to the CloudFormation template. AWS documentation don't help me with that. Is that possible at all or are there any workarounds how to export and import Lambda function test events?
Lambda test functionality is available only in the UI console, You can use Cloudformation Custom Resource to invoke a function from a cloudformation template. Resource properties allow AWS CloudFormation to create a custom payload to send to the Lambda function.
Sample code:
Resources:
EnableLogs:
Type: Custom::EnableLogs
Version: '1.0'
Properties:
ServiceToken: arn:aws:lambda:us-east-1:acc:function:rds-EnableRDSLogs-1O6XLL6LWNR5Z
DBInstanceIdentifier: mydb
the event parameter provides the resource properties. ex:
event['ResourceProperties']['DBInstanceIdentifier']
For an automatic deployment workflow, I want to start a cloudformation deployment and trigger a lambda function when done.
I know, I can add a cloudwatch event that triggers whenever an event occurs on cloudformation in my account. But I do not want to trigger the lambda on any cloudformation template being deployed, but only on templates, where I decide on deployment that the lambda should be triggered.
I could add code to the lambda function, making it decide for itself if it was supposed to be triggered. That would probably work, but I wonder if there is a better more direct solution?
Ideas?
Custom resources enable you to write custom provisioning logic in
templates that AWS CloudFormation runs anytime you create, update
Ex: Custom Lambda resource to enable RDS logs after the RDS DB is created.
Resources:
EnableLogs:
Type: Custom::EnableLogs
Version: '1.0'
Properties:
ServiceToken: arn:aws:lambda:us-east-1:acc:function:rds-EnableRDSLogs-1O6XLL6LWNR5Z
DBInstanceIdentifier: mydb
See my python gist here
I've created some CloudFormation templates to deploy Inspector Templates/Targets and associated Lambda functions that parse the outputs and deliver findings to Slack. Is it possible to include in the CF template for Inspector an SNS Topic association as is done when creating a template in the Inspector portal?
It is not an available parameter of AWS::Inspector::AssessmentTemplate. Is this something I will just have to add manually via the portal?
I see the SNS option is available only in the UI and CLI/API, I guess the UI/CLI creates Cloudwatch Events rule for you in the background, you create your own rule using AWS::Events::Rule
Reference: Event Patterns
EventRule:
Type: "AWS::Events::Rule"
Properties:
Description: "EventRule"
EventPattern:
source:
- "aws.inspector"
detail-type:
- "AWS API Call via CloudTrail"
resources:
- arn:aws:inspector:us-west-2:123456789012:target/0-nvgVhaxX/template/0-7sbz2Kz0
detail:
eventSource:
- "inspector.amazonaws.com"
eventName:
- "ASSESSMENT_RUN_COMPLETED"
State: "ENABLED"
Targets:
- arn:aws:sns:us-west-2:123456789012:exampletopic
This is how I did it. I used the cloud formation template to create the assessment target, assessment resource group, and assessment template. Also, included a cloudwatch event rule to trigger assessment runs on a weekly basis.
As of today, there is no support for adding an SNS Topic through the Inspector Assessment template cloud formation resource, I went through the boto3 API for event subscription. Refer the API here: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/inspector.html#Inspector.Client.subscribe_to_event
If you refer the above API Doc you will be able to develop a small python lambda function to subscribe your inspector assessment template to the SNS topic. Then call that lambda function using a custom resource as follows in the same template where the assessment template is provisioned or defined.
Custom resource would look something like below:
SubscribeToEvent:
Type: "Custom::<whatever_name>"
Version: "1.0"
Properties:
ServiceToken: !GetAtt <Lambda function logical name>.Arn
AssessmentTemplateArn: !GetAtt <Assessment template logical name>.Arn
topicArn: !Sub arn:aws:sns:${AWS::Region}:${account number}:<Nameofthetopic>
If you are trying to refer a cross-account topic or a topic which exist in another account, in that case, you need to update the topic policy to grant publish topic permissions to AWS Inspector Account. To find the AWS Account numbers refer here : https://docs.aws.amazon.com/inspector/latest/userguide/inspector_assessments.html#sns-topic
I am trying to create a lambda function from a CloudFormation template based on this example:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-lambda.html
As can be seen from this link:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html
there is no way to add a trigger for the lambda function (like a S3 upload trigger).
Is there a workaround to specify the trigger while writing the template?
You can use cloudwatch rule to trigger your lambda function :
AWSTemplateFormatVersion: '2010-09-09'
Resources:
MyCloudWatchRule:
Type: "AWS::Events::Rule"
Properties:
Description: "Rule to trigger lambda"
Name: "MyCloudWatchRule"
EventPattern: <Provide Valid JSON Event pattern>
State: "ENABLED"
Targets:
- Arn: "arn:aws:lambda:us-west-2:12345678:function:MyLambdaFunction"
Id: "1234567-acvd-awse-kllpk-123456789"
Ref :
https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEventsandEventPatterns.html
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-events-rule.html#aws-resource-events-rule-syntax
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-events-rule-target.html
It's been a while so I imagine you've solved the problem, but I'll put in my 2 cents to help others.
It's best to use SAM (Serverless Application Model) for this kind of things. So use AWS::Serverless::Function instead of AWS::Lambda::Function
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html
In there, you can specify an EventSource which accepts the following possible values:
S3
SNS
Kinesis
DynamoDB
SQS
Api
Schedule
CloudWatchEvent
CloudWatchLogs
IoTRule
AlexaSkill
Cognito
HttpApi
SAM does the rest of the work. Follow this guide for the rest of the details:
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-deploying.html
Nowadays, this issue is fixed by Amazon:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-events-rule.html#aws-resource-events-rule--examples
Just create Lambda permissions like in the example.
Lambda function can be triggered by several AWS resources such as S3, SNS, SQS, API, etc. Checkout for the full list at AWS docs
I suggest you use Altostra Designer, which let you create and configure Lambda Function super quick and also choose what will trigger it.
You need to add a NotificationConfiguration to the S3 bucket definition. However, this will lead to a circular dependency where the S3 bucket refers to the Lambda function and the Lambda function refers to the S3 bucket.
To avoid this circular dependency, create all resources (including the S3 bucket and the Lambda function) without specifying the notification configuration. Then, after you have created your stack, update the template with a notification configuration and then update the stack.
Here is a SAM based YAML example for CloudWatch log group trigger
lambdaFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri:
Bucket: someBucket
Key: someKey
Description: someDescription
Handler: function.lambda_handler
MemorySize:
Ref: MemorySize
Runtime: python3.7
Role: !GetAtt 'iamRole.Arn'
Timeout:
Ref: Timeout
Events:
NRSubscription0:
Type: CloudWatchLogs
Properties:
LogGroupName: 'someLogGroupName'
FilterPattern: "" #Match everything
For S3 example event see https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-s3.html
This schedules my cloudformation lambda to run once per day but I'd like it to fire upon creation one time.
Transform: AWS::Serverless-2016-10-31
...
EventListFunction:
Type: 'AWS::Serverless::Function'
Properties:
...
Events:
Schedule1:
Type: Schedule
Properties:
Schedule: rate(1 day)
Here are a few options:
Manually create an SNS Topic. Add an AWS::SNS::Subscription to your stack with the lambda function as the Endpoint and the SNS topic as the TopicArn. On stack creation/update, configure Stack Event Notifications to be sent to this SNS topic.
Add a Custom Resource referencing the newly-created function, which will call the function on creation. In order for the Custom Resource creation to complete and not cause a rollback in your stack, you will need to adapt your Lambda function to support the CloudFormation request/response format (see Custom Resource Reference). Also note that the function will also be called again on stack deletion, and this will also need to be handled.
Add the Lambda function to the Stack Outputs, then write a simple script that performs both the stack update and invokes the Lambda function after completion.
Look at AWS:: CloudFormation::CustomResource to call it