Infrastructure Security Day 4
SCS-C03 · Domain 3 · Infrastructure Security (18%) · Day 4 of 5

Hardening and accessing compute

Day 3 connected networks to on-premises and checked them with Network Access Analyzer. Today we secure the servers themselves: building hardened images with EC2 Image Builder, protecting credentials with IMDSv2, giving compute the right roles, keeping it patched with Patch Manager and Inspector, and reaching it safely with Session Manager, Instance Connect and the Serial Console.

Skill 3.2.1 hardened imagesSkill 3.2.2 compute rolesSkill 3.2.4 patchingSkill 3.2.5 secure admin access~90 min read + 30 min lab
01

Hardened AMIs and container images

Skill 3.2.1 asks you to build hardened images for EC2 and containers. The idea is simple: instead of fixing each server after it starts, you build one clean, locked-down image, test it, scan it, and launch everything from it. This image is often called a golden AMI. When the image needs a change, you build a new version and replace the old servers. You don’t log in and patch them by hand.

Hardening means removing what you don’t need and locking what stays: no unused packages or open services, no default passwords, no SSH keys baked in, the SSM Agent and CloudWatch agent installed, IMDSv2 required, disk encryption on, and settings that follow a benchmark such as CIS or DISA STIG.

Concept profile

EC2 Image Builder

often confused with Creating AMIs by hand (or Packer scripts you run yourself)
?What is it?

A managed AWS service that automates building, testing, scanning and distributing secure AMIs and container images on a schedule or when the base image changes.

⚙How does it work?
  • An image recipe (for an AMI) or container recipe (for a Docker image) names a base image and a list of components.
  • Build components change the build instance (install agents, apply STIG hardening, remove tools). Test components run on an instance launched from the new image.
  • The infrastructure configuration sets where the build runs: instance type, subnet, security group, instance profile, logging to S3.
  • The distribution configuration copies the AMI to other Regions, shares it with accounts or OUs, and can update launch templates. Container images go to Amazon ECR.
  • The pipeline can run an Amazon Inspector vulnerability scan on the new image. It distributes the image only if all tests pass.
{ }Structure
Base imageAmazon Linux,Windows, or acontainer baseBuild stepsCIS / STIG hardeninstall agentsremove extrasTest stepsboot checksyour test scriptsfail = no imageInspector scanCVE findingson the new imagebefore releaseDistributeRegions, accounts,OUs, launchtemplate updateImage pipeline = recipe + infrastructure configuration + distribution configuration + schedule.Image recipe makes an AMI; container recipe makes a Docker image and pushes it to Amazon ECR.The image is distributed only if every test component passes.Result: a versioned golden image. Launch from it; never harden servers by hand after launch.
A pipeline turns a base image into a tested, scanned golden image.
⇄Image Builder vs Creating AMIs by hand (or Packer scripts you run yourself)
Image BuilderHand-built AMIs
RepeatableYes: versioned recipesDepends on who built it
HardeningAWS-managed STIG components + your ownManual steps, easy to forget
TestingTest components gate releaseUsually none
UpdatesScheduled rebuilds when base changesOld images drift
DistributionRegions, accounts, OUs, launch templatesCopy and share by hand
!Common mistakes the exam tests
  • Hardening servers after launch with scripts instead of building it into the image.
  • Baking secrets, access keys or SSH keys into the AMI. Use roles and Secrets Manager at run time.
  • Sharing an AMI with an encrypted snapshot but not giving the other account use of the KMS key (the AWS managed key can’t be shared; use a customer managed key).
  • Forgetting the build instance needs an instance profile with SSM permissions: Image Builder runs components through Systems Manager.
  • Building once and never rebuilding: a golden AMI from last year is missing a year of patches.
✓Benefits and use cases
  • Same hardened baseline for every EC2 instance in the organization.
  • Hardened base images for containers in ECR.
  • Proof for auditors: versioned recipes and test results.

Container images and keeping the fleet on approved images

For containers, the same rules apply: start from a small trusted base image (for example a minimal or distroless image), run as a non-root user, don’t include shells and build tools you don’t need, keep secrets out of layers, and store images in Amazon ECR with scan on push or Inspector enhanced scanning and tag immutability. To make sure people only launch approved AMIs, you can use the EC2 Allowed AMIs account setting (or an IAM/SCP condition on the image ID or owner), and use AWS Config rules such as approved-amis-by-id to find instances that drifted.

Think of it like · a bakery

A bakery makes every loaf from one tested recipe.

AWS conceptFamiliar thing
Golden AMI≈The master dough that every loaf starts from
Image recipe≈The written recipe card with base flour and steps
Build component≈A step in the recipe: add salt, knead, remove lumps
Test component≈Tasting one loaf before the batch goes to the shops
Distribution≈Delivery vans taking the same bread to every branch
Hand-built servers≈Each baker improvising, so no two loaves are the same
Real AWS example · create an Image Builder pipeline

A pipeline that rebuilds a hardened AMI every week and scans it with Inspector.

$ aws imagebuilder create-image-pipeline \
    --name hardened-al2023 \
    --image-recipe-arn arn:aws:imagebuilder:eu-west-1:111122223333:image-recipe/al2023-stig/1.0.0 \
    --infrastructure-configuration-arn arn:aws:imagebuilder:eu-west-1:111122223333:infrastructure-configuration/build-private \
    --distribution-configuration-arn arn:aws:imagebuilder:eu-west-1:111122223333:distribution-configuration/org-share \
    --image-scanning-configuration imageScanningEnabled=true \
    --schedule 'scheduleExpression=cron(0 3 ? * sun *),pipelineExecutionStartCondition=EXPRESSION_MATCH_AND_DEPENDENCY_UPDATES_AVAILABLE'

The start condition means it only builds when the base image or a component has a new version.

Exam-style scenario

A company launches hundreds of EC2 instances from an Amazon Linux base AMI and then runs a long hardening script at boot. Some instances start serving traffic before the script finishes, and auditors find different settings on different servers. The company wants a consistent, tested, hardened image in three Regions with the least operational effort. What should it do?

  1. A. Run the hardening script with Systems Manager Run Command after launch.
  2. B. Use EC2 Image Builder with a recipe that includes STIG hardening and test components, Inspector scanning, and a distribution configuration for the three Regions; launch instances from the output AMI.
  3. C. Create an AMI by hand from one hardened instance and copy it to the Regions.
  4. D. Use AWS Config to detect non-compliant instances.
Show the worked answer

Answer: B

Image Builder bakes the hardening into a tested, scanned, versioned AMI and distributes it automatically.

Why not the others

  • A: Still hardens after launch, so the timing gap and drift remain.
  • C: Manual, not repeatable, and goes stale.
  • D: Detects drift but doesn’t build anything.
How the exam tests this
  • “Automate hardened, tested AMIs”→ EC2 Image Builder pipeline.
  • “Hardening to a DoD standard”→ Image Builder STIG components.
  • “Share golden AMI with all accounts in an OU”→ Distribution configuration (org/OU sharing).
  • “Only allow launches from approved AMIs”→ Allowed AMIs setting or SCP on image ID / owner.
  • “Encrypted AMI shared but launch fails”→ Share the customer managed KMS key.
