Skip to content
DevOps Architect

    Syllabus / Infrastructure / 11

    STARTUP TO ENTERPRISE
    11 / 14 • CLOUD PLATFORM

    ☁️AWS for DevOps Engineers

    Build reliable, secure systems on AWS. EKS, ECR with scanning, IAM/IRSA, VPC design, ALB Ingress Controller, CloudWatch, and multi-account architectures.

    Free Tier EKS + Terraform Control Tower

    Architecture & How It Works 11.1

    AWS is organized into Regions containing multiple Availability Zones. EKS provides a managed control plane. IAM with IRSA allows pods to assume IAM roles via OIDC without long-lived credentials.

    graph TD Region[Region us-east-1] --> AZa[AZ-1a] Region --> AZb[AZ-1b] AZa --> EKSControl[EKS Control Plane] AZa --> Nodes[Managed Nodes] Nodes --> Pods[Pods] Pods -->|IRSA| S3[S3 / other AWS]

    Core Components 11.2

    ServiceDevOps RoleKey Integration
    EKSManaged Kuberneteseksctl, EKS add-ons, ALB Ingress
    ECRPrivate registryScan on push, lifecycle policies
    IAM / IRSAWorkload identityOIDC provider, service account annotation
    VPC CNINetworkingENI allocation, security groups
    CloudWatchObservabilityContainer Insights, Log Groups

    WSL Hands-On Lab 11.3

    CLI → eksctl EKS → IRSA → Helm + ALB → ECR → CloudWatch

    aws lab
    $ aws configure
    $ eksctl create cluster --name devops-lab --region us-east-1 --nodegroup-name ng --node-type t3.medium --nodes 2
    $ eksctl create iamserviceaccount --name s3-reader --cluster devops-lab --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess --approve
    • Configure AWS CLI and create EKS cluster with eksctl
    • Deploy application using Helm with ALB Ingress
    • Configure and test IRSA for S3 access from a pod
    • Push image to ECR and configure lifecycle + scanning
    • Enable Container Insights and validate metrics in CloudWatch

    Real-World Project 11.4

    EC2 + RDS + Route53 on free tier

    EKS + ECR + RDS + ALB via eksctl and Terraform

    Multi-account AWS Organizations + Control Tower + Transit Gateway + EKS Anywhere

    Troubleshooting 11.5

    Check node IAM role, security groups, bootstrap logs, and subnet tags for the cluster.

    Verify serviceaccount annotation, OIDC identity provider exists, and VPC endpoints if private.

    Confirm ingress class, subnet tags (kubernetes.io/role/elb), and IAM permissions for the ALB controller.

    30-Day Roadmap 11.6

    WEEK 1
    AWS Fundamentals
    • CLI + IAM mastery
    • VPC deep dive
    • EC2 + security groups
    WEEK 2
    EKS & Networking
    • eksctl clusters
    • ALB Ingress Controller
    • VPC CNI tuning
    WEEK 3
    IAM & Security
    • IRSA + OIDC
    • Least privilege roles
    • Secrets Manager
    WEEK 4
    Multi-Account
    • Organizations + SCPs
    • Control Tower
    • Transit Gateway

    Deep Dive: Multi-Account & Cost Controls 11.7

    Landing Zone Design

    Use AWS Control Tower or custom terraform-aws-modules/organization. Create separate accounts for prod, non-prod, security, and network. Enforce SCPs and centralized logging.

    Cost Observability

    Enable Cost Explorer + CUR. Tag every resource with owner, environment, project. Use Kubecost or CloudWatch + Lambda to surface per-namespace spend on EKS.

     Real Incident: Public S3 Bucket Exposes Customer PII

    Discovery: GuardDuty at 02:30 UTC — S3/BucketPubliclyAccessible. Bucket made public by data engineer, containing 140K customer records.

    # Auto-remediation Lambda triggered by GuardDuty EventBridge rule
    $ aws s3api put-public-access-block \
      --bucket acme-analytics-exports-2024 \
      --public-access-block-configuration \
        BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
    Bucket locked within 47 seconds of GuardDuty finding

    Prevention: SCP denying s3:PutBucketAcl with public-read. AWS Config Rule auto-remediation. OPA in Terraform CI blocking public ACLs.

    Enterprise: GuardDuty, Config & Transit Gateway 11.8

    guardduty-remediation-lambda.py
    import boto3
    
    def handler(event, context):
        finding = event['detail']
        finding_type = finding['type']
    
        if 'S3/BucketPubliclyAccessible' in finding_type:
            bucket = finding['resource']['s3BucketDetails'][0]['name']
            boto3.client('s3').put_public_access_block(
                Bucket=bucket,
                PublicAccessBlockConfiguration={
                    'BlockPublicAcls': True, 'IgnorePublicAcls': True,
                    'BlockPublicPolicy': True, 'RestrictPublicBuckets': True
                }
            )
    
        elif 'CryptoCurrency/BitcoinTool' in finding_type:
            instance_id = finding['resource']['instanceDetails']['instanceId']
            ec2 = boto3.client('ec2')
            # Quarantine: apply deny-all security group
            ec2.modify_instance_attribute(
                InstanceId=instance_id,
                Groups=['sg-quarantine-00000000']
            )
            # Snapshot for forensics
            ec2.create_snapshots(
                InstanceSpecification={'InstanceId': instance_id},
                Description='GuardDuty forensic - cryptominer isolated'
            )
    # Enable Security Hub + aggregate all org accounts
    $ aws securityhub enable-security-hub \
      --enable-default-standards --region us-east-1
    $ aws securityhub create-finding-aggregator \
      --region-linking-mode ALL_REGIONS
    
    # List non-compliant S3 buckets
    $ aws configservice get-compliance-details-by-config-rule \
      --config-rule-name s3-bucket-public-read-prohibited \
      --compliance-types NON_COMPLIANT
    transit-gateway.tf
    resource "aws_ec2_transit_gateway" "main" {
      description                     = "Enterprise hub TGW"
      auto_accept_shared_attachments  = "disable"
      default_route_table_association = "disable"
      tags = { Name = "enterprise-tgw" }
    }
    
    # Share TGW with spoke accounts via RAM
    resource "aws_ram_resource_share" "tgw" {
      name = "transit-gateway-share"
    }
    
    resource "aws_ram_resource_association" "tgw" {
      resource_arn       = aws_ec2_transit_gateway.main.arn
      resource_share_arn = aws_ram_resource_share.tgw.arn
    }
    
    # Spoke account attaches their VPC
    resource "aws_ec2_transit_gateway_vpc_attachment" "spoke" {
      transit_gateway_id = data.aws_ec2_transit_gateway.hub.id
      vpc_id             = aws_vpc.spoke.id
      subnet_ids         = aws_subnet.private[*].id
    }
    eks-blueprints-addons.tf
    module "eks_blueprints_addons" {
      source  = "aws-ia/eks-blueprints-addons/aws"
      version = "~> 1.0"
    
      cluster_name      = module.eks.cluster_name
      cluster_endpoint  = module.eks.cluster_endpoint
      cluster_version   = module.eks.cluster_version
      oidc_provider_arn = module.eks.oidc_provider_arn
    
      eks_addons = {
        vpc-cni = {
          most_recent = true
          configuration_values = jsonencode({
            env = {
              ENABLE_PREFIX_DELEGATION = "true"  # 110 pods/node vs 29
            }
          })
        }
        aws-ebs-csi-driver = { most_recent = true }
        coredns            = { most_recent = true }
        kube-proxy         = { most_recent = true }
      }
    
      enable_aws_load_balancer_controller = true
      enable_karpenter                    = true
      enable_cert_manager                 = true
      enable_external_secrets             = true
      enable_aws_for_fluentbit            = true
    }
    • Enable GuardDuty, create EventBridge + Lambda auto-remediation for public S3 findings
    • Enable AWS Config + Security Hub, verify s3-bucket-public-read-prohibited compliance
    • Deploy EKS Blueprints addons: ALB controller + Karpenter + prefix delegation VPC CNI
    • Write SCP denying s3:PutBucketAcl with public-read across all non-sandbox accounts
    • Design Transit Gateway hub-spoke architecture for prod + dev + shared-services accounts

    Run: aws configure

    Extra commands from this lesson (13) are kept out of this page. Quizzes were not in the source HTML.