Datadog's lambda log forwarder changes function name to lowercase - amazon-web-services

I have followed the Datadog's documentation (here) for manually configure AWS account with Datadog. Set-up includes a Lambda function provided by Datadog (here) which is triggered by Cloudwatch log group and lambda pushes logs to Datadog.
Problem is that when logs are pushed, Datadog's log forwarder lambda changes name of function, tags and rest of the to small case. Now, when I use '!Ref ' while creating query for Datadog monitor using Cloudformation, then query contains autogenerated name of lambda which is mixture of small and upper case alphabets. But query does not work as Datadog changes name of the function while pushing logs.
Can someone suggest the work around here?

You could use a Cloudformation macro to transform strings in your template, in this case using the Lower operation to make your !Refs lowercase. Keep in mind that you need to define and deploy macros as lambdas.

Related

CloudWatch Alarm for multiple Lambda functions in a CloudFormation stack

I am using SAM and CloudFormation to deploy multiple Lambda functions and other resources. The function names are generated by CloudFormation and have the following format:
stack-name-function-name-8H2609XXXXX with the suffix automatically generated by CloudFormation
The CloudWatch log groups automatically created for all individual Lambda functions have therefore following name format:
/aws/lambda/stack-name-function-name-8H2609XXXXX
I am trying to find a way to trigger CloudWatch Alarm for the Lambda functions in a stack. When creating a MetricFilter in CloudFormation I have to specify CloudWatch LogGroupName. With 100s of Lambdas with names generated by CloudFormation, following the basic pattern would mean creating 100s of filters that would somehow have to know the names of all functions (outputs and imports maybe but that would be really inflexible when function names change, would require constant redeploying of the "alarm" stack that I was hoping to keep filters in)
Is there a way to maybe trigger alarm for a group of log groups? I imagined using wildcard would be easy on a filter for log group name like /aws/lambda/stack-name-*. Or any other nicer approach than having to manage all the filters?

AWS: Preemptively configure LambdaEdge log groups using Terraform

If given the correct permissions, Lambda functions will automatically create CloudWatch log groups to hold log output from the Lambda. Same for LambdaEdge functions with the addition that the log groups are created in each region in which the LambdaEdge function has run and the name of the log group includes the name of the region. The problem is that the retention time is set to forever and there is no way to change that unless you wait for the log group to be created and then change the retention config after the fact.
To address this, I would like to create those log groups preemptively in Terraform. The problem is that the region would need to be set in the provider meta argument or passed in the providers argument to a module. I had originally thought that I could get the set of all AWS regions using the aws_regions data source and then dynamically create a provider for each region. However, there is currently no way to dynamically generate providers (see https://github.com/hashicorp/terraform/issues/24476).
Has anyone solved this or a similar problem in some other way? Yes, I could create a script using the AWS CLI to do this, but I'd really like to keep everything in Terraform. Using Terragrunt is also an option, but I wanted to see if there were any solutions using pure Terraform before I go that route.

Automatically Add CloudWatch LogGroup to another LogGroup?

I have a Logger Lambda function that listens on a specific LogGroup and process specific log details.
I would like to attach the newly created LogGroups of other lambdas to that specific LogGroup, so it will process them as well - but since these other lambdas are created automatically, I need to do this automatically. Can I do it? How?
So there's no way to directly replicate the logs stored in a CloudWatch log group to another log group. You could do this by creating a subscription filter with a Lambda function to push the logs from each log group to the common one, but this would increase the costs for CloudWatch.
What I would suggest is either of the following:
Create a subscription filter for each of the log groups used by your Lambda functions to the common Lambda function so that it is triggered when logs are pushed to any of the log groups. This event can be set up after creating each function. Note, you would have to update the function policy of the common Lambda to allow it to be invoked from each log group (or just set up a wildcard).
Push all the logs for all of the functions to a single log group. This would take the least effort, but you would have to figure out how to effectively separate the logs per function (if that is required for your use case).

CloudWatch logs for Lambda

I would like to ask about Lambda and CloudWatch logs. I see that once you create a Lambda the log structure behind is always like "/aws/lambda/".
What I would like to do is my own CloudWatch group "/myLogs" and then set to Lambda to log into this CloudWatch group. As I was reading some documentation about this it looks like that this was not possible in past, is there any update on that now is it possible to do it and how ?
Thanks.
By default, the log group gets created by the name /aws/lambda/.
I haven't explored through console, but if you are using cdk, you can use aws_logRetention method construct of aws_lambda construct.
https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.aws_lambda/LogRetention.html
This will create a log group by the name you provide (but it will still follow the convention of /aws/lambda/....
You can set the retention days as well and manage the logs.
You can try it once.

Serverless-ly Query External REST API from AWS and Store Results in S3?

Given a REST API, outside of my AWS environment, which can be queried for json data:
https://someExternalApi.com/?date=20190814
How can I setup a serverless job in AWS to hit the external endpoint on a periodic basis and store the results in S3?
I know that I can instantiate an EC2 instance and just setup a cron. But I am looking for a serverless solution, which seems to be more idiomatic.
Thank you in advance for your consideration and response.
Yes, you absolutely can do this, and probably in several different ways!
The pieces I would use would be:
CloudWatch Event using a cron-like schedule, which then triggers...
A lambda function (with the right IAM permissions) that calls the API using eg python requests or equivalent http library and then uses the AWS SDK to write the results to an S3 bucket of your choice:
An S3 bucket ready to receive!
This should be all you need to achieve what you want.
I'm going to skip the implementation details, as it is largely outside the scope of your question. As such, I'm going to assume your function already is written and targets nodeJS.
AWS can do this on its own, but to make it simpler, I'd recommend using Serverless. We're going to assume you're using this.
Assuming you're entirely new to serverless, the first thing you'll need to do is to create a handler:
serverless create --template "aws-nodejs" --path my-service
This creates a service based on the aws-nodejs template on the provided path. In there, you will find serverless.yml (the configuration for your function) and handler.js (the code itself).
Assuming your function is exported as crawlSomeExternalApi on the handler export (module.exports.crawlSomeExternalApi = () => {...}), the functions entry on your serverless file would look like this if you wanted to invoke it every 3 hours:
functions:
crawl:
handler: handler.crawlSomeExternalApi
events:
- schedule: rate(3 hours)
That's it! All you need now is to deploy it through serverless deploy -v
Below the hood, what this does is create a CloudWatch schedule entry on your function. An example of it can be found over on the documentation
First thing you need is a Lambda function. Implement your logic, of hitting the API and writing data to S3 or whatever, inside the Lambda function. Next thing, you need a schedule to periodically trigger your lambda function. Schedule expression can be used to trigger an event periodically either using a cron expression or a rate expression. The lambda function you created earlier should be configured as the target for this CloudWatch rule.
The resulting flow will be, CloudWatch invokes the lambda function whenever there's a trigger (depending on your CloudWatch rule). Lambda then performs your logic.