First of all, Happy new year to everyone as this is my first post for this year.
Now let’s talk about the post. If your enterprise/business is looking to use managed services from AWS like API gateway and AppSync because of their feature-rich options but also want a secure connection to the domain layer then this is the post for you. If all these layers are alien to you then you can take refresher from my digital transformation architecture post.
So the problem statement is that I have all my domain microservices running on a Kubernetes in a private cluster/customer-owned VPC with only private subnets (which is no brainer from a security standpoint) but AWS managed services spins up in their own VPC which is not known to your AWS account. Bummer ha !! Don’t worry AWS thought of a solution for this too and released AWS private link but still doesn’t cover AppSync if your EXP API layer needs to be in graphQL. So let’s walk through both the services and how we can implement a secure solution.
How do we start?
First and foremost we need to set up the AWS private link implementation in our AWS account. As mentioned in the AWS documentation we need to have the Network load balancer set up which will front the Kubernetes cluster as a VPC endpoint. This will be used as a configuration when you set up your API in API Gateway or AppSync.
But Amit my K8 uses the standard ELB as an ingress controller and will I lose anything if I change it to NLB?
A valid concern but based on my experience and reading on NLB even though its relatively new but actually as few advantages over ELB of
- More Scalability
- Zonal isolation
- Source/remote address preservation
- Long-lived TCP connections
- Reduced bandwidth usage
Now, let’s look at the changes we will have to make to our Kubernetes ingress controller manifest files. I have highlighted the changes below.
This shows the type of change to NLB. Important thing is that we make this of type internal which will force it to spin up in private subnet otherwise installation fails.
Another important change you have to make is to have the traffic policy as local, this is required to make sure that NLB can do the health check to the pods. In my experience, I have seen that the AWS console shows that the health check has failed to the K8 nodes but when you access the APIs over NLB it works. It will take some traffic to show the healthy nodes as it has to do with how NLB constructs these health check calls.
API Gateway Set up With VPC Link
Below shows the architecture for this integration where the traffic is terminated securely to the NLB and then to the private cluster.
Now that we have the NLB set up we can use that in API gateway to set up the VPC link. This set up will generate the VPC Link ID and you will use that in your method integration set up.
After this, you can deploy your API and access the resource which will securely connect to the private NLB over private IPs to access the domain layers.
AWS AppSync Set up
By default, the HTTP data source of the AppSync only accesses the public endpoints. Set up with AppSync is not well documented and requires the intermediate serverless layer to access the private resources. Below is an architecture for this layer.
The approach i took was to spin up a private lambda which invocates in the same private subnet as NLB and able to communicate over the private IP.
Appsync is now configured with the Lambda data source to access the microservice instead of the HTTP data source. This is protected by the IAM role which only works in your AWS account as you set up the STS assume role for app sync service to connect to your private lambda.
If this is still uncomfortable for you and you want specific security then I recommend using the AWS WAF in front of the AppSync which gives the powerful security rules like rate limiting, specific Web ACLs per HTTP method , query type, and text, etc.
Connect with Me
If you are interested for a conversation or a chat. Please reach me on my linkedin.