Must remember
  • Harden in the image, not after launch.
  • Recipe + components (build / test) + infra + distribution.
  • Tests must pass before distribution.
  • No secrets or keys in images.
  • Shared encrypted AMI needs a customer managed key.
02

IMDSv2: protecting instance credentials

Every EC2 instance can read the Instance Metadata Service (IMDS) at 169.254.169.254. It returns the instance ID, user data and, most importantly, the temporary credentials of the instance role. If an attacker tricks a web app into fetching a URL for them (server-side request forgery, SSRF), IMDSv1 hands over those credentials with a simple GET. IMDSv2 adds a session token that a simple SSRF request can’t get.

Concept profile

IMDSv2 (session-oriented metadata)

often confused with IMDSv1
?What is it?

A version of the instance metadata service that only answers requests that carry a session token, which the caller must first get with a PUT request.

⚙How does it work?
  • Step 1: PUT /latest/api/token with header X-aws-ec2-metadata-token-ttl-seconds (up to 6 hours).
  • Step 2: send the token in X-aws-ec2-metadata-token on every GET.
  • Requests with an X-Forwarded-For header are refused, which blocks many open proxies.
  • The token reply uses an IP TTL equal to the hop limit. With hop limit 1 it can’t reach a container behind an extra network hop; AWS recommends 2 when containers run on the instance.
  • Set HttpTokens=required per instance, in the launch template, as an account-level default per Region, or on the AMI (ImdsSupport=v2.0).
{ }Structure
Process on instance 1. PUT /latest/api/token X-aws-ec2-metadata- token-ttl-seconds 3. GET with header X-aws-ec2-metadata-token ask for a token 2. token (TTL up to 6 h) GET + token IMDS 169.254.169.254 Returns role credentials, instance ID, user data… Token response is an IP packet with TTL = hop limit, so it can’t travel far off the host. Hop limit 1 = only the host OS (blocks containers) 2 = recommended when containers run Higher = more places can reach IMDS Defaults to 2 for V2-only defaults / AMIs Enforce IMDSv2 Account default per Region: V2 only AMI flag ImdsSupport = v2.0 SCP/IAM: ec2:MetadataHttpTokens Role guard: ec2:RoleDelivery ≥ 2.0
Token first, then data. The hop limit keeps the token close to the host.
⇄IMDSv2 vs IMDSv1
IMDSv2IMDSv1
Request stylePUT for token, then GET with tokenPlain GET
SSRF riskMuch lowerHigh: one GET leaks credentials
Proxy with X-Forwarded-ForRefusedAnswered
Hop limit mattersYes, token TTLNo
Exam hint“require”, “enforce”, “SSRF”Legacy; turn off
!Common mistakes the exam tests
  • Turning on IMDSv2 required before checking old software: very old SDKs and agents may only speak v1. Use the CloudWatch metric MetadataNoToken to find v1 callers first.
  • Leaving the hop limit at 1 on hosts that run containers in bridge mode: the containers time out.
  • Thinking the account default changes existing instances: it only affects new launches. Fix old ones with modify-instance-metadata-options.
  • Setting ImdsSupport=v2.0 on an AMI casually: it can’t be undone on that AMI.
  • Forgetting to stop people from switching back: deny ec2:ModifyInstanceMetadataOptions unless ec2:Attribute/HttpTokens is required.
✓Benefits and use cases
  • Block SSRF credential theft from web apps on EC2.
  • Organization-wide guardrail with an SCP.
  • Required by many security benchmarks and Security Hub controls (EC2.8).

Enforcing IMDSv2 across an organization

Use several layers. In every account and Region, set the account-level default to “V2 only” with modify-instance-metadata-defaults (new instances then get HttpTokens=required and hop limit 2), and you can also turn on IMDSv2 enforcement so any launch that isn’t set to require IMDSv2 fails. In AWS Organizations, an SCP can deny ec2:RunInstances when ec2:MetadataHttpTokens is not required, and can cap ec2:MetadataHttpPutResponseHopLimit. A declarative policy for EC2 can also set the IMDS default for whole OUs. As a final safety net, a deny on ec2:RoleDelivery less than 2.0 blocks API calls signed with role credentials that were fetched through IMDSv1.

Think of it like · a hotel front desk

Getting your room key from reception.

AWS conceptFamiliar thing
IMDS≈The front desk that hands out room keys
IMDSv1≈The desk gives a key to anyone who phones and says a room number
IMDSv2 token≈You must come to the desk in person first and get a visitor pass
Hop limit≈The pass only works inside the lobby, not if passed out the window
Account default≈Hotel rule: every new desk clerk follows the pass system
SCP condition≈Head office refuses to open any new hotel without the pass system
Real AWS example · enforce IMDSv2 in an account and with an SCP

Set the Region default, then add an organization guardrail.

$ aws ec2 modify-instance-metadata-defaults --region eu-west-1 \
    --http-tokens required --http-put-response-hop-limit 2

$ aws ec2 modify-instance-metadata-options --instance-id i-0abc1234 \
    --http-tokens required --http-endpoint enabled

SCP:
{ "Version": "2012-10-17", "Statement": [
  { "Sid": "RequireImdsV2", "Effect": "Deny", "Action": "ec2:RunInstances",
    "Resource": "arn:aws:ec2:*:*:instance/*",
    "Condition": { "StringNotEquals": { "ec2:MetadataHttpTokens": "required" } } },
  { "Sid": "NoV1Switch", "Effect": "Deny", "Action": "ec2:ModifyInstanceMetadataOptions",
    "Resource": "arn:aws:ec2:*:*:instance/*",
    "Condition": { "StringNotEquals": { "ec2:Attribute/HttpTokens": "required" },
                   "Null": { "ec2:Attribute/HttpTokens": "false" } } } ]}

The second command fixes an existing instance; account defaults only apply to new launches.

Exam-style scenario

A penetration test shows that a web application on EC2 can be tricked into requesting http://169.254.169.254/latest/meta-data/iam/security-credentials/ and returning the role credentials. The company runs hundreds of accounts. It wants to stop this for current instances and make sure no new instance is ever launched with the old behavior. What should it do?

  1. A. Remove the instance role and store access keys in the application config.
  2. B. Set HttpTokens to required on existing instances, set the IMDS account default to V2 only in each Region, and attach an SCP that denies ec2:RunInstances unless ec2:MetadataHttpTokens is required.
  3. C. Block 169.254.169.254 in the security group.
  4. D. Add a WAF rule on the ALB only.
Show the worked answer

Answer: B

IMDSv2 defeats simple SSRF; defaults plus an SCP stop new v1 instances in every account.

Why not the others

  • A: Long-term keys are worse and can still leak.
  • C: Security groups don’t filter traffic to the link-local IMDS address.
  • D: Helps, but doesn’t fix the root cause or other apps; and doesn’t enforce anything for new instances.
