Lesson 072 · AWS Learning Path

AWS 072: Launch and connect to EC2 with a role, user data, and IMDSv2

· Published · 23 min read

Human, workload, and federated identities pass authentication before authorization grants cloud access

1. Real-world scenario

A small operations team needs a Linux application server in AWS. The server must:

  • launch in the VPC and public subnet built earlier in Project P04;
  • receive temporary AWS permissions through an IAM role;
  • configure itself at first boot with user data;
  • require IMDSv2 for instance metadata;
  • support administration through AWS Systems Manager Session Manager;
  • have no inbound SSH or RDP rule;
  • prove that the operating system, bootstrap process, web service, role, and metadata controls are working;
  • be removed safely when the lab ends.

This is a learning server, not a production design. A production workload would normally add a launch template, multiple instances across Availability Zones, load balancing, monitoring, backup, patching, vulnerability management, and a controlled deployment process.

2. Learning objective and final outcome

By the end of this lesson, the student can:

  1. explain every important EC2 launch input;
  2. create an EC2 service role and instance profile;
  3. launch one Amazon Linux 2023 instance with exact network, storage, identity, tag, user-data, and metadata settings;
  4. connect through Session Manager without opening inbound TCP 22;
  5. verify cloud-init, Apache, SSM Agent, the instance profile, and IMDSv2;
  6. diagnose the most common launch and connection failures;
  7. either preserve the instance briefly for AWS 073 or remove all chargeable resources.

The lab is complete only when the student produces both technical evidence and cleanup evidence.

3. Final architecture

 Student
   |
   | AWS Console and pre-authenticated AWS CloudShell
   v
 AWS APIs: EC2, IAM and Systems Manager
   |
   +---------------- IAM control -------------------+
   |                                                |
   |  Instance profile: nw-p04-ec2-ssm              |
   |  Role: nw-p04-ec2-ssm                          |
   |  Policy: AmazonSSMManagedInstanceCore           |
   |                                                |
   +-----------------------+------------------------+
                           |
                           v
 VPC: nw-p04-vpc, 10.42.0.0/16
   |
   +-- Public subnet: nw-p04-public-a, 10.42.10.0/24
       |
       +-- Route 0.0.0.0/0 -> Internet gateway
       |
       +-- Security group: nw-p04-ec2-sg
       |     Inbound: none
       |     Outbound: allowed for this learning lab
       |
       +-- EC2: nw-p04-web-1
             Amazon Linux 2023, x86_64
             t3.micro
             Temporary public IPv4 for outbound connectivity
             8 GiB encrypted gp3 root volume
             SSM Agent -> Systems Manager over outbound HTTPS
             cloud-init -> installs and starts Apache
             IMDS endpoint -> IMDSv2 token required

The public IPv4 address is not an administration path. There is no inbound SSH rule. The address gives the instance an inexpensive, short-lived outbound path through the internet gateway so that SSM Agent and the package manager can reach their service endpoints. A private production instance would normally use an approved egress path or interface VPC endpoints instead.

4. Prerequisites, permissions, Region, and cost warning

Required prior work

The student must already have:

  • completed the account, billing, Console, CloudShell, CLI, IAM, VPC, EC2, user-data, IMDSv2, EBS, and snapshot concept lessons;
  • created the Project P04 VPC and public subnet;
  • created a security group with no inbound rules;
  • verified that the public subnet has a route to an internet gateway;
  • configured a budget alert;
  • signed in with an administrative learning identity, not the AWS account root user.

Required permissions

The learning identity needs the relevant permissions for:

  • EC2 describe, run, tag, wait, connect, stop and terminate operations;
  • IAM role, managed-policy attachment, instance-profile, and cleanup operations;
  • iam:PassRole for the specific nw-p04-ec2-ssm role;
  • Systems Manager managed-node discovery and starting a session.

If an organization supplies the account, the instructor should provide a scoped lab policy. Do not solve AccessDenied by using the root user.

Exact values for this sample

