{"id":21996748,"url":"https://github.com/nsriram/aws-lambda-layer-example","last_synced_at":"2025-04-30T21:02:33.398Z","repository":{"id":140597792,"uuid":"160513648","full_name":"nsriram/aws-lambda-layer-example","owner":"nsriram","description":"aws lambda layer example","archived":false,"fork":false,"pushed_at":"2018-12-05T12:17:30.000Z","size":3,"stargazers_count":24,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T19:51:18.927Z","etag":null,"topics":["aws","aws-lambda","cli","lambda-layers"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nsriram.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-05T12:17:16.000Z","updated_at":"2024-10-03T22:37:49.000Z","dependencies_parsed_at":"2024-07-11T22:07:41.093Z","dependency_job_id":null,"html_url":"https://github.com/nsriram/aws-lambda-layer-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsriram%2Faws-lambda-layer-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsriram%2Faws-lambda-layer-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsriram%2Faws-lambda-layer-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsriram%2Faws-lambda-layer-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nsriram","download_url":"https://codeload.github.com/nsriram/aws-lambda-layer-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251782736,"owners_count":21642983,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","aws-lambda","cli","lambda-layers"],"created_at":"2024-11-29T22:12:30.052Z","updated_at":"2025-04-30T21:02:33.390Z","avatar_url":"https://github.com/nsriram.png","language":null,"readme":"# Lambda Layers for NodeJS - An Example\n\nThis article outlines the steps involved in building a node js lambda using lambda layers for library dependencies, using [AWS CLI](https://github.com/aws/aws-cli).\n\nThe example will build a lambda function that will return current time using [momentjs](https://github.com/moment/moment/) library. The lambda will not bundle [momentjs](https://github.com/moment/moment/) via `package.json`, `node_modules`, but will use [momentjs](https://github.com/moment/moment/) via lambda layers.\n\nFollowing are assumed to be available on your computer.\n1. [AWS](https://aws.amazon.com) Account\n2. [IAM Role](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html) to manage and execute lambda functions\n3. [AWS CLI](https://github.com/aws/aws-cli) version **1.16.69**\n\n## 1 : Create and publish momentjs lambda layer.\n\nWhat is a lambda layer ?\n**(Source: AWS Docs)** : A layer is a ZIP archive that contains libraries, a custom runtime, or other dependencies. With layers, you can use libraries in your function without needing to include them in your deployment package. \n\n### 1.1 Create an empty nodejs project.\n```\n\u003e cd ~\n\u003e mkdir momentjs-lambda-layer\n\u003e cd momentjs-lambda-layer\n\u003e npm init -y\n```\n\n### 1.2 Add momentjs package dependency\n```\n\u003e yarn add moment\n```\n\n### 1.3 Package momentjs and its node_module dependencies. \n\n* The packaging should use the folder structure shown below for nodejs lambda layers. This folder structure is a requirement from lambda layers.\n\n```\nmomentjs-lambda-layer.zip\n└ nodejs/node_modules/moment\n```\n\n* Move the `node_modules` into nodejs subdirectory and package them as a zip archive file.\n**_Note_**: The packaged zip file is moved to `/tmp` folder.\n\n```\n\u003e mkdir -p dist/nodejs\n\u003e cp package.json dist/nodejs\n\u003e cd dist/nodejs\n\u003e yarn --production\n\u003e cd ..\n\u003e zip -r /tmp/momentjs-lambda-layer.zip nodejs\n```\n### 1.4 Publish the momentjs as a lambda layer.\n**_Note_** : Your [AWS CLI](https://github.com/aws/aws-cli) is assumed to be setup. You can execute `aws lambda list-layers` to get a response listing the layers.\ne.g., response\n```\n{ \"Layers\": [] }\n```\n\nPublish the lambda layer under MIT license. We are not using S3, but directly pushing the zip file that was created earlier.\n\n```\n\u003e aws lambda publish-layer-version --layer-name \"momentjs-lambda-layer\" \\\n  --description \"NodeJS module of Moment JS library\" \\\n  --license-info \"MIT\" \\\n  --compatible-runtimes \"nodejs8.10\" \\\n  --zip-file \"fileb:////tmp/momentjs-lambda-layer.zip\"\n```\n\nIf the publishing was successful, you should see a response similar to the one below, returning the `LayerVersionArn`.\n**_Note_** :\n- You can publish as many times a layer and they will be automatically published to the next version.\n\n```\n{\n    \"LayerVersionArn\": \"arn:aws:lambda:\u003cAWS_REGION\u003e:\u003cAWS_ACCOUNT_ID\u003e:layer:momentjs-lambda-layer:1\",\n    \"Description\": \"NodeJS module of Moment JS library\",\n    \"CreatedDate\": \"2018-12-05T10:31:36.211+0000\",\n    \"LayerArn\": \"arn:aws:lambda:\u003cAWS_REGION\u003e:\u003cAWS_ACCOUNT_ID\u003e:layer:momentjs-lambda-layer\",\n    \"Content\": {\n        \"CodeSize\": 743941,\n        \"CodeSha256\": \"nakCb8UDFbyzPrbcCde4xRK9K5EZ5MiPZxW49kl3AGI=\",\n        \"Location\": \"https://awslambda-ap-se-1-layers.s3.\u003cAWS_REGION\u003e.amazonaws.com/snapshots/\u003cAWS_ACCOUNT_ID\u003e/momentjs-lambda-layer-...\"\n    },\n    \"Version\": 1,\n    \"CompatibleRuntimes\": [\n        \"nodejs8.10\"\n    ],\n    \"LicenseInfo\": \"MIT\"\n}\n```\n\n## 2 : Create the 'CurrentTime' lambda.\n\n### 2.1 Create an empty nodejs project.\n**_Note_**: This example intentionally avoids ES6 `import`.\n\n```\n\u003e cd ~\n\u003e mkdir current-time-lambda\n\u003e cd current-time-lambda\n\u003e npm init -y\n```\n\nCopy the simple lambda code, that returns the current time using momentjs library, into `currentTimeLambda.js` file.\n\n```\n\u003e echo \"const moment = require('moment');\n\nexports.handler = (event, context, callback) =\u003e {\n  const time = moment().format('MMMM Do YYYY, h:mm:ss a');\n  callback(null, { time });\n};\" \u003e currentTimeLambda.js\n```\n\n**_Note_** : \n- The lambda source has reference to moment.js, but moment.js is not included in package.json. \n- We will attach the lambda layer that was created earlier to this lambda in following steps.\n\n### 2.2 Package the lambda source\n\nHere, we only need the single js file containing the lambda function. The essential purpose of lambda layers - simplify the bundling of lambda and separate the node_modules (dependencies) concern.\n\n```\n\u003e zip -r /tmp/currentTimeLambda.js.zip currentTimeLambda.js\n```\n\n### 2.3 Deploy the lambda\n**_Note_** :\n- Region, IAM role and AWS profile are specific to the user.\n- `AWS_ROLE_FOR_LAMBDA` is used as the IAM role that has lambda management permissions.\n- `AWS_PROFILE` used here is the value configured in `~/.aws/config` file, while setting up AWS CLI.\n- The packaged file `currentTimeLambda.js.zip` is directly uploaded and S3 is not used.\n\n```\naws lambda create-function \\\n    --region \u003cAWS_REGION\u003e \\\n    --function-name currentTimeLambda \\\n    --handler 'currentTimeLambda.handler' \\\n    --runtime nodejs8.10 \\\n    --role \"arn:aws:iam::\u003cAWS_ACCOUNT_ID\u003e:role/AWS_ROLE_FOR_LAMBDA\" \\\n    --zip-file 'fileb:///tmp/currentTimeLambda.js.zip' \\\n    --profile \u003cAWS_PROFILE\u003e\n```\n\nOn successful creation of lambda, you should see a response similar to the one below.\n\n```\n{\n    \"TracingConfig\": {\n        \"Mode\": \"PassThrough\"\n    },\n    \"CodeSha256\": \"9Bi4aWpD8XRFI7udqYo1NTy0WlYAkUVXw6iQKK0NYBo=\",\n    \"FunctionName\": \"currentTimeLambda\",\n    \"CodeSize\": 14236,\n    \"RevisionId\": \"3e64f4fb-c146-47fd-bfb0-d3a14486b001\",\n    \"MemorySize\": 128,\n    \"FunctionArn\": \"arn:aws:lambda:\u003cAWS_REGION\u003e:\u003cAWS_ACCOUNT_ID\u003e:function:currentTimeLambda\",\n    \"Version\": \"$LATEST\",\n    \"Role\": \"arn:aws:iam::\u003cAWS_ACCOUNT_ID\u003e:role/AWS_ROLE_FOR_LAMBDA\",\n    \"Timeout\": 3,\n    \"LastModified\": \"2018-12-05T10:48:10.171+0000\",\n    \"Handler\": \"currentTimeLambda.handler\",\n    \"Runtime\": \"nodejs8.10\",\n    \"Description\": \"\"\n}\n```\n_Note_ : If you try executing the lambda function, it will throw error mentioning `momentjs` library missing.\n\n## 3 : Update lambda to refer to lambda layer.\n\n### 3.1. Attach the lambda layer to the lambda function. \n\n* For this we need the `LayerVersionArn` that was returned by AWS when the lambda layer was created. Refer to step 1.4 above.\n* Layers and lambda runtimes compatibility should be checked when this association is done.\n\n```\n\u003e aws lambda update-function-configuration \\\n  --function-name currentTimeLambda \\\n  --layers arn:aws:lambda:\u003cAWS_REGION\u003e:\u003cAWS_ACCOUNT_ID\u003e:layer:momentjs-lambda-layer:1\n```\n\nIf the above command of lambda layer association was successful, you should see the layer listed in the lambda details as below.\n\n```\n{\n    \"Layers\": [\n        {\n            \"CodeSize\": 743941,\n            \"Arn\": \"arn:aws:lambda:\u003cAWS_REGION\u003e:\u003cAWS_ACCOUNT_ID\u003e:layer:momentjs-lambda-layer:1\"\n        }\n    ],\n    \"FunctionName\": \"currentTimeLambda\",\n    \"LastModified\": \"2018-12-05T10:51:28.445+0000\",\n    \"RevisionId\": \"2ca09f6f-e85a-4cbd-a5ed-4f52db28bb07\",\n    \"MemorySize\": 128,\n    \"Version\": \"$LATEST\",\n    \"Role\": \"arn:aws:iam::\u003cAWS_ACCOUNT_ID\u003e:role/AWS_ROLE_FOR_LAMBDA\",\n    \"Timeout\": 3,\n    \"Runtime\": \"nodejs8.10\",\n    \"TracingConfig\": {\n        \"Mode\": \"PassThrough\"\n    },\n    \"CodeSha256\": \"9Bi4aWpD8XRFI7udqYo1NTy0WlYAkUVXw6iQKK0NYBo=\",\n    \"Description\": \"\",\n    \"CodeSize\": 14236,\n    \"FunctionArn\": \"arn:aws:lambda:\u003cAWS_REGION\u003e:\u003cAWS_ACCOUNT_ID\u003e:function:currentTimeLambda\",\n    \"Handler\": \"currentTimeLambda.handler\"\n}\n```\n\n## 4 : Invoke lambda to validate the usage of layer\n\n### 4.1 Invoke the lambda\n* Now, we will invoke the lambda (that was deployed without momentjs node_module) to verify that it uses lambda layer for momentjs dependency.\n\n```\n\u003e  aws lambda invoke --function-name currentTimeLambda --log-type Tail --payload '{}' outputfile.txt\n```\n\nSuccessful invocation should list a response similar to the following.\n\n```\n{\n    \"LogResult\": \"U1RBUlQgUmVxdWVzdElkOiAwZ...HVyYXRpb246IDEwMCBtcyAJTWVtb3J5IFNpemU6IDEyOCBNQglNYXggTWVtb3J...E1CCQo=\",\n    \"ExecutedVersion\": \"$LATEST\",\n    \"StatusCode\": 200\n}\n```\n### 4.1 View the output\n- To ensure the current time is responded by lambda, view the contents of `output.txt` file. You should see the time.\n\n```\n\u003e cat outputfile.txt\n{\"time\":\"December 5th 2018, 10:53:55 am\"}%\n```\n\n🏁 If you have seen the timestamp, **Congrats !** You got your first  lambda layer working  🏁\n\n\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnsriram%2Faws-lambda-layer-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnsriram%2Faws-lambda-layer-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnsriram%2Faws-lambda-layer-example/lists"}