Book Finder is a simple OCR app powered by AWS Serverless. It allows a user to upload images and search for text contained in them.
- AWS account
- IAM Admin (ability to create roles and permissions)
- Shell (bash)
- node/npm
- make
- aws
- Static website hosting
As with any AWS resource, there are financial risks. Please monitor any resources that you create with these instructions. I have accounted for security and throttling across the app, but my solution may not be comprehensive. Proceed at your own risk.
You must create a versioned S3 bucket before creating the main stack. This is where Lambda code will be stored for deployment via CFN.
Run the following commands (replace 'my-bucket' with a GLOBALLY UNIQUE lowercase bucket name):
aws s3 mb s3://my-bucket
aws s3api put-bucket-versioning --bucket my-bucket --versioning-configuration Status=Enabled
In Makefile
(located in server
), change the value of lambda_bucket
to your bucket name.
In book-finder.yml
(located in server
), change the default value of the LambdaBucketName
parameter to your bucket name.
Before creating the main stack, you will need to create the node.js canvas lambda layer and add its ARN to your CFN file (book-finder.yml
).
- In your AWS console, navigate to the Serverless Application Repository via Services.
- Click Available applications on the left
- Search for canvas
- Click lambda-layer-canvas-nodejs by Charoite Lee
- Click Deploy
- In your terminal, run:
aws lambda list-layers
- Copy the value of
LayerVersionArn
forLayerName
canvas-nodejs
- Search for
REKOG LAMBDA
inbook-finder.yml
- Update the value of the
Layers
property of theS3TriggerLambda
resource with theLayerVersionArn
and save the file
In your lambda
directory, run:
npm install
This will prepare the necessary node modules for the Lambda environment.
Before creating the main stack, you need to ensure that all of your bucket names (in addition to the Lambda bucket created earlier) are GLOBALLY UNIQUE. In the book-finder.yml
CFN file, you'll need to change the Default values for the ResultsBucketName
and UploadBucketName
parameters. To help with this, you can create a unique string to be appended to the values in place of the 'xxxxx' that is currently present. (NOTE: Bucket names cannot conain capital letters.) You can also use the following shell command to generate a unique alphanumeric string:
tr -dc a-z0-9 </dev/urandom | head -c 8 ; echo ''
The rest of the AWS resources are contained in a single stack created via Makefile
.
- In your local terminal, navigate to the
server
directory - Run
make
The Makefile will check for updates to Lambda code before zipping the functions and uploading them to the previously created versioned Lambda bucket.
The front-end is a simple static site, so it can run on localhost. I used VS Code's Live Server extension for development. The site is hosted via Netlify's Continuous Deployment feature.
(NOTE: If you are testing with localhost, please be aware that the resource paths for some links may not work correctly. This is because the root directory name (book-finder
) is excluded from the URL by Netlify, but is required in localhost.)
You will need to change a few values in your config.js
file (found in book-finder
) to hook it up to your AWS stack.
APIEndpointID
- To find the ID of your REST API (
bookfinder-api-gateway
), run:
aws apigateway get-rest-apis
- To find the ID of your REST API (
region
- Replace with the default region of your AWS account as defined in your AWS
config
file, e.g.us-west-2
- Replace with the default region of your AWS account as defined in your AWS
You can also find the above information in the console.
Thank you for checking out my project. If you encountered any issues, or if you have a suggestion or request, submit an issue.
Before deleting your stack, you must empty all S3 buckets that are part of the stack. You will need the unique bucket names generated by CFN first. Use this command to find your bucket names:
aws s3 ls
Use the following command to delete the contents of each bucket (you will need to do this for all three buckets):
aws s3 rm s3://your-bucket-name --recursive
To delete the main stack and the stack created for the node.js canvas lambda layer, run:
aws cloudformation delete-stack --stack-name book-finder
aws cloudformation delete-stack --stack-name serverlessrepo-lambda-layer-canvas-nodejs
To delete the node.js canvas lambda layer, which still exists because of its retention policy, first run:
aws lambda list-layers
Note the Version
(your-version-number
in the following command), then run:
aws lambda delete-layer-version --layer-name canvas-nodejs --version-number your-version-number
To delete the versioned Lambda bucket and all of its contents, run (replace all instances of my-bucket
in the following commands with your bucket name):
(NOTE: One or both of the first two commands may fail - simply continue to the third command if they do.)
aws s3api delete-objects --bucket my-bucket --delete "$(aws s3api list-object-versions \
--bucket my-bucket --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"
aws s3api delete-objects --bucket my-bucket --delete "$(aws s3api list-object-versions \
--bucket my-bucket --query='{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}}')"
aws s3 rb s3://my-bucket
For the curious, see this StackOverflow answer.
Finally, remove the lambda.zip
file from your server
directory if it exists.
CloudWatch logs are not deleted by this process and will persist for up to 3 days after stack deletion. You may delete them via the console if you wish.
This software is licensed under the GNU General Public License v3.0 or later.
See LICENSE to see the full text of the license.