Using aws waf with ek
TypeScriptAWS WAF (Web Application Firewall) is used to protect your web applications from common web exploits that could affect application availability, compromise security, or consume excessive resources. On the other hand, Amazon EKS (Elastic Kubernetes Service) is a managed Kubernetes service that makes it easy to run Kubernetes on AWS without needing to install and operate your own Kubernetes control plane.
Integrating AWS WAF with EKS typically involves protecting the ingress resources that expose your EKS services to the internet. It could also be used to add additional layers of security around your EKS-hosted applications by setting up rules to filter traffic based on various criteria, such as IP addresses, HTTP headers, HTTP body, or custom URIs.
Now, I'll walk you through a Pulumi program in TypeScript that will set up a simple EKS cluster and associate an AWS WAF web ACL (Access Control List) with an Application Load Balancer that fronts the EKS cluster.
First, let's setup the EKS Cluster. We'll be using the
@pulumi/eks
package which provides a high-level interface to easily create and configure EKS clusters.import * as aws from "@pulumi/aws"; import * as eks from "@pulumi/eks"; // Create an EKS cluster with the default configuration. const cluster = new eks.Cluster("my-cluster", { roleMappings: [{ groups: ["system:masters"], roleArn: "arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>", username: "admin", }], }); // Export the cluster kubeconfig. export const kubeconfig = cluster.kubeconfig;
In the above code, replace
<ACCOUNT_ID>
with your AWS account ID and<ROLE_NAME>
with the name of an IAM role with the necessary permissions assigned.Next, let's set up AWS WAF.
import * as aws from "@pulumi/aws"; // Create an IP set to specify allowable IP addresses. const ipSet = new aws.wafregional.IpSet("myIpSet", { ipSetDescriptors: [ { type: "IPV4", value: "192.0.7.0/24" }, ], }); // Create a size constraint set to filter requests based on the length of query parameters. const sizeConstraintSet = new aws.wafregional.SizeConstraintSet("mySizeConstraintSet", { sizeConstraints: [{ fieldToMatch: { type: "QUERY_STRING" }, comparisonOperator: "GT", size: 1024, // 1KB textTransformation: "NONE", }], }); // Create a web ACL. const webAcl = new aws.wafregional.WebAcl("myWebAcl", { metricName: "myWebAcl", defaultAction: { type: "ALLOW", // Default action to allow requests }, rules: [{ // Association rule action: { type: "BLOCK" }, priority: 1, ruleId: ipSet.id, }], });
In the code block for AWS WAF, the
IpSet
resource specifies a set of IP addresses that you want to allow or block. You should replace192.0.7.0/24
with the address range that makes sense for your use case. TheSizeConstraintSet
resource sets up a filter to block requests where the query string is longer than 1KB.Finally, you need to associate the WAF Web ACL with an Application Load Balancer (ALB) that is exposed to the public internet and fronts the Kubernetes services in your EKS cluster. Here's how you could do that:
import * as aws from "@pulumi/aws"; // Assuming an ALB is already created and setup with the EKS cluster, use the ARN of the ALB. const albArn = "<ALB_ARN>"; // Replace with your ALB ARN // Associate the WAF Web ACL with the ALB. const webAclAssociation = new aws.wafregional.WebAclAssociation("myWebAclAssociation", { resourceArn: albArn, webAclId: webAcl.id, },); // Export the ALB's DNS name and zone ID for access. export const albDnsName = albArn.apply(arn => aws.lb.getLoadBalancer({ arn })).then(lb => lb.dnsName); export const albZoneId = albArn.apply(arn => aws.lb.getLoadBalancer({ arn })).then(lb => lb.zoneId);
In this final piece of the program, replace
<ALB_ARN>
with the ARN of your Application Load Balancer. TheWebAclAssociation
resource is what glues the WAF Web ACL to the ALB to protect your EKS services.To actually use this program, you'll need to deploy these resources using Pulumi and AWS credentials configured for your environment. Make sure to review each resource and specification like the IP sets and size constraints to configure your firewall according to your own security requirements. Also, to actually create an ALB and hook it up with the EKS, you might need additional configuration which is beyond the scope of this example.