SettingLab valueWhy
Regionap-south-1One fixed Region prevents accidental cross-Region resources
VPCnw-p04-vpcExisting Project P04 network
VPC CIDR10.42.0.0/16Existing Project P04 address range
Subnetnw-p04-public-aShort-lived outbound path without a NAT gateway
Subnet CIDR10.42.10.0/24Existing Project P04 public subnet
Security groupnw-p04-ec2-sgNo inbound rules; outbound access for the lab
Instance namenw-p04-web-1Predictable evidence and cleanup
AMILatest AWS-provided Amazon Linux 2023 x86_64 AMICurrent AWS image with cloud-init and normally preinstalled SSM Agent
Instance typet3.microSmall learning instance; verify availability and current price
Key pairNoneSession Manager is the administration path
IAM role and profilenw-p04-ec2-ssmTemporary permissions for SSM Agent
Root volume8 GiB, gp3, encrypted, delete on terminationSmall encrypted root device with explicit cleanup behavior
Public IPv4Enabled temporarilyShort-lived outbound connectivity; it can create a charge
IMDS endpointEnabledThe instance uses metadata and its role
Metadata versionV2 only, token requiredReject tokenless IMDSv1 requests
Metadata hop limit1Appropriate for this non-container host
Tags in metadataDisabledNot required for this lab
Detailed monitoringDisabledAvoid unnecessary lab cost
Termination protectionDisabledThe cleanup exercise must be possible

If t3.micro is unavailable in the selected Availability Zone, choose another small current type that is compatible with the x86_64 AMI. Record the substitution and explain it.

Cost gate

Before clicking Launch instance:

  1. Open AWS Pricing Calculator or the EC2 pricing page for ap-south-1.
  2. Estimate 60 minutes of active EC2 for this lesson, the planned active intervals through AWS 079, 8 GiB of gp3 EBS retained through AWS 080, and a public IPv4 address during every running interval.
  3. Record the per-lesson estimate and the maximum Project P04 cost envelope.
  4. Set a 60-minute running-resource timer.

Free Tier eligibility and credits differ by account and date. Never promise that this lab is free.

Potential charges include:

  • EC2 while the instance is running;
  • EBS until the volume is deleted;
  • the public IPv4 address while assigned;
  • data transfer or additional services if the student changes the design.

IAM roles, instance profiles, security groups, and this small amount of user data do not have an hourly resource charge. A budget alert reports spend but does not stop resources automatically.

Preflight in CloudShell

Open AWS CloudShell from the AWS Console. CloudShell already has AWS CLI v2 and uses the signed-in Console identity.

NW_REGION="ap-south-1"
NW_VPC_NAME="nw-p04-vpc"
NW_SUBNET_NAME="nw-p04-public-a"
NW_SG_NAME="nw-p04-ec2-sg"

aws --version

aws sts get-caller-identity \
  --region "$NW_REGION" \
  --query 'Arn' \
  --output text

Expected result:

  • aws --version reports AWS CLI version 2.
  • The second command returns the ARN of the signed-in learning identity.
  • Do not publish the account ID from that ARN.

Discover the resources created in AWS 060:

NW_VPC_ID=$(
  aws ec2 describe-vpcs \
    --region "$NW_REGION" \
    --filters "Name=tag:Name,Values=$NW_VPC_NAME" \
    --query 'Vpcs[0].VpcId' \
    --output text
)

NW_SUBNET_ID=$(
  aws ec2 describe-subnets \
    --region "$NW_REGION" \
    --filters \
      "Name=vpc-id,Values=$NW_VPC_ID" \
      "Name=tag:Name,Values=$NW_SUBNET_NAME" \
    --query 'Subnets[0].SubnetId' \
    --output text
)

NW_SG_ID=$(
  aws ec2 describe-security-groups \
    --region "$NW_REGION" \
    --filters \
      "Name=vpc-id,Values=$NW_VPC_ID" \
      "Name=group-name,Values=$NW_SG_NAME" \
    --query 'SecurityGroups[0].GroupId' \
    --output text
)

printf 'VPC=%s\nSubnet=%s\nSecurityGroup=%s\n' \
  "$NW_VPC_ID" "$NW_SUBNET_ID" "$NW_SG_ID"

Expected result: one ID beginning with vpc-, one with subnet-, and one with sg-.

If any value is None, empty, or from another VPC, stop. Correct AWS 060 before launching an instance.

Inspect the subnet and security group:

aws ec2 describe-subnets \
  --region "$NW_REGION" \
  --subnet-ids "$NW_SUBNET_ID" \
  --query 'Subnets[0].{VpcId:VpcId,AZ:AvailabilityZone,CIDR:CidrBlock,AvailableIPs:AvailableIpAddressCount,AutoPublicIPv4:MapPublicIpOnLaunch}' \
  --output table

aws ec2 describe-security-groups \
  --region "$NW_REGION" \
  --group-ids "$NW_SG_ID" \
  --query 'SecurityGroups[0].{VpcId:VpcId,Inbound:IpPermissions,Outbound:IpPermissionsEgress}' \
  --output json

