Skip to content

Commit

Permalink
feat: publish lib as Lambda Layer (#1095)
Browse files Browse the repository at this point in the history
Co-authored-by: Florian Chazal <chazalf@amazon.com>
  • Loading branch information
flochaz and Florian Chazal authored Oct 10, 2022
1 parent a574406 commit 83f6efb
Show file tree
Hide file tree
Showing 17 changed files with 12,416 additions and 12,088 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish_layer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ on:
required: true
# Automatic trigger after release
workflow_run:
workflows: ["release"]
workflows: ["Make Release"]
types:
- completed

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ The following tools need to be installed on your system prior to starting workin
- [AWS SAM CLI >= 1.49.0](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)
- AWS SAM CLI is a command line interface for AWS Serverless Application Model (SAM), it's used in one of the examples, and it's part of the pre-push hook.
- [Docker](https://docs.docker.com/get-docker/)
- If you are not planning on making changes to the documentation, you can skip this step.
- Docker is used to build documentation and Layer.

First, [fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) the repository, and then run the following commands to clone and initialize the repository locally.

Expand Down
227 changes: 227 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,233 @@ Core utilities such as Tracer, Logger, Metrics, and Event Handler will be availa

## Installation

You can use Powertools through [AWS Lambda Layer](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-concepts.html#gettingstarted-concepts-layer) or install it as your dependency via NPM:

* **Lambda Layer**: [**arn:aws:lambda:{region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:1**](#){: .copyMe}:clipboard:
* **NPM**: **`npm install @aws-lambda-powertools/tracer @aws-lambda-powertools/metrics @aws-lambda-powertools/logger`**

???+ hint "Support this project by using Lambda Layers :heart:"
Lambda Layers allow us to understand who uses this library in a non-intrusive way. This helps us justify and gain future investments for other Lambda Powertools languages.

When using Layers, you can add Lambda Powertools as a dev dependency to not impact the development process.


### Lambda Layer

[Lambda Layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html){target="_blank"} is a .zip file archive that can contain additional code, pre-packaged dependencies, data, or configuration files. Layers promote code sharing and separation of responsibilities so that you can iterate faster on writing business logic.

You can include Lambda Powertools Lambda Layer using [AWS Lambda Console](https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html#invocation-layers-using){target="_blank"}, or your preferred deployment framework.

??? note "Note: Expand to copy any regional Lambda Layer ARN"

| Region | Layer ARN
|--------------------------- | ---------------------------
| `us-east-1` | [arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `us-east-2` | [arn:aws:lambda:us-east-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `us-west-1` | [arn:aws:lambda:us-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `us-west-2` | [arn:aws:lambda:us-west-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `ap-south-1` | [arn:aws:lambda:ap-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `eu-central-1` | [arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `eu-west-1` | [arn:aws:lambda:eu-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `eu-west-2` | [arn:aws:lambda:eu-west-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `eu-west-3` | [arn:aws:lambda:eu-west-3:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `eu-north-1` | [arn:aws:lambda:eu-north-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `ca-central-1` | [arn:aws:lambda:ca-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:
| `sa-east-1` | [arn:aws:lambda:sa-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1](#){: .copyMe}:clipboard:

??? question "Can't find our Lambda Layer for your preferred AWS region?"
You can use our [CDK Layer Construct](https://github.com/aws-samples/cdk-lambda-powertools-python-layer){target="_blank"}, or NPM like you normally would for any other library.

Please do file a feature request with the region you'd want us to prioritize making our Lambda Layer available.

=== "SAM"

```yaml hl_lines="5"
MyLambdaFunction:
Type: AWS::Serverless::Function
Properties:
Layers:
- !Sub arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:1
```

=== "Serverless framework"

```yaml hl_lines="5"
functions:
hello:
handler: lambda_function.lambda_handler
layers:
- arn:aws:lambda:${aws:region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:1
```

=== "CDK"

```typescript hl_lines="11 16"
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
export class SampleFunctionWithLayer extends Construct {
constructor(scope: Construct, id: string) {
super(scope, id);
// Create a Layer with AWS Lambda Powertools for TypeScript
const powertoolsLayer = lambda.LayerVersion.fromLayerVersionArn(
this,
'PowertoolsLayer',
`arn:aws:lambda:${cdk.Stack.of(this).region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:1`
);
new lambda.Function(this, 'Function', {
runtime: lambda.Runtime.NODEJS_16_X,
// Add the Layer to a Lambda function
layers: [powertoolsLayer],
code: lambda.Code.fromInline(`
const { Logger } = require('@aws-lambda-powertools/logger');
const { Metrics } = require('@aws-lambda-powertools/metrics');
const { Tracer } = require('@aws-lambda-powertools/tracer');
const logger = new Logger({logLevel: 'DEBUG'});
const metrics = new Metrics();
const tracer = new Tracer();
exports.handler = function(event, ctx) {
logger.debug("Hello World!");
}`),
handler: 'index.handler',
});
}
}
```

=== "Terraform"

```terraform hl_lines="9 38"
terraform {
required_version = "~> 1.0.5"
required_providers {
aws = "~> 3.50.0"
}
}
provider "aws" {
region = "{region}"
}
resource "aws_iam_role" "iam_for_lambda" {
name = "iam_for_lambda"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Effect": "Allow"
}
]
}
EOF
}
resource "aws_lambda_function" "test_lambda" {
filename = "lambda_function_payload.zip"
function_name = "lambda_function_name"
role = aws_iam_role.iam_for_lambda.arn
handler = "index.test"
runtime = "nodejs16.x"
layers = ["arn:aws:lambda:{region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:1"]
source_code_hash = filebase64sha256("lambda_function_payload.zip")
}
```

=== "Amplify"

```zsh
# Create a new one with the layer
❯ amplify add function
? Select which capability you want to add: Lambda function (serverless function)
? Provide an AWS Lambda function name: <NAME-OF-FUNCTION>
? Choose the runtime that you want to use: NodeJS
? Do you want to configure advanced settings? Yes
...
? Do you want to enable Lambda layers for this function? Yes
? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1
❯ amplify push -y
# Updating an existing function and add the layer
❯ amplify update function
? Select the Lambda function you want to update test2
General information
- Name: <NAME-OF-FUNCTION>
? Which setting do you want to update? Lambda layers configuration
? Do you want to enable Lambda layers for this function? Yes
? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:1
? Do you want to edit the local lambda function now? No
```

=== "Get the Layer .zip contents"
Change `{region}` to your AWS region, e.g. `eu-west-1`

```bash title="AWS CLI"
aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:1 --region {region}
```

The pre-signed URL to download this Lambda Layer will be within `Location` key.

???+ warning "Warning: Limitations"

Container Image deployment (OCI) or inline Lambda functions do not support Lambda Layers.

If you use `esbuild` to bundle your code, make sure to exclude `@aws-lambda-powertools` from being bundled since the packages will be brought by the Layer:

=== "SAM" (check the [doc](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-using-build-typescript.html) for more details)

```yaml hl_lines="5"
MyLambdaFunction:
Type: AWS::Serverless::Function
Properties:
...
Metadata:
# Manage esbuild properties
BuildMethod: esbuild
BuildProperties:
Minify: true
External:
- '@aws-lambda-powertools/commons'
- '@aws-lambda-powertools/logger'
- '@aws-lambda-powertools/metrics'
- '@aws-lambda-powertools/tracer'
```

=== "Serverless framework (check the [doc](https://floydspace.github.io/serverless-esbuild/) for more details)"

```yaml hl_lines="5"
custom:
esbuild:
external:
- '@aws-lambda-powertools/commons'
- '@aws-lambda-powertools/logger'
- '@aws-lambda-powertools/metrics'
- '@aws-lambda-powertools/tracer'
```

=== "CDK (check the [doc](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs.BundlingOptions.html#externalmodules) for more details)"

```typescript hl_lines="11 16"
new awsLambdaNodejs.NodejsFunction(this, 'Function', {
...
bundling: {
externalModules: [
'@aws-lambda-powertools/commons',
'@aws-lambda-powertools/logger',
'@aws-lambda-powertools/metrics',
'@aws-lambda-powertools/tracer',
],
}
});
```

### NPM Modules

The AWS Lambda Powertools for TypeScript utilities (which from here will be referred as Powertools) follow a modular approach, similar to the official [AWS SDK v3 for JavaScript](https://github.com/aws/aws-sdk-js-v3).
Each TypeScript utility is installed as standalone NPM package.

Expand Down
1 change: 1 addition & 0 deletions examples/cdk/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ node_modules
# CDK asset staging directory
.cdk.staging
cdk.out
lib
2 changes: 1 addition & 1 deletion examples/cdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The example functions, located in the `src` folder, are invoked automatically, t
## Deploying the stack

* Navigate to this location of the repo in your terminal (`examples/cdk`)
* `npm install`
* `npm ci`
* `npm run cdk deploy --all --profile <YOUR_AWS_PROFILE>`

Note: Prior to deploying you may need to run `cdk bootstrap aws://<YOU_AWS_ACCOUNT_ID>/<AWS_REGION> --profile <YOUR_AWS_PROFILE>` if you have not already bootstrapped your account for CDK.
Expand Down
14 changes: 7 additions & 7 deletions examples/cdk/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/cdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@aws-sdk/client-sts": "^3.53.0",
"@middy/core": "^2.5.6",
"@types/aws-lambda": "^8.10.86",
"aws-cdk-lib": "2.27.0",
"aws-cdk-lib": "^2.0.0",
"aws-sdk": "^2.1088.0",
"constructs": "^10.0.82",
"source-map-support": "^0.5.16"
Expand Down
Loading

0 comments on commit 83f6efb

Please sign in to comment.