How the exam tests this
  • “SSRF stole instance role credentials”→ Require IMDSv2 (HttpTokens=required).
  • “Containers on EC2 can’t reach IMDS after v2”→ Raise hop limit to 2.
  • “Org-wide: no launches without IMDSv2”→ SCP on ec2:MetadataHttpTokens.
  • “Find apps still using v1”→ CloudWatch MetadataNoToken metric.
  • “New instances default to v2 without changing templates”→ Account-level IMDS defaults.
Must remember
  • v2 = PUT token, then GET with header.
  • Hop limit 2 for containers.
  • Account default: per Region, new instances only.
  • SCP key: ec2:MetadataHttpTokens = required.
  • ec2:RoleDelivery ≥ 2.0 blocks v1-fetched creds.
03

Instance profiles, service roles and execution roles

Skill 3.2.2 is about giving compute permissions without access keys. Every AWS compute service has a way to attach an IAM role so that code receives short-lived credentials automatically. The exam checks that you pick the right role in the right place, especially the two roles of an ECS task, and that you keep each role small.

Concept profile

ECS task role

often confused with ECS task execution role
?What is it?

The IAM role that the application code inside the containers uses to call AWS services (for example S3, DynamoDB, SQS). It is set as taskRoleArn in the task definition.

⚙How does it work?
  • Both roles trust ecs-tasks.amazonaws.com.
  • Task role: the SDK in the container finds credentials through the ECS container credentials endpoint. Each task gets only its own role.
  • Task execution role (executionRoleArn): used by the ECS or Fargate agent, not your code, to pull images from private ECR, send awslogs logs to CloudWatch, and fetch Secrets Manager or Parameter Store values injected as environment variables.
  • Managed policy AmazonECSTaskExecutionRolePolicy covers ECR and logs; add secretsmanager:GetSecretValue, ssm:GetParameters and kms:Decrypt (for a customer managed key) when you inject secrets.
  • On EC2 launch type, containers could also reach the instance profile through IMDS unless you block it, so block it (for example the ECS agent setting ECS_AWSVPC_BLOCK_IMDS for awsvpc tasks).
{ }Structure
EC2 instanceInstance profileholds one roletrust: ec2creds via IMDSPassRole to launchLambda functionExecution roletrust: lambdalogs: BasicExecution policy+ app accessECS taskTask role = appExecution role =agent: pull ECR,logs, secretstrust: ecs-tasksEKS podPod Identity:agent + associationtrust: pods.eksIRSA: OIDC+ service accountSame idea everywhere: no access keys in codeAWS hands short-lived credentials to the workload. The trust policy names the service; the permissionspolicy says what the code may do. The person who attaches the role needs iam:PassRole for it.
Each compute service gets credentials its own way; the principle is the same.
⇄Task role vs ECS task execution role
Task roleTask execution role
Used byYour application codeECS / Fargate agent
Typical permissionsS3, DynamoDB, SQS, KMS for app dataECR pull, CloudWatch Logs, secrets for injection
Task definition fieldtaskRoleArnexecutionRoleArn
Symptom when wrongAccessDenied in app logsTask stuck: CannotPullContainerError, secret fetch fails
Visible to containersYesNo
!Common mistakes the exam tests
  • Adding S3 permissions to the execution role and wondering why the app gets AccessDenied: the app uses the task role.
  • Adding secretsmanager:GetSecretValue to the task role when the secret is injected through secrets in the task definition: injection uses the execution role.
  • Giving one broad instance role to an ECS host so all tasks share it.
  • Forgetting iam:PassRole: the person or pipeline that launches the instance or registers the task definition must be allowed to pass that role.
  • Using long-term access keys in environment variables instead of roles.
✓Benefits and use cases
  • Each microservice gets only the AWS permissions it needs.
  • Image pulls and logging work without the app knowing any credentials.
  • Clear audit trail in CloudTrail per role.

EC2, Lambda and EKS

EC2: an instance profile is a container that holds one role; the role trusts ec2.amazonaws.com, and the instance gets its credentials through IMDS. You can swap the role on a running instance. Lambda: every function has an execution role trusting lambda.amazonaws.com; AWSLambdaBasicExecutionRole gives CloudWatch Logs, and AWSLambdaVPCAccessExecutionRole adds the ENI permissions for VPC functions. Who may invoke the function is a different thing: that is the function’s resource-based policy. EKS: with EKS Pod Identity, you install the Pod Identity Agent add-on and create an association between a role and a Kubernetes service account; the role trusts pods.eks.amazonaws.com, needs no OIDC provider, and can be reused across clusters. The older IRSA uses the cluster’s OIDC provider and a trust policy per cluster. Pod Identity doesn’t support pods on Fargate, so those still use IRSA. A service role is the general name for a role a service assumes to act for you (for example the Image Builder or Systems Manager maintenance window role); a service-linked role is predefined by the service and you can’t edit its permissions.

Think of it like · a company building

Who carries which badge.

AWS conceptFamiliar thing
Instance profile≈A badge holder clipped to a worker, with exactly one badge inside
Lambda execution role≈A day pass printed for each delivery person
ECS task role≈The badge of the worker who actually does the job in the office
ECS execution role≈The badge of the security guard who brings in the worker’s tools and keys
EKS Pod Identity≈Reception gives each team member a badge based on their team name
iam:PassRole≈Permission to hand someone a badge you don’t wear yourself
Real AWS example · task definition with both roles

The app reads S3 with the task role; the agent pulls the image, ships logs and injects a secret with the execution role.

{ "family": "orders-api",
  "taskRoleArn": "arn:aws:iam::111122223333:role/orders-app-s3-read",
  "executionRoleArn": "arn:aws:iam::111122223333:role/ecsTaskExecutionRole",
  "networkMode": "awsvpc", "requiresCompatibilities": ["FARGATE"],
  "containerDefinitions": [{
    "name": "api", "image": "111122223333.dkr.ecr.eu-west-1.amazonaws.com/orders:1.4",
    "secrets": [{ "name": "DB_PASSWORD",
      "valueFrom": "arn:aws:secretsmanager:eu-west-1:111122223333:secret:prod/db-AbCd" }],
    "logConfiguration": { "logDriver": "awslogs", "options": {
      "awslogs-group": "/ecs/orders", "awslogs-region": "eu-west-1",
      "awslogs-stream-prefix": "api" } } }] }

If the task fails with ResourceInitializationError while fetching the secret, fix the execution role, not the task role.

Exam-style scenario

A Fargate task fails to start with an error saying it couldn’t retrieve a Secrets Manager secret referenced in the task definition. The application role, which reads from S3, works in other tasks. The secret is encrypted with a customer managed KMS key. What should the security engineer change?

  1. A. Add secretsmanager:GetSecretValue to the task role.
  2. B. Add secretsmanager:GetSecretValue for that secret and kms:Decrypt for the key to the task execution role.
  3. C. Attach an instance profile to the Fargate task.
  4. D. Make the secret’s resource policy allow everyone in the account.
