Lab 02 — Secure Amazon EKS Worker Nodes
Mission Information
Section titled “Mission Information”| Item | Details |
|---|---|
| Lab ID | AWS-EKS-SEC-LAB-02 |
| Difficulty | Advanced |
| Estimated Time | 5–7 Hours |
| AWS Services | Amazon EKS, Amazon EC2, IAM, VPC, KMS, Systems Manager, CloudWatch, GuardDuty, AWS Config |
| Platform | AWS |
| Cost | AWS Charges May Apply |
| Primary Role | Cloud Security Engineer |
| Supporting Roles | Kubernetes Administrator, Platform Engineer, DevSecOps Engineer, SOC Analyst |
| Module | Amazon EKS Security |
| Previous Lab | Lab 01 — Secure Amazon EKS |
| Next Lab | Lab 03 — Secure Amazon EKS Networking |
Mission Scenario
Section titled “Mission Scenario”CloudNova Technologies has deployed its first secure Amazon EKS cluster.
The control plane has been configured with:
- IAM-based authentication
- Kubernetes RBAC
- Control-plane logging
- AWS KMS encryption
- CloudTrail monitoring
- GuardDuty protection
- Private networking
- Amazon ECR integration
During the production-readiness review, the Cloud Security team identified that the worker-node security baseline is incomplete.
The current worker nodes present several potential risks:
- Nodes may have unnecessary IAM permissions.
- EC2 instance metadata protections have not been validated.
- Root Amazon EBS volumes are not governed centrally.
- Node operating-system patching is not formally scheduled.
- Workloads with different trust levels can run on the same nodes.
- SSH access has not been formally restricted.
- Node security groups allow broader communication than required.
- Runtime monitoring is inconsistent.
- Node replacement and incident-isolation procedures are undocumented.
- Node groups do not have standard security labels, taints, or ownership tags.
- Sensitive workloads are not isolated onto dedicated node groups.
- Node configuration changes are not consistently recorded.
The CISO has directed the Kubernetes Security team to create and validate an enterprise Amazon EKS worker-node security baseline.
Your mission is to deploy, assess, harden, monitor, and govern Amazon EKS worker nodes before production workloads are approved.
Learning Objectives
Section titled “Learning Objectives”By completing this lab, you will learn how to:
- Explain the Amazon EKS worker-node security model
- Review managed node-group architecture
- Create a secure node IAM role
- Apply least-privilege permissions
- Configure a secure EC2 launch template
- Require modern instance metadata protections
- Encrypt node storage with AWS KMS
- Deploy worker nodes in private subnets
- Restrict node security-group access
- Disable unnecessary remote administration
- Review node bootstrap configuration
- Apply Kubernetes labels and taints
- Isolate sensitive workloads
- Configure resource reservations
- Review kubelet security
- Validate container-runtime configuration
- Implement node patching and replacement
- Enable AWS Systems Manager access
- Configure CloudWatch node monitoring
- Enable GuardDuty Runtime Monitoring
- Validate node-drain procedures
- Isolate a compromised node
- Review node autoscaling security
- Collect enterprise security evidence
- Produce a worker-node hardening report
Enterprise Worker-Node Architecture
Section titled “Enterprise Worker-Node Architecture” AWS Production Account
│
▼
Amazon VPC
┌────────────────────────────────────────────────────┐ │ │ │ Private Subnets │ │ │ │ ┌────────────────────────────────────────────┐ │ │ │ Amazon EKS Managed Node Group │ │ │ │ │ │ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ │ │ Worker Node │ │ Worker Node │ │ │ │ │ │ │ │ │ │ │ │ │ │ Hardened OS │ │ Hardened OS │ │ │ │ │ │ Encrypted EBS│ │ Encrypted EBS│ │ │ │ │ │ IMDSv2 │ │ IMDSv2 │ │ │ │ │ │ SSM Access │ │ SSM Access │ │ │ │ │ │ Runtime Agent│ │ Runtime Agent│ │ │ │ │ └──────────────┘ └──────────────┘ │ │ │ └────────────────────────────────────────────┘ │ │ │ └────────────────────────────────────────────────────┘
│ │ │ ▼ ▼ ▼
AWS KMS CloudWatch Logs GuardDuty
│ │ │ └─────────────────┼─────────────────┘ │ ▼
Security OperationsNode Security Responsibility Model
Section titled “Node Security Responsibility Model”AWS Responsibility
• Physical infrastructure• EKS managed control plane• Underlying AWS facilities• EC2 hardware and hypervisor
│
▼
Customer Responsibility
• Node IAM role• Operating-system lifecycle• Launch-template settings• Instance metadata protection• Security groups• EBS encryption• Node labels and taints• Workload placement• Runtime monitoring• Patch and replacement process• Access control• Incident responseWorker-Node Hardening Workflow
Section titled “Worker-Node Hardening Workflow”Discover Existing Nodes
│
▼
Review Node IAM Permissions
│
▼
Create Secure Launch Template
│
▼
Enable Storage and Metadata Protection
│
▼
Deploy Private Managed Node Group
│
▼
Apply Labels and Taints
│
▼
Validate Kubelet and Runtime Security
│
▼
Enable Monitoring and Runtime Detection
│
▼
Test Drain, Replacement and Isolation
│
▼
Collect Evidence and ReportLab Outcomes
Section titled “Lab Outcomes”By the end of this lab, you will have:
- Assessed existing Amazon EKS worker nodes
- Created a dedicated node IAM role
- Reviewed node-role permissions
- Created a secure EC2 launch template
- Required secure instance metadata access
- Enabled encrypted Amazon EBS storage
- Restricted remote-administration exposure
- Deployed a private managed node group
- Applied node ownership labels
- Applied workload-isolation taints
- Deployed a workload to a dedicated node group
- Reviewed kubelet configuration
- Validated container-runtime configuration
- Configured Systems Manager access
- Enabled node monitoring
- Reviewed GuardDuty Runtime Monitoring
- Tested node cordon and drain
- Documented compromised-node isolation
- Reviewed node-group update controls
- Created a worker-node risk register
- Produced an enterprise hardening report
Security Notice
Section titled “Security Notice”This lab creates AWS resources that may incur charges.
Use only:
- An authorised AWS account
- A non-production EKS cluster
- Approved AWS Regions
- Approved IAM identities
- Approved container images
Do not:
- Run destructive commands in production
- Terminate nodes without validating workload impact
- expose SSH to the internet
- Place AWS access keys on worker nodes
- Attach administrative policies to node roles
- Modify node bootstrap settings without testing
- Drain critical workloads without reviewing disruption controls
- store sensitive information in user data
- weaken instance metadata protection
- retain resources after the lab unless formally approved
Prerequisites
Section titled “Prerequisites”Before starting, ensure that you have:
- Completed Lab 01 — Secure Amazon EKS
- An existing Amazon EKS cluster
- AWS CLI
- kubectl
- eksctl
- jq
- Helm
- Git Bash or PowerShell
- IAM permissions to manage EKS node groups
- IAM permissions to manage roles and policies
- EC2 launch-template permissions
- AWS KMS permissions
- CloudWatch permissions
- Systems Manager permissions
- Access to an approved evidence repository
Tools Used
Section titled “Tools Used”| Tool | Purpose |
|---|---|
| AWS CLI | AWS resource configuration and assessment |
| kubectl | Kubernetes node and workload administration |
| eksctl | Managed node-group deployment |
| IAM | Node identity and permission management |
| EC2 Launch Templates | Secure node configuration |
| AWS KMS | Amazon EBS encryption |
| Systems Manager | Controlled node administration |
| CloudWatch | Node logging and monitoring |
| GuardDuty | Runtime threat detection |
| AWS Config | Configuration compliance |
| jq | JSON analysis |
| Helm | Security-agent deployment |
| VS Code | Configuration and reporting |
Recommended Lab File Structure
Section titled “Recommended Lab File Structure”lab-02-secure-eks-worker-nodes/├── configuration/│ ├── environment.sh│ ├── nodegroup-config.yaml│ ├── launch-template.json│ └── cloudwatch-config.json├── iam/│ ├── node-trust-policy.json│ ├── node-role-policies.md│ └── permission-review.md├── manifests/│ ├── secure-workload.yaml│ ├── sensitive-workload.yaml│ ├── pod-disruption-budget.yaml│ └── node-maintenance-job.yaml├── assessment/│ ├── node-inventory.md│ ├── kubelet-review.md│ ├── runtime-review.md│ ├── network-review.md│ ├── patching-review.md│ └── incident-isolation-plan.md├── evidence/│ ├── aws-identity.json│ ├── cluster-details.json│ ├── nodegroups.json│ ├── nodes.yaml│ ├── node-role.json│ ├── launch-template.json│ ├── security-groups.json│ ├── volumes.json│ ├── node-labels.txt│ ├── kubelet-config.txt│ └── monitoring-status.txt└── reports/ ├── findings-register.md ├── risk-register.md ├── remediation-plan.md └── worker-node-security-report.mdTask 01 — Create the Lab Workspace
Section titled “Task 01 — Create the Lab Workspace”Git Bash
Section titled “Git Bash”mkdir -p lab-02-secure-eks-worker-nodes/{configuration,iam,manifests,assessment,evidence,reports}
cd lab-02-secure-eks-worker-nodesPowerShell
Section titled “PowerShell”New-Item -ItemType Directory -Force ` -Path lab-02-secure-eks-worker-nodes\configuration
New-Item -ItemType Directory -Force ` -Path lab-02-secure-eks-worker-nodes\iam
New-Item -ItemType Directory -Force ` -Path lab-02-secure-eks-worker-nodes\manifests
New-Item -ItemType Directory -Force ` -Path lab-02-secure-eks-worker-nodes\assessment
New-Item -ItemType Directory -Force ` -Path lab-02-secure-eks-worker-nodes\evidence
New-Item -ItemType Directory -Force ` -Path lab-02-secure-eks-worker-nodes\reports
Set-Location lab-02-secure-eks-worker-nodesTask 02 — Define Environment Variables
Section titled “Task 02 — Define Environment Variables”Git Bash
Section titled “Git Bash”export AWS_REGION="ap-south-1"export CLUSTER_NAME="ghc-secure-eks"export NODEGROUP_NAME="ghc-secure-workers"export NODE_ROLE_NAME="ghc-eks-node-role"export LAUNCH_TEMPLATE_NAME="ghc-secure-eks-node-template"export KMS_ALIAS="alias/ghc-eks-node-storage"Save the variables.
cat > configuration/environment.sh <<EOFexport AWS_REGION="${AWS_REGION}"export CLUSTER_NAME="${CLUSTER_NAME}"export NODEGROUP_NAME="${NODEGROUP_NAME}"export NODE_ROLE_NAME="${NODE_ROLE_NAME}"export LAUNCH_TEMPLATE_NAME="${LAUNCH_TEMPLATE_NAME}"export KMS_ALIAS="${KMS_ALIAS}"EOFPowerShell
Section titled “PowerShell”$env:AWS_REGION = "ap-south-1"$env:CLUSTER_NAME = "ghc-secure-eks"$env:NODEGROUP_NAME = "ghc-secure-workers"$env:NODE_ROLE_NAME = "ghc-eks-node-role"$env:LAUNCH_TEMPLATE_NAME = "ghc-secure-eks-node-template"$env:KMS_ALIAS = "alias/ghc-eks-node-storage"Task 03 — Verify AWS Identity
Section titled “Task 03 — Verify AWS Identity”aws sts get-caller-identity \ > evidence/aws-identity.jsonReview:
cat evidence/aws-identity.jsonConfirm:
- AWS account is authorised
- Role or user is expected
- No root identity is being used
- Region is approved
- Permissions are sufficient
Task 04 — Validate Cluster Access
Section titled “Task 04 — Validate Cluster Access”Update kubeconfig.
aws eks update-kubeconfig \ --name "${CLUSTER_NAME}" \ --region "${AWS_REGION}"Verify the context.
kubectl config current-contextCheck cluster information.
kubectl cluster-infoSave evidence.
aws eks describe-cluster \ --name "${CLUSTER_NAME}" \ --region "${AWS_REGION}" \ > evidence/cluster-details.jsonTask 05 — Discover Existing Managed Node Groups
Section titled “Task 05 — Discover Existing Managed Node Groups”aws eks list-nodegroups \ --cluster-name "${CLUSTER_NAME}" \ --region "${AWS_REGION}" \ > evidence/nodegroups.jsonReview:
aws eks list-nodegroups \ --cluster-name "${CLUSTER_NAME}" \ --region "${AWS_REGION}" \ --output tableFor each node group, record:
| Field | Details |
|---|---|
| Node-group name | |
| Status | |
| Capacity type | |
| Instance types | |
| Minimum size | |
| Desired size | |
| Maximum size | |
| Node IAM role | |
| Subnets | |
| Launch template | |
| AMI type | |
| Kubernetes version | |
| Release version |
Task 06 — Build the Node Inventory
Section titled “Task 06 — Build the Node Inventory”Export node information.
kubectl get nodes \ -o widekubectl get nodes \ -o yaml \ > evidence/nodes.yamlCreate assessment/node-inventory.md.
| Node | Node Group | Instance Type | Availability Zone | OS | Runtime | Status |
|---|---|---|---|---|---|---|
Task 07 — Map Kubernetes Nodes to EC2 Instances
Section titled “Task 07 — Map Kubernetes Nodes to EC2 Instances”Retrieve instance-provider identifiers.
kubectl get nodes \ -o custom-columns='NODE:.metadata.name,PROVIDER-ID:.spec.providerID'Retrieve EKS node-group labels.
kubectl get nodes \ -L eks.amazonaws.com/nodegroup \ -L node.kubernetes.io/instance-type \ -L topology.kubernetes.io/zoneSave evidence.
kubectl get nodes \ -L eks.amazonaws.com/nodegroup \ -L node.kubernetes.io/instance-type \ -L topology.kubernetes.io/zone \ > evidence/node-labels.txtTask 08 — Review Existing Node IAM Roles
Section titled “Task 08 — Review Existing Node IAM Roles”Describe the node group.
aws eks describe-nodegroup \ --cluster-name "${CLUSTER_NAME}" \ --nodegroup-name "<existing-node-group>" \ --region "${AWS_REGION}"Identify the node IAM role.
Review attached policies.
aws iam list-attached-role-policies \ --role-name "<existing-node-role>"Review inline policies.
aws iam list-role-policies \ --role-name "<existing-node-role>"Task 09 — Assess Node IAM Permissions
Section titled “Task 09 — Assess Node IAM Permissions”Create iam/permission-review.md.
Check whether the node role has:
- Only required EKS worker-node permissions
- Required container-registry pull permissions
- Required networking permissions
- Systems Manager permissions only when approved
- No administrator policy
- No broad business-service permissions
- No unrestricted access to AWS Secrets Manager
- No unrestricted access to Amazon S3
- No direct application permissions
- No permissions intended for Kubernetes Pods
Application permissions should be provided through workload-specific AWS identity mechanisms rather than the EC2 node role.
Task 10 — Create the Node IAM Trust Policy
Section titled “Task 10 — Create the Node IAM Trust Policy”Create iam/node-trust-policy.json.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ]}Create the role.
aws iam create-role \ --role-name "${NODE_ROLE_NAME}" \ --assume-role-policy-document file://iam/node-trust-policy.jsonTask 11 — Attach Required Node Policies
Section titled “Task 11 — Attach Required Node Policies”Attach the organisation-approved policies required by the node group.
Example:
aws iam attach-role-policy \ --role-name "${NODE_ROLE_NAME}" \ --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicyaws iam attach-role-policy \ --role-name "${NODE_ROLE_NAME}" \ --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryPullOnlyAttach the networking policy only according to the organisation’s selected EKS networking and identity architecture.
Document every attached policy and its justification.
Task 12 — Add Systems Manager Access
Section titled “Task 12 — Add Systems Manager Access”Where approved, attach controlled Systems Manager permissions to the node role.
aws iam attach-role-policy \ --role-name "${NODE_ROLE_NAME}" \ --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCoreSystems Manager should be preferred over unrestricted inbound SSH access.
Confirm the organisation permits this managed policy or replace it with an approved custom policy.
Task 13 — Verify the Node Role
Section titled “Task 13 — Verify the Node Role”aws iam get-role \ --role-name "${NODE_ROLE_NAME}" \ > evidence/node-role.jsonaws iam list-attached-role-policies \ --role-name "${NODE_ROLE_NAME}"Validate:
- Trusted principal is EC2
- No users can directly assume the role
- No wildcard trust relationship exists
- Attached permissions are documented
- Application permissions are absent
Task 14 — Create a KMS Key for Node Storage
Section titled “Task 14 — Create a KMS Key for Node Storage”Create a customer-managed KMS key.
aws kms create-key \ --description "CloudNova Amazon EKS worker node storage encryption" \ --key-usage ENCRYPT_DECRYPT \ --origin AWS_KMS \ > evidence/node-kms-key.jsonRetrieve the key ID.
export NODE_KMS_KEY_ID=$(jq -r '.KeyMetadata.KeyId' evidence/node-kms-key.json)Create an alias.
aws kms create-alias \ --alias-name "${KMS_ALIAS}" \ --target-key-id "${NODE_KMS_KEY_ID}"Task 15 — Review KMS Governance
Section titled “Task 15 — Review KMS Governance”Validate:
- Key administrators are separate from key users
- Key rotation is enabled where required
- Key policy follows least privilege
- Node role receives only necessary cryptographic permissions
- CloudTrail records KMS activity
- Key deletion requires a controlled process
- Production and non-production keys are separated
Enable rotation where applicable.
aws kms enable-key-rotation \ --key-id "${NODE_KMS_KEY_ID}"Task 16 — Design the Secure Launch Template
Section titled “Task 16 — Design the Secure Launch Template”The launch template should govern:
- Instance metadata settings
- Encrypted root storage
- KMS key
- Security groups
- Monitoring
- Instance tags
- No public IP requirement through subnet design
- No SSH key unless formally approved
- Approved instance profile
- Approved user data
Create configuration/launch-template.json.
{ "LaunchTemplateName": "ghc-secure-eks-node-template", "VersionDescription": "Secure Amazon EKS worker-node baseline", "LaunchTemplateData": { "MetadataOptions": { "HttpEndpoint": "enabled", "HttpTokens": "required", "HttpPutResponseHopLimit": 1, "InstanceMetadataTags": "disabled" }, "Monitoring": { "Enabled": true }, "BlockDeviceMappings": [ { "DeviceName": "/dev/xvda", "Ebs": { "DeleteOnTermination": true, "Encrypted": true, "VolumeSize": 30, "VolumeType": "gp3" } } ], "TagSpecifications": [ { "ResourceType": "instance", "Tags": [ { "Key": "Environment", "Value": "training" }, { "Key": "Owner", "Value": "cloud-security" }, { "Key": "ManagedBy", "Value": "eks" }, { "Key": "DataClassification", "Value": "internal" } ] }, { "ResourceType": "volume", "Tags": [ { "Key": "Environment", "Value": "training" }, { "Key": "Owner", "Value": "cloud-security" } ] } ] }}Add the approved KMS key to the EBS configuration before deployment.
Task 17 — Require Secure Instance Metadata Access
Section titled “Task 17 — Require Secure Instance Metadata Access”Confirm the launch template requires:
"HttpTokens": "required"This prevents use of unauthenticated instance-metadata requests.
Review the hop limit.
"HttpPutResponseHopLimit": 1The selected value must align with the organisation’s container-networking and workload-identity architecture.
Document any approved deviation.
Task 18 — Prevent Unnecessary SSH Access
Section titled “Task 18 — Prevent Unnecessary SSH Access”Do not specify an EC2 key pair unless remote SSH access has been formally approved.
Confirm:
- No port 22 rule from
0.0.0.0/0 - No shared private key
- No personal key pairs
- Systems Manager is available for controlled administration
- Emergency access is logged
- Node access follows change control
Task 19 — Create the Launch Template
Section titled “Task 19 — Create the Launch Template”aws ec2 create-launch-template \ --cli-input-json file://configuration/launch-template.json \ > evidence/launch-template.jsonReview:
aws ec2 describe-launch-templates \ --launch-template-names "${LAUNCH_TEMPLATE_NAME}"Task 20 — Review Launch-Template Security
Section titled “Task 20 — Review Launch-Template Security”Validate:
| Control | Expected |
|---|---|
| Metadata tokens | Required |
| Metadata endpoint | Enabled only where needed |
| Hop limit | Approved |
| Root volume | Encrypted |
| KMS key | Approved |
| Delete on termination | Enabled |
| Volume type | Approved |
| Detailed monitoring | Enabled |
| Public IP | Not assigned through private subnet |
| SSH key | Not configured unless approved |
| Security group | Restricted |
| Tags | Complete |
| User data | No credentials |
Task 21 — Identify Private Subnets
Section titled “Task 21 — Identify Private Subnets”Retrieve EKS cluster subnets.
aws eks describe-cluster \ --name "${CLUSTER_NAME}" \ --region "${AWS_REGION}" \ --query 'cluster.resourcesVpcConfig.subnetIds' \ --output textReview each subnet.
aws ec2 describe-subnets \ --subnet-ids <subnet-id-1> <subnet-id-2>Confirm private node subnets:
- Do not automatically assign public IP addresses
- Have appropriate routes
- Use approved NAT or VPC endpoints
- Are distributed across Availability Zones
- Have required EKS subnet tags
- Do not expose nodes directly to the internet
Task 22 — Review VPC Endpoints
Section titled “Task 22 — Review VPC Endpoints”Assess whether private nodes can use VPC endpoints for approved AWS services, such as:
- Amazon ECR API
- Amazon ECR Docker registry
- Amazon S3 where required by image operations
- AWS Systems Manager
- Systems Manager Messages
- EC2 Messages where applicable
- CloudWatch Logs
- AWS STS
- AWS KMS
VPC endpoints can reduce reliance on broad internet egress.
Task 23 — Review the Cluster Security Group
Section titled “Task 23 — Review the Cluster Security Group”Retrieve cluster security-group details.
aws eks describe-cluster \ --name "${CLUSTER_NAME}" \ --region "${AWS_REGION}" \ --query 'cluster.resourcesVpcConfig.clusterSecurityGroupId' \ --output textExport security-group evidence.
aws ec2 describe-security-groups \ --group-ids <cluster-security-group-id> \ > evidence/security-groups.jsonTask 24 — Review Node Security-Group Rules
Section titled “Task 24 — Review Node Security-Group Rules”Validate:
- Node-to-control-plane communication is allowed only as required
- Node-to-node traffic follows the selected networking architecture
- No unnecessary inbound internet access exists
- Administrative ports are restricted
- Outbound access is reviewed
- Security-group references are used where appropriate
- Rules have documented owners and purposes
Task 25 — Create the Managed Node-Group Configuration
Section titled “Task 25 — Create the Managed Node-Group Configuration”Create configuration/nodegroup-config.yaml.
apiVersion: eksctl.io/v1alpha5kind: ClusterConfig
metadata: name: ghc-secure-eks region: ap-south-1
managedNodeGroups: - name: ghc-secure-workers minSize: 2 desiredCapacity: 2 maxSize: 4
privateNetworking: true
instanceTypes: - t3.medium
iam: instanceRoleARN: arn:aws:iam::<AWS-ACCOUNT-ID>:role/ghc-eks-node-role
launchTemplate: id: <LAUNCH-TEMPLATE-ID> version: "<LAUNCH-TEMPLATE-VERSION>"
labels: workload-tier: standard environment: training security-zone: restricted owner: cloud-security
taints: - key: workload-tier value: standard effect: NoSchedule
tags: Environment: training Owner: cloud-security ManagedBy: eksctl SecurityBaseline: hardenedReplace all placeholders before deployment.
Task 26 — Validate the Configuration File
Section titled “Task 26 — Validate the Configuration File”Review the configuration for:
- Correct cluster name
- Correct Region
- Correct node IAM role
- Correct launch-template ID
- Correct launch-template version
- Private networking
- Approved instance types
- Minimum two nodes where resilience is required
- Labels
- Taints
- Ownership tags
Task 27 — Create the Secure Managed Node Group
Section titled “Task 27 — Create the Secure Managed Node Group”eksctl create nodegroup \ -f configuration/nodegroup-config.yamlMonitor the node group.
aws eks describe-nodegroup \ --cluster-name "${CLUSTER_NAME}" \ --nodegroup-name "${NODEGROUP_NAME}" \ --region "${AWS_REGION}" \ --query 'nodegroup.status'Task 28 — Validate Node Registration
Section titled “Task 28 — Validate Node Registration”kubectl get nodes \ -o wideReview EKS node-group labels.
kubectl get nodes \ -L eks.amazonaws.com/nodegroup \ -L workload-tier \ -L security-zone \ -L ownerConfirm:
- Nodes are Ready
- Nodes belong to the expected node group
- Labels are present
- Taints are present
- Nodes use approved instance types
- Nodes are distributed across Availability Zones
Task 29 — Validate Node Taints
Section titled “Task 29 — Validate Node Taints”kubectl describe nodes \ | grep -A3 "Taints"Or inspect a specific node.
kubectl describe node <node-name>Confirm the intended taint exists.
workload-tier=standard:NoScheduleTask 30 — Deploy a Workload Without a Toleration
Section titled “Task 30 — Deploy a Workload Without a Toleration”Create manifests/secure-workload.yaml.
apiVersion: apps/v1kind: Deploymentmetadata: name: secure-web namespace: default labels: app: secure-webspec: replicas: 2 selector: matchLabels: app: secure-web template: metadata: labels: app: secure-web spec: automountServiceAccountToken: false securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault containers: - name: web image: nginxinc/nginx-unprivileged:stable ports: - containerPort: 8080 securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL resources: requests: cpu: 100m memory: 128Mi limits: cpu: 250m memory: 256Mi volumeMounts: - name: cache mountPath: /tmp - name: nginx-cache mountPath: /var/cache/nginx volumes: - name: cache emptyDir: {} - name: nginx-cache emptyDir: {}Apply the workload.
kubectl apply \ -f manifests/secure-workload.yamlReview scheduling.
kubectl get pods \ -o wideThe Pods should not schedule onto the tainted node group without a matching toleration.
Task 31 — Add a Toleration and Node Selector
Section titled “Task 31 — Add a Toleration and Node Selector”Update the Pod specification.
spec: template: spec: nodeSelector: workload-tier: standard
tolerations: - key: workload-tier operator: Equal value: standard effect: NoScheduleReapply.
kubectl apply \ -f manifests/secure-workload.yamlValidate placement.
kubectl get pods \ -o wideTask 32 — Create a Dedicated Sensitive-Workload Node Group
Section titled “Task 32 — Create a Dedicated Sensitive-Workload Node Group”Create a separate node-group design for sensitive workloads.
Recommended controls:
- Dedicated node IAM role
- Dedicated node-group labels
- Dedicated taints
- Restricted security group
- Approved instance family
- Encrypted storage
- Stronger monitoring
- Limited workload eligibility
- Separate scaling policy
Example labels:
labels: workload-tier: sensitive data-classification: confidential security-zone: highExample taint:
taints: - key: dedicated value: sensitive effect: NoScheduleTask 33 — Deploy a Sensitive Workload
Section titled “Task 33 — Deploy a Sensitive Workload”Create manifests/sensitive-workload.yaml.
apiVersion: apps/v1kind: Deploymentmetadata: name: sensitive-api namespace: defaultspec: replicas: 2 selector: matchLabels: app: sensitive-api template: metadata: labels: app: sensitive-api spec: automountServiceAccountToken: false
nodeSelector: workload-tier: sensitive
tolerations: - key: dedicated operator: Equal value: sensitive effect: NoSchedule
securityContext: runAsNonRoot: true seccompProfile: type: RuntimeDefault
containers: - name: api image: nginxinc/nginx-unprivileged:stable securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: drop: - ALL resources: requests: cpu: 100m memory: 128Mi limits: cpu: 250m memory: 256Mi volumeMounts: - name: temporary-data mountPath: /tmp
volumes: - name: temporary-data emptyDir: {}Deploy only after the sensitive node group exists.
Task 34 — Review Node Operating-System Details
Section titled “Task 34 — Review Node Operating-System Details”kubectl get nodes \ -o custom-columns='NODE:.metadata.name,OS-IMAGE:.status.nodeInfo.osImage,KERNEL:.status.nodeInfo.kernelVersion,RUNTIME:.status.nodeInfo.containerRuntimeVersion,KUBELET:.status.nodeInfo.kubeletVersion'Assess:
- Approved EKS-optimised image
- Supported operating system
- Supported kernel
- Supported container runtime
- Consistent kubelet version
- No unexpected custom images
Task 35 — Review the Node AMI
Section titled “Task 35 — Review the Node AMI”Describe the node group.
aws eks describe-nodegroup \ --cluster-name "${CLUSTER_NAME}" \ --nodegroup-name "${NODEGROUP_NAME}" \ --region "${AWS_REGION}" \ --query 'nodegroup.{amiType:amiType,releaseVersion:releaseVersion,version:version}'Confirm:
- AMI type is approved
- Release version is current according to organisational policy
- Custom AMIs follow a secure build process
- Image provenance is documented
- Vulnerability scanning is completed
- Old node images are replaced
Task 36 — Review Kubelet Configuration
Section titled “Task 36 — Review Kubelet Configuration”Use an approved administrative method such as Systems Manager to inspect a non-production node.
Review:
- Anonymous authentication
- Authorisation mode
- Read-only port
- TLS configuration
- Certificate rotation
- Configuration-file permissions
- Event limits
- Resource reservations
- Logging
- Node registration settings
Create assessment/kubelet-review.md.
Node:
Kubelet Version:
Anonymous Authentication:
Authorisation Mode:
Read-Only Port:
Client Certificate Rotation:
Server Certificate Configuration:
Configuration Ownership:
Configuration Permissions:
Reserved Resources:
Eviction Thresholds:
Findings:
Risk:Task 37 — Review Container Runtime Security
Section titled “Task 37 — Review Container Runtime Security”Create assessment/runtime-review.md.
Assess:
- Container runtime version
- Runtime configuration ownership
- Runtime socket access
- Runtime logging
- Image garbage collection
- Registry configuration
- Untrusted registry access
- Runtime monitoring
- Supported version
- Patch status
Do not expose the runtime socket to ordinary workloads.
Task 38 — Review Host-Level Access
Section titled “Task 38 — Review Host-Level Access”Check whether workloads can access:
- Host filesystem
- Container runtime socket
- Host networking
- Host process namespace
- Host IPC namespace
- Device interfaces
- Kernel modules
- Privileged mode
Use policy controls to prevent unauthorised host access.
Task 39 — Review DaemonSets
Section titled “Task 39 — Review DaemonSets”kubectl get daemonsets \ -A \ -o wideAssess each DaemonSet for:
- Owner
- Purpose
- Privileges
- HostPath mounts
- Host namespaces
- Service Account
- Image source
- Resource limits
- Update strategy
- Security context
Security agents may need elevated access, but every privilege must be justified.
Task 40 — Validate Amazon EBS Encryption
Section titled “Task 40 — Validate Amazon EBS Encryption”Map worker nodes to EC2 instances and volumes.
aws ec2 describe-instances \ --filters "Name=tag:eks:cluster-name,Values=${CLUSTER_NAME}" \ > evidence/worker-instances.jsonReview attached volumes.
aws ec2 describe-volumes \ --filters "Name=tag:eks:cluster-name,Values=${CLUSTER_NAME}" \ > evidence/volumes.jsonConfirm:
Encryptedis true- Approved KMS key is used
- Volume tags are present
- Volumes delete with terminated nodes where appropriate
- No unmanaged data volumes exist
Task 41 — Validate Instance Metadata Configuration
Section titled “Task 41 — Validate Instance Metadata Configuration”Retrieve metadata options.
aws ec2 describe-instances \ --filters "Name=tag:eks:cluster-name,Values=${CLUSTER_NAME}" \ --query 'Reservations[].Instances[].{InstanceId:InstanceId,HttpTokens:MetadataOptions.HttpTokens,HttpEndpoint:MetadataOptions.HttpEndpoint,HopLimit:MetadataOptions.HttpPutResponseHopLimit}' \ --output tableExpected:
HttpTokensisrequired- Endpoint state matches policy
- Hop limit matches approved design
- No node uses legacy metadata settings
Task 42 — Verify Nodes Are Not Publicly Addressable
Section titled “Task 42 — Verify Nodes Are Not Publicly Addressable”aws ec2 describe-instances \ --filters "Name=tag:eks:cluster-name,Values=${CLUSTER_NAME}" \ --query 'Reservations[].Instances[].{InstanceId:InstanceId,PrivateIP:PrivateIpAddress,PublicIP:PublicIpAddress,Subnet:SubnetId}' \ --output tableConfirm worker nodes do not have public IP addresses.
Task 43 — Validate Systems Manager Registration
Section titled “Task 43 — Validate Systems Manager Registration”aws ssm describe-instance-information \ --query 'InstanceInformationList[].{InstanceId:InstanceId,PingStatus:PingStatus,Platform:PlatformName,AgentVersion:AgentVersion}' \ --output tableConfirm:
- Nodes appear as managed instances
- Agent status is online
- No inbound SSH is required
- Session activity is logged
- Access is limited to approved administrators
Task 44 — Review Systems Manager Session Governance
Section titled “Task 44 — Review Systems Manager Session Governance”Validate:
- Named users or roles
- MFA
- Session logging
- Approved log destination
- Encryption
- Limited session duration
- Change ticket requirement
- Emergency-access procedure
- Post-session review
Task 45 — Review Node Patch Management
Section titled “Task 45 — Review Node Patch Management”Create assessment/patching-review.md.
Document:
Node Group:
Operating System:
AMI Type:
Current Release:
Approved Release:
Patch Owner:
Patch Frequency:
Emergency Patch SLA:
Testing Environment:
Maintenance Window:
Drain Procedure:
Replacement Procedure:
Rollback Plan:
Evidence Location:Amazon EKS managed node groups should be updated through a controlled replacement process rather than relying on uncontrolled manual changes.
Task 46 — Review the Node-Group Update Configuration
Section titled “Task 46 — Review the Node-Group Update Configuration”aws eks describe-nodegroup \ --cluster-name "${CLUSTER_NAME}" \ --nodegroup-name "${NODEGROUP_NAME}" \ --region "${AWS_REGION}" \ --query 'nodegroup.updateConfig'Assess:
- Maximum unavailable nodes
- Maximum unavailable percentage
- Workload resilience
- PodDisruptionBudgets
- Maintenance window
- Rollback readiness
Task 47 — Create a Pod Disruption Budget
Section titled “Task 47 — Create a Pod Disruption Budget”Create manifests/pod-disruption-budget.yaml.
apiVersion: policy/v1kind: PodDisruptionBudgetmetadata: name: secure-web-pdb namespace: defaultspec: minAvailable: 1 selector: matchLabels: app: secure-webApply:
kubectl apply \ -f manifests/pod-disruption-budget.yamlValidate:
kubectl get poddisruptionbudgets \ -ATask 48 — Test Node Cordon
Section titled “Task 48 — Test Node Cordon”Select a non-critical training node.
kubectl cordon <node-name>Validate:
kubectl get nodesThe node should show:
SchedulingDisabledTask 49 — Test Node Drain
Section titled “Task 49 — Test Node Drain”Review workload impact first.
kubectl get pods \ -A \ -o wide \ --field-selector spec.nodeName=<node-name>Drain the approved training node.
kubectl drain <node-name> \ --ignore-daemonsets \ --delete-emptydir-dataValidate workload rescheduling.
kubectl get pods \ -A \ -o wideTask 50 — Return the Node to Service
Section titled “Task 50 — Return the Node to Service”kubectl uncordon <node-name>Validate:
kubectl get nodesDocument:
- Drain duration
- Workloads disrupted
- Pods rescheduled
- PodDisruptionBudget behaviour
- Errors
- Recovery result
Task 51 — Simulate a Compromised-Node Response
Section titled “Task 51 — Simulate a Compromised-Node Response”Do not intentionally compromise the node.
Create assessment/incident-isolation-plan.md.
Document the authorised response process:
1. Confirm the alert.2. Identify the affected node.3. Preserve logs and metadata.4. Cordon the node.5. Assess workload impact.6. Drain safe workloads.7. Isolate network access.8. Capture approved forensic evidence.9. Revoke exposed credentials.10. Terminate and replace the node.11. Scan affected images and workloads.12. Review node IAM-role activity.13. Review CloudTrail and GuardDuty.14. Validate replacement node.15. Complete incident review.Task 52 — Review Credential Exposure Risk
Section titled “Task 52 — Review Credential Exposure Risk”Assess whether a compromised node could access:
- Node IAM credentials
- Kubernetes node credentials
- Pod credentials
- Secrets mounted to workloads
- Container-registry tokens
- Systems Manager channels
- Attached volumes
- Runtime socket
- Kubelet API
Document controls that reduce credential exposure.
Task 53 — Review Workload Identity Separation
Section titled “Task 53 — Review Workload Identity Separation”Verify application Pods do not rely on the EC2 node role for business-service permissions.
Assess:
- Workload-specific AWS identity
- Kubernetes Service Account ownership
- Least-privilege role
- Namespace restrictions
- Token audience
- Trust conditions
- Credential rotation
- CloudTrail attribution
Task 54 — Enable CloudWatch Node Monitoring
Section titled “Task 54 — Enable CloudWatch Node Monitoring”Review available node and container telemetry.
Monitor:
- CPU
- Memory
- Disk
- Network
- Node readiness
- Pod failures
- Filesystem pressure
- Memory pressure
- PID pressure
- Kubelet errors
- Container runtime errors
Store the approved CloudWatch agent or observability configuration in:
configuration/cloudwatch-config.jsonTask 55 — Validate Node Conditions
Section titled “Task 55 — Validate Node Conditions”kubectl describe nodesReview:
- Ready
- MemoryPressure
- DiskPressure
- PIDPressure
- NetworkUnavailable
Create an evidence file.
kubectl get nodes \ -o json \ | jq '.items[] | { node: .metadata.name, conditions: .status.conditions }' \ > evidence/node-conditions.jsonTask 56 — Create Node Security Alerts
Section titled “Task 56 — Create Node Security Alerts”Recommended alerts:
- Node becomes NotReady
- Node reports disk pressure
- Node reports memory pressure
- Unexpected node joins cluster
- Unexpected node-group scaling
- EC2 instance metadata setting changes
- Security-group rule changes
- Node IAM-role policy changes
- Root-volume encryption disabled
- Systems Manager session initiated
- GuardDuty runtime finding
- Repeated kubelet authentication failures
Task 57 — Review GuardDuty Runtime Monitoring
Section titled “Task 57 — Review GuardDuty Runtime Monitoring”Verify GuardDuty coverage for the EKS environment.
Review:
- Runtime monitoring status
- Required agent deployment
- Node coverage
- Findings destination
- Notification workflow
- SIEM integration
- Suppression rules
- Finding ownership
Do not suppress findings without a documented investigation and approval process.
Task 58 — Review GuardDuty Findings
Section titled “Task 58 — Review GuardDuty Findings”aws guardduty list-detectorsUsing the approved detector ID:
aws guardduty list-findings \ --detector-id <detector-id>Review findings associated with:
- EKS
- EC2 worker nodes
- Runtime activity
- Credential use
- Network communication
- Malware or suspicious processes
Task 59 — Review CloudTrail Activity
Section titled “Task 59 — Review CloudTrail Activity”Search for events involving:
CreateNodegroupUpdateNodegroupVersionUpdateNodegroupConfigDeleteNodegroupCreateLaunchTemplateCreateLaunchTemplateVersionModifyInstanceMetadataOptionsAuthorizeSecurityGroupIngressAttachRolePolicyPutRolePolicyStartSessionTerminateInstances
Confirm:
- Events are captured
- Identity is attributable
- Logs are retained
- Alerts exist for sensitive changes
- Changes map to approved tickets
Task 60 — Review AWS Config Coverage
Section titled “Task 60 — Review AWS Config Coverage”Assess whether AWS Config records:
- EC2 instances
- Security groups
- IAM roles
- Launch templates
- EBS volumes
- KMS keys
- EKS clusters
- EKS node groups
Recommended compliance checks should identify:
- Unencrypted volumes
- Public security-group access
- Insecure metadata settings
- Unapproved instance types
- Missing tags
- IAM-policy changes
- Unsupported node configurations
Task 61 — Review Node Autoscaling Security
Section titled “Task 61 — Review Node Autoscaling Security”Assess whether node autoscaling is configured securely.
Review:
- Autoscaler IAM permissions
- Service Account identity
- Node-group scope
- Minimum and maximum capacity
- Tag-based discovery
- Scaling-event logging
- Instance-type restrictions
- Availability Zone distribution
- Denial-of-service risk
- Cost alarms
Task 62 — Review Node-Group Capacity Types
Section titled “Task 62 — Review Node-Group Capacity Types”Document whether the node group uses:
- On-Demand capacity
- Spot capacity
- Mixed capacity
Assess:
- Workload criticality
- Interruption tolerance
- PodDisruptionBudgets
- Minimum availability
- Sensitive-workload placement
- Capacity-diversity requirements
- Business-continuity impact
Critical workloads should not depend solely on interruptible capacity without approved resilience controls.
Task 63 — Review Node Resource Reservations
Section titled “Task 63 — Review Node Resource Reservations”Assess kubelet reservations for:
- Kubernetes system processes
- Operating-system processes
- Eviction thresholds
- Pod density
- CPU
- Memory
- Ephemeral storage
- PID availability
Improper reservations can create node instability and denial-of-service risk.
Task 64 — Review Maximum Pod Density
Section titled “Task 64 — Review Maximum Pod Density”Review:
- Instance type
- Networking plugin configuration
- Maximum Pods per node
- IP-address capacity
- Workload density
- Blast radius
- Resource overcommitment
High workload density can increase the impact of a node failure or compromise.
Task 65 — Review Node Labels for Trust Decisions
Section titled “Task 65 — Review Node Labels for Trust Decisions”Identify labels used for scheduling.
kubectl get nodes \ --show-labelsAssess whether:
- Security-sensitive labels are centrally managed
- Developers cannot modify protected node labels
- Admission policies validate workload selectors
- Labels identify environment and ownership
- Labels do not expose unnecessary sensitive information
- Scheduling decisions do not rely on untrusted labels
Task 66 — Review Node Taint Governance
Section titled “Task 66 — Review Node Taint Governance”Document:
| Taint | Purpose | Workload Class | Owner | Exception Process |
|---|---|---|---|---|
Validate that tolerations are granted only to authorised workloads.
Task 67 — Review Node-Group Tagging
Section titled “Task 67 — Review Node-Group Tagging”Required tags may include:
- Environment
- Owner
- CostCentre
- BusinessUnit
- DataClassification
- ManagedBy
- Cluster
- NodeGroup
- SecurityBaseline
- BackupClassification
- IncidentPriority
Check tags.
aws ec2 describe-instances \ --filters "Name=tag:eks:cluster-name,Values=${CLUSTER_NAME}" \ --query 'Reservations[].Instances[].{InstanceId:InstanceId,Tags:Tags}' \ --output jsonTask 68 — Review Node Image Governance
Section titled “Task 68 — Review Node Image Governance”For custom node images, confirm:
- Source image is approved
- Build pipeline is controlled
- Build logs are retained
- Vulnerability scanning is completed
- Malware scanning is completed
- Image is signed where supported
- Software inventory is retained
- Unnecessary packages are removed
- Credentials are absent
- Image expiration is defined
- Rebuild schedule exists
Task 69 — Review Node Bootstrap Governance
Section titled “Task 69 — Review Node Bootstrap Governance”Assess node bootstrap configuration for:
- Cluster endpoint
- Cluster certificate authority
- Kubelet arguments
- Node labels
- Node taints
- DNS configuration
- Reserved resources
- Maximum Pods
- Log configuration
- No embedded credentials
User data must not contain long-lived secrets or private keys.
Task 70 — Perform the Worker-Node Security Assessment
Section titled “Task 70 — Perform the Worker-Node Security Assessment”Complete the assessment matrix.
| Security Domain | Expected Control | Status |
|---|---|---|
| Node IAM role | Least privilege | |
| Application identity | Separate from node role | |
| Trust policy | EC2 only | |
| Metadata service | Token required | |
| Root storage | Encrypted | |
| KMS key | Approved and governed | |
| Subnets | Private | |
| Public IP | Disabled | |
| Security groups | Restricted | |
| SSH | Disabled or tightly governed | |
| Systems Manager | Controlled and logged | |
| Operating system | Supported | |
| Node AMI | Approved | |
| Kubelet | Hardened | |
| Container runtime | Supported and protected | |
| Node labels | Governed | |
| Node taints | Applied | |
| Workload isolation | Implemented | |
| Patch management | Documented | |
| Managed node update | Controlled | |
| Pod disruption | Protected | |
| CloudWatch monitoring | Enabled | |
| GuardDuty monitoring | Enabled | |
| CloudTrail logging | Enabled | |
| AWS Config | Enabled | |
| Incident isolation | Documented and tested | |
| Autoscaling | Least privilege and governed | |
| Resource reservations | Reviewed | |
| Tags | Complete |
Rate each control as:
- Effective
- Partially Effective
- Ineffective
- Not Applicable
- Not Verified
Task 71 — Create the Findings Register
Section titled “Task 71 — Create the Findings Register”Create reports/findings-register.md.
| Finding ID | Finding | Severity | Resource | Owner | Due Date | Status |
|---|---|---|---|---|---|---|
| EKS-NODE-001 | Open |
Use the following template:
Finding ID:
Title:
Affected Cluster:
Affected Node Group:
Affected Instances:
Security Domain:
Description:
Evidence:
Business Impact:
Security Impact:
Likelihood:
Severity:
Root Cause:
Recommended Remediation:
Compensating Controls:
Owner:
Due Date:
Validation Method:
Status:Task 72 — Assign Risk Ratings
Section titled “Task 72 — Assign Risk Ratings”Critical Risk
Section titled “Critical Risk”Examples:
- Worker nodes have public IP addresses and unrestricted administrative access
- Node role has administrator permissions
- Nodes contain long-lived AWS access keys
- Unauthorised workloads can access the container-runtime socket
- Root volumes containing sensitive data are unencrypted
- Compromised nodes cannot be isolated
- Node credentials are shared
- Unsupported nodes contain known exploitable vulnerabilities
High Risk
Section titled “High Risk”Examples:
- Legacy instance metadata access is permitted
- Node IAM role includes application permissions
- Security groups allow excessive inbound access
- SSH is open to broad networks
- Nodes are not patched within the required SLA
- Sensitive workloads share general-purpose nodes
- Runtime monitoring is unavailable
- Custom node AMIs are not governed
- Nodes operate in public subnets
Medium Risk
Section titled “Medium Risk”Examples:
- Missing node labels
- Missing taints
- Incomplete CloudWatch alarms
- Systems Manager sessions are not centrally logged
- Node-group update settings are weak
- Resource reservations are incomplete
- Tags are inconsistent
- Autoscaling permissions are broader than required
Low Risk
Section titled “Low Risk”Examples:
- Minor tag-format issue
- Missing documentation
- Inconsistent naming
- Non-critical monitoring improvement
- Evidence-file naming issue
Task 73 — Create the Risk Register
Section titled “Task 73 — Create the Risk Register”Create reports/risk-register.md.
| Risk ID | Risk | Severity | Likelihood | Impact | Owner | Treatment |
|---|---|---|---|---|---|---|
| EKS-NODE-RISK-001 | Node role contains excessive AWS permissions | High | Medium | High | Remediate | |
| EKS-NODE-RISK-002 | Instance metadata tokens are not required | High | Medium | High | Remediate | |
| EKS-NODE-RISK-003 | Sensitive workloads share standard nodes | Medium | Medium | Medium | Reduce | |
| EKS-NODE-RISK-004 | Node patching evidence is incomplete | Medium | High | Medium | Remediate |
Task 74 — Create the Remediation Plan
Section titled “Task 74 — Create the Remediation Plan”Create reports/remediation-plan.md.
Immediate — 0 to 7 Days
Section titled “Immediate — 0 to 7 Days”- Remove administrative permissions from node roles.
- Revoke exposed or embedded AWS credentials.
- Restrict public SSH access.
- Isolate compromised or untrusted nodes.
- Encrypt unencrypted node volumes.
- Prevent unauthorised runtime-socket access.
- Remove nodes with unsupported critical vulnerabilities.
- Restore runtime-monitoring coverage.
Short-Term — 8 to 30 Days
Section titled “Short-Term — 8 to 30 Days”- Require secure instance metadata tokens.
- Move nodes to private subnets.
- Restrict node security groups.
- Implement Systems Manager administration.
- Separate application permissions from node roles.
- Create dedicated sensitive-workload node groups.
- Implement node labels and taints.
- Update node AMIs.
- Configure node alerts.
Medium-Term — 31 to 90 Days
Section titled “Medium-Term — 31 to 90 Days”- Automate node-image validation.
- Implement regular managed node-group replacement.
- Standardise launch templates.
- Automate configuration-compliance checks.
- Improve node-drain testing.
- Integrate runtime findings with the SIEM.
- Standardise node tagging.
- Improve autoscaling governance.
Long-Term — 90+ Days
Section titled “Long-Term — 90+ Days”- Establish enterprise node-image pipelines.
- Implement continuous worker-node compliance.
- Automate insecure-node isolation.
- Create multi-cluster node-security dashboards.
- Integrate node risks with GRC systems.
- Implement automated node lifecycle governance.
- Conduct regular worker-node incident simulations.
Task 75 — Collect Evidence
Section titled “Task 75 — Collect Evidence”Collect:
- AWS identity
- Cluster details
- Node-group inventory
- Node IAM role
- Attached IAM policies
- Launch-template configuration
- Instance metadata settings
- EBS encryption details
- KMS key details
- Node security groups
- Private subnet evidence
- Node labels
- Node taints
- Node AMI details
- Kubelet configuration
- Container-runtime configuration
- Systems Manager registration
- CloudWatch monitoring
- GuardDuty status
- AWS Config status
- CloudTrail events
- Drain test
- Incident-isolation plan
- Findings register
- Risk register
- Remediation plan
Suggested evidence filenames:
01-aws-identity.json02-cluster-details.json03-nodegroups.json04-nodes.yaml05-node-role.json06-node-role-policies.json07-launch-template.json08-instance-metadata.json09-volumes.json10-kms-key.json11-security-groups.json12-private-subnets.json13-node-labels.txt14-node-taints.txt15-node-ami.json16-kubelet-review.md17-runtime-review.md18-ssm-registration.json19-cloudwatch-status.txt20-guardduty-status.json21-aws-config-status.json22-cloudtrail-events.json23-drain-test.md24-incident-isolation-plan.md25-findings-register.md26-risk-register.md27-remediation-plan.md28-worker-node-security-report.mdTask 76 — Validate Evidence Integrity
Section titled “Task 76 — Validate Evidence Integrity”Generate hashes for key evidence.
Git Bash
Section titled “Git Bash”sha256sum evidence/* \ > evidence/evidence-hashes.txtPowerShell
Section titled “PowerShell”Get-ChildItem evidence -File | Get-FileHash -Algorithm SHA256 | Format-Table | Out-File evidence\evidence-hashes.txtConfirm:
- Files are time stamped
- Evidence is attributable
- Storage is access controlled
- Sensitive values are removed
- Hashes are retained
- Evidence cannot be casually modified
Task 77 — Create the Worker-Node Security Report
Section titled “Task 77 — Create the Worker-Node Security Report”Create reports/worker-node-security-report.md.
Assessment Title:Amazon EKS Worker-Node Security Assessment
Assessment ID:
Assessment Date:
Assessor:
Organisation:
AWS Account:
AWS Region:
Cluster Name:
Node Groups Reviewed:
Worker Nodes Reviewed:
Kubernetes Version:
AMI Types:
Node IAM Roles:
Launch Templates:
Private Subnet Status:
Public IP Status:
Instance Metadata Status:
Root-Volume Encryption Status:
KMS Key:
SSH Access Status:
Systems Manager Status:
Node Security-Group Status:
Node Operating-System Status:
Kubelet Security Status:
Container-Runtime Status:
Node Label Governance:
Node Taint Governance:
Sensitive-Workload Isolation:
Patch-Management Status:
Node-Group Update Status:
Drain-Test Result:
CloudWatch Monitoring Status:
GuardDuty Runtime Status:
AWS Config Status:
CloudTrail Status:
Critical Findings:
High Findings:
Medium Findings:
Low Findings:
Immediate Remediation:
Short-Term Remediation:
Medium-Term Remediation:
Residual Risk:
Overall Node Security Status:
Approved
Conditionally Approved
Rejected
Production Recommendation:
Reassessment Date:
Approvals:
Cloud Security Engineer:
Kubernetes Security Engineer:
Platform Engineering:
DevSecOps:
SOC:
Risk Owner:Task 78 — Clean Up Test Workloads
Section titled “Task 78 — Clean Up Test Workloads”kubectl delete \ -f manifests/secure-workload.yaml \ --ignore-not-foundkubectl delete \ -f manifests/sensitive-workload.yaml \ --ignore-not-foundkubectl delete \ -f manifests/pod-disruption-budget.yaml \ --ignore-not-foundTask 79 — Decide Whether to Retain the Node Group
Section titled “Task 79 — Decide Whether to Retain the Node Group”Retain the node group only when:
- It is authorised for continued use
- Costs are approved
- Security review is complete
- Ownership is assigned
- Monitoring is enabled
- Patch management is defined
- Cleanup is not required by the training plan
Otherwise, delete it.
eksctl delete nodegroup \ --cluster "${CLUSTER_NAME}" \ --region "${AWS_REGION}" \ --name "${NODEGROUP_NAME}"Task 80 — Clean Up Supporting Resources
Section titled “Task 80 — Clean Up Supporting Resources”After deleting the node group, review and remove unused:
- Launch templates
- Launch-template versions
- IAM roles
- Attached policies
- KMS aliases
- KMS keys
- Security groups
- CloudWatch log groups
- Alarms
- Test manifests
- Temporary evidence containing sensitive data
Do not schedule KMS-key deletion until all encrypted dependencies have been confirmed and formal approval has been obtained.
Enterprise Worker-Node Security Checklist
Section titled “Enterprise Worker-Node Security Checklist”| Control | Status |
|---|---|
| Assessment workspace created | ☐ |
| AWS identity verified | ☐ |
| Cluster access validated | ☐ |
| Node groups inventoried | ☐ |
| Kubernetes nodes inventoried | ☐ |
| Nodes mapped to EC2 instances | ☐ |
| Node IAM roles reviewed | ☐ |
| Dedicated node role created | ☐ |
| Node-role trust policy validated | ☐ |
| Least-privilege policies attached | ☐ |
| Application permissions removed from node role | ☐ |
| KMS key created and governed | ☐ |
| Secure launch template created | ☐ |
| Instance metadata tokens required | ☐ |
| Metadata hop limit reviewed | ☐ |
| Root EBS volume encrypted | ☐ |
| SSH access restricted | ☐ |
| Systems Manager configured | ☐ |
| Private subnets validated | ☐ |
| Public IP addresses absent | ☐ |
| VPC endpoints reviewed | ☐ |
| Cluster security group reviewed | ☐ |
| Node security groups reviewed | ☐ |
| Managed node group deployed | ☐ |
| Node labels validated | ☐ |
| Node taints validated | ☐ |
| Workload scheduling tested | ☐ |
| Sensitive workload isolation reviewed | ☐ |
| Operating-system version reviewed | ☐ |
| Node AMI reviewed | ☐ |
| Kubelet security reviewed | ☐ |
| Container runtime reviewed | ☐ |
| DaemonSets reviewed | ☐ |
| Instance metadata configuration validated | ☐ |
| EBS encryption validated | ☐ |
| Systems Manager registration validated | ☐ |
| Session governance reviewed | ☐ |
| Patch process documented | ☐ |
| Node-group update configuration reviewed | ☐ |
| PodDisruptionBudget created | ☐ |
| Node cordon tested | ☐ |
| Node drain tested | ☐ |
| Node returned to service | ☐ |
| Incident-isolation plan documented | ☐ |
| Credential exposure assessed | ☐ |
| Workload identity separation reviewed | ☐ |
| CloudWatch monitoring enabled | ☐ |
| Node conditions reviewed | ☐ |
| Node alerts defined | ☐ |
| GuardDuty Runtime Monitoring reviewed | ☐ |
| GuardDuty findings reviewed | ☐ |
| CloudTrail events reviewed | ☐ |
| AWS Config coverage reviewed | ☐ |
| Autoscaling security reviewed | ☐ |
| Capacity-type risk reviewed | ☐ |
| Resource reservations reviewed | ☐ |
| Pod density reviewed | ☐ |
| Label governance reviewed | ☐ |
| Taint governance reviewed | ☐ |
| Tagging reviewed | ☐ |
| Node image governance reviewed | ☐ |
| Bootstrap governance reviewed | ☐ |
| Findings register completed | ☐ |
| Risk register completed | ☐ |
| Remediation plan completed | ☐ |
| Evidence collected | ☐ |
| Evidence integrity validated | ☐ |
| Final report completed | ☐ |
| Cleanup completed | ☐ |
Skills Developed
Section titled “Skills Developed”By completing this lab, you will be able to:
- Assess Amazon EKS worker-node architecture
- Design least-privilege node IAM roles
- Create secure EC2 launch templates
- Protect EC2 instance metadata
- Encrypt node storage with AWS KMS
- Deploy worker nodes in private subnets
- Restrict worker-node security groups
- Replace SSH with controlled Systems Manager access
- Apply Kubernetes node labels and taints
- Isolate sensitive workloads
- Review EKS-optimised node images
- Assess kubelet security
- Assess container-runtime security
- Implement node patch and replacement processes
- Configure node monitoring and detection
- Test node cordon and drain operations
- Design compromised-node isolation procedures
- Review autoscaling security
- Produce enterprise worker-node security evidence
- Create remediation and risk reports
Knowledge Check
Section titled “Knowledge Check”Question 1
Section titled “Question 1”Why should Amazon EKS worker nodes use a dedicated IAM role?
Answer: A dedicated role limits node permissions to the infrastructure actions required by the node and prevents unrelated application permissions from being shared across all workloads.
Question 2
Section titled “Question 2”Why should application Pods avoid using the EC2 node role?
Answer: Every Pod on the node may otherwise gain access to the same AWS permissions, increasing credential exposure and violating least privilege.
Question 3
Section titled “Question 3”Why should modern EC2 instance metadata tokens be required?
Answer: Token-based metadata access reduces the risk of unauthorised metadata requests and helps protect temporary instance credentials.
Question 4
Section titled “Question 4”Why should worker nodes be deployed in private subnets?
Answer: Private subnets reduce direct internet exposure and allow node access to be controlled through approved network paths, NAT, VPC endpoints, and management services.
Question 5
Section titled “Question 5”Why is Systems Manager preferred over open SSH access?
Answer: Systems Manager can provide identity-based, logged, and controlled administrative sessions without exposing an inbound SSH service or distributing private keys.
Question 6
Section titled “Question 6”What is the purpose of Kubernetes node taints?
Answer: Taints prevent workloads from scheduling onto selected nodes unless the workload has an approved matching toleration.
Question 7
Section titled “Question 7”How do node labels support workload isolation?
Answer: Labels allow workloads to select approved node groups based on trust level, data classification, hardware requirements, or security zone.
Question 8
Section titled “Question 8”Why should node patching generally use controlled node replacement?
Answer: Replacement provides a repeatable way to deploy an approved image, reduces configuration drift, and avoids relying on uncontrolled manual changes to long-running nodes.
Question 9
Section titled “Question 9”Why must node-drain procedures be tested?
Answer: Drain testing confirms workloads can move safely during patching, incident response, scaling, or node replacement without unacceptable service disruption.
Question 10
Section titled “Question 10”What should happen when a worker node is suspected of compromise?
Answer: The node should be identified, cordoned, investigated, safely drained where appropriate, isolated, replaced, and reviewed for credential, workload, image, and network exposure.
Lab Summary
Section titled “Lab Summary”In this lab, you secured the Amazon EKS worker-node layer.
You implemented and assessed:
- Node IAM roles
- Least-privilege permissions
- Secure role trust
- EC2 launch templates
- Instance metadata protection
- Encrypted Amazon EBS storage
- AWS KMS governance
- Private subnet deployment
- Restricted security groups
- Systems Manager access
- Managed node groups
- Node labels
- Node taints
- Sensitive-workload isolation
- Operating-system security
- Node-image governance
- Kubelet security
- Container-runtime security
- Patch management
- Node-group updates
- Pod disruption controls
- Node cordon and drain
- Compromised-node isolation
- CloudWatch monitoring
- GuardDuty Runtime Monitoring
- CloudTrail auditing
- AWS Config compliance
- Autoscaling security
- Evidence and reporting
Amazon EKS worker nodes process application workloads, hold temporary credentials, run the container runtime, connect to the Kubernetes control plane, and provide access to application data.
A compromised or poorly governed worker node can therefore affect:
- Multiple Pods
- AWS identities
- Kubernetes credentials
- Network communication
- Persistent data
- Runtime security
- Cluster availability
- Compliance evidence
Secure worker nodes require more than patched operating systems.
They require:
- Strong identity controls
- Private networking
- Encrypted storage
- Secure metadata access
- Controlled administration
- Workload isolation
- Runtime monitoring
- Repeatable replacement
- Incident readiness
- Enterprise governance
What’s Next?
Section titled “What’s Next?”Next Lab: Lab 03 — Secure Amazon EKS Networking
In the next lab, you will secure Amazon EKS networking by reviewing VPC architecture, private subnets, cluster endpoint access, security groups, network ACLs, Amazon VPC CNI controls, Kubernetes NetworkPolicies, ingress security, egress governance, load balancers, DNS security, VPC Flow Logs, and Zero Trust network segmentation.