Required interpretation:

  • The VPC IDs must match.
  • The subnet must have available IPv4 addresses.
  • An empty Inbound list is correct for this lab.
  • The lab needs outbound DNS and HTTPS access.
  • AutoPublicIPv4 does not control the explicit per-instance choice used below.

In the VPC Console, also verify that the subnet's effective route table has 0.0.0.0/0 targeting the Project P04 internet gateway.

5. AWS Management Console lab

Use this as the primary beginner path.

Part A: Create the EC2 role

  1. Open IAM.
  2. Choose Roles, then Create role.
  3. For trusted entity type, choose AWS service.
  4. For service or use case, choose EC2.
  5. Add the AWS managed policy AmazonSSMManagedInstanceCore.
  6. Set the role name to nw-p04-ec2-ssm.
  7. Add these tags:
  • Project = NitWings-P04
  • Environment = Lab
  1. Review the trust relationship. Its service principal must be ec2.amazonaws.com.
  2. Create the role.

The IAM Console creates an instance profile with the same name and places the role in it. The instance profile is the object selected during EC2 launch.

Part B: Prepare the user-data script

Copy this exact script. It contains no password, access key, token, account ID, or other secret.

#!/bin/bash
set -euxo pipefail

dnf install -y httpd

cat > /var/www/html/index.html <<'HTML'
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>NitWings EC2 Lab</title>
</head>
<body>
  <h1>NitWings EC2 lab is ready</h1>
  <p>Amazon Linux 2023 completed the AWS 072 bootstrap.</p>
</body>
</html>
HTML

systemctl enable --now httpd
printf 'AWS 072 bootstrap complete\n' > /var/lib/nitwings-aws-072-ready

User data is not a secret store. Encoding performed by the Console or CLI is not encryption.

Part C: Launch the instance

  1. Open EC2, select ap-south-1, choose Instances, then Launch instances.
  2. Under Name and tags:
  • Name: nw-p04-web-1
  • Add Project = NitWings-P04
  • Add Environment = Lab
  • Add DeleteAfterLesson = AWS080
  • Apply the project tags to the instance and volume.
  1. Under Application and OS Images:
  • Choose Quick Start
  • Choose Amazon Linux
  • Select the latest AWS-provided Amazon Linux 2023 AMI
  • Confirm architecture 64-bit (x86)
  1. Under Instance type, choose t3.micro.
  2. Under Key pair, choose Proceed without a key pair.
  3. Under Network settings, choose Edit:
  • VPC: nw-p04-vpc
  • Subnet: nw-p04-public-a
  • Auto-assign public IP: Enable
  • Firewall: Select existing security group
  • Security group: nw-p04-ec2-sg
  • Confirm there are no inbound rules.
  1. Under Configure storage:
  • Size: 8 GiB
  • Type: gp3
  • Encrypted: enabled
  • Delete on termination: enabled
  1. Expand Advanced details:
  • IAM instance profile: nw-p04-ec2-ssm
  • Shutdown behavior: Stop
  • Termination protection: disabled
  • Detailed CloudWatch monitoring: disabled
  • Tenancy: shared
  • Metadata accessible: enabled
  • Metadata version: V2 only (token required)
  • Metadata response hop limit: 1
  • Allow tags in instance metadata: disabled
  • User data: paste the script exactly as plain text
  1. Review the Summary. Confirm that only one instance will launch.
  2. Choose Launch instance.
  3. Open the instance details and privately record its instance ID.

The DeleteAfterLesson=AWS080 tag is a label, not automation. The learner must still stop the instance between study sessions and complete the deletion workflow in AWS 080.

Part D: Wait for readiness

Wait for:

  • instance state: Running;
  • system status check: passed;
  • instance status check: passed.

Then open Systems Manager, choose Fleet Manager, and verify that the instance appears as an online managed node. Registration can take several minutes after EC2 reports Running.

Part E: Connect without SSH

  1. In Systems Manager, choose Session Manager.
  2. Choose Start session.
  3. Select nw-p04-web-1.
  4. Enter the reason AWS 072 verification.
  5. Start the session.

Do not add inbound TCP 22 merely because the instance takes time to appear.

6. Matching CloudShell and AWS CLI build

This is the equivalent CLI path. It is not an instruction to create a second simultaneous instance.

Choose one:

  • build through the Console and use CLI for inspection; or
  • terminate the Console-built instance, then repeat the build with CLI.

