Definitive Guide To Elastic Kubernetes Service (EKS) Security
Definitive Guide To Elastic Kubernetes Service (EKS) Security
Conclusion 42
While the Cloud Native Computing Federation requires all Customers share the responsibility for the security and
certified Kubernetes offerings to use a standard set of core compliance of their use of services with AWS. AWS takes
API groups, their conformance program still leaves a great responsibility for securing their infrastructure and addressing
deal of leeway for the exact feature set and management of security issues in their software. The customer must ensure
the various Kubernetes managed services. Users of these the security of their own applications and also must correctly
platforms will need to understand what features and tools use the controls offered to protect their data and workloads
their cloud provider makes available, as well as which pieces within the AWS infrastructure.
of the management role falls on the user. That share of the
workload becomes even more critical with respect to securing Kubernetes brings some specific security requirements to
the Kubernetes cluster, the workloads deployed to it, and its the table. For a managed Kubernetes service like EKS, users
underlying infrastructure. have three main layers that require action: the workloads
We will cover general Kubernetes cluster security, including the standard controls and best practices for
minimizing the risk around cluster workloads. We will go over the specific requirements for securing an EKS
cluster and its associated infrastructure. EKS as a service requires a great deal of care and consideration,
not to mention actual effort, before it can be used securely for production workloads. We hope this guide
proves valuable for achieving a secure cloud-native journey.
For existing clusters, most of these protections can be applied at any time. However, creating replacement clusters and migrating
workloads would provide a fresh environment and an opportunity to apply workload protections, described in later sections, as
the deployments get migrated.
What to do: Follow recommended security best practices for your AWS account, particularly for AWS IAM
permissions, VPC network controls, and EC2 resources.
VPC Layout
Why: Creating a VPC with network security in mind will be key for protecting EKS nodes from external
threats.
What to do: Place your nodes on private subnets only. Public subnets should only be used for external-
facing load balancers or NAT gateways. For external access to services running on the EKS cluster, use load
balancers managed by Kubernetes Service resources or Ingress controllers, rather than allowing direct
access to node instances. If your workloads need Internet access or you are using EKS managed node
groups, with their requirement of having Internet access, use NAT gateways for VPC egress.
What to do: Your options for locking down this access depend on whether you are trying to secure existing
clusters or create new clusters. For reference, the cluster creator authenticates against the Kubernetes API
as user kubernetes-user in the group system:masters.
You may also want to go through your AWS support channels and ask them to change this immutable
cluster admin authentication behavior.
What to do: Decide which type suits your needs best. The fact that every node in a managed group gets
a public IP address will be problematic for some security teams, while other teams may be more able or
willing to fill the automation gap between managed and self-managed node groups.
What to do: Options for preventing access to the node’s SSH port:
• Do not enable ssh access for node instances. In rare cases, not being able to ssh to the node may
make troubleshooting more difficult, but system and EKS logs generally contain enough information for
diagnosing problems. Usually, terminating problematic nodes is preferable to diagnosing issues, unless
you see frequent node issues which may be symptomatic of chronic problems.
• Install the Calico CNI (Container Network Interface) and use Kubernetes Network Policies to block all
pod egress traffic to port 22.
• You can use the AWS Systems Manager Session Manager instead of running sshd to connect to nodes.
Note that this option only works for self-managed node groups as it requires installing an agent on
each node. You need to add the agent’s installation to the user data field, which cannot be modified in
managed node groups.
• See the next section on EC2 security groups for EKS nodes for additional options.
The issue gets more complicated. Starting with Kubernetes 1.14, EKS now adds a cluster security group that
applies to all nodes (and therefore pods) and control plane components. This cluster security group has one
rule for inbound traffic: allow all traffic on all ports to all members of the security group. This security group
ensures that all cluster-related traffic between nodes and the control plane components remains open.
However, because the pods also by extension share this security group with the nodes, their access to the
nodes and the control plane is also unrestricted on the VPC network.
Each node group also generally has its own security group. Users of self-managed node groups will need to
create the security group for the node group. Managed node groups each have an automatically-created
security group. Why not just add a rule to the node security groups limiting access to port 22 for ssh,
perhaps to the security group of a bastion host? Unfortunately, that won’t work, either. All security group
rules are of type “allow.” When an EC2 network interface has two or more security groups that apply, their
rules get merged additively. If multiple groups have rules that include the same port, the most permissive
rule for that port gets applied.
What to do: EKS users have a few options that can be used alone or in combination for mitigating the
default EKS security group issues.
• Users can customize the AWS VPC CNI networking configuration. The default behavior of the CNI, to
share the node’s primary ENI with pods, can be changed to reserving one ENI for only the node’s IP
address by setting the configuration variable AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG to true.
• Benefits
• The nodes can now have their own security groups which do not apply to pods.
• Also allows the pods to be placed on different subnets than the nodes, for greater control and to
manage limited IP space.
• Create a subnet in the VPC dedicated to bastion hosts and which has its own network ACL separate from
the cluster’s subnets. Add a rule to the network ACL for the cluster’s subnets to allow access to sensitive
ports like ssh on the node subnets only from the bastion subnet’s CIDR block and follow that rule with an
explicit DENY rule from 0.0.0.0/0.
• Benefits
• Relatively simple to set up
• Generally requires no regular maintenance or updates
• Drawbacks
• Applies to all interfaces on the node subnets, which may have unintended consequences if the
subnets are shared with other non-EKS EC2 instances and resources.
• Close down the cluster security group, which is left completely open for all traffic within the security
group by default. Note that you will still need to ensure that the cluster security group allows access to
critical ports on the control plane, especially the cluster API endpoint.
• Benefits
• Addresses the security group issue at the security group level
• Drawbacks
• Requires time and research to craft the rules to restrict ingress traffic without breaking cluster
networking
While some of the recommendations in this section require action before or at the time of cluster creation,
many can still be applied later. If necessary, prioritize the following protections, and then work on the
remaining tasks as time permits.
• Cloud Infrastructure Security - Creating and maintaining best practices for your AWS account and
the resources you use will always require ongoing vigilance. Always start here when tightening your cloud
security.
• Control SSH Access to Nodes - Isolating the nodes from the containers they host as much as possible is
a critical protection for your cluster. In addition, limit node SSH access from other sources.
What to do: At this time, even AWS does not recommend running sensitive workloads on Fargate.
For users who have variable loads, the Kubernetes cluster autoscaler can manage creating and terminating
nodes as needed based on the cluster’s current capacity requirements.
What to do: Currently the EFS CSI driver cannot actually create EFS file systems. It can only make existing file
systems available to an EKS cluster as persistent volumes. Make changing the permissions or ownership of
the top-level directory part of the standard procedure for creating EFS file systems for use by the driver.
As an alternative, you can add an init container which does have root privileges to chown the filesystem to
the runtime user. When a pod has an init container, the main containers will not run until the init container
has exited successfully. This method is less secure overall, although the risk of exploitation of the init
container running as root is slightly decreased due to the short lifespan of init containers. An example
method could be by adding a block like the following to your PodSpec:
initContainers:
- name: chown-efs
# Update image to current release without using latest tag
image: busybox:1.31.1
# Put your application container’s UID and EFS mount point here
command: [‘sh’, ‘-c’, ‘/bin/chown 1337 /my/efs/mount’]
securityContext:
# We’re running as root, so add some protection
readOnlyRootFilesystem: true
volumeMounts:
- name: efs-volume
mountPath: /my/efs/mount
Then make sure to add runAsUser: 1337 (or whatever UID you chose) to the pod-level securityContext.
Some of these popular components need to interact with AWS service APIs, which requires AWS IAM
credentials. The EKS documentation for installing and configuring some of these services does not always
address or recommend secure methods for keeping these often-critical deployments and their IAM
credentials safely isolated from user workloads.
Add-ons covered in the EKS documentation that require IAM credentials include the cluster autoscaler, the
Amazon EBS CSI driver, the AWS App Mesh controller, and the ALB ingress controller. Other third-party
Kubernetes controllers, including ingress controllers, container storage interface (CSI) drivers, and secrets
management interfaces, may also need the ability to manage AWS resources.
Some of these add-ons which serve important functions for management and maintenance of the cluster,
like the cluster autoscaler, and which tend to be standard options on other managed Kubernetes offerings,
would normally run on master nodes, which generally allow only pods for critical system services. For
managed Kubernetes services, the cloud provider would generally install the service on the control plane
and the user would only need to configure the runtime behavior. Because EKS will not install or manage
these services, not only does that work fall on users who need them, the user also has to take extra
measures to lock down these services because they are not in their normally isolated environment.
What to do: Locking down these critical, privileged components requires addressing several different areas
of concern. Below, we describe some of the general considerations for managing IAM credentials for cluster
workloads. At the end of this section, we give step-by-step instructions for locking down privileged add-ons
and isolating their IAM credentials.
Carefully evaluating the recommended IAM policies for opportunities to limit the scope to the resources
actually needed by the cluster, as well as protecting the IAM credentials tied to these policies, becomes
critical to reducing the risk of the exploitation of the access key or token and to limiting the potential for
damage if the credentials do get compromised.
Privileges for many AWS API actions can be scoped to a specific resource or set of resources by using the
IAM policy Condition element. In the section on Cluster Design, we recommended tagging all your cluster
resources with unique tags for each cluster, largely because tag values can help limit IAM permission grants.
Some AWS API actions do not support evaluating access by tags, but those actions tend to be read-only
calls like Describe* (list). Write actions, which can modify, create, or destroy resources, usually support
conditional scoping.
For example, compare the suggested policy for the cluster autoscaler on the left with the policy on the right,
which scopes write actions to resources with a specific cluster’s tag.
As mentioned above, controllers that play a role in managing the cluster itself normally would get deployed
to the master nodes or control plane of a cluster, out of reach of user workloads on the worker nodes. For
managed services like EKS, unless the provider offers the option to manage the add-on itself, the user can
only install these components on worker nodes.
We can still add a measure of security by mimicking to a degree the isolation of master nodes by creating a
separate node group dedicated to critical workloads. By using node taints, we can restrict which pods can
A common method to deliver AWS IAM credentials to single-tenant EC2 instances uses the EC2 metadata
endpoint and EC2 instance profiles, which are associated with an IAM role. One of the metadata endpoint’s
paths, /iam/security-credentials, returns temporary IAM credentials associated with the instance’s
role. Kubernetes nodes, however, are very much multi-tenant. Even if all the workloads on your nodes are
the applications you deployed, the mix of workloads provides more opportunities that an attacker can try to
exploit to get access. Even if you wanted the pods of one deployment to share the instance’s credentials and
IAM permissions, which still is not a good idea, you would have to prevent all the other pods on the node
from doing the same. You also do not want to create static IAM access keys for the pods and deliver them as
a Kubernetes secret as an alternative. Some options exist for managing pod IAM tokens and protecting the
credentials belonging to the instance.
1. For the cluster deployments that do need IAM credentials, a few options exist.
a. AWS offers a way to integrate IAM roles with cluster service accounts. This method requires
configuring an external OpenID provider to serve the authentication tokens.
b. Two similar open-source projects exist to intercept requests from pods to the metadata endpoint
and return temporary IAM credentials with scoped permissions: kiam and kube2iam. kiam seems
to be a little more secure, offering the ability to limit the AWS IAM permissions to server pods, which
should therefore be strongly isolated like the controllers mentioned above.
c. Use a service like Hashicorp Vault, which can dynamically manage AWS IAM access and now
supports Kubernetes pod secret injection.
2. (Skip this step if you are using kiam or kube2iam.) Use Network Policies to block pod egress to the
metadata endpoint after installing the Calico CNI. You can use a Kubernetes NetworkPolicy resource
type, but note these resources would need to be added to every namespace in the cluster.
However, Calico offers some additional resource types, including a GlobalNetworkPolicy which applies to
all the namespaces in the cluster.
apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
name: deny-instance-metadata
spec:
types:
- Egress
egress:
- action: Deny
destination:
nets:
- 169.254.169.254/32
source: {}
This section will use the Kubernetes cluster autoscaler service as an example for how to deploy privileged
add-ons with some additional protections. The EKS documentation for installing the cluster autoscaler,
which can dynamically manage adding and removing nodes based on the cluster workload, does not always
follow best practices for either cluster or EC2 security. The alternative shown below will yield more security,
partially by mimicking the protected nature of master nodes in a standard Kubernetes cluster.
Note that the cluster autoscaler service can only manage scaling for the cluster in which it is deployed. If you
want to use node autoscaling in multiple EKS clusters, you will need to do the following for each cluster.
1. The recommended IAM policy for the cluster autoscaler service grants permission to modify all the
autoscaling groups in the AWS account, not just the target cluster’s node groups. Use the following policy
instead to limit the write operations to one cluster’s node groups, replacing the CLUSTER_NAME in the
Condition with your cluster’s name. (The Describe* operations cannot be restricted by resource tags.)
{
"Version": "2012-10-17",
"Id”: "LimitedClusterAutoscalerPermissions",
"Statement": [
{
"Sid": "RestrictByTag",
"Action": [
"autoscaling:SetDesiredCapacity",
"autoscaling:TerminateInstanceInAutoScalingGroup"
],
"Resource": "*",
"Effect": "Allow",
"Condition": {
"StringLike": {
"autoscaling:ResourceTag/kubernetes.io/cluster/CLUSTER_NAME": "owned"
}
}
2. Create a separate node group for the privileged controllers. Using nodes that are not shared with
unprivileged user workloads will help restrict access to these additional AWS IAM permissions and will
help safeguard critical system workloads like the autoscaler service.
a. Use a node taint not used for other node groups. (Managed node groups do not support automatic
tainting of nodes, so either use a self-managed node group or automate a way to taint this group’s
nodes when they join the cluster.) This example uses a taint with key=privileged, value=true, of type
NoSchedule.
b. Add a label for the nodes in the form node-group-name=<name of privileged node group>
c. Attach the above IAM policy to the IAM role used by the node group’s EC2 instance profile, or,
preferably, set up one of the alternative IAM credential delivery methods described above.
3. Make sure the autoscaling groups for the node groups that need to be managed by the cluster autoscaler
have the following tags (eksctl will add these automatically when it creates node groups):
a. k8s.io/cluster-autoscaler/<cluster-name>: owned
b. k8s.io/cluster-autoscaler/enabled: true
5. Save the following script to a file and set the variables at the top to the appropriate values for your
cluster. You may need to make further edits if you use a different node taint or node group label than the
examples in step 2.
#!/bin/bash
set -e
# Deploy
kubectl apply -f \
https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-
autoscaler/cloudprovider/aws/examples/cluster-autoscaler-autodiscover.yaml
# Add the taint toleration and the node selector blocks to schedule
# the cluster autoscaler on the privileged node group
kubectl -n kube-system patch deployment.apps/cluster-autoscaler \
--patch="$(cat <<EOF
spec:
template:
6. Check to make sure the cluster-autoscaler pod in the kube-system namespace gets scheduled on a
privileged node and starts running successfully. Once it is running, check the pod’s logs to make sure
there are no errors and that it can successfully make the AWS API calls it requires.
7. Do not allow user workloads to add a toleration for the taint used by the privileged nodegroup. One
method to prevent unwanted pods from tolerating the taint and running on the privileged nodes would
be to use an admission controller like the Open Policy Agent’s Gatekeeper.
To complete protection of the IAM credentials on all your cluster’s nodes, use kiam, kube2iam, or IAM role
for EKS service accounts (the last option requires configuring a OpenID Connect provider for your AWS
account) to manage scoped credentials for the cluster autoscaler and other workloads that need to access
AWS APIs. This would allow you to detach the IAM policy above from the node group’s instance profile
and to use a Network Policy to block pod access to the EC2 metadata endpoint to protect the node’s IAM
credentials.
Even if you do not use any add-ons, but you do have workloads which need to access AWS APIs, be sure to
apply a credential management option from Manage IAM Credentials for Pods.
Creating restrictions to allow only necessary service-to-service and cluster egress connections decreases the
number of potential targets for malicious or misconfigured pods and limits their ability to exploit the cluster
resources.
The Calico CNI (Container Network Interface) offers the ability to control network traffic to and from the
cluster’s pods by implementing the standard Kubernetes Network Policy API. Calico also offers some custom
extensions to the standard policy type. Network policies can control both ingress and egress traffic. Different
pod attributes, like labels or namespaces, can be used in addition to standard IP CIDR blocks to define the
rules.
What to do: Install Calico and create network policies to limit pod traffic only to what is required. See our
posts on guidelines for writing ingress and egress network policies. Test the policies to make sure they block
unwanted traffic while allowing required traffic. Note that the NetworkPolicy resource type can exist in a
cluster even though the cluster’s network setup does not actually support network policies. Therefore it
would be possible to successfully create the policies, but they would have no effect.
Note that open-source Calico does not support Windows at this point, nor do most of the other CNI Network
Policy providers. If you need Windows nodes, you may want to place them on dedicated VPC subnets and
use VPC network ACLs to limit traffic to and from the nodes. Limiting pod-to-pod traffic is not possible
without a cluster-aware solution, though.
What to do: EKS provides a couple options for protecting a cluster’s API endpoint.
• Disable the public endpoint and only use a private endpoint in the cluster’s VPC. This method provides
the best protection but access to the endpoint from outside the VPC, if needed, would require going
through a bastion host.
• Restrict the IP addresses that can connect to the public endpoint by using a whitelist of CIDR blocks.
In addition to protecting the API service from Internet traffic, use network policies to block traffic from pods
in the cluster to the API endpoint, only allowing workloads which require access.
What to do: Enable the private endpoint for your cluster. EKS supports having both a public and private
endpoint enabled for a cluster, so even if you still require the public endpoint, you can still keep your cluster
traffic inside the VPC by using a private endpoint.
What to do: After installing the Calico CNI, create a GlobalNetworkPolicy to prevent all pods from
connection to the kubelet’s port 10250/TCP.
apiVersion: crd.projectcalico.org/v1
kind: GlobalNetworkPolicy
metadata:
name: deny-kubelet-port
spec:
types:
- Egress
egress:
- action: Deny
protocol: TCP
destination:
nets:
- 0.0.0.0/0
ports:
- 10250
source: {}
What to do: If only sources inside the cluster’s VPC need to access the service’s endpoint, add the following
annotation to the Kubernetes Service manifest to create an internal load balancer: service.beta.
kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
If the load balancer needs to be Internet-facing but should not be open to all IP addresses, you can add the
field loadBalancerSourceRanges to the Service specification.
Securing your cluster’s network traffic and access will be crucial for the entire cluster’s security.
All of the considerations in this section provide critical protection, and most of them require minimal effort.
We recommend prioritizing all of them.
What to do:
1. Use a minimal, secure base image. Google’s “Distroless” images are a good choice because they do
not install OS package managers or shells.
2. Only install tools needed for the container’s application. Debugging tools should be omitted from
production containers.
3. Instead of putting exploitable tools like curl in your image for long-running applications, if you only
need network tools at pod start-time, consider using separate init containers or delivering the data
using a more Kubernetes-native method, such as ConfigMaps.
4. Remove the package manager from the image as a Dockerfile build step.
5. Keep your images up-to-date. This practice includes watching for new versions of both the base
image and any third-party tools you install.
What to do: Use an image scanner. A number of open-source and proprietary options exist, but be sure
to choose a solution that scans for vulnerabilities in operating system packages and in third-party runtime
libraries for the programming languages your software uses. Amazon ECR (Elastic Container Registry) offers
a scanning service, but it can only detect vulnerabilities in OS packages. As an example of the importance of
software library scanning, the Apache Struts vulnerability exploited in the Equifax hack would not have been
detected by an OS package scan alone, because Struts is a set of Java libraries, and most Linux distributions
no longer manage software library dependencies that are not required by system services.
To address CVEs when they are found in your internally maintained images, your organization should have
a policy for updating and replacing images known to have serious, fixable vulnerabilities for images that
are already deployed. Image scanning should be part of your CI/CD pipeline process and images with high-
severity, fixable CVEs should generate an alert and fail a build.
If you also deploy third-party container images in your cluster, scan those as well. If those images have
serious fixable vulnerabilities that do not seem to get addressed by the maintainer, you should consider
building your own images for those tools.
Baking image scanning into your continuous integration pipeline for new container images and into cluster
monitoring to detect older images with issues will help drive improvements to building secure images. In
addition, ensuring the security of your build environment plays a crucial role in ensuring your images are
not compromised from the start.
In addition to the workload protections below, also make sure you use Kubernetes Network Policies with the Calico CNI, described
in the Networking section.
Namespaces
Why: Kubernetes namespaces provide scoping for cluster objects, allowing fine-grained cluster object
management. Kubernetes RBAC rules for most resource types apply at the namespace level. Controls
like network policies and many add-on tools and frameworks like service meshes also often apply at the
namespace scope.
What to do: Plan out how you want to assign namespaces before you start deploying workloads to your
clusters. Having one namespace per application provides the best opportunity for control, although it does
bring extra management overhead when assigning RBAC role privileges and default network policies. If you
do decide to group more than one application into a namespace, the main criteria should be whether those
applications have common RBAC requirements and whether it would be safe to grant those privileges to the
service accounts and users which need Kubernetes API access in that namespace.
What to do: Configuring Kubernetes RBAC effectively and securely requires some understanding of the
Kubernetes API. You can start with the official documentation, read about some best practices, and you may
also want to work through some tutorials.
Once your team has solid working knowledge of RBAC, create some internal policies and guidelines.
Make sure you also regularly audit your Role permissions and RoleBindings. Pay special attention to
minimizing the use of ClusterRoles and ClusterRoleBindings, as these apply globally across all
namespaces and to resources that do not support namespaces. (You can use the output of kubectl api-
resources in your cluster to see which resources are not namespace-scoped.)
Do not grant write access to ConfigMaps in ClusterRoles, which apply globally across all namespaces. Use
RoleBindings to limit these permissions to specific namespaces.
What to do: Use the PodSpec Security Context to define the exact runtime requirements for each workload.
Use Pod Security Policies and/or admission controllers like Open Policy Agent (OPA) Gatekeeper to enforce
those best practices by the Kubernetes API at object creation time.
Some guidelines:
1. Do not allow containers to run as root. Running as root creates by far the greatest risk, because root
in a container has root on the node.
2. Do not use the host network or process space. Again, these settings create the potential for
compromising the node and every container running on it.
3. Do not allow privilege escalation.
4. Use a read-only root filesystem in the container.
5. Use the default (masked) /proc filesystem mount.
Pod Security Policies are enabled automatically for all EKS clusters starting with platform version 1.13. EKS
gives them a completely-permissive default policy named eks.privileged.
What to do: Create policies which enforce the recommendations under Limit Container Runtime Privileges,
shown above. Policies are best tested in a non-production environment running the same applications as
your production cluster, after which you can deploy them in production.
Once you have migrated all your workloads to stricter policies, remove the capability to
deploy user workloads using the permissive default policy by deleting the ClusterRoleBinding
eks:podsecuritypolicy:authenticated.
One increasingly popular option to use for a validating admission controller is Open Policy Agent (OPA)
Gatekeeper. The Gatekeeper admission controller uses custom Kubernetes resources to configure the
requirements for Kubernetes resources. Users can create policies tailored to their needs and applications to
enforce a variety of best practices by preventing non-conforming objects from getting created in a cluster.
While some overlap of Pod Security Policy capabilities exists, OPA allows restrictions not just on pods, but on
any cluster resource using virtually any field.
What to do: You can write a custom admission controller to suit your specific needs, or install Gatekeeper or
similar tool in your cluster. Note that while some example resources for enforcing common requirements
in Gatekeeper exist, the policy configuration language and management come with a rather steep learning
curve. As OPA and Gatekeeper gain greater adoption, more community resources should become available.
What to do: EKS clusters can be configured to send control plane logs to Amazon CloudWatch. At a
minimum, you will want to collect the following logs:
• api - the Kubernetes API server log
• audit - the Kubernetes audit log
• authenticator - the EKS component used to authenticate AWS IAM entities to the Kubernetes API
Note that if you choose a solution like Prometheus running in your cluster, not only will you need to make
sure to deploy it securely to prevent data tampering if the cluster becomes compromised, but you will also
want to forward the most critical, if not all, metrics to an external collector to preserve their integrity and
availability.
What to do: Monitor your EKS nodes as you would any other EC2 instance. For managed node groups,
Amazon CloudWatch remains the only viable option, because you can not modify the user data to automate
to install a third-party collection agent at boot time nor can you use your own AMI (Amazon Machine Image)
with the agent baked in. Self-managed node groups allow much more flexibility.
If you do use CloudWatch, you will want to enable detailed monitoring for the best observability.
What to do: Plan how to get notifications and how to handle security patches for your cluster and its nodes.
As EKS provides little automation around any part of this process, you will probably want to create your own
automation based on your needs and resources.
EKS leaves a large share of operational overhead to the user. Auditors will expect all of the practices
described here to be in place. Prioritizing and maintaining all of the initial set up and ongoing tasks will be
foundational to tracking the health and security of your clusters.