Add AWS Powertools
Paweł Piwosz
Posted on November 27, 2021
Recap
We have definitely better logging ability now. But notice one thing - what we have, allows us to understand the global information about Lambda. We still do not understand the internals. We know that execution suffered by cold start. But.. how much?
AWS Powertools
Fortunately, we have tooling which we can use to know more.
Unfortunatelly though, this tool is available for Python and Java only. At least, at this moment.
Python | Java |
---|---|
https://github.com/awslabs/aws-lambda-powertools-python | https://github.com/awslabs/aws-lambda-powertools-java |
According to Roadmap there is some work on .Net support. Hopefully we will see it soon. Personally, I would like to see nodejs and golang support too.
But we are talking about Python.
We already added one layer, for Lambda Insights. This time we need to do exactly the same thing, add new layer, but we will do it completelly differently. And we will work with the SAM template only.
Ok, First, as you remember, adding Lambda Insights in SAM template was quite easy:
Layers:
- !Sub "arn:aws:lambda:${AWS::Region}:580247275435:layer:LambdaInsightsExtension:14"
We used !Sub
to make substitution of ${AWS::Region}
into actual region. It will not work with Powertools, as it is available in a few locations only.
We also have the version specified = :14
on the end. This time we will specify it differently too.
To say more, we will not reffer to lambda
, but serverlessrepo
.
In orger to have it completed, we create the new resource in our template. I placed it just below Resources:
statement.
Resources:
AwsLambdaPowertoolsPythonLayer:
Type: AWS::Serverless::Application
Properties:
Location:
ApplicationId: arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer
SemanticVersion: 1.22.0 # change to latest semantic version available in SAR
At the time of writting this tutorial, the available version was 1.22.0
Obviously, we can check which versions we can use and which one is the last one.
aws serverlessrepo list-application-versions --application-id arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer
Sometimes we need to add --region <region>
(in my case it will be eu-west-1) and --profile <profile_name>
. Let's see it:
aws serverlessrepo list-application-versions --application-id arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer --region eu-west-1 --profile demo
Output should look similar to this:
{
"Versions": [
{
"ApplicationId": "arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer",
"CreationTime": "2020-08-25T11:36:35.772Z",
"SemanticVersion": "1.3.0",
"SourceCodeUrl": "https://github.com/awslabs/aws-lambda-powertools-python"
},
It is not too handy to go through it. Let's make it better to select the last version.
aws serverlessrepo list-application-versions --application-id arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer --region eu-west-1 --profile demo --query 'Versions[*].SemanticVersion'
And now we have:
[
"1.3.0",
"1.3.1",
"1.4.0",
"1.5.0",
"1.6.0",
"1.7.0",
"1.8.0",
"1.9.0",
"1.10.0",
"1.10.1",
"1.10.2",
"1.10.3",
"1.10.4",
"1.10.5",
"1.11.0",
"1.12.0",
"1.13.0",
"1.14.0",
"1.15.0",
"1.15.1",
"1.16.0",
"1.16.1",
"1.17.0",
"1.17.1",
"1.18.0",
"1.18.1",
"1.19.0",
"1.20.0",
-- More --
Better. But still... We have all versions and we need to scroll to grab the last one. Also, not perfect for scripting.
Let's nail it.
aws serverlessrepo list-application-versions --application-id arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer --region eu-west-1 --profile demo --query 'Versions[::-1].SemanticVersion | [0]'
And now we have:
"1.22.0"
Perfect.
What we have done? we used ---query
in order to go through Versions
and select all in reverse order [::-1]
. We took into consideration only one field of Versions
, which is .SemanticVersion
. And on the end we piped it with |
and took only the first value [0]
. That's it :)
Ok, so we confirmed the version. We can safely use it in our resource description, shown on the beginning of this article.
But it is not the end!
Now it is time to add this layer to definition of our Lambda function.
Layers:
- !GetAtt AwsLambdaPowertoolsPythonLayer.Outputs.LayerVersionArn
- !Sub "arn:aws:lambda:${AWS::Region}:580247275435:layer:LambdaInsightsExtension:14"
Notice, we added it before Insights, what is not that important. What is important, is the difference between these two definitions. In case of Powertools we used !GetAtt
in order to get the attribute of the defined resource. In case of AWS::Serverless::Application
we can use !Ref
which is simply the id of the resource, or '!GetAtt
to collect Outputs.ApplicationOutputName
which is the ApplicationOutputName
. Another words, we "anchor" the layer definition to created application.
We need to complete last step here, the configuration of Powertools. According to documentation, Lambda needs to have some Variables set. We will do it directly in SAM template.
Layers:
- !GetAtt AwsLambdaPowertoolsPythonLayer.Outputs.LayerVersionArn
- !Sub "arn:aws:lambda:${AWS::Region}:580247275435:layer:LambdaInsightsExtension:14"
Environment:
Variables:
LOG_LEVEL: "INFO"
POWERTOOLS_SERVICE_NAME: simpleFunctionService
POWERTOOLS_METRICS_NAMESPACE: simpleFunctionMetrics
I attached the snipped with previously added layer to show where to place variables.
What we have here?
We say what LOG_LEVEL
we want. In our case it is "INFO" and it is enough. Also, it is the default value (another is DEBUG). We also set the POWERTOOLS_SERVICE_NAME
, it is simply the name of the service which will be visible through all logs entries, and POWERTOOLS_METRICS_NAMESPACE
which will be used to construct the namespace for the metrics in CloudWatch.
These three are the basic for our setup.
Last but not least, we need to remember that the IAM Role which we use (well, IAM Policy) needs to have access, therefore the easiest ay which you can go is just simply add serverlessrepo:*
to your policy. It is ok for tests and plays, but for "professional use" please narrow it down.
Also, if you are creating the setup through CloudFormation, remember about CAPABILITY_AUTO_EXPAND
capability. It is needed in order to operate with layer added the way we did.
More about it you can read in documentation
Ok, we addedd the Powertools layer. But doing simply this we achieved nothing. What we need to do, is implementation in the code, what we will do in the next episode.
Posted on November 27, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.