Part A: Create the role and instance profile

If the Console path already created nw-p04-ec2-ssm, reuse it and skip this part.

Create nw-p04-ec2-trust.json in CloudShell:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Run:

aws iam create-role \
  --role-name nw-p04-ec2-ssm \
  --assume-role-policy-document file://nw-p04-ec2-trust.json \
  --tags Key=Project,Value=NitWings-P04 Key=Environment,Value=Lab

aws iam attach-role-policy \
  --role-name nw-p04-ec2-ssm \
  --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

aws iam create-instance-profile \
  --instance-profile-name nw-p04-ec2-ssm

aws iam add-role-to-instance-profile \
  --instance-profile-name nw-p04-ec2-ssm \
  --role-name nw-p04-ec2-ssm

aws iam get-instance-profile \
  --instance-profile-name nw-p04-ec2-ssm \
  --query 'InstanceProfile.{Name:InstanceProfileName,Role:Roles[0].RoleName}' \
  --output table

Expected result: both the instance profile and contained role are named nw-p04-ec2-ssm.

IAM changes can take a short time to propagate. If EC2 reports that the profile is invalid immediately after creation, verify the profile again and retry after it becomes visible. Do not create duplicate roles.

Part B: Save the user-data script

Save the Part B script as nw-p04-user-data.sh in CloudShell. Confirm its first line and size:

head -n 1 nw-p04-user-data.sh
wc -c nw-p04-user-data.sh

Expected result:

  • first line: #!/bin/bash;
  • size: far below the EC2 Linux raw user-data limit.

Part C: Resolve the current AMI and root device

NW_AMI_ID=$(
  aws ssm get-parameter \
    --region "$NW_REGION" \
    --name /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 \
    --query 'Parameter.Value' \
    --output text
)

NW_ROOT_DEVICE=$(
  aws ec2 describe-images \
    --region "$NW_REGION" \
    --image-ids "$NW_AMI_ID" \
    --query 'Images[0].RootDeviceName' \
    --output text
)

NW_BLOCK_DEVICE="DeviceName=${NW_ROOT_DEVICE},Ebs={VolumeSize=8,VolumeType=gp3,Encrypted=true,DeleteOnTermination=true}"

printf 'AMI=%s\nRootDevice=%s\n' "$NW_AMI_ID" "$NW_ROOT_DEVICE"

Expected result: an AMI ID beginning with ami- and a valid root-device name. Resolving the AWS public parameter avoids placing a soon-obsolete AMI ID in the lesson.

Part D: Test authorization

Run the launch with --dry-run first:

aws ec2 run-instances \
  --region "$NW_REGION" \
  --image-id "$NW_AMI_ID" \
  --instance-type t3.micro \
  --subnet-id "$NW_SUBNET_ID" \
  --security-group-ids "$NW_SG_ID" \
  --associate-public-ip-address \
  --iam-instance-profile Name=nw-p04-ec2-ssm \
  --metadata-options "HttpEndpoint=enabled,HttpTokens=required,HttpPutResponseHopLimit=1,InstanceMetadataTags=disabled" \
  --block-device-mappings "$NW_BLOCK_DEVICE" \
  --user-data file://nw-p04-user-data.sh \
  --count 1 \
  --dry-run

Expected result: DryRunOperation. AWS intentionally returns it as an error-shaped response to say that the caller appears authorized.

UnauthorizedOperation means the learning identity lacks a required permission. A dry run does not prove that capacity, quota, bootstrap, network connectivity, or runtime health will succeed.

Part E: Launch exactly one instance

NW_INSTANCE_ID=$(
  aws ec2 run-instances \
    --region "$NW_REGION" \
    --image-id "$NW_AMI_ID" \
    --instance-type t3.micro \
    --subnet-id "$NW_SUBNET_ID" \
    --security-group-ids "$NW_SG_ID" \
    --associate-public-ip-address \
    --iam-instance-profile Name=nw-p04-ec2-ssm \
    --metadata-options "HttpEndpoint=enabled,HttpTokens=required,HttpPutResponseHopLimit=1,InstanceMetadataTags=disabled" \
    --block-device-mappings "$NW_BLOCK_DEVICE" \
    --user-data file://nw-p04-user-data.sh \
    --instance-initiated-shutdown-behavior stop \
    --tag-specifications \
      'ResourceType=instance,Tags=[{Key=Name,Value=nw-p04-web-1},{Key=Project,Value=NitWings-P04},{Key=Environment,Value=Lab},{Key=DeleteAfterLesson,Value=AWS080}]' \
      'ResourceType=volume,Tags=[{Key=Name,Value=nw-p04-web-1-root},{Key=Project,Value=NitWings-P04},{Key=Environment,Value=Lab},{Key=DeleteAfterLesson,Value=AWS080}]' \
    --count 1 \
    --query 'Instances[0].InstanceId' \
    --output text
)

