Misc scribbles

Making a serverless website for photo upload pt. 1

2020-12-24

I set out to make a serverless website for photo uploads. Our dearly departed dixie dog needed a place to have photo uploads.

I didn't want to get charged dollars per month for a running ec2 instance, so I wanted something that was lightweight e.g. serverless, and easy

I decided to follow this tutorial

https://aws.amazon.com/blogs/compute/uploading-to-amazon-s3-directly-from-a-web-or-mobile-application/

I really liked the command line deployment (aws-sam) because fiddling around with the AWS web based control panel is ridiculously complicated

For example I also tried following this tutorial which uses the web based UI (https://www.youtube.com/watch?v=mw_-0iCVpUc) and it just did not work for me....I couldn't stay focused (blame ADHD or just my CLI obsession?) and certain things like "Execution role" that they say to modify are not there in the web UI anymore, so I just gave up (I did try though!)

To install aws-sam I used homebrew

brew tap aws/tap
brew install aws-sam-cli
brew install aws-sam-cli # I had to run the install command twice ref https://github.com/aws/aws-sam-cli/issues/2320#issuecomment-721414971
 
git clone https://github.com/aws-samples/amazon-s3-presigned-urls-aws-sam
cd amazon-s3-presigned-urls-aws-sam
sam deploy --guided
 
# proceeds with a guided installation, I used all defaults except I
# made "UploadRequestFunction may not have authorization definedIs
Is this okay? [y/N]: y"

They then in the tutorial describe trying to use postman to test

I test with curl instead

curl 'https://fjgbqj5436.execute-api.us-east-2.amazonaws.com/uploads'
 
{
  "uploadURL": "https://sam-app-s3uploadbucket-1653634.s3.us-east-2.amazonaws.com/112162.jpg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxx&X-Amz-Date=20201224T174804Z&X-Amz-Expires=300&X-Amz-Security-Token=yyy&X-Amz-SignedHeaders=host",
  "Key": "112162.jpg"
}

The premise of this is you make a request, and then the response from the API is a pre-signed URL that then allows you to upload directly to S3. You can use curl <url> --upload-file yourfile.jpg. This automatically does a PUT request to the s3 bucket (yes, this is talking directly to s3 now, not the lambda! the lambda is just for generating the "pre-signed URL" to let you upload). Careful to copy it exactly as is

curl "https://sam-app-s3uploadbucket-1653634.s3.us-east-2.amazonaws.com/112162.jpg?Content-Type=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=xxx&X-Amz-Date=20201224T174804Z&X-Amz-Expires=300&X-Amz-Security-Token=yyy&X-Amz-SignedHeaders=host" --upload-file test.jpg

There is no response, but I can then check the s3 console and see the file upload is successful (all files are renamed)

Figure shows that the file upload is successful :)

Then we can edit the file frontend/index.html from the repo we cloned to contain the lambda with the /uploads/ suffix

Then we manually upload this file to another s3 bucket or test it locally

aws s3 cp index.html s3://mybucket/
 
 
# then ...visit that in the browser

At this point the files are getting uploaded but not publicly accessible. To make them publicly accessible we uncomment the ACL: 'public-read' in the getSignedURL/app.js folder in the github repo

Figure showing the public-read uncommented

Figure showing the lines that need uncommenting in template.yaml in the root of the github repo that allows putObject in s3 with the public-read ACL

Re-run sam deploy --guided, same thing as at the start

Now the objects are publicly accessible!