Show the worked answer

Answer: B

Secrets injected through the task definition are fetched by the agent with the execution role, which also needs the customer managed key.

Why not the others

  • A: The app doesn’t fetch this secret; the agent does.
  • C: Fargate has no instance profile you manage.
  • D: Too broad, and the execution role still lacks KMS permissions.
How the exam tests this
  • “Container app needs DynamoDB access”→ ECS task role.
  • “Task can’t pull from private ECR”→ Task execution role.
  • “Lambda needs to write logs”→ Execution role with AWSLambdaBasicExecutionRole.
  • “Pods need AWS access, no OIDC setup”→ EKS Pod Identity.
  • “User can launch EC2 but not attach a role”→ Missing iam:PassRole.
Must remember
  • Instance profile holds one role.
  • Task role = app; execution role = agent (ECR, logs, secrets).
  • Lambda execution role ≠ who can invoke.
  • Pod Identity trusts pods.eks.amazonaws.com; no Fargate.
  • Attaching a role needs iam:PassRole.
04

Patch Manager and continuous validation

Skill 3.2.4 is about keeping running compute patched and proving it. AWS Systems Manager Patch Manager scans and installs operating system patches (and some application patches) on managed nodes: EC2 instances and on-premises servers that run the SSM Agent and have permission to talk to Systems Manager. Amazon Inspector then checks continuously for known vulnerabilities.

Concept profile

Patch baseline

often confused with Patch policy
?What is it?

The rules that say which patches are approved for an operating system: classification and severity filters, an auto-approval delay or cutoff date, and lists of explicitly approved and rejected patches.

⚙How does it work?
  • AWS provides predefined baselines (for example AWS-DefaultPatchBaseline for Windows Server). Most approve critical and important security patches 7 days after release. You can’t edit them.
  • A custom baseline lets you set the delay, a cutoff date, severity for compliance reports, and approved or rejected lists. If a patch is in both lists, it is rejected.
  • Each managed node uses exactly one baseline. You can make a custom baseline the default for an OS.
  • Patching runs the AWS-RunPatchBaseline document with operation Scan (report only) or Install (patch, then reboot if needed).
  • Results become patch compliance data in Systems Manager Compliance, and can flow to AWS Config, Explorer and Security Hub.
{ }Structure
Patch policyQuick Setuporg, OUs, Regionsor one accountPatch baselinerules: class,severity, delayapprove / rejectScan schedulee.g. dailyScan onlyno rebootInstall schedulee.g. weeklyInstall + rebootif neededComplianceper account andRegion; Config,Explorer, HubBoth operations run the AWS-RunPatchBaseline document on managed nodes (SSM Agent + role).Without patch policies: maintenance window + Run Command task, one account-Region at a time.Amazon Inspector watches continuously and finds CVEs that the baseline did not approve yet.Patch Manager answers “is it patched to my rules?”; Inspector answers “is it vulnerable?”.
A patch policy ties baselines and schedules together across accounts.
⇄Patch baseline vs Patch policy
Patch baselinePatch policy
What it isWhich patches are approvedWhere and when to scan and install
ScopeOne OS typeOrg, OUs, accounts and Regions
Created inPatch ManagerQuick Setup
SchedulesNoneSeparate scan and install schedules
Needs patch groupsOlder setups used tagsNo
!Common mistakes the exam tests
  • Expecting predefined baselines to install a patch released yesterday: they wait 7 days. Create a custom baseline or add it to the approved list.
  • Running Install during business hours: schedule installs in a maintenance window or a patch policy schedule, because nodes may reboot.
  • Patching a node that isn’t managed: it needs the SSM Agent, network path to SSM (or VPC endpoints) and an instance profile like AmazonSSMManagedInstanceCore (or Default Host Management Configuration).
  • Thinking compliance means “no vulnerabilities”: it means “matches your baseline”. Use Inspector for CVEs.
  • Patching long-lived servers forever instead of also rebuilding the golden AMI.
✓Benefits and use cases
  • Central patching of every account and Region from one place.
  • Compliance reports for auditors.
  • Different schedules for scanning (daily) and installing (weekly).

Patch policies, maintenance windows and Inspector

AWS now recommends patch policies, made in Quick Setup. One patch policy can cover all accounts and Regions in AWS Organizations (or chosen OUs, or one account), with a chosen baseline for each OS and separate scan and install schedules. It doesn’t need patch groups. A maintenance window is the older, flexible way: a schedule with a duration and a cutoff, targets (instance IDs, tags or resource groups) and tasks (Run Command, Automation, Lambda or Step Functions). A maintenance window works in one account and Region. Patch now patches on demand. For continuous validation, Amazon Inspector scans EC2 instances using the SSM Agent (agent-based, rescans when new software is installed or a new CVE appears) or EBS snapshots (agentless, in hybrid mode), and also scans ECR images and Lambda functions. Findings go to Security Hub and EventBridge, so you can trigger an automatic patch run.

Think of it like · a school’s vaccination program

Keeping every pupil protected and proving it.

AWS conceptFamiliar thing
Patch baseline≈The list of approved vaccines and how long after release they may be used
Patch policy≈The ministry plan that covers every school in the country
Maintenance window≈The afternoon slot when the nurse visits one school
Scan operation≈Checking each pupil’s vaccination card
Install operation≈Actually giving the missing vaccines
Inspector≈A doctor who checks pupils for new diseases every day
Real AWS example · custom baseline and an on-demand scan

Approve critical security patches after 2 days, then scan tagged nodes and read compliance.

$ aws ssm create-patch-baseline --name al2023-fast-security \
    --operating-system AMAZON_LINUX_2023 \
    --approval-rules 'PatchRules=[{PatchFilterGroup={PatchFilters=[{Key=CLASSIFICATION,Values=[Security]},{Key=SEVERITY,Values=[Critical,Important]}]},ApproveAfterDays=2,ComplianceLevel=CRITICAL}]'

$ aws ssm send-command --document-name AWS-RunPatchBaseline \
    --targets Key=tag:Env,Values=prod --parameters Operation=Scan

$ aws ssm list-compliance-summaries --filters Key=ComplianceType,Values=Patch
ComplianceType  CompliantCount  NonCompliantCount  (Critical: 3)
Patch           118             3

Use Operation=Install inside a maintenance window or patch policy schedule, not ad hoc in production.

Exam-style scenario

A company with 60 accounts in AWS Organizations and workloads in four Regions wants all EC2 instances scanned for missing patches every day and patched every Sunday night, using one central configuration with the least effort. Auditors also want proof of patch compliance per account. What should the security engineer do?

  1. A. Create a maintenance window with a patching task in every account and Region.
  2. B. Create a Systems Manager patch policy in Quick Setup for the organization, with a daily scan schedule, a weekly install schedule and the chosen baselines; review patch compliance in Systems Manager and Security Hub.
  3. C. Run yum update with a cron job on each instance.
  4. D. Enable Amazon Inspector only.
Show the worked answer

Answer: B

