Amazon Web Services Posted November 11, 2022 Share Posted November 11, 2022 Introduction The Center for Internet Security (CIS) Benchmarks are best practices for the secure configuration of a target system. They define various Benchmarks for Kubernetes control plane and the data plane. For Amazon EKS clusters, it is strongly recommended to follow the CIS Amazon EKS Benchmark. If the data plane of an Amazon EKS cluster uses Amazon Linux 2 as a node group Operating System, it is recommended to implement the CIS Amazon Linux 2 Benchmark. This blog provides detailed, step-by-step instructions on how customers can build an Amazon EKS Amazon Machine Image (AMI) compliant with the CIS Amazon Linux2 Benchmarks. As Kubernetes adoption grows, many organizations are choosing it as their platform to build and host their modern and secure applications. Security is one of the primary design criteria for many workloads, especially those dealing with sensitive data, such as financial data processing. These workloads have a stringent requirement to adhere to various security and compliance controls. Many Amazon EKS customers, especially enterprise customers from Banking and Finance, are looking for guidance from AWS on hardening Amazon EKS. This is primarily for meeting the security and compliance requirements, such as Amazon Linux 2 (AL2) CIS Benchmark Level 1 or Level 2. Amazon EKS AMI Hardening Process The Amazon Linux 2 (AL2) CIS Benchmarks define two profiles for hardening i.e. Level1 and Level 2. A Level 1 profile is intended to be practical and prudent, provide a clear security benefit, and not inhibit the utility of the technology beyond acceptable means. A Level 2 profile is intended for environments or use cases where security is paramount, acts as a defense in depth measure, and may negatively inhibit the utility or performance of the technology. There are two approaches for hardening the Amazon EKS AMI for CIS Benchmark Level 1 or Level 2 profiles. Use the standard Amazon EKS Optimized AMI as a base and add hardening on top of it. This process requires someone to apply all of configuration mentioned in the Amazon Linux 2 CIS Benchmark specification. Use the Amazon Linux 2 (AL2) CIS Benchmark Level 1 and Level 2AMI from the AWS Marketplace as a base, and add Amazon EKS specific components on top of it. This blog addresses this approach and provides step by step instructions on how build an Amazon EKS hardened AMI, leveraging the Amazon AL2 CIS Benchmark AMI. The following is a proposed solution for hardening an Amazon EKS AMI and deploying in an Amazon EKS Cluster. The proposed approach is outlined below. Subscribe to the CIS Amazon Linux 2 Benchmark – Level 2 AMI from the market place. Note: this will incur costs for the software subscription in addition to the EC2 instance type used. Build a custom Amazon EKS AMI using above Amazon Linux (AL2) AMI as the base AMI. Create an Amazon EKS Cluster along with an Amazon EKS managed node group which uses the above custom Amazon EKS AMI. Deploy a sample application on this node group. Solution walk through Pre-requisites You will need the following to complete the tutorial: AWS CLI version 2 eksctl kubectl git Note: We have tested the CLI steps in this post on Amazon Linux 2. Let’s start by setting a few environment variables. export AWS_REGION=us-east-1 export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text) export CLUSTER_NAME=eks-cluster Subscribe to CIS Amazon Linux 2 Benchmark – Level 2 AMI Note: the below section mentions Level 2 but the same procedure can be used for Level 1. Go to the CIS Amazon Linux 2 Benchmark – Level 2 AWS Marketplace page. Click on “Continue to Subscribe” on the top-right of the page. On the next page, Accept Terms and Conditions and follow the instructions. Ensure that the newly subscribed CIS Amazon Linux 2 Benchmark – Level 2 AMI appears in your EC2 console. Make a note of the following properties of the AMI and export them into an environment variables AMI ID AMI name Owner account ID export AMI_ID="ami-xxxxxxxxxxxxxxx" export AMI_NAME="CIS Amazon Linux 2 xxxxxxxxxxxx" export AMI_OWNER_ACCOUNT_ID="xxxxxxxxxxx" Building a custom Amazon EKS AMI Clone the repo for building a custom Amazon EKS AMI git clone https://github.com/awslabs/amazon-eks-ami.git cd amazon-eks-ami/ Install the Packer tool for your platform. Below instructions assume you are using an Amazon Linux based machine to build the AMI. sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo sudo yum -y install packer Get the default Amazon Virtual Private Cloud (VPC) ID and get one of the subnet IDs and replace them in eks-worker-al2.json. The packer tool will launch a temporary Amazon EC2 Instance in this subnet to create the custom Amazon EKS AMI. VPC_ID=$(aws ec2 describe-vpcs --filters=Name=isDefault,Values=true --query 'Vpcs[].VpcId' --output text) echo $VPC_ID SUBNET_ID=$(aws ec2 describe-subnets --filters "Name=vpc-id,Values=$VPC_ID" | jq '.Subnets[0].SubnetId') echo $SUBNET_ID Run the following commands to modify the configuration file eks-worker-al2.json. sed -i -e 's#"remote_folder": ""#"remote_folder": "/home/ec2-user"#g' eks-worker-al2.json sed -i -e 's#"launch_block_device_mappings_volume_size": "4"#"launch_block_device_mappings_volume_size": "20"#g' eks-worker-al2.json sed -i -e 's#/tmp#/home/ec2-user#g' eks-worker-al2.json sed -i -e 's#{{ user `remote_folder`}}#/home/ec2-user#g' eks-worker-al2.json sed -i -e 's#/tmp#/home/ec2-user#g' scripts/install-worker.sh Run the following Make command with command line options, which are passed to packer tool as configuration parameters. make 1.23 aws_region=$AWS_REGION source_ami_id=$AMI_ID source_ami_owners=$AMI_OWNER_ACCOUNT_ID source_ami_filter_name="$AMI_NAME" subnet_id=$SUBNET_ID The successful build looks something like below. Make a note of the custom Amazon EKS AMI. ==> amazon-ebs: Terminating the source AWS instance... ==> amazon-ebs: Cleaning up any extra volumes... ==> amazon-ebs: No volumes to clean up, skipping ==> amazon-ebs: Deleting temporary security group... ==> amazon-ebs: Deleting temporary keypair... ==> amazon-ebs: Running post-processor: manifest ==> amazon-ebs: Running post-processor: manifest Build 'amazon-ebs' finished after 8 minutes 31 seconds. ==> Wait completed after 8 minutes 31 seconds ==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created: us-east-1: ami-0f92014aa12e5ab96 Set an environment variable with the above custom Amazon EKS AMI. export EKS_AMI_ID="ami-xxxxxxxxxxx" Create Amazon EKS Cluster with EKS Managed Node group using custom EKS AMI Run the below command to create an Amazon EKS Cluster along with a managed node group using custom Amazon EKS AMI. cat > cluster.yaml <<EOF --- apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: $CLUSTER_NAME region: $AWS_REGION version: "1.23" managedNodeGroups: - name: custom-ng desiredCapacity: 2 ami: $EKS_AMI_ID overrideBootstrapCommand: | #!/bin/bash set -ex /etc/eks/bootstrap.sh $CLUSTER_NAME EOF eksctl create cluster -f cluster.yaml Once the cluster is created, ensure that kubectl is working. kubectl get nodes NAME STATUS ROLES AGE VERSION ip-192-168-1-4.ec2.internal Ready <none> 3m7s v1.23.9-eks-ba74326 ip-192-168-34-254.ec2.internal Ready <none> 3m7s v1.23.9-eks-ba74326 Deploy a sample application Let’s deploy a sample application to these new nodes. kubectl apply -f - <<EOF --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: selector: matchLabels: app: nginx replicas: 2 template: metadata: labels: app: nginx spec: nodeSelector: eks.amazonaws.com/nodegroup: custom-ng containers: - image: public.ecr.aws/nginx/nginx:latest imagePullPolicy: Always name: nginx resources: limits: cpu: 100m memory: 200Mi requests: cpu: 100m memory: 200Mi ports: - name: http containerPort: 80 --- EOF Ensure the Nginx pods are running fine on these new nodes. kubectl get pod -lapp=nginx NAME READY STATUS RESTARTS AGE nginx-68485cdd49-lwrmm 1/1 Running 0 9s nginx-68485cdd49-r7hg6 1/1 Running 0 9s Cleanup Use these commands to delete the resources created during this post: kubectl delete deployment nginx eksctl delete cluster -f cluster.yaml --wait Follow this link to cancel the Amazon Marketplace subscription for the CIS Amazon Linux 2 Benchmark Level 2 AMI. Conclusion In this blog, we showed you a detailed procedure on how to build an Amazon EKS AMI based on the AWS Market place AMI for CIS Benchmark Amazon Linux 2 profile and also on how to leverage the custom AMI with EKS Managed node groups. These instructions remain same for both CIS Benchmark Amazon Linux 2 Level 1 as well. Check out our Containers Roadmap! If you have ideas about how we can improve Amazon container services, please use our Containers Roadmap to provide feedback and review our existing roadmap items. View the full article Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.