optimising aws hosted app that generates and serves files using caching - amazon-web-services

I have an app composed of several microservices, all running as separate python lambda functions. The user-interface is a react app hosted on s3. The user inputs several variables which feed in to the serverless backend via API gateway, which generates a powerpoint file.
For a given set of variables the powerpoint output will be identical each time. As such, it makes no sense to regenerate and store the file each time. I looked into https://aws.amazon.com/elasticache/ but am unsure on how to integrate it here. Should I be storing these powerpoint files in s3 and only generating if the file is not already present, then serve a link pointing to the s3 bucket? This seems slow and cumbersome. What would be the most efficient way to serve up these powerpoint files repetitively?

You can use API gateway caching to cache data.
Goto api gateway => Click on "Stages" => stage_name => "Settings" tab => "Enable API caching"
More details here: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html
see below image

Related

In Squarespace Developer Mode, can one save the AWS CLI SDK to the website's server-side "Home" directory? If so, how?

The Current Situation
My Squarespace website uses client-side, custom JavaScript and JQuery injected into the Head section of a page as well as the Amazon Web Services Command Line Interface SDK. The custom JS, the JQuery and JS Libraries, and the SDK are loaded into the page Head each time the page is loaded.
That Is Objectionable
The SDK uses two predetermined, static, handshake credentials to connect to the AWS server. They are stored in a file, "credentials," in a hidden directory, .aws, created by the SDK when it first loads. At that point, however, they have no values.
The Situation Exposes Supposedly Secret AWS Login Credentials To A Potential Hack
Currently, it is necessary to set their values programmatically when the page loads by executing a CLI "updateConfig" command in the custom JS. The credential values are thus in a plain-text config file client-side.
As such, they are not so secret. Any site visitor who loads the page in his browser could use the browser's developer tools to view the source code and, potentially, discover the supposedly secret credentials thus compromising the security of the AWS account.
One Ought Not Put The Secret Credentials In Client-side JS
For that reason, AWS rather forcefully insists that one not put the credentials in client-side source code. The preferred method is to instantiate the SDK on the server-side and set the credentials one time only. Thereafter, the hidden .aws directory and the credentials file persist server-side at the root level of the website's Home Directory.
The Problem
So the problem is to load the SDK in the server-side Home Directory where it will persist over the site's lifetime.
The Question
The question is on a Squarespace website can one load the SDK server-side at the root level on the site's Home Directory. Can it be done in Developer Mode? How?
Unfortunately, Squarespace doesn't support the use of server-side/back-end code:
You can't add server-side code. Server-side code is handled by a server, not by a browser, and includes:
- PHP
- Ruby
- Ruby on Rails
- SQL
That would also include server-side JavaScript/Node. Because Squarespace only supports the front-end addition of HTML, CSS and Javascript within Code Injection, Code Blocks, and Developer Mode, you need to use front-end JavaScript in order to utilize third-party APIs (which is what you're doing currently).
Enabling Developer Mode only exposes template files for the site. Beyond the JSON-T templating engine, Developer Mode doesn't enable any sort of server-side logic or requests to take place. Therefore, it seems the answer to your question is no.
A potential alternative solution may be to use Google Apps Script or Google Cloud Functions instead, storing the credentials in the code there, and making a front-end request (via JavaScript on your website) to that endpoint in order to perform the handshake and get back the data you need.

How can I hide an API key in a GitHub public repo?

I am doing a simple front-end project where I (or a user) make an API call to the openweathermap api, fetch weather info and display it on a website.
Simple HTML, CSS and vanilla JS
So I want to keep the repo public & host the site with GitHub Pages... but my js file contains the API key which is required at runtime.
Extra Info:
(all this I found when I searched)
I know there is a way to keep an API key in a GitHub secret, then reference it in a yml file as an environmental variable in GitHub Actions.
But how can I put that secret in js code at runtime for any user who access my website?
Please note that what you're attempting to do is not secure. Even if there was a way to get GH Pages to inject the secret API key into the js file at the time of the request, every web client would then have a copy of that js file with the cleartext key embedded.
You will need some sort of minimal backend which stores the API key securely and relays calls from your static web page to the openweathermap API.
There are many ways to set up such a backend. The older question linked in the comments discusses some approaches. Note that nowadays, you could use a serverless FaaS service such as AWS Lambda or Azure Functions.
This is a perfectly valid question by the way and you're certainly not "too dumb". Good luck!

Deploying AWS chatbot without the use of the S3 Bucket

Im trying to integrate an AWS chatbot to my Website with the help from this github repository https://github.com/aws-samples/aws-lex-web-ui , and im trying to get this deployed completely locally which means the S3 bucket will not be used, only the "cognito id" will be used,is that possible?
Yes, that is possible. Take a look at the methods of integration:
Only Method 1 uses S3 Bucket. You probably want method 3 to create a stand-alone page or an embedded iframe. Here are the links to those directions:
Stand-alone Page
Embeddable iframe
Note that method 3 says to use the libraries from the dist folder. That is commonly overlooked.

How to correctly upload photos/files in a Django + Angular decoupled application to S3?

I have a decoupled applications build with Django 2, an API with DRF and an Angular 6 frontend application. I want to enable users to upload photos for their profiles, and probably in the future some pdfs, and after some research I figured out that the most convenient thing to do would be to store these files in an Amazon S3 bucket.
I have found numerous resources about how to upload files to an S3 bucket on both, Angular and Django, and now I was wondering what would be the best approach to do this in my decoupled application: should I manage it on the frontend and not use my backend at all? or should I pass the file from my angular to my Django app and then upload it to the bucket from there?
Some pros and cons of both approaches? It's my first time doing this and I haven't been able to find many resources for decoupled applications.
Any help is welcome! thanks!
The best practice
Anything related to data must be managed by your backend i.e Django, Angular is just a client.
You should pass the file from angular to Django app and then upload it
to the s3 bucket from there
Cons using client
Suppose in future, if you will develop mobile apps to consume your rest APIs then you need to rewrite the whole management there also.
You have to keep your s3 bucket API keys on the client and it is easily accessible to hackers.
dist folder size will be going to increase that will affect the load time of your site
If you are uploading files from client to S3 bucket, it will use the user's internet and in most of the cases it is slower than your sever's internet

What is the recommended way to handle large file uploads to s3?

I'm using AWS SDK for Ruby to upload large files from users to s3.
The server is a sinatra app with a POST /images endpoint accepting multipart/form-data. I'm experiencing a noticeable delay with user uploads. This is to be expected, because it's making a request to s3 synchronously. I wanted to move this to a background job using something like Sidekiq, but I'm not sure I like that solution.
I read online that some people are promoting direct uploads to s3 on the client side. Some even called this a "best practice." I'm hesitant to do this for several reasons:
My client side code would be heavily tied down to my cloud provider. I love AWS (great experiences), but I like to remain somewhat cloud-agnostic. I don't want my mobile and web apps to have to know the details of my AWS setup. If I choose to move away from s3 at a later date (unlikely but plausible), I would want this to be a seamless transition. Obviously, this works ok for a web app, because I can always redeploy quickly. However, I have to worry about mobile. Users may not update, and everything will become a lot more complicated if some users are uploading to s3 and some are uploading to another service.
Business logic regarding determining which bucket and region to use would need to either exist on the client side or I'd need to expose an endpoint for determining which bucket and region to use for each user. Then, I'd have to make a request to my server to figure out the parameters before I can begin uploading to s3. I want to be able to change buckets or re-route users to alternative regions and so I'm not a fan of this tight coupling or the additional request.
Security is a huge concern. When files are uploaded and processed through my server, I can utilize AWS IAM to properly ensure that these files are only coming from my server. I believe that I have to grant an "all-write" privilege to users which is problematic. If I use AWS IAM credentials in JavaScript, I do not see how you can ensure that users do not get unlimited write access to my bucket. All client side javascript, can be read by a user. In addition, I'm unaware of how to process validations. On my server, I can scan the files and determine whether or not to upload to s3. If I upload directly from the client, I would have to move this processing into lambda functions. I'm ok with that, but there is a chance the object could be retrieved by users before the processing has occurred. Then, I'd have to build some sort of locking system to prevent access before processing.
So, the bottom line is I have no idea where to go from here. I've hacked around some solutions, but I'm not thrilled with any of them. I'd love to learn how other startups and enterprises are tackling this kind of problem. What would you recommend? How would you counter my argument? Forgive me if I'm missing something, I'm still relatively an AWS-newbie.
If you're worried about changing the post service I would suggest using an API and that way you can change the backed storage for your service. The mobile or web client would call the service and then your api would place the file where it needed to go. The api you have more control over and you could just created a signed s3 url to send to the client and let them still do the uploading.
An api, like in 1, solves this problem too, the client doesn't have to do all the work.
Use Simple Token Services and Temporary Security Credentials.
I agree with strongjz, you should use an API to upload your files from the server side.
Cloudinary provides an API for uploading images and videos to the cloud.
From what I know from my experience in using Cloudinary it is the right solution for you.
All your images, videos and required metadata are stored and managed by Cloudinary in Amazon S3 buckets owned by Cloudinary.
The default maximum file size limit for videos is 40MB. This can be customized for paid plans.
For example in Ruby:
Cloudinary::Uploader.upload("sample_spreadsheet.xls", :resource_type =>
:raw)