printf 'InstanceId=%s\n' "$NW_INSTANCE_ID"

Immediately start the 60-minute running-resource timer.

Wait for the instance and both EC2 status checks:

aws ec2 wait instance-running \
  --region "$NW_REGION" \
  --instance-ids "$NW_INSTANCE_ID"

aws ec2 wait instance-status-ok \
  --region "$NW_REGION" \
  --instance-ids "$NW_INSTANCE_ID"

The waiters print no output when the target state is reached. A nonzero exit requires inspection rather than blind repetition.

Console-to-CLI mapping

Console choiceCLI parameter
Amazon Linux 2023 AMI--image-id "$NW_AMI_ID"
t3.micro--instance-type t3.micro
Public subnet--subnet-id "$NW_SUBNET_ID"
Existing security group--security-group-ids "$NW_SG_ID"
Enable public IPv4--associate-public-ip-address
IAM instance profile--iam-instance-profile Name=nw-p04-ec2-ssm
IMDSv2 requiredHttpTokens=required
Metadata endpoint enabledHttpEndpoint=enabled
Hop limit 1HttpPutResponseHopLimit=1
User-data text box--user-data file://nw-p04-user-data.sh
Encrypted 8 GiB gp3 root--block-device-mappings "$NW_BLOCK_DEVICE"
Instance and volume tags--tag-specifications

7. Verification and expected output

Verify launch settings from CloudShell

aws ec2 describe-instances \
  --region "$NW_REGION" \
  --instance-ids "$NW_INSTANCE_ID" \
  --query 'Reservations[0].Instances[0].{State:State.Name,AZ:Placement.AvailabilityZone,Type:InstanceType,Subnet:SubnetId,Profile:IamInstanceProfile.Arn,HttpTokens:MetadataOptions.HttpTokens,HopLimit:MetadataOptions.HttpPutResponseHopLimit,MetadataTags:MetadataOptions.InstanceMetadataTags,RootDevice:RootDeviceName}' \
  --output table

Required values:

  • State: running;
  • Type: t3.micro, unless an approved substitute was recorded;
  • Subnet: the Project P04 public subnet;
  • Profile: an ARN ending in instance-profile/nw-p04-ec2-ssm;
  • HttpTokens: required;
  • HopLimit: 1;
  • MetadataTags: disabled.

Verify the root EBS deletion setting:

aws ec2 describe-instances \
  --region "$NW_REGION" \
  --instance-ids "$NW_INSTANCE_ID" \
  --query 'Reservations[0].Instances[0].BlockDeviceMappings[].Ebs.{VolumeId:VolumeId,Status:Status,DeleteOnTermination:DeleteOnTermination}' \
  --output table

Required value: DeleteOnTermination is True.

Check Systems Manager registration:

aws ssm describe-instance-information \
  --region "$NW_REGION" \
  --filters "Key=InstanceIds,Values=$NW_INSTANCE_ID" \
  --query 'InstanceInformationList[0].{PingStatus:PingStatus,Platform:PlatformName,AgentVersion:AgentVersion}' \
  --output table

Expected result: PingStatus becomes Online. If no row appears immediately, use the troubleshooting section.

Verify inside the Session Manager shell

Run:

whoami
hostnamectl
sudo systemctl is-active amazon-ssm-agent
sudo cloud-init status --wait
sudo systemctl is-active httpd
curl -sS http://127.0.0.1/
sudo cat /var/lib/nitwings-aws-072-ready

Expected evidence:

  • the session normally starts as ssm-user;
  • the operating system identifies as Amazon Linux 2023;
  • SSM Agent is active;
  • cloud-init reports status: done;
  • Apache is active;
  • the local HTTP request contains NitWings EC2 lab is ready;
  • the marker file contains AWS 072 bootstrap complete.

If cloud-init did not finish successfully:

sudo tail -n 80 /var/log/cloud-init-output.log
sudo journalctl -u cloud-init -u cloud-final --no-pager -n 80

Do not rerun the entire user-data script blindly. Identify the failed command first.