Patch policies cover the whole organization and all Regions with separate scan and install schedules.

Why not the others

  • A: Works but needs 240 separate windows to build and maintain.
  • C: No central control or compliance reporting.
  • D: Inspector finds vulnerabilities but doesn’t install patches.
How the exam tests this
  • “Patch whole organization, many Regions”→ Patch policy (Quick Setup).
  • “Approve patches 3 days after release”→ Custom baseline auto-approval delay.
  • “Patch only during a weekend slot”→ Maintenance window (or install schedule).
  • “Report only, don’t change anything”→ AWS-RunPatchBaseline Scan.
  • “Continuously find new CVEs on EC2”→ Amazon Inspector.
Must remember
  • Baseline = what; policy/window = where and when.
  • Predefined baselines wait 7 days.
  • Approved + rejected → rejected.
  • Patch policies: org-wide, no patch groups.
  • Compliance ≠ no CVEs; use Inspector.
05

Session Manager: shell access with no open ports

Skill 3.2.5 asks how admins should reach instances securely. The best default answer is AWS Systems Manager Session Manager. The SSM Agent on the instance opens an outbound HTTPS connection to Systems Manager, and the admin connects through that, so the instance needs no inbound ports, no SSH keys, no bastion host and not even a public IP. Access is controlled by IAM, and every session can be logged.

Concept profile

AWS Systems Manager Session Manager

often confused with SSH through a bastion host
?What is it?

A Systems Manager tool that gives an interactive shell (or PowerShell) and port forwarding to managed nodes through the console or the AWS CLI with the Session Manager plugin.

⚙How does it work?
  • The instance needs the SSM Agent, an instance profile such as AmazonSSMManagedInstanceCore (or Default Host Management Configuration), and outbound 443 to Systems Manager, or VPC interface endpoints for ssm and ssmmessages (plus ec2messages for older agents) in a private subnet.
  • Users need IAM permission ssm:StartSession, which you can limit by instance tags and by the session document.
  • Session preferences: KMS encryption of session data (a symmetric key; both the user and the instance role need permission to use it), Run As user, idle timeout, max session duration, and shell profile.
  • Logging: session commands and output to an S3 bucket and/or CloudWatch Logs (CloudWatch can stream live). CloudTrail records who started and ended each session.
  • Port forwarding (AWS-StartPortForwardingSession) reaches a port on the instance, and AWS-StartPortForwardingSessionToRemoteHost reaches another host, such as a private RDS database, through the instance.
{ }Structure
Admin console or CLI + Session Manager plugin IAM: ssm:StartSession TLS 443 Systems Manager session preferences: KMS key, run-as user, idle timeout, logging ssm · ssmmessages outbound Instance private subnet SSM Agent + role SG: no inbound rules no SSH key, no bastion Session logs (what was typed + output) S3 bucket (encrypted) and/or CloudWatch Logs CloudWatch can stream as the session runs Not for port forwarding or SSH sessions Who and when CloudTrail: StartSession, TerminateSession Session history in the console No internet? VPC endpoints for SSM
The agent dials out; the admin rides that connection. Nothing listens for inbound traffic.
⇄Session Manager vs SSH through a bastion host
Session ManagerSSH via bastion
Inbound portsNone22 on the bastion and targets
CredentialsIAM, short-livedSSH keys to manage and rotate
Command loggingS3 / CloudWatch Logs built inYou build it yourself
Who connectedCloudTrail StartSessionBastion OS logs
Private subnet, no internetYes, with VPC endpointsNeeds a reachable bastion
!Common mistakes the exam tests
  • Opening port 22 “just in case”: Session Manager doesn’t need it. Remove the rule.
  • Expecting port forwarding or SSH-over-Session-Manager sessions to have command logs: logging isn’t available for those, because Session Manager only tunnels the encrypted traffic.
  • Turning on KMS encryption but not giving the instance profile permission to use the key: sessions fail.
  • Forgetting the ssmmessages endpoint in a private VPC: the node shows as managed but sessions can’t open.
  • Granting ssm:StartSession on *: limit it with tag conditions on the instances.
✓Benefits and use cases
  • Remove bastion hosts and SSH keys.
  • Full audit of admin commands for compliance.
  • Reach private databases through port forwarding.
Think of it like · a bank vault with a phone line

Reaching the vault without opening its door to the street.

AWS conceptFamiliar thing
SSM Agent outbound≈The vault calls the bank’s switchboard; nobody can call the vault directly
No inbound ports≈The vault has no street door at all
IAM ssm:StartSession≈The switchboard checks your staff card before connecting you
Session logs in S3≈Every word on the call is recorded and filed
KMS encryption≈The call is scrambled with the bank’s own code book
Port forwarding≈The switchboard patches you through to the room behind the vault
Real AWS example · restrict sessions by tag and use port forwarding

Allow sessions only to instances tagged Team=web, then tunnel to a private database.

{ "Version": "2012-10-17", "Statement": [
  { "Effect": "Allow", "Action": "ssm:StartSession",
    "Resource": "arn:aws:ec2:*:111122223333:instance/*",
    "Condition": { "StringEquals": { "ssm:resourceTag/Team": "web" } } },
  { "Effect": "Allow", "Action": "ssm:StartSession",
    "Resource": "arn:aws:ssm:*::document/AWS-StartPortForwardingSessionToRemoteHost" },
  { "Effect": "Allow", "Action": ["ssm:TerminateSession", "ssm:ResumeSession"],
    "Resource": "arn:aws:ssm:*:*:session/${aws:userid}-*" } ]}

$ aws ssm start-session --target i-0abc1234 \
    --document-name AWS-StartPortForwardingSessionToRemoteHost \
    --parameters host=db.cluster-xyz.eu-west-1.rds.amazonaws.com,portNumber=5432,localPortNumber=15432

The ${aws:userid} condition lets users end only their own sessions.

Exam-style scenario

A financial company must remove SSH access to its EC2 instances in private subnets with no internet access. Auditors require a record of every command administrators type, encrypted with a company-managed key, kept for one year. What should the security engineer configure?

  1. A. A bastion host with SSH key rotation and OS audit logs.
  2. B. Session Manager with VPC endpoints for ssm and ssmmessages, session preferences that encrypt with a customer managed KMS key and send logs to an encrypted S3 bucket with a one-year lifecycle, and security groups with no inbound rules.
  3. C. EC2 Instance Connect with public IP addresses.
  4. D. Session Manager port forwarding to port 22 and SSH logging.
Show the worked answer

Answer: B

Session Manager needs no inbound ports, works privately through endpoints, and logs commands to S3 with KMS.

Why not the others

  • A: Keeps SSH open and needs custom logging.
  • C: Needs public reachability on port 22 and doesn’t record commands.
  • D: SSH and port forwarding sessions aren’t logged by Session Manager.
