Building an Amazon EKS Cluster Preconfigured to Run Financial Workloads
Safeguard sensitive financial information and reduce administrative overhead with AWS Fargate
About | |
---|---|
✅ AWS experience | 200 - Intermediate |
⏱ Time to complete | 30 minutes |
🧩 Prerequisites | - AWS Account |
📢 Feedback | Any feedback, issues, or just a 👍 / 👎 ? |
⏰ Last Updated | 2024-01-15 |
- An active Amazon Web Services (AWS) account.
- Install and configure the latest version of the AWS CLI (v2). To check your version, run:
aws --version
. - Install the latest version of kubectl. To check your version, run:
kubectl version
. - Install the latest version of eksctl. To check your version, run:
eksctl info
.
- Serverless Compute: AWS Fargate obviates the need for overseeing underlying infrastructure, sparing you from having to managed EC2 instances. Traditional Kubernetes deployments often involve manual provisioning, scaling, patching, and maintenance of these instances. With Fargate, AWS takes care of these tasks, reducing administrative overhead. When AWS Fargate creates a Fargate pod, it attaches an ENI in the isolated subnet to the pod.
- Authentication: Necessary IAM Roles for Service Accounts (IRSAs) mappings to enable communication between Kubernetes pods and AWS services. This includes the AWS Load Balancer Controller (LBC) used to expose applications, Kubernetes External DNS to automatically manage DNS records and facilitate external service discovery, and Cert Manager to streamline management of SSL/TLS certificates. Additionally, an OpenID Connect (OIDC) endpoint enables seamless and secure communication.
- Sample Application Deployment: Deploy a sample workload in an mTLS namespace. This workload encompasses the deployment of a sample application configured to use Fargate for the compute capacity.
- Networking Modes: Cluster endpoint access control lets you configure whether the endpoint is reachable from the public internet or through your VPC. You can enable the public endpoint (default), private endpoint, or both endpoints at the same time. You can change the endpoint settings at anytime using the EKS console or API. Disabling the public endpoint is mostly ideal for Financial workloads that intends to prevent unwanted connectivity from the internet.
- Control Plane Logging: Enable Amazon EKS control plane logging to provide audit and diagnostic logs directly from the Amazon EKS control plane to CloudWatch Logs.
- Secret Encryption: Further encrypt Kubernetes secrets with KMS keys that you create or import keys generated from another system to AWS KMS and use them with the cluster. The KMS keys that you create are customer managed keys (CMK). This further encryption is considered a security best practice for applications that store sensitive data.
cluster-config.yaml
file, you'll define the settings for IAM roles for service accounts, your own AWS KMS key to enable secret encryption in your cluster, enabled all the available control log type that corresponds to the available components of the Kubernetes control plane and configure log retention for 60 days. you'll also create several Linux node pools provided by Fargate Profiles for the respective workloads in specified namespaces.- Create a Customer Managed Key (CMK) in the region you in intend to create the cluster to further encrypt your Kubernetes secrets. We will input the CMK into the create cluster command:
1
2
3
4
export AWS_DEFAULT_REGION="us-east-2"
aws kms create-alias --alias-name alias/fgsecurityquickstart --target-key-id $(aws kms create-key --query KeyMetadata.Arn --output text)
export KMS_KEY_ARN=$(aws kms describe-key --key-id alias/fgsecurityquickstart --query KeyMetadata.Arn --output text)
echo $KMS_KEY_ARN
- Create a
cluster-config.yaml
file and paste the following contents into it. Replace theregion
with your preferred region. The region should be the same as the CMK created in earlier step.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: fg-security-quickstart
region: us-east-2
version: "1.30"
tags:
# Add more cloud tags if needed for billing
environment: fargate-security-quickstart
iam:
withOIDC: true
serviceAccounts:
- metadata:
name: aws-load-balancer-controller
namespace: kube-system
wellKnownPolicies:
awsLoadBalancerController: true
- metadata:
name: external-dns
namespace: kube-system
wellKnownPolicies:
externalDNS: true
- metadata:
name: cert-manager
namespace: cert-manager
wellKnownPolicies:
certManager: true
vpc:
cidr: 10.20.0.0/24
# optional: disable public access to endpoint and only allow private access
clusterEndpoints:
publicAccess: true
privateAccess: true
fargateProfiles:
- name: fp-default
selectors:
- namespace: default
- name: fp-nginx-ingress
selectors:
- namespace: ingress-nginx
- name: fp-mtls
selectors:
- namespace: mtls
- name: fp-kube-system
selectors:
- namespace: kube-system
- name: fp-cert-manager
selectors:
- namespace: cert-manager
cloudWatch:
clusterLogging:
# enable all types of cluster control plane logs
enableTypes: ["*"]
# Sets the number of days to retain the logs for (see [CloudWatch docs](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutRetentionPolicy.html#API_PutRetentionPolicy_RequestSyntax)).
# By default, log data is stored in CloudWatch Logs indefinitely.
logRetentionInDays: 60
secretsEncryption:
# replace this with the ARN of the KMS key
keyARN: "arn:aws:kms:us-east-2:000000000000:key/00000000-0000-0000-0000-000000000000"
- Create the EKS cluster using the
cluster-config.yaml
.
1
eksctl create cluster -f cluster-config.yaml
1
2024-07-25 11:19:16 [✔] EKS cluster "fg-security-quickstart" in "us-east-2" region is ready
1
kubectl get pods -A -o wide
1
2
3
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-system coredns-747476996f-bnmrs 1/1 Running 0 7m14s 10.20.0.168 fargate-ip-10-20-0-168.us-east-2.compute.internal <none> <none>
kube-system coredns-747476996f-zhvvp 1/1 Running 0 7m14s 10.20.0.133 fargate-ip-10-20-0-133.us-east-2.compute.internal <none> <none>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
cat << EOF > mtls.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: mtls-app
labels:
app: mtls
spec:
replicas: 1
selector:
matchLabels:
app: mtls
template:
metadata:
labels:
app: mtls
spec:
containers:
- name: mtls-app
image: hashicorp/http-echo
args:
- "-text=Sample Application in Amazon EKS on Fargate"
kind: Service
apiVersion: v1
metadata:
name: mtls-service
spec:
selector:
app: mtls
ports:
- port: 5678 # Default port for the container image
EOF
1
2
3
kubectl create namespace mtls
kubectl create -f mtls.yaml -n mtls
1
kubectl get pods -n mtls -o wide
1
2
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mtls-app-f586f477c-9h4lj 1/1 Running 0 54s 10.20.0.145 fargate-ip-10-20-0-145.us-east-2.compute.internal <none> <none>
1
2
3
kubectl run tmp --image=nginx:alpine -n mtls
kubectl get pod tmp -n mtls
1
kubectl exec -it tmp -n mtls -- curl http://mtls-service:5678
1
Sample Application in Amazon EKS on Fargate
1
2
3
4
5
# Delete the namespace and all resources
kubectl delete namespace mtls
# Delete the cluster
eksctl delete cluster -f ./cluster-config.yaml
kubectl
commands must be executed from within the VPC or a connected network. To build on this setup, the installation of the ExternalDNS, AWS Load Balancer Controller and Fargate logging are still required. For an example, explore the tutorial on setting up mTLS in Amazon EKS Fargate.Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.