Verify IMDSv2

Inside the instance:

NW_IMDS_TOKEN=$(
  curl -sS -X PUT \
    -H 'X-aws-ec2-metadata-token-ttl-seconds: 60' \
    http://169.254.169.254/latest/api/token
)

NW_METADATA_INSTANCE_ID=$(
  curl -sS \
    -H "X-aws-ec2-metadata-token: $NW_IMDS_TOKEN" \
    http://169.254.169.254/latest/meta-data/instance-id
)

printf 'MetadataInstanceId=%s\n' "$NW_METADATA_INSTANCE_ID"

curl -sS -o /dev/null -w 'TokenlessHTTP=%{http_code}\n' \
  http://169.254.169.254/latest/meta-data/instance-id

Required result:

  • the token-authenticated request returns the current instance ID;
  • the tokenless request returns HTTP 401.

Never retrieve or publish the values under the metadata role-credential path.

Verify only the attached role name:

curl -sS \
  -H "X-aws-ec2-metadata-token: $NW_IMDS_TOKEN" \
  http://169.254.169.254/latest/meta-data/iam/security-credentials/

Expected result: nw-p04-ec2-ssm.

8. Why the design works

AMI and instance type

The AMI supplies the bootable operating-system image. The instance type supplies a compatible compute, memory, network, and EBS performance profile. The x86_64 AMI and t3.micro type are compatible.

Subnet and public IPv4

The selected subnet fixes the Availability Zone and route-table context. The public IPv4 address is mapped to the instance's primary private IPv4 address. Together with the internet-gateway route and outbound security-group rules, it provides returnable outbound connectivity.

The existence of a public IPv4 address does not create an inbound path by itself. The route, security group, NACL, host firewall, and listening application all matter.

Security group

The security group has no inbound rules, so the lab does not expose SSH, RDP, or Apache to the internet. Session Manager uses an agent-initiated outbound managed channel.

IAM role and instance profile

The role defines the temporary permissions. The instance profile is the EC2 container that carries the role during launch. SSM Agent obtains rotating role credentials through the instance metadata service. No long-lived AWS access key is stored on the server.

The operator also needs iam:PassRole to launch EC2 with that role. Being allowed to create an EC2 instance does not automatically grant permission to pass every IAM role.

User data and cloud-init

EC2 makes the user data available during launch. Amazon Linux 2023 uses cloud-init to process the shell script. The script installs Apache, creates a deterministic page, starts the service, and writes a completion marker.

Linux user data normally runs during the first boot cycle. It should be short, versioned, idempotent where possible, observable, and free of secrets.

IMDSv2

The client first sends an HTTP PUT request for a time-limited token. It then supplies the token in metadata GET requests. Setting HttpTokens=required rejects tokenless IMDSv1 calls.

IMDSv2 protects the credential-delivery path, but it does not reduce the permissions in the role. Least-privilege IAM is still required.

Session Manager

Session Manager requires:

  • a supported and running SSM Agent;
  • instance permissions, supplied here by AmazonSSMManagedInstanceCore;
  • outbound HTTPS connectivity to the required Systems Manager endpoints;
  • operator permission to start the session;
  • matching Region and managed-node status.

It does not require an inbound TCP 22 rule, an SSH key pair, a bastion host, or a public SSH service.

9. Common failures and troubleshooting

SymptomLikely causeEvidence to checkCorrect action
Role does not appear in EC2Missing instance profile, wrong name, missing iam:ListInstanceProfiles, or IAM propagationIAM role and instance-profile detailsCreate or correct the profile, add the role, verify permission, then wait for propagation
UnauthorizedOperation at launchMissing EC2 permission or iam:PassRoleCloudTrail event and encoded authorization message where availableGrant only the required action and exact pass-role resource
Invalid IAM Instance ProfileProfile is absent, empty, misspelled, or not propagatedaws iam get-instance-profileCorrect the profile and retry after it contains the role
No instance capacitySelected type is temporarily unavailable in that AZEC2 launch errorUse an approved compatible type or another project subnet/AZ
EC2 running but no SSM nodeWrong Region, missing role, stopped agent, no DNS/outbound HTTPS, no public IPv4/IGW path, or service endpoint problemInstance profile, route table, public address, SG egress, agent logFix the failed prerequisite; do not open SSH as the first response
Only one status check passesGuest OS, network, or underlying host problemSystem versus instance status checkFollow the matching EC2 status-check branch
cloud-init failedScript syntax, repository access, package failure, or service error/var/log/cloud-init-output.log and journalCorrect the specific command and relaunch a clean disposable instance
Apache inactiveUser data incomplete or package/service failuresystemctl status httpd and cloud-init logCorrect bootstrap logic; do not expose port 80 to hide the failure
Tokenless metadata returns 200IMDSv2 is optionalEC2 metadata optionsSet HttpTokens to required, then retest compatibility
Metadata request times outEndpoint disabled, local firewall, bad address, or proxy behaviorEC2 metadata options and local routeUse 169.254.169.254, bypass external proxies, and verify endpoint state
Unexpected duplicate chargesBoth Console and CLI tracks were launched togetherEC2 Global View, tags, BillingTerminate the unneeded instance and delete retained volumes