How the exam tests this
  • “No inbound ports, no bastion, no keys”→ Session Manager.
  • “Record every command typed”→ Session logging to S3 / CloudWatch Logs.
  • “Private subnet, no NAT”→ VPC endpoints ssm + ssmmessages.
  • “Connect to private RDS from a laptop”→ Port forwarding to remote host.
  • “Who opened a session and when”→ CloudTrail StartSession.
Must remember
  • Agent dials out on 443; zero inbound.
  • Logs: S3 and/or CloudWatch Logs.
  • No command logs for port forwarding / SSH.
  • KMS: user and instance role need the key.
  • Limit StartSession by tags and document.
06

Instance Connect, Instance Connect Endpoint and Serial Console

Session Manager isn’t the only secure door. EC2 Instance Connect pushes a short-lived SSH public key, controlled by IAM. EC2 Instance Connect Endpoint (EICE) lets you SSH or RDP to instances in private subnets with no public IP and no bastion. The EC2 Serial Console is the emergency door when the instance’s network or boot is broken. The exam gives a clue in the question and expects you to pick the matching door.

Concept profile

EC2 Instance Connect Endpoint (EICE)

often confused with Bastion host
?What is it?

An identity-aware TCP proxy placed in a subnet of your VPC that lets users open a tunnel to a private IP and port of an instance, after IAM checks, with no public IP, internet gateway or bastion.

⚙How does it work?
  • Create the endpoint in a subnet; it gets a network interface and a security group. Allow that security group (or the VPC CIDR) on port 22 or 3389 in the instance security group.
  • Users call ec2-instance-connect:OpenTunnel. Conditions can limit the port (remotePort), the target IP (privateIpAddress) and the duration (maxTunnelDuration, at most 3,600 seconds).
  • A connection lasts at most 1 hour, and one endpoint has a limit of concurrent connections. It is for admin traffic, not bulk data.
  • You can use your own key pair, or EC2 Instance Connect to push a temporary key.
  • Every connection attempt, successful or not, is logged in CloudTrail. The endpoint itself has no charge.
{ }Structure
Session ManagerNetwork: outbound443 from agentInbound ports: noneAuth: IAMLogs: S3 / CWLBest defaultInstance ConnectNetwork: SSH tothe instance IPInbound: port 22Auth: key pushedfor 60 secondsCloudTrail callConnect EndpointNetwork: private,no public IP or IGWInbound: from EICEAuth: OpenTunnelPorts 22 / 3389Max 1 hourSerial ConsoleNetwork: noneneeded at allNitro, runningAccount-level onPassword userBoot, broken netPick from the clue: “no inbound ports + audit” → Session Manager; “private instance, plain SSH/RDP” → EICE;“short-lived SSH key from IAM” → Instance Connect; “instance won’t boot / no network” → Serial Console.
Four doors into an instance; the clue in the question picks one.
⇄EICE vs Bastion host
EICEBastion host
Public IP neededNoBastion needs one
Servers to patchNone (managed)The bastion itself
AuthorizationIAM OpenTunnel + conditionsSSH keys on the bastion
AuditCloudTrail per connectionBastion OS logs
CostNo charge for the endpointInstance hours
!Common mistakes the exam tests
  • Thinking EC2 Instance Connect (without the endpoint) works for private instances from the internet: it only pushes a key; you still need network reachability to port 22.
  • Forgetting that Instance Connect pushes a key valid for only 60 seconds: you must connect within that time.
  • Expecting EICE to log the commands typed: it logs connections in CloudTrail, not session content. For command logs choose Session Manager.
  • Using the Serial Console without first allowing it at the account level (it is off by default) and setting up a password-based OS user.
  • Leaving Serial Console access on for everyone: restrict it with IAM and an SCP, because it bypasses network controls.
✓Benefits and use cases
  • Plain SSH or RDP to private instances without bastions.
  • Tools that need real SSH (scp, IDE remote) with IAM control.
  • Short, auditable admin connections.

EC2 Instance Connect and the Serial Console

EC2 Instance Connect uses ec2-instance-connect:SendSSHPublicKey to push a one-time public key into instance metadata for 60 seconds; the condition key ec2:osuser limits which OS user. The instance needs the Instance Connect package (preinstalled on Amazon Linux and Ubuntu AMIs) and must be reachable on port 22, either directly or through EICE. The EC2 Serial Console connects to the instance’s serial port, so it works even when networking, SSH or the boot process is broken. It works only on Nitro-based (and most bare metal) instances in the running state, is disabled by default at the account level, and needs a password-based user on the OS (or GRUB/SysRq set up for Linux, SAC for Windows). Control it with ec2:EnableSerialConsoleAccess and ec2-instance-connect:SendSerialConsoleSSHPublicKey.

Think of it like · ways into an apartment building

Different doors for different needs.

AWS conceptFamiliar thing
Session Manager≈The concierge’s intercom: you never open the street door
Instance Connect≈A one-minute door code texted to you by the landlord
Instance Connect Endpoint≈A staff entrance from the private car park, checked by security
Serial Console≈The fire service’s emergency key box used when the doors won’t open
Bastion host≈A guard hut you must staff, lock and repair yourself
Real AWS example · SSH to a private instance through EICE

Create the endpoint once, then connect with the CLI; the tunnel is authorized by IAM.

$ aws ec2 create-instance-connect-endpoint --subnet-id subnet-0priv1 \
    --security-group-ids sg-0eice --preserve-client-ip
{ "InstanceConnectEndpoint": { "InstanceConnectEndpointId": "eice-0123456789abcdef0",
    "State": "create-in-progress", ... } }

$ aws ec2-instance-connect ssh --instance-id i-0abc1234 \
    --connection-type eice --os-user ec2-user

$ aws ec2-instance-connect open-tunnel --instance-id i-0win5678 \
    --remote-port 3389 --local-port 13389

The second command pushes a temporary key and opens the tunnel; the third forwards RDP for a Windows instance.

Exam-style scenario

An instance stopped responding after an engineer changed its network configuration. SSH, Session Manager and Instance Connect all fail because the instance has no working network. The team needs to log in and fix the configuration without replacing the instance. What should they use?

  1. A. EC2 Instance Connect Endpoint.
  2. B. EC2 Serial Console, after enabling serial console access for the account and using a password-based OS user.
  3. C. Session Manager port forwarding.
  4. D. Reboot the instance and wait.
Show the worked answer

Answer: B

The serial console reaches the instance through its serial port, without any network.

Why not the others

  • A: Still needs the instance’s network to accept TCP on 22.
  • C: Session Manager needs the agent to reach Systems Manager over the network.
  • D: The broken configuration stays after a reboot.
How the exam tests this
  • “Private instance, plain SSH/RDP, no bastion”→ EC2 Instance Connect Endpoint.
  • “Short-lived SSH key controlled by IAM”→ EC2 Instance Connect (60 s key).
  • “Limit EICE to port 22 and one subnet”→ Conditions remotePort, privateIpAddress.
  • “Network or boot broken, need console”→ EC2 Serial Console.
  • “Need command-level logs”→ Session Manager, not EICE.
