I have 2 different modules, one is loyalty and another one is wallet. (both are written in java)
loyalty app is hosted on an AWS elastic beanstalk and I have an AWS API Gateway on top of it.
now I'm about to build the wallet and it will need to use some functionalities of loyalty module. I can put it under loyalty but it wouldn't make sense since they both server different purposes.
so I thought I would put wallet on another AWS elastic beanstalk with AWS API Gateway on top but then I wonder, if wallet wants to call loyalty to use any of its functions, how should it be done? I'm not sure if it's a good idea to call the API gateway on top of loyalty to access its functions. Or is it a correct way?
Whether it is a "correct" way depends on your architecture and design preferences. You can call one beanstalk application from another via API gateway, especially if you are calling public API methods, and one beanstalk application can call another directly (provided your subnets and security groups are set up to allow this (the default security group used set up by VPC does allow this)).
If you are intending to call private API methods in your loyalty app, then it would make sense to call the 'loyalty` app directly, because even assuming you have proper authentication controls on your API gateway methods it is even better for them to simply not be exposed to the public at all.
More generally, if the loyalty and wallet apps should be considered to be part of the same service, then I would put both under the same API gateway instance, and would allow wallet to call loyalty directly without going through API gateway.
I am not good at AWS, but by my understanding, your question sounds like your are mixing the deployment structure and source code structure. I think you can write shared source code for both, and deploy dlls(not dll in AWS?) seperately. I think it's not good to call API gateway.
Related
Imagine a use case where multiple REST APIs (pure API with no UI) are deployed using Cloud Run or Cloud Functions. Each API:
is unique and for a specific outside client, which will use it for
various unknown purposes.
needs to be secured so that it can only be used by the corresponding
client.
The APIs need to be available via the same custom domain, e.g.:
api.example.com/client_1
api.example.com/client_2
The clients are potentially many, so any solution must be possible to automate programmatically.
Is there a good approach for achieving this using GCP? I understand that an API Gateway along with Load Balancing can be used to achieve availability via a custom domain. However I’m not sure how to best tackle the security part. Using API keys seems like an option, but IIUC each key would have access to all APIs encapsulated by the Gateway in that case. Also I’m not sure if the API keys can be created programmatically in a straightforward manner using one of the GCP client libraries.
Are there better options I’m missing?
Using API Gateway for your use case might not be the best possible option, reason being below section of GCP documentation:
Custom domain names are not supported for API Gateway. If you want to customize the domain name, you have to create a load balancer to use your custom domain name and then direct requests to the gateway.dev domain of your deployed API.
This might in turn increase the costs for your application.
So, I would suggest creating your REST APIs via nodejs and deploying it over Cloud Run. Cloud Run supports canonicalizing DNS names.
NOTE: It is still not supported in every regions, so you might want to be thoughtful about that with respect to your Latency Issues.
Coming to the part of securing your API's below can be followed:
You can use create API Keys and configure your API to accept these keys via header/query params
To create your application's API key you can follow the google document:
https://support.google.com/googleapi/answer/6158862?hl=en
https://medium.com/swlh/secure-apis-in-cloud-run-cloud-functions-and-app-engine-using-cloud-endpoints-espv2-beta-b51b1c213aea
You can create multiple APIs using the same domain even without using Load Balancers and complex coding by using OpenAPI. This document outlines the procedure for creating multiple APIs using the sub domains in GCP. There are multiple ways for applying authentication to your OpenAPI follow this documentation for enabling authentication in OpenAPI. Hope this might help you.
I’m trying to pick up API gateway.
What are the different use cases for alb vs API gateway? I’ll be honest to say that I am not completely familiar with the concept of an API. I know we can invoke it backend, and the analogy that it’s a restaurant menu. However, beyond that, I am not clear what the difference is. Is it that applications using ALB has a user interface, but not API gateway? I tried reading through documentation on the features, but got even more lost. As such, I am hoping someone can share the use cases for both services so that I can visualise what it’s used for and the reason for the features. Thanks!
API GW is focused on API and has some additional options - e.g. API definition via swagger, execution of a lambda function, converting the call to an event bridge event, support of authenticators (iam, cognito), multiple deployment stages etc.
The load balancer listens on a port and that's about it.
Q: In what cases would you require these API GW features as opposed to just using an ALB?
A: One obvious benefit is a serverless or "low code". Let's say you want an API which processes asynchronous requests.
It is possible to create an API endpoint which queues all incoming requests to a SQS queue with just one AWS CLI command with no programming (provided the resources do exist):
https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-aws-services.html
Each API endpoint can be served by a different AWS resource including EC2/ALB.
ALB is well suited for things like traditional monolithic applications (LAMP, Java application servers etc.)
We currently have multiple APIs that are not behind a gateway. The APIs that are exposed publicly use OpenID Connect for authentication and claims authorization. Some of the APIs are internal only and are network secured behind a firewall.
We plan to setup Kong Gateway Enterprise in front of our APIs. We should be able to centralize token validation from public clients at the gateway. We could possibly centralize some basic authorization as well (e.g. scopes). Some logic will probably still need to happen in the upstream API. So, those APIs will still need to know the context of the caller (client and user).
Ideally, we would like to be able to have APIs that can be exposed publicly and also called internally to avoid duplicating logic. I'd like to understand some secure approaches for making this happen with Kong. Exactly how to setup the system behind the gateway is still unclear to me.
Some questions I have are:
Should we have both an internal gateway and an external? Is there guidance on how to choose when to create separate gateways?
If we have multiple upstream services in a chain, how do you pass along the auth context?
Custom headers?
Pass along the original JWT?
How can we make a service securely respond to both internal and external calls?
We could setup up a mesh and use mTLS but wouldn't the method of passing the auth context be different between mTLS and the gateway?
We could set custom headers from Kong and have other internal services render them as well. But since this isn't in a JWT, aren't we loosing authenticity of the claims?
We could have every caller, including internal services, get their own token but that could make the number of clients and secrets difficult to manage. Plus, it doesn't handle the situation when those services are still acting on behalf of the user as a part of an earlier request.
Or we could continue to keep separate internal and external services but duplicate some logic.
Some other possibly helpful notes:
There is no other existing PKI other than our OIDC provider.
Services will not all be containerized. Think IIS on EC2.
Services are mostly REST-ish.
There is a lot there to unpack here, and the answer is: it depends
Generally, you should expose the bare minimum API externally, so a separate gateway in the DMZ with only the API endpoints required by external clients. Your generally going to be making more internal changes so you don't want to expose a sensitive endpoint by accident.
Don’t be too concerned about duplication when it comes to APIs, it’s quite common to have multiple API gateways, even egress gateways for external communication. There are patterns like (BFF - Backend for frontend pattern) where each client has its own gateway for orchestration, security, routing, logging, auditing. The more clients are isolated from each other the easier and less risky it is to make API changes.
In regards to propagating the Auth context, it really comes down to trust, and how secure your network and internal actors are. If you're using a custom header then you have to consider the "Confused Deputy Problem". Using a signed JWT solves that, but if the token gets leaked it can be used maliciously against any service in the chain.
You can use RFC8693 Token exchange to mitigate that and even combine it with MTLS, but again that could be overkill for your app. If the JWT is handled by an external client, it becomes even riskier. In that case, it should ideally be opaque and only accepted by the external-facing gateway. That GW can then exchange it for a new token for all internal communication.
I am very new to AWS Lambda and am struggling to understand its functionalities based on many examples I found online (+reading endless documentations). I understand the primary goal of using such service is to implement a serverless architecture that is cost and probably effort-efficient by allowing Lambda and the API Gateway to take on the role of managing your server (so serverless does not mean you don't use a server, but the architecture takes care of things for you). I organized my research into two general approaches taken by developers to deploy a Flask web application to Lambda:
Deploy the entire application to Lambda using zappa-and zappa configurations (json file) will be the API Gateway authentication.
Deploy only the function, the parsing blackbox that transforms user input to a form the backend endpoint is expecting (and backwards as well) -> Grab a proxy url from the API Gateway that configures Lambda proxy -> Have a separate application program that uses the url
(and then there's 3, which does not use the API Gateway and invokes the Lambda function in the application itself-but I really want to get a hands on experience using the API Gateway)
Here are the questions I have for each of the above two approaches:
For 1, I don't understand how Lambda is calling the functions in the Flask application. According to my understanding, Lambda only calls functions that have the parameters event and context-or are the url calls (url formulated by the API Gateway) actually the events calling the separate functions in the Flask application, thus enabling Lambda to function as a 'serverless' environment-this doesn't make sense to me because event, in most of the examples I analyzed, is the user input data. That means some of the functions in the application have no event and some do, which means Lambda somehow magically figures out what to do with different function calls?
I also know that Lambda does have limited capacity, so is this the best way? It seems to be the standard way of deploying a web application on Lambda.
For 2, I understand the steps leading to incorporating the API Gateway urls in the Flask application. The Flask application therefore will use the url to access the Lambda function and have HTTP endpoints for user access. HOWEVER, that means, if I have the Flask application on my local computer, the application will only be hosted when I run the application on my computer-I would like it to have persistent public access (hopefully). I read about AWS Cloud9-would this be a good solution? Where should I deploy the application itself to optimize this architecture-without using services that take away the architecture's severless-ness (like an EC2 instance maybe OR on S3, where I would be putting my frontend html files, and host a website)? Also, going back to 1 (sorry I am trying to organize my ideas in a coherent way, and it's not working too well), will the application run consistently as long as I leave the API Gateway endpoint open?
I don't know what's the best practice for deploying a Flask application using AWS Lambda and the API Gateway but based on my findings, the above two are most frequently used. It would be really helpful if you could answer my questions so I could actually start playing with AWS Lambda! Thank you! (+I did read all the Amazon documentations, and these are the final-remaining questions I have before I start experimenting:))
Zappa has its own code to handle requests and make them compatible with the "Flask" format. Keep in mind that you aren't really using Flask as intended in either cases when using Lambda. Lambdas are invoked only when calls are made, flask usually keeps running looking for requests. But the continuously running part is handled by the API Gateway here. Zappa essentially creates a single ANY request on API gateway, this request is passed to your lambda handler which interprets it and uses it to invoke your flask function.
If you you are building API Gateway + Lambda you don't need to use Flask. It would be much easier to simply make a function that is invoked by the parameters passed to lambda handler by the API Gateway. The front end application you can host on S3 (if it is static or Angular).
I would say the best practice here would be to not use Flask and go with the API Gateway + Lambda option. This lets you put custom security and checks on your APIs as well as making the application a lot more stable as every request has its own lambda.
I am trying to setup a microservice architecture on AWS, each microservice is a REST API.
Some of the services are running on ECS using Fargate and some of the services are running as a set of lambdas.
I am trying to have each api route resolve to the correct service, whether it is a ECS or Lambda based service.
I can see how it would be possible using only ECS services (with Application Load Balancer and listeners) or using only Lambdas (with an API Gateway). But I just cant seem to figure out how to mix the two together.
I have been searching relentlessly all week and I cannot find any decent documentation or an example of how to implement something similar to this.
There appears to be a limit to the number of routes for ALB or API Gateway. If I have several lambda based services there will need to be a declared path for each Lambda function and they will use up the path limit very quickly.
Should there be an intermediary step between each service and the API Gateway? For instance, each Lambda service has its own API Gateway which 'groups' those functions together. Which would mean there will be a nested set of API Gateways that the parent API Gateway routes to. This doesn't feel correct though.
Any help in the right direction would be appreciated.
Thanks
Your AWS account's API Gateway REST and Websocket routes/resources limit can be increased with a request to AWS support.