Troubleshooting order

Use this order to avoid random changes:

  1. Confirm account and Region.
  2. Read the exact API or Console error.
  3. Confirm instance state and both status checks.
  4. Confirm the attached instance profile.
  5. Confirm SSM Agent state.
  6. Confirm DNS and outbound HTTPS path.
  7. Inspect cloud-init and service logs.
  8. Change one control at a time.
  9. Retest and record the evidence.

10. Cleanup procedure

Option A: Retain the controlled project through AWS 079

AWS 073 attaches, formats, snapshots, and restores an EBS data volume.

If continuing with the linear Project P04 path:

  1. Keep only this instance, its root volume, its instance profile, and the Project P04 network.
  2. Do not allocate an Elastic IP except for the timed AWS 075 lab, where it is released immediately.
  3. Close the Session Manager session when it is not being used.
  4. Keep the running-resource timer active whenever the instance is running.
  5. If AWS 073 does not start immediately, stop the instance, wait for stopped, and record that the root EBS volume continues to incur storage cost.
  6. Restart the instance only for a later lesson that requires live evidence, then stop it again when that lesson ends.
  7. Delete temporary data volumes, snapshots, logs, and the AWS 075 Elastic IP in the lesson that creates them.
  8. Complete final dependency-aware project cleanup in AWS 080.

Do not leave the instance running between study sessions or overnight.

Option B: End the lab now

From CloudShell:

aws ec2 terminate-instances \
  --region "$NW_REGION" \
  --instance-ids "$NW_INSTANCE_ID" \
  --query 'TerminatingInstances[0].{InstanceId:InstanceId,Previous:PreviousState.Name,Current:CurrentState.Name}' \
  --output table

aws ec2 wait instance-terminated \
  --region "$NW_REGION" \
  --instance-ids "$NW_INSTANCE_ID"

Confirm that no Project P04 EBS volume from this instance remains:

aws ec2 describe-volumes \
  --region "$NW_REGION" \
  --filters "Name=tag:Project,Values=NitWings-P04" \
  --query 'Volumes[?State!=`deleted`].{VolumeId:VolumeId,State:State,SizeGiB:Size,Attachments:Attachments[].InstanceId}' \
  --output table

If the project contains no deliberately retained EBS volume, the table should be empty. Investigate before deleting any volume whose ownership is uncertain.

Remove the lab role and instance profile:

aws iam remove-role-from-instance-profile \
  --instance-profile-name nw-p04-ec2-ssm \
  --role-name nw-p04-ec2-ssm

aws iam delete-instance-profile \
  --instance-profile-name nw-p04-ec2-ssm

aws iam detach-role-policy \
  --role-name nw-p04-ec2-ssm \
  --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore

aws iam delete-role \
  --role-name nw-p04-ec2-ssm

Keep the Project P04 VPC, subnet, route table, internet gateway, NACL, and security group only if the next project lesson requires them. These particular VPC components have no hourly charge by themselves, but always verify that the project does not contain a NAT gateway, interface endpoint, Elastic IP, load balancer, or another billed resource.

Final cleanup evidence

Record:

  • the terminated instance ID;
  • no unexpected available EBS volume;
  • no allocated Elastic IP;
  • the deleted instance profile and role, unless continuing immediately;
  • the EC2 Console showing no running Project P04 instance;
  • the Region checked;
  • the time cleanup completed.

Billing data can be delayed. An empty Cost Explorer result immediately after cleanup is not proof that no charge occurred.

11. Architecture and certification decision points

  1. What determines the instance Availability Zone?

The subnet.

  1. Why does the instance need an instance profile?

EC2 uses the profile to attach the IAM role and deliver rotating temporary credentials.

  1. Why is iam:PassRole important?

