Amazon EKS — IAM & Security — Practice Exercises

3 minute read

Chapter 9 — Practice Exercises


Exercise 1: IRSA Setup

Question: Your application pod needs to read from S3 bucket data-bucket and write to DynamoDB table sessions. Create the IAM policy, IRSA setup commands, and pod spec.

Show Solution

IAM Policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::data-bucket",
        "arn:aws:s3:::data-bucket/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": ["dynamodb:PutItem", "dynamodb:GetItem", "dynamodb:UpdateItem"],
      "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/sessions"
    }
  ]
}

Create IRSA:

$ aws iam create-policy --policy-name app-policy --policy-document file://policy.json

$ eksctl create iamserviceaccount \
    --cluster demo \
    --name app-sa \
    --namespace production \
    --attach-policy-arn arn:aws:iam::123456789012:policy/app-policy \
    --approve

Pod spec:

apiVersion: v1
kind: Pod
metadata:
  name: app
  namespace: production
spec:
  serviceAccountName: app-sa
  containers:
    - name: app
      image: my-app:latest

Exercise 2: RBAC Design

Question: Create RBAC rules for: (a) Developers can view pods and logs in staging, (b) Ops team can manage deployments in all namespaces, (c) CI/CD service account can create/update deployments in production.

Show Solution

(a) Developer pod viewer — namespace-scoped:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-viewer
  namespace: staging
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-pod-viewer
  namespace: staging
subjects:
  - kind: Group
    name: developers
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-viewer
  apiGroup: rbac.authorization.k8s.io

(b) Ops deployment manager — cluster-scoped:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: deployment-manager
rules:
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: ops-deployment-manager
subjects:
  - kind: Group
    name: operations
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: deployment-manager
  apiGroup: rbac.authorization.k8s.io

(c) CI/CD deployer — namespace-scoped:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deployer
  namespace: production
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["create", "update", "patch"]
  - apiGroups: [""]
    resources: ["services", "configmaps"]
    verbs: ["create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cicd-deployer
  namespace: production
subjects:
  - kind: ServiceAccount
    name: cicd-sa
    namespace: production
roleRef:
  kind: Role
  name: deployer
  apiGroup: rbac.authorization.k8s.io

Exercise 3: Pod Security

Question: Write a pod spec that passes the restricted Pod Security Standard. Include all required security contexts.

Show Solution
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: my-app:latest
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop: ["ALL"]
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 500m
          memory: 256Mi
      volumeMounts:
        - name: tmp
          mountPath: /tmp
  volumes:
    - name: tmp
      emptyDir: {}    # Writable /tmp since root FS is read-only

Exercise 4: Security Audit

Question: You’ve inherited an EKS cluster. List 10 things you would check in a security audit and the commands to check them.

Show Solution
# 1. API endpoint access
$ aws eks describe-cluster --name cluster --query 'cluster.resourcesVpcConfig'

# 2. Control plane logging
$ aws eks describe-cluster --name cluster --query 'cluster.logging'

# 3. Envelope encryption
$ aws eks describe-cluster --name cluster --query 'cluster.encryptionConfig'

# 4. Kubernetes version
$ aws eks describe-cluster --name cluster --query 'cluster.version'

# 5. RBAC — who has cluster-admin?
$ kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name=="cluster-admin") | .subjects'

# 6. Pods running as root
$ kubectl get pods -A -o json | jq '.items[] | select(.spec.securityContext.runAsNonRoot != true) | .metadata.name'

# 7. Pods with privileged containers
$ kubectl get pods -A -o json | jq '.items[] | select(.spec.containers[].securityContext.privileged == true) | .metadata.name'

# 8. Network policies
$ kubectl get networkpolicies -A

# 9. IRSA usage (vs node IAM)
$ kubectl get sa -A -o json | jq '.items[] | select(.metadata.annotations."eks.amazonaws.com/role-arn") | .metadata.name'

# 10. Image sources (ECR vs public)
$ kubectl get pods -A -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' | sort -u

Exercise 5: Secrets Security

Question: Your cluster stores database passwords as Kubernetes Secrets. What are 3 security risks and how would you mitigate each?

Show Solution

Risk 1: Secrets stored as base64 in etcd (not encrypted)

Mitigation: Enable KMS envelope encryption
$ aws eks create-cluster ... --encryption-config '[{"resources":["secrets"],"provider":{"keyArn":"arn:aws:kms:..."}}]'

Risk 2: Anyone with namespace access can read Secrets

Mitigation: RBAC — restrict secrets access
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: []    # No access to secrets

Risk 3: Secrets visible in pod spec (env vars)

Mitigation: Use AWS Secrets Manager with CSI driver
- Secrets stored in AWS Secrets Manager
- Mounted as files (not env vars)
- Rotation supported
- Audit trail via CloudTrail

What’s Next?

Expose your apps: Chapter 10 — Load Balancing & Ingress.