Must remember
  • Instance Connect key lives 60 seconds.
  • EICE: OpenTunnel, no public IP, max 1 hour.
  • EICE logs connections, not commands.
  • Serial Console: off by default, Nitro, running, password user.
  • Serial Console works with no network.
07

Cheatsheet extras: EC2 key pairs, dedicated tenancy and hypervisor isolation

Your cheat sheet has a whole chapter on EC2 security that sections 01–06 only touched: how SSH key pairs really work (and why deleting one doesn’t lock anyone out), Dedicated Instances vs Dedicated Hosts, and what the hypervisor does to keep customers apart. These come up as “who can still log in?” and “which tenancy meets the licence or compliance rule?” questions.

Concept profile

EC2 key pair

often confused with a KMS asymmetric key
?What is it?

A public/private key pair (RSA or ED25519) for logging in to an instance. AWS stores only the public key; you keep the private .pem file. On Windows, the private key decrypts the initial Administrator password.

⚙How does it work?
  • Create it in EC2, or generate it yourself (ssh-keygen, OpenSSL) and import only the public key.
  • At first boot, cloud-init copies the public key into ~/.ssh/authorized_keys of the default user. After that, the instance doesn’t ask AWS again.
  • Add more users or keys by editing authorized_keys on the instance.
  • You can’t change the key pair of a running instance from the console or API.
  • Deleting a key pair in EC2 only removes AWS’s copy; existing instances still accept the old private key.
  • ED25519 keys don’t work for Windows password decryption.
{ }Structure
Your laptop private key: mykey.pem chmod 400 mykey.pem Lose it = lose access EC2 key pair store public key only used at launch time deleting it ≠ revoking copied once at first boot The instance ~/.ssh/authorized_keys every public key listed here can log in Revoke = delete the line (Run Command for many instances) Better: Session Manager ssh -i mykey.pem ec2-user@host KMS can’t do this KMS private keys never leave KMS, so ssh can’t use them as a .pem
The private key stays with you; the instance trusts whatever is in authorized_keys.
⇄EC2 key pair vs KMS asymmetric key
EC2 key pairKMS asymmetric key
Private keyDownloaded once by youNever leaves KMS HSMs
Used forSSH login, Windows passwordSign/verify, encrypt/decrypt through the KMS API
RevocationEdit authorized_keys on each instanceKey policy, disable or schedule deletion
Logged in CloudTrailOnly create/import/delete key pair callsEvery use of the key
!Common mistakes the exam tests
  • “Delete the key pair in the console” to stop a former employee: it doesn’t remove the public key from instances.
  • “Change the key pair with modify-instance-attribute”: there is no such option.
  • “Change the AMI’s key pair and reboot”: running instances aren’t affected.
  • Storing private keys in user data, AMIs or a shared S3 bucket.
  • Lost key, no other access: stop the instance, attach its root volume to a helper instance, edit authorized_keys (or use Session Manager / EC2 Instance Connect if set up).
✓Benefits and use cases
  • Break-glass login when Systems Manager is down.
  • Import keys from your own PKI or HSM process.
  • Rotate at scale with Run Command; store needed keys in Secrets Manager or Parameter Store.
Concept profile

Dedicated Hosts

often confused with Dedicated Instances
?What is it?

A whole physical server allocated to your account. You see its sockets and cores and choose which instances land on it.

⚙How does it work?
  • Allocate a host, then launch with tenancy host. Host affinity keeps an instance on the same host after stop/start.
  • Lets you use server-bound licences (per socket or per core, for example Windows Server, SQL Server, Oracle) and meet rules that demand a known physical server.
  • Billed per host, whatever runs on it. Can be shared across accounts with AWS RAM.
  • Dedicated Instances (tenancy dedicated) also run on hardware no other customer uses, but you don’t pick or see the host; billed per instance plus a per-Region fee.
  • VPC tenancy dedicated forces every instance in that VPC to be dedicated.
⇄Dedicated Host vs Dedicated Instance vs default
Dedicated HostDedicated InstanceDefault (shared)
Other customers on the serverNoNoYes (isolated by the hypervisor)
See sockets/cores, control placementYesNoNo
Bring your own per-socket/core licenceYesNoNo
BillingPer hostPer instance + Region feePer instance
Exam hint“existing server-bound licences”, “same physical server”“hardware not shared with other customers”, no licence detailEverything else
!Common mistakes the exam tests
  • Choosing Dedicated Instances for BYOL per-core licences: you need Dedicated Hosts.
  • Thinking dedicated tenancy is required for security: Nitro isolation is strong enough for most compliance; dedicated is for licences or explicit rules.
  • Expecting Dedicated Instances to be alone even among your own account’s non-dedicated instances: they can share hardware with your other instances.
✓Benefits and use cases
  • Oracle or SQL Server licences tied to physical cores.
  • A regulator that requires single-tenant hardware.
  • Predictable placement for audits.

The hypervisor and the shared responsibility line

The hypervisor is the layer that creates virtual machines on a physical host and keeps them apart. Older material (the cheat sheet included) describes the Xen hypervisor, PV vs HVM guests and CPU “rings”. Today almost all instance types run on the AWS Nitro System: dedicated Nitro cards handle networking, storage and security, and a minimal KVM-based Nitro Hypervisor handles only CPU and memory. Use HVM AMIs; PV is legacy.

FactWhat to remember
AWS operator accessNitro has no mechanism for anyone, including AWS staff, to log in to the host or read guest memory. Older material: admins need MFA, hardened admin hosts, all access logged.
Memory scrubbingMemory is zeroed when it is taken away from a guest, before it can go to another customer.
Storage scrubbingEBS blocks are wiped before reuse (not at the moment you delete the volume). Nitro instance store NVMe data is encrypted with keys destroyed when the instance stops.
Hypervisor-level firewallSecurity groups are enforced outside the guest OS, so a root user inside the instance can’t turn them off.
Customer sideYou fully control the guest OS: patches, users, host firewall, keys. AWS has no access to it.
Think of it like · an apartment building

Many tenants, one landlord, and very solid walls.

AWS conceptFamiliar thing
Key pair public key≈The lock fitted to your door; the private key is the key in your pocket
authorized_keys≈The list of keys the lock accepts; to lock someone out you change the lock, not the landlord’s spare-key list
Deleting the EC2 key pair≈The landlord shreds the copy of your lock design; the lock on the door still works
Dedicated Instance≈A building only your company lives in, but you don’t pick the floor
Dedicated Host≈Renting the whole building and choosing which flat each person gets
Nitro hypervisor≈Soundproof walls and a landlord with no master key
Real AWS example · revoke a leaked key on many instances

Run Command removes the old public key and adds a new one on every instance tagged team=payments. No SSH session needed.

$ aws ssm send-command --document-name "AWS-RunShellScript" \
    --targets "Key=tag:team,Values=payments" \
    --parameters 'commands=[
      "sed -i \"/old-dev-key/d\" /home/ec2-user/.ssh/authorized_keys",
      "echo \"ssh-ed25519 AAAAC3Nz...new ops-2026\" >> /home/ec2-user/.ssh/authorized_keys"
    ]' --comment "Rotate SSH key after offboarding"

