diff --git a/sample-apps/efs-nodejs/1-create-bucket.sh b/sample-apps/efs-nodejs/1-create-bucket.sh deleted file mode 100755 index 55a9a5a3..00000000 --- a/sample-apps/efs-nodejs/1-create-bucket.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash -set -eo pipefail -BUCKET_ID=$(dd if=/dev/random bs=8 count=1 2>/dev/null | od -An -tx1 | tr -d ' \t\n') -BUCKET_NAME=lambda-artifacts-$BUCKET_ID -echo $BUCKET_NAME > bucket-name.txt -aws s3 mb s3://$BUCKET_NAME \ No newline at end of file diff --git a/sample-apps/efs-nodejs/2-deploy-vpc.sh b/sample-apps/efs-nodejs/2-deploy-vpc.sh deleted file mode 100755 index 8fbc72c1..00000000 --- a/sample-apps/efs-nodejs/2-deploy-vpc.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -set -eo pipefail -aws cloudformation deploy --template-file template-vpcefs.yml --stack-name efs-nodejs-vpc diff --git a/sample-apps/efs-nodejs/20231030-efsreaderror.log b/sample-apps/efs-nodejs/20231030-efsreaderror.log deleted file mode 100644 index f8369311..00000000 --- a/sample-apps/efs-nodejs/20231030-efsreaderror.log +++ /dev/null @@ -1,25 +0,0 @@ -$ ./4-invoke.sh -{ - "StatusCode": 200, - "ExecutedVersion": "$LATEST" -} -{"writeTimeMs":60.659086,"readTimeMs":"Read error: Error: ENOENT: no such file or directory, open '/mnt/efs0/test.bin'","fileSizeBytes":0} -{ - "StatusCode": 200, - "ExecutedVersion": "$LATEST" -} -{"writeTimeMs":60.002857,"readTimeMs":79.54446,"fileSizeBytes":1398104} -{ - "StatusCode": 200, - "ExecutedVersion": "$LATEST" -} -{"writeTimeMs":50.76445,"readTimeMs":39.566218,"fileSizeBytes":1398104} -{ - "StatusCode": 200, - "ExecutedVersion": "$LATEST" -} -{"writeTimeMs":60.457508,"readTimeMs":199.181445,"fileSizeBytes":1398104} -{ - "StatusCode": 200, - "ExecutedVersion": "$LATEST" -} \ No newline at end of file diff --git a/sample-apps/efs-nodejs/3-deploy.sh b/sample-apps/efs-nodejs/3-deploy.sh deleted file mode 100755 index 275b7dc6..00000000 --- a/sample-apps/efs-nodejs/3-deploy.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -set -eo pipefail -ARTIFACT_BUCKET=$(cat bucket-name.txt) -STACK=efs-nodejs -if [[ $# -eq 1 ]] ; then - STACK=$1 - echo "Deploying to stack $STACK" -fi -aws cloudformation package --template-file template.yml --s3-bucket $ARTIFACT_BUCKET --output-template-file out.yml -aws cloudformation deploy --template-file out.yml --stack-name $STACK --capabilities CAPABILITY_NAMED_IAM - -# attach to different VPC -#aws cloudformation deploy --template-file out.yml --stack-name $STACK --capabilities CAPABILITY_NAMED_IAM --parameter-overrides vpcStackName=lambda-vpc diff --git a/sample-apps/efs-nodejs/4-invoke.sh b/sample-apps/efs-nodejs/4-invoke.sh deleted file mode 100755 index d2463a0a..00000000 --- a/sample-apps/efs-nodejs/4-invoke.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -eo pipefail -FUNCTION=$(aws cloudformation describe-stack-resource --stack-name efs-nodejs --logical-resource-id function --query 'StackResourceDetail.PhysicalResourceId' --output text) - -while true; do - aws lambda invoke --function-name $FUNCTION --payload fileb://event.json out.json - cat out.json - echo "" - sleep 2 -done diff --git a/sample-apps/efs-nodejs/5-cleanup.sh b/sample-apps/efs-nodejs/5-cleanup.sh deleted file mode 100755 index ad33b9cd..00000000 --- a/sample-apps/efs-nodejs/5-cleanup.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash -set -eo pipefail -STACK=efs-nodejs -if [[ $# -eq 1 ]] ; then - STACK=$1 - echo "Deleting stack $STACK" -fi -FUNCTION=$(aws cloudformation describe-stack-resource --stack-name $STACK --logical-resource-id function --query 'StackResourceDetail.PhysicalResourceId' --output text) -aws cloudformation delete-stack --stack-name $STACK -echo "Deleted $STACK stack." - -if [ -f bucket-name.txt ]; then - ARTIFACT_BUCKET=$(cat bucket-name.txt) - if [[ ! $ARTIFACT_BUCKET =~ lambda-artifacts-[a-z0-9]{16} ]] ; then - echo "Bucket was not created by this application. Skipping." - else - while true; do - read -p "Delete deployment artifacts and bucket ($ARTIFACT_BUCKET)? (y/n)" response - case $response in - [Yy]* ) aws s3 rb --force s3://$ARTIFACT_BUCKET; rm bucket-name.txt; break;; - [Nn]* ) break;; - * ) echo "Response must start with y or n.";; - esac - done - fi -fi - -while true; do - read -p "Delete function log group (/aws/lambda/$FUNCTION)? (y/n)" response - case $response in - [Yy]* ) aws logs delete-log-group --log-group-name /aws/lambda/$FUNCTION; break;; - [Nn]* ) break;; - * ) echo "Response must start with y or n.";; - esac -done - -rm -f out.yml out.json lib/nodejs/package-lock.json -rm -rf lib/nodejs/node_modules diff --git a/sample-apps/efs-nodejs/README.md b/sample-apps/efs-nodejs/README.md deleted file mode 100644 index 0effd7c4..00000000 --- a/sample-apps/efs-nodejs/README.md +++ /dev/null @@ -1,90 +0,0 @@ -# Using Amazon EFS for file storage - -This application demonstrates the use of Amazon EFS with AWS Lambda. You can use Amazon EFS to create file systems that provide shared storage to Lambda functions and other compute resources. Your functions mount a folder in the file system to a local directory with the NFS protocol. The sample application creates a VPC network, file system, function, and supporting resources with AWS CloudFormation. - -The function takes a event with the following structure: - -``` -{ - "fileName": "test.bin", - "fileSize": 1048576 -} -``` - -The function creates a file of the specified size (1MB in this case) and then reads it into memory. - -The project source includes function code and supporting resources: - -- `dbadmin` - A Node.js function that reads and writes files. -- `lib` - A Lambda layer with the npm modules used by the application's function. -- `event.json` - A JSON document that can be used to test the application's function. -- `template.yml` - An AWS CloudFormation template that creates the application. -- `template-vpcefs.yml` - A template that creates the VPC and Amazon EFS file system. -- `1-create-bucket.sh`, `2-deploy-vpc.sh`, etc. - Shell scripts that use the AWS CLI to deploy and manage the application. - -Use the following instructions to deploy the sample application. - -# Requirements - -To deploy the sample application, you need the following tools: - -- [Node.js 18 with npm](https://nodejs.org/en/download/releases/). -- The Bash shell. For Linux and macOS, this is included by default. In Windows 10, you can install the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10) to get a Windows-integrated version of Ubuntu and Bash. -- [The AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) v1.17 or newer. - -To run the sample application in AWS, you need permission to use Lambda and the following services. - -- Amazon EFS ([pricing](https://aws.amazon.com/efs/pricing/)) -- Amazon VPC ([pricing](https://aws.amazon.com/vpc/pricing/)) -- AWS Identity and Access Management -- AWS CloudFormation - -Standard charges apply for each service. - -# Setup - -Download or clone this repository. - - $ git clone https://github.com/awsdocs/aws-lambda-developer-guide.git - $ cd aws-lambda-developer-guide/sample-apps/efs-nodejs - -To create a new bucket for deployment artifacts, run `1-create-bucket.sh`. - - efs-nodejs$ ./1-create-bucket.sh - make_bucket: lambda-artifacts-a5e491dbb5b22e0d - -To create the VPC and EFS file system, run the `2-deploy-vpc.sh` script. - - efs-nodejs$ ./2-deploy-vpc.sh - -# Deploy - -To deploy the application, run `3-deploy.sh`. - - efs-nodejs$ ./3-deploy.sh - Uploading to e678bc216e6a0d510d661ca9ae2fd941 2678 / 2678.0 (100.00%) - Successfully packaged artifacts and wrote output template to file out.yml. - Waiting for changeset to be created.. - Waiting for stack create/update to complete - Successfully created/updated stack - efs-nodejs - -This script uses AWS CloudFormation to deploy the Lambda functions and an IAM role. If the AWS CloudFormation stack that contains the resources already exists, the script updates it with any changes to the template or function code. - -# Test - -To invoke the function with a test event, use the invoke script. - - efs-nodejs$ ./4-invoke.sh - { - "StatusCode": 200, - "ExecutedVersion": "$LATEST" - } - {"writeTimeMs":3.316225,"readTimeMs":166.129772,"fileSizeBytes":1398104} - -Let the script invoke the function a few times and then press `CRTL+C` to exit. - -# Cleanup - -To delete the application, run the cleanup script. - - efs-nodejs$ ./5-cleanup.sh diff --git a/sample-apps/efs-nodejs/event.json b/sample-apps/efs-nodejs/event.json deleted file mode 100644 index 8fdc7054..00000000 --- a/sample-apps/efs-nodejs/event.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "fileName": "test.bin", - "fileSize": 1048576 -} diff --git a/sample-apps/efs-nodejs/function/index.mjs b/sample-apps/efs-nodejs/function/index.mjs deleted file mode 100644 index b95cc249..00000000 --- a/sample-apps/efs-nodejs/function/index.mjs +++ /dev/null @@ -1,58 +0,0 @@ -import fs from 'node:fs/promises' -const crypto = await import('node:crypto') -const dir = process.env.mountPath - -export const handler = async (event) => { - console.log("EVENT: %s", JSON.stringify(event, null, 2)) - const filePath = dir + "/" + event.fileName - const fileSize = event.fileSize - // generate file - const buffer = crypto.randomBytes(fileSize) - // write operation - const writeTimeMs = await writeFile(filePath, buffer) - // read file - const readTimeMs = await readFile(filePath) - // stat file - const fileStat = await fs.stat(filePath) - const fileSizeBytes = fileStat.size - console.log("File size: %s bytes", fileSizeBytes) - // format response - var response = { - "writeTimeMs": writeTimeMs, - "readTimeMs": readTimeMs, - "fileSizeBytes": fileSizeBytes - } - return response -} - -var readFile = async function(filePath){ - console.log("Attempting to read file: %s", filePath) - const readstart = process.hrtime() - var fileContents - try { - fileContents = await fs.readFile(filePath, "utf8") - const readend = process.hrtime(readstart) - const readTimeMs = readend[0] * 1000 + readend[1] / 1000000 - console.log("Read completed in %dms", readTimeMs) - return readTimeMs - } catch (error){ - console.error(error) - return "Read error: " + error - } -} - -var writeFile = async function(filePath, buffer){ - console.log("Attempting to write file: %s", filePath) - var writestart = process.hrtime() - try { - const fileBase64 = buffer.toString('base64') - fs.writeFile(filePath, fileBase64) - var writeend = process.hrtime(writestart) - const writeTimeMs = writeend[0] * 1000 + writeend[1] / 1000000 - console.log("Write completed in %dms", writeTimeMs) - return writeTimeMs - } catch (error){ - console.error(error) - return "Write error: " + error - } -} \ No newline at end of file diff --git a/sample-apps/efs-nodejs/template-vpcefs.yml b/sample-apps/efs-nodejs/template-vpcefs.yml deleted file mode 100644 index 6eddd588..00000000 --- a/sample-apps/efs-nodejs/template-vpcefs.yml +++ /dev/null @@ -1,119 +0,0 @@ -AWSTemplateFormatVersion: 2010-09-09 -Resources: - fileSystem: - Type: AWS::EFS::FileSystem - mountTargetA: - Type: AWS::EFS::MountTarget - Properties: - FileSystemId: !Ref fileSystem - SubnetId: !Ref privateSubnetA - SecurityGroups: - - !GetAtt privateVPC.DefaultSecurityGroup - mountTargetB: - Type: AWS::EFS::MountTarget - Properties: - FileSystemId: !Ref fileSystem - SubnetId: !Ref privateSubnetB - SecurityGroups: - - !GetAtt privateVPC.DefaultSecurityGroup - accessPoint: - Type: AWS::EFS::AccessPoint - Properties: - FileSystemId: !Ref fileSystem - PosixUser: - Uid: "1001" - Gid: "1001" - RootDirectory: - CreationInfo: - OwnerGid: "1001" - OwnerUid: "1001" - Permissions: "755" - Path: "/efs-nodejs-storage" - privateVPC: - Type: AWS::EC2::VPC - Properties: - CidrBlock: 172.31.0.0/16 - Tags: - - Key: Name - Value: !Ref AWS::StackName - privateSubnetA: - Type: AWS::EC2::Subnet - Properties: - VpcId: !Ref privateVPC - AvailabilityZone: - Fn::Select: - - 0 - - Fn::GetAZs: "" - CidrBlock: 172.31.3.0/24 - MapPublicIpOnLaunch: false - Tags: - - Key: Name - Value: !Join ["-", [!Ref "AWS::StackName","subnet-a"]] - privateSubnetB: - Type: AWS::EC2::Subnet - Properties: - VpcId: !Ref privateVPC - AvailabilityZone: - Fn::Select: - - 1 - - Fn::GetAZs: "" - CidrBlock: 172.31.2.0/24 - MapPublicIpOnLaunch: false - Tags: - - Key: Name - Value: !Join ["-", [!Ref "AWS::StackName","subnet-b"]] - privateRouteTable: - Type: AWS::EC2::RouteTable - Properties: - VpcId: !Ref privateVPC - privateSubnetARouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref privateSubnetA - RouteTableId: !Ref privateRouteTable - privateSubnetBRouteTableAssociation: - Type: AWS::EC2::SubnetRouteTableAssociation - Properties: - SubnetId: !Ref privateSubnetB - RouteTableId: !Ref privateRouteTable -Outputs: - privateVPCSecurityGroup: - Description: Default security for Lambda VPC - Value: !GetAtt privateVPC.DefaultSecurityGroup - Export: - Name: !Join ["-", [!Ref "AWS::StackName","vpc-sg"]] - privateVPCID: - Description: VPC ID - Value: !Ref privateVPC - Export: - Name: !Join ["-", [!Ref "AWS::StackName","vpc"]] - privateSubnetAID: - Description: Private Subnet A ID - Value: !Ref privateSubnetA - Export: - Name: !Join ["-", [!Ref "AWS::StackName","subnet-a"]] - privateSubnetBID: - Description: Private Subnet B ID - Value: !Ref privateSubnetB - Export: - Name: !Join ["-", [!Ref "AWS::StackName","subnet-b"]] - fileSystemId: - Description: File system ID - Value: !Ref fileSystem - Export: - Name: !Join ["-", [!Ref "AWS::StackName","filesystem"]] - mountTargetA: - Description: Mount point A ID - Value: !Ref mountTargetA - Export: - Name: !Join ["-", [!Ref "AWS::StackName","mounttarget-a"]] - mountTargetB: - Description: Mount point B ID - Value: !Ref mountTargetB - Export: - Name: !Join ["-", [!Ref "AWS::StackName","mounttarget-b"]] - accessPointArn: - Description: Access point ARN - Value: !GetAtt accessPoint.Arn - Export: - Name: !Join ["-", [!Ref "AWS::StackName","accesspoint"]] diff --git a/sample-apps/efs-nodejs/template.yml b/sample-apps/efs-nodejs/template.yml deleted file mode 100644 index a45fc05b..00000000 --- a/sample-apps/efs-nodejs/template.yml +++ /dev/null @@ -1,44 +0,0 @@ -AWSTemplateFormatVersion: 2010-09-09 -Description: An AWS Lambda application that connects to an EFS file system in the VPC to share files. -Transform: AWS::Serverless-2016-10-31 -Parameters: - vpcStackName: - Default: efs-nodejs-vpc - Description: VPC and file system stack name - Type: String - mountPath: - Default: "/mnt/efs0" - Description: File system mount path - Type: String -Resources: - function: - Type: AWS::Serverless::Function - Properties: - CodeUri: function/. - Description: Use a file system. - FileSystemConfigs: - - LocalMountPath: !Ref mountPath - Arn: - Fn::ImportValue: !Sub "${vpcStackName}-accesspoint" - Environment: - Variables: - mountPath: !Ref mountPath - MemorySize: 128 - Timeout: 15 - Runtime: nodejs18.x - Tracing: Active - Handler: index.handler - VpcConfig: - SecurityGroupIds: - - Fn::ImportValue: - !Sub "${vpcStackName}-vpc-sg" - SubnetIds: - - Fn::ImportValue: - !Sub "${vpcStackName}-subnet-a" - - Fn::ImportValue: - !Sub "${vpcStackName}-subnet-b" - # Function's execution role - Policies: - - AWSLambdaVPCAccessExecutionRole - - AmazonElasticFileSystemClientReadWriteAccess - - AWSXRayDaemonWriteAccess diff --git a/sample-apps/nodejs-apig/template.yml b/sample-apps/nodejs-apig/template.yml index 57970a15..e01993f3 100644 --- a/sample-apps/nodejs-apig/template.yml +++ b/sample-apps/nodejs-apig/template.yml @@ -12,7 +12,7 @@ Resources: Type: AWS::Serverless::Function Properties: Handler: index.handler - Runtime: nodejs18.x + Runtime: nodejs22.x CodeUri: function/. Description: Call the AWS Lambda API Timeout: 10