It controls which roles a launcher may attach. Without it, EC2 creation permission could become a privilege-escalation path.

  1. Does a security group create a route?

No. Security groups filter traffic. Route tables choose network targets.

  1. Does Session Manager work with no inbound rules?

Yes, when the agent, instance role, operator permissions, Region, DNS, and outbound endpoint connectivity are correct.

  1. Does a public subnet automatically give every instance a public IPv4 address?

No. Address assignment is a separate subnet or network-interface launch choice.

  1. Why require IMDSv2?

It requires a session token for metadata requests and rejects tokenless IMDSv1 calls.

  1. Does IMDSv2 make an overpowered role safe?

No. IAM policy still defines what stolen or misused credentials can do.

  1. Where should an application password go?

Not in user data. Use an appropriate secret service and retrieve it with a scoped role at runtime.

  1. What happens to the root volume at termination?

It is deleted only when DeleteOnTermination is enabled for that mapping.

Short scenarios

Scenario 1: Security policy prohibits inbound SSH and public bastions, but operators need a shell. Decision: Use Session Manager with managed-node prerequisites and scoped operator IAM.

Scenario 2: The instance launches, but Session Manager does not list it. Decision: Inspect the instance profile, SSM Agent, Region, DNS, and outbound endpoint path before changing inbound rules.

Scenario 3: An application inside a container cannot reach IMDSv2 when the host hop limit is 1. Decision: Test the container path and deliberately choose the documented hop limit. Do not make IMDSv1 optional as a shortcut.

Scenario 4: Auto Scaling must reproduce the same instance configuration. Decision: Move the reviewed settings into a versioned launch template and automate bootstrap.

Scenario 5: The web service is active locally but users cannot reach it. Decision: This lab intentionally has no inbound rule. For a real service, evaluate load balancer, route, SG, NACL, host firewall, listener, TLS, health, and DNS together.

Scenario 6: The instance is terminated, but the bill continues. Decision: Check retained EBS volumes, snapshots, Elastic IPs, NAT gateways, endpoints, load balancers, other Regions, and billing-data delay.

Student submission

Submit one short evidence package:

  1. the architecture diagram annotated in the student's own words;
  2. the EC2 configuration table showing instance type, subnet, profile, IMDSv2, hop limit, and root-volume cleanup behavior;
  3. SSM managed-node Online evidence;
  4. Session Manager output for SSM Agent, cloud-init, Apache, local HTTP, and IMDSv2;
  5. a two-paragraph explanation of role versus instance profile and route versus security group;
  6. one diagnosed failure or a written diagnosis of a supplied failure;
  7. cleanup evidence.

Redact account IDs, public IP addresses, session IDs, credential material, and any personally identifying information.

Instructor mastery rubric

AreaPointsPass evidence
Architecture and prerequisites10Student explains the control and data paths before launch
Account, Region, and cost gate10Correct identity, Region, estimate, and timer
EC2 configuration20Correct AMI/type, subnet, SG, encrypted root, tags and deletion setting
IAM and Session Manager15Correct role/profile and connection without inbound SSH
User data and verification15cloud-init complete, Apache active, deterministic local page
IMDSv210Token request succeeds and tokenless request returns 401
Troubleshooting10Evidence-led diagnosis without random permission or firewall expansion
Cleanup10Instance and unintended storage removed; retained items justified

Pass mark: 80 out of 100, with no critical safety failure.

Automatic failure conditions:

  • using the root user for the lab;
  • publishing credentials or metadata role-credential values;
  • opening SSH or RDP to 0.0.0.0/0 or ::/0;
  • leaving an unplanned billed resource running;
  • claiming completion without verification or cleanup evidence.

30-second recap

  • An EC2 launch combines image, compute, network, storage, identity, bootstrap, metadata, and tags.
  • The subnet determines the Availability Zone.
  • An instance profile carries the IAM role to EC2.
  • Session Manager can provide shell access without inbound SSH.
  • User data bootstraps the server but must not contain secrets.
  • IMDSv2 requires a token but does not replace least-privilege IAM.
  • Cleanup and cost verification are part of the technical result.

Official sources

Completion gate

Pass at 80 out of 100 with no critical safety failure. Required evidence includes the reviewed architecture and cost gate, correct EC2 and IAM configuration, an Online Systems Manager node, Session Manager verification, successful cloud-init and local HTTP evidence, an IMDSv2 token test with tokenless rejection, one diagnosed failure, and cleanup or the approved AWS 073 retention record.

Advertisement