$ aws ec2 delete-key-pair --key-name old-dev-key   # only removes AWS's copy

The first command is what actually locks the developer out. The second only tidies up the EC2 key pair list.

Exam-style scenario

A company must move an Oracle database to EC2 and reuse its existing Oracle licences, which are counted per physical core. The auditor also wants proof of which physical server the database ran on. Which option meets both needs?

  1. A. Dedicated Instances in a VPC with dedicated tenancy.
  2. B. Dedicated Hosts with host affinity, using the host ID in records.
  3. C. Default tenancy with a placement group.
  4. D. Default tenancy with Nitro Enclaves.
Show the worked answer

Answer: B

Only Dedicated Hosts expose sockets and cores for per-core licensing and keep the instance on a known physical server.

Why not the others

  • A: Single-tenant, but no visibility of cores or host.
  • C: Placement groups control spread, not tenancy or licensing.
  • D: Enclaves isolate data processing; they don’t solve licensing.
How the exam tests this
  • “Fired developer still has the .pem”→ Replace the public key in authorized_keys on each instance (Run Command at scale).
  • “Use KMS for SSH”→ Not possible; KMS private keys can’t be exported.
  • “Existing per-socket/per-core licences”→ Dedicated Hosts.
  • “No other customer on the hardware, nothing about licences”→ Dedicated Instances.
  • “Can AWS staff read my instance memory?”→ No: Nitro has no operator access; memory is scrubbed.
  • “Who patches the guest OS?”→ You (shared responsibility).
Must remember
  • AWS keeps the public key only; deleting the key pair ≠ revoking access.
  • Revoke = edit authorized_keys.
  • Dedicated Host = licences + placement; Dedicated Instance = just single-tenant.
  • Nitro: no operator access, memory zeroed, EBS wiped before reuse.
  • Use HVM AMIs; Xen/PV is legacy.
08

Lecture summary map

Day 4 on one screen.

1. Mind map

① Golden imagesImage Builder pipelineBuild + test componentsNo secrets in images② IMDSv2Token: PUT then GETHop limit 2 containersSCP MetadataHttpTokens③ Compute rolesInstance profileTask vs execution rolePod Identity, PassRole④ PatchingBaseline = whatPatch policy = org-wideInspector = CVEs⑤ Session ManagerNo inbound portsLogs to S3 / CWLPort forwarding⑥ Other doorsInstance Connect 60 sEICE: private, 1 hSerial Console: no netInfra Security 4hardening + access
Tap a branch to jump back to that part of the lecture. Try redrawing this map from memory on paper.

2. Match the requirement to the control

“Every new server must start hardened”→Image Builder golden AMI“Stop SSRF from stealing role credentials”→IMDSv2 required“No instance may launch with IMDSv1”→SCP on ec2:MetadataHttpTokens“App in a container needs S3 access”→ECS task role“Task can’t pull the image or secret”→ECS task execution role“Patch all accounts and Regions”→Patch policy (Quick Setup)“No inbound ports, log every command”→Session Manager + S3/CWL“Instance won’t boot, fix GRUB”→EC2 Serial Console
The left column is the exam wording; the right column is the answer.

3. “If the question says… pick…”

Same hardened baseline for every new serverImage Builder golden AMI
Hardening to DoD standardImage Builder STIG components
SSRF leaked instance credentialsRequire IMDSv2
Containers on EC2 lost IMDS accessHop limit 2
App in ECS gets AccessDenied on S3Fix the task role
Task can’t pull image or inject secretFix the task execution role
Can launch EC2 but can’t attach the roleGrant iam:PassRole
Patch every account and Region centrallyPatch policy in Quick Setup
Approve patches sooner than 7 daysCustom patch baseline
No open ports and full command auditSession Manager + S3/CloudWatch logs
Plain SSH to private instance, no bastionEC2 Instance Connect Endpoint
Broken network or bootEC2 Serial Console
Day 4 in one sentence

Launch from a hardened image, lock credentials with IMDSv2 and small roles, keep it patched, and get in only through doors that need no open ports.

09

Must-remember cheat sheet

1. Harden in the image with Image Builder.
2. Image Builder: tests must pass before distribution.
3. Shared encrypted AMI: share the customer managed key.
4. IMDSv2: PUT token, then GET with header.
5. Hop limit 2 for containers on EC2.
6. SCP: deny RunInstances unless ec2:MetadataHttpTokens = required.
7. Account IMDS default: per Region, new instances only.
8. ECS task role = app; execution role = ECR, logs, secrets.
9. Instance profile holds one role; launch needs iam:PassRole.
10. Pod Identity: pods.eks.amazonaws.com, no OIDC, no Fargate.
11. Predefined baselines wait 7 days.
12. Patch policy: org-wide, scan and install schedules.
13. Session Manager: no inbound ports; logs to S3 / CWL.
14. No command logs for port forwarding / SSH sessions.
15. Instance Connect key: 60 s. EICE tunnel: max 1 h.
16. Serial Console: off by default, works with no network.
17. Deleting a key pair ≠ revoking: edit authorized_keys.
18. BYOL per core → Dedicated Host.
19. Nitro: no operator access, memory zeroed.
10

Core quiz

Check the basics first. Pick an answer, then press Check.

11

Hard quiz

Harder than most real exam questions on purpose, with one “choose two” and one matching question. Aim for 9 out of 12 before Day 5.

12

Practice test questions (from your mock exams)

These 8 questions come from your own SCS-003 mock exams, matched to today’s topics. Each one was checked against current AWS behaviour: where a mock answer used old features (OAI, Classic Load Balancer, Inspector Classic) the wording was updated, and the explanation says so. The source is shown at the end of each explanation, for example “(Mock 5 · Q12)”.

13

Hands-on lab (30 minutes, low cost)

  1. Create an IAM role for EC2 with AmazonSSMManagedInstanceCore. Launch a t3.micro (or t4g.micro) Amazon Linux 2023 instance with this instance profile, no key pair, a security group with no inbound rules, and metadata set to IMDSv2 required.
  2. Open Session Manager from the console. Run TOKEN=$(curl -s -X PUT http://169.254.169.254/latest/api/token -H "X-aws-ec2-metadata-token-ttl-seconds: 300"), then curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/iam/info. Try the same GET without the token and see the 401.
  3. In Session Manager Preferences, turn on logging to a CloudWatch Logs group, start a new session, type a few commands, and find them in the log group. Find the StartSession event in CloudTrail.
  4. In Patch Manager, run Patch now with operation Scan on the instance and open the patch compliance report.
  5. Run aws ec2 get-instance-metadata-defaults to see your account’s IMDS default in this Region (change it only if you understand the effect on your other launches).
  6. Clean up: terminate the instance, delete the log group, and remove any patch policy or maintenance window you created. Inspector, KMS keys and an EICE in another AZ can add small charges; don’t leave them running in a personal account.
Official sources: Session Manager Use IMDSv2