Recover a Containerized EC2 Service
Diagnose and recover a containerized EC2 web service with AWS operations tools.
Introduction
30 Second Summary
A website can stop loading while the computer behind it is still running. Fast recovery depends on finding the exact point where the request stops.
In this project, you will run Apache HTTP Server in a container on Amazon EC2 inside a custom Amazon VPC. You will run a controlled outage drill that ends with a recovered service, an Amazon CloudWatch health alarm, and an encrypted Amazon EBS snapshot.
What You'll Build
You will demonstrate a live web service recovering from a controlled outage while its host remains monitored and protected by an encrypted snapshot.
By the end of this project, you'll have:
- A public Apache service you can open in your browser to prove traffic reaches the container.
- A layered troubleshooting method that separates container health, host health, routing, and security-group access.
- A monitored recovery point where you can inspect the EC2 status alarm and confirm the encrypted snapshot exists.
- Secret Mission: Diagnose and recover a second outage caused by a stopped container while the EC2 health alarm remains OK.
Are there any prerequisites?
You need an AWS account with administrator access, a Linux device, and basic AWS knowledge. You do not need a local AWS CLI, SSH key, or Docker installation because every server task happens through the AWS Management Console.
Before We Start
Before the hands-on work begins, this checkpoint commits you to a clear recovery goal. You are building a containerized Amazon EC2 web service whose failures you can isolate across the container, host, routing, and security-group layers.
Prepare the Network and Management Access
Before a server can host the incident lab, it needs a low-cost path to the internet. It also needs auditable management access with SSH closed.
Your custom Amazon VPC supplies the public route. AWS Identity and Access Management (IAM) supplies the instance role that AWS Systems Manager Session Manager uses later.
In this step, get ready to:
- Confirm your AWS account is ready for the lab.
- Create the custom public network.
- Create the EC2 management controls.
Confirm your AWS account is ready
The AWS Management Console is the control plane for every resource in this lab. Selecting us-east-1 keeps the network resources in one region.
Billing screens can feel high-stakes. This check only shows whether credits or Free Tier usage may cover the lab.
- In your browser, go to the AWS Management Console sign-in page.
- Sign in using your administrator access.
- Confirm the console home page loads without browser compatibility warnings.
- Open the region selector in the upper-right corner.
- Select US East (N. Virginia) with region code us-east-1.
- Use the console search bar to open Billing and Cost Management.
- Review your available credits or current Free Tier usage.
You should now see US East (N. Virginia) in the console header. You should also know whether your account has credits or Free Tier coverage available.
Why check costs first?
This lab is estimated to cost under $0.10 with same-session cleanup. Your account can still incur charges when credits or free allowances do not apply.
The design avoids NAT gateways and VPC endpoints. That keeps the network focused on the troubleshooting objective.
Create the public network path
The Amazon VPC creation workflow can build the network boundary plus its internet path as one resource bundle. Its resource map also gives you a visual check before the EC2 instance exists.
What makes a subnet public?
A public subnet uses a route table that sends 0.0.0.0/0 traffic to an internet gateway.
An instance also needs a public IPv4 address before it can use that route for IPv4 internet traffic.
- Use the AWS Management Console search bar to open Amazon VPC.
- Select Create VPC.
- Choose VPC and more.
- Set the generated resource name to cloudops-lab-vpc.
- Set the IPv4 CIDR block to 10.0.0.0/16.
- Set the Availability Zone count to 1.
- Set the public subnet count to 1.
- Set the private subnet count to 0.
Why a public-only lab?
Production workloads often use private subnets plus managed network paths. Those components add cost and configuration that do not support this lab's first troubleshooting objective.
One public subnet keeps the path visible. Session Manager still lets you manage the host without opening SSH.
- Choose the option that creates no NAT gateways.
- Choose the option that creates no VPC endpoints.
- Review the Resource map preview to confirm it shows one VPC plus one public subnet.
AWS may take about a minute to create the complete bundle. A short wait here means the related network resources are being connected.
- Create the resource bundle by selecting Create VPC.
Good progress. Your lab now has a dedicated network boundary with a route toward the internet.
- Open the details for cloudops-lab-vpc after creation finishes.
- Open its Resource map.
- Trace the public subnet through its route table to the internet gateway.
- In the Amazon VPC subnet list, select the public subnet belonging to cloudops-lab-vpc.
- Confirm automatic public IPv4 assignment is enabled for that subnet.
You should see a local route for 10.0.0.0/16 plus a default route for 0.0.0.0/0 that targets the lab internet gateway.
Network bundle look different?
- Confirm that cloudops-lab-vpc is selected before reading the resource map.
- Check that the wizard created one public subnet with no private subnets.
- Edit the public subnet settings if automatic public IPv4 assignment is disabled.
help me troubleshoot my VPC resource map. The NextWork community can also help compare your console state.
Create the management role and security group
An EC2 role gives the future instance permission to register with Systems Manager. The console also creates an instance profile that carries this role to the instance.
- Use the AWS Management Console search bar to open IAM.
- Select Roles from the IAM navigation.
- Select Create role.
- Choose AWS service as the trusted entity type.
- Choose EC2 as the use case.
- Continue to the permissions selection.
How does the role work?
The EC2 trust choice allows an instance to receive the role. The attached policy gives Systems Manager the permissions required to manage that instance.
This produces an auditable browser-shell path. The security group can keep SSH closed.
- Search the permissions list for AmazonSSMManagedInstanceCore.
- Select the checkbox beside AmazonSSMManagedInstanceCore.
- Continue to the role details.
- Enter CloudOpsLabEc2Role as the role name.
- Create the role by selecting Create role.
- Select CloudOpsLabEc2Role from the roles list.
- Confirm AmazonSSMManagedInstanceCore appears as an attached policy.
That is the management path sorted. IAM now has the EC2 role plus its matching instance profile.
A security group controls traffic at the instance boundary. This lab permits public HTTP traffic while leaving SSH out of the inbound rules.
- Use the AWS Management Console search bar to open Amazon EC2.
- Open the Network & Security section in the left navigation.
- Select Security Groups.
- Select Create security group.
- Enter cloudops-web-sg as the security group name.
- Enter HTTP access for the CloudOps incident lab as the description.
- Select cloudops-lab-vpc in the VPC field.
Why leave SSH closed?
Session Manager provides the browser shell used later in the lab. An SSH rule would add an unnecessary public management path.
Keeping SSH out also makes the incident easier to isolate. The only inbound application rule is HTTP.
- Add one inbound rule.
- Set the inbound rule type to HTTP.
- Set the IPv4 source to 0.0.0.0/0.
- Confirm the generated rule uses TCP port 80.
- Leave the inbound rule list with no SSH rule.
- Keep the default outbound allow-all rule unchanged.
- Create the security group by selecting Create security group.
Your network controls are now in place. Public web traffic has a permitted path while remote administration remains assigned to Session Manager.
Security group settings missing?
- Confirm the selected VPC is cloudops-lab-vpc.
- Check that the only inbound rule uses TCP port 80 from 0.0.0.0/0.
- Confirm the default outbound rule remains present.
help me check my EC2 role and security group. The NextWork community can also help compare your resource settings.
Before you perform the final check, do you expect the route map and access controls to show one complete public web path?
- Switch back to the Amazon VPC console.
- Open the Resource map for cloudops-lab-vpc.
- Switch back to the IAM console.
- Find CloudOpsLabEc2Role in the roles list.
- Switch back to the Amazon EC2 console.
- Select cloudops-web-sg from the security groups list.
You should see one public subnet linked to a route table whose default route reaches the internet gateway. The subnet should have public IPv4 addressing enabled.
You should find CloudOpsLabEc2Role with AmazonSSMManagedInstanceCore attached. Its matching instance profile should contain the role.
You should see cloudops-web-sg in the lab VPC with TCP port 80 open from 0.0.0.0/0. It should have no SSH ingress plus the default outbound rule.
✔️ My resources match
Your public network and management controls are ready for the EC2 host.
ⓧ I'd like to double check the full setup
Compare every resource with this final state:
- CloudOpsLabEc2Role: IAM role created for EC2 with AmazonSSMManagedInstanceCore attached.
- CloudOpsLabEc2Role instance profile: Instance profile containing the CloudOpsLabEc2Role role.
- cloudops-lab-vpc: Created in us-east-1 with IPv4 CIDR 10.0.0.0/16, one Availability Zone, one public subnet, no private subnets, no NAT gateways, and no VPC endpoints.
- cloudops-lab-vpc internet gateway: Created and attached to cloudops-lab-vpc.
- cloudops-lab-vpc public route table: Associated with the lab public subnet and configured with local route 10.0.0.0/16 plus default route 0.0.0.0/0 to the lab internet gateway.
- cloudops-lab-vpc public subnet: Created in the lab VPC in one us-east-1 Availability Zone with public IPv4 addressing enabled and a route table route for 0.0.0.0/0 to the lab internet gateway.
- cloudops-web-sg: Security group in cloudops-lab-vpc with inbound TCP port 80 from 0.0.0.0/0, no inbound SSH rule, and the default outbound allow-all rule.
Your network path and management guardrails are ready. Next, you will launch the EC2 host and serve the Apache default page from a container.
Launch the Container Host
Your network path and management role are ready. The lab now needs an Amazon EC2 host that turns those controls into a reachable service.
This host runs Amazon Linux 2023. You will manage it through Systems Manager Session Manager without opening SSH.
Docker runs Apache HTTP Server inside a container. Its default page becomes your known-good baseline before the incident.
In this step, get ready to:
- Launch a secured EC2 instance in the lab public subnet.
- Connect to the host through Session Manager without SSH.
- Run the Apache container and reach its page over HTTP.
Launch the EC2 instance
The instance belongs in the public subnet you created earlier. Its security group exposes only the web service.
An encrypted Amazon EBS root volume protects the host storage. IMDSv2 limits access to instance metadata.
- In the AWS Management Console from earlier, enter EC2 in the top search bar.
- Select EC2 from the results.
You should see the EC2 dashboard for us-east-1.
- Start a new instance launch from the EC2 dashboard.
The launch page groups the host settings into sections. Each choice appears in the launch summary as you configure it.
- Enter cloudops-web-host as the instance name.
- Select the latest x86_64 Amazon Linux 2023 AMI.
The launch summary should now show cloudops-web-host with an x86_64 Amazon Linux 2023 image.
- Choose t3.micro as the instance type.
- Select Proceed without key pair (Not recommended).
Why launch without a key pair?
Session Manager provides IAM-backed browser access to the host. Port 22 stays closed because this lab does not use SSH.
- Select cloudops-lab-vpc as the VPC.
- Select the public subnet inside cloudops-lab-vpc.
The network summary should now place the instance on the subnet with a route to the internet gateway.
- Set Auto-assign Public IP to enabled.
- Choose the existing cloudops-web-sg security group.
How the web path fits together
The public IPv4 address gives browser traffic a destination. The security group admits TCP traffic on port 80.
The public subnet route sends internet traffic through the attached internet gateway. Every layer must line up for the page to load.
- Set the root volume to 8 GiB using gp3.
- Enable encryption for the root volume.
The storage summary should now show one encrypted 8 GiB gp3 root volume.
The remaining controls sit in Advanced details, so it is normal to need a careful scan.
- Keep basic monitoring enabled.
- Set T3 CPU credits to Standard.
The instance now uses basic monitoring without T3 surplus-credit mode.
- Select CloudOpsLabEc2Role in the IAM instance profile field.
- Keep instance metadata configured to require IMDSv2.
The final summary should show the instance profile and the required metadata protection.
Costs start when you launch
Launching the instance starts metered EC2 usage. Its public IPv4 address and EBS volume can also incur charges.
You will clean up these resources at the end of the lab. Same-session cleanup keeps the bill small.
- Launch cloudops-web-host.
Provisioning can take several minutes while AWS starts the host and completes its health checks. A short wait here is normal.
- Wait until cloudops-web-host is running.
- Wait until both EC2 status checks have passed.
- Record the instance's public IPv4 address here: your instance public IPv4 address.
That is the host layer ready. Your instance has passed AWS infrastructure checks and has a public address for the web test.
Connect through Session Manager
Session Manager gives you a browser shell through the instance profile attached at launch. The connection works without a key pair or an inbound SSH rule.
Why Session Manager instead of SSH?
Session Manager uses IAM permissions to control access. It also keeps interactive session activity inside AWS management tooling.
This leaves port 22 closed. The lab stays focused on the application path through port 80.
A new instance can take several minutes to register with Systems Manager. Waiting preserves the no-SSH design.
- Select cloudops-web-host in the EC2 instance list.
- Choose Connect.
- Select Session Manager.
- Choose Connect.
You should see a browser-based shell for cloudops-web-host. The Linux session uses the system-generated ssm-user account.
Session Manager is not ready?
Confirm that both EC2 status checks have passed. A newly launched managed node may need a few more minutes to register.
Check that CloudOpsLabEc2Role is attached as the instance profile. Confirm that its role still has AmazonSSMManagedInstanceCore attached.
Do not add an SSH rule while you wait. Help me diagnose why this EC2 instance is unavailable in Session Manager.
Serve Apache with Docker
A Docker image packages the web server. Running that image creates the service process on your EC2 host.
- Check the current Docker installation by running this command in the Session Manager shell:
docker --version
What does this command check?
The command confirms whether the Docker CLI is installed. It also prints the installed client version.
✔️ I see version 25.0.16
Docker Engine 25.0.16 is already installed. Continue below to start the Docker service.
ⓧ I see an older version
The installed package is older than the version used by this lab. Update it from the Amazon Linux 2023 repository.
- Update Docker and print the resulting version by running these commands:
sudo yum install -y docker
docker --version
What do these commands do?
- The first command installs the current Docker package available for this Amazon Linux 2023 release.
- The second command prints the Docker client version after the package operation.
You should see 25.0.16 in the version output.
ⓧ Command not found
Docker is not installed on the instance yet. Install it from the Amazon Linux 2023 repository.
- Install Docker and print the installed version by running these commands:
sudo yum install -y docker
docker --version
What do these commands do?
- The first command installs Docker without pausing for confirmation.
- The second command confirms that the Docker CLI is available.
You should see 25.0.16 in the version output.
Docker installation failed?
Confirm that the instance still has default outbound access through cloudops-web-sg. Confirm that the public subnet still routes internet traffic through its internet gateway.
A repository connection problem points to the outbound network path. Help me diagnose a Docker package installation failure on Amazon Linux 2023.
- Start Docker Engine by running this command:
sudo service docker start
What does this command do?
This starts the Docker daemon on Amazon Linux 2023. The daemon creates containers and manages their images.
- Grant the active Session Manager user Docker access by running these commands:
sudo usermod -aG docker $USER
newgrp docker
What do these commands do?
- The first command adds the current Linux user to the docker group.
- The second command activates that group in the current shell.
- Docker group membership grants root-level privileges. Limit this access to trusted administrators.
Before you check the daemon, what Docker server version do you expect to see?
- Verify the active Docker daemon by running this command:
docker info
What does this command prove?
Docker returns system-wide client and server information only when your shell can reach the daemon. The server details confirm that Docker Engine is running.
You should see Docker server information with version 25.0.16.
Cannot reach the Docker daemon?
Run the Docker service start command again if the server information is unavailable. Repeat the group commands if the shell reports an access problem.
Make sure you ran newgrp docker in the same Session Manager shell. Help me restore Docker daemon access for ssm-user.
The first container run can take a minute while Docker downloads the Apache image, so a short pause is expected.
- Create the detached Apache container by running this command:
docker container run -d --name my_container -p 80:80 httpd:2.4.69-alpine
What does this command do?
- The -d option runs the container in the background.
- The --name option assigns the project name my_container.
- The -p 80:80 option publishes host port 80 to container port 80.
- The final value selects the pinned httpd:2.4.69-alpine image.
Docker prints the new container ID and returns control to your shell.
Before you list the containers, which name and port mapping do you expect to find?
- Verify the running container by running this command:
docker container ls
What does this command prove?
This lists running containers. It lets you confirm the container name and the published port before testing the public route.
You should see my_container with an Up status. The port details should show host port 80 published to container port 80.
Container missing from the list?
Scroll up to the container run output and check whether Docker completed the image download. Confirm that the container name is exactly my_container.
Confirm that no other process already uses host port 80. Help me diagnose why my Apache container is not running.
Before you open the public address, do you expect the request to reach the Apache container?
- Open a new browser tab.
- Load the public web address by entering:
http://[[INSTANCE_PUBLIC_IP="your instance public IPv4 address"]]
How does the request reach Apache?
The browser sends an HTTP request to the instance's public IPv4 address. The security group allows the request on TCP port 80.
Docker forwards host port 80 to the Apache container. This proves the network and application layers work together.
You should see the Apache HTTP Server default page displaying It works!.
You now have a known-good service baseline. The EC2 host, Docker daemon, container, port publishing, public route, and security group all support a successful browser request.
Page does not load?
Confirm that the address starts with http://. Confirm that it uses the current public IPv4 address for cloudops-web-host.
Check that cloudops-web-sg still allows inbound TCP port 80 from 0.0.0.0/0.
Run the container-list command again to confirm that my_container is still running. Help me trace why the Apache page is unreachable.
Your container host is live and serving traffic. Next, you will remove one network rule and use this baseline to isolate the failed layer.
Break and Diagnose Network Connectivity
Your live Apache HTTP Server page gives you a known-good baseline. It proves the containerized service on Amazon EC2 worked before this incident.
Now you need to test whether one network control can break that baseline. The experiment changes only the security group rule in Amazon VPC.
Your diagnosis compares browser behavior with internal evidence. Each healthy layer narrows the fault.
In this step, get ready to:
- Remove the HTTP ingress rule from cloudops-web-sg.
- Observe the external web service failure while the EC2 host remains healthy.
- Use AWS Systems Manager Session Manager with Docker to isolate the blocked network layer.
Remove the HTTP ingress rule
An inbound security group rule controls which traffic can reach the instance. Removing the sole HTTP rule changes the network boundary without changing the server configuration.
- Use the service search in the AWS Management Console from earlier to return to the Amazon VPC console.
- Choose Security groups in the left navigation pane.
- Select cloudops-web-sg.
- Choose Actions.
- Choose Edit inbound rules.
- Choose Delete beside the HTTP rule for TCP port 80 from 0.0.0.0/0.
- Choose Save rules.
You should now see no entries under Inbound rules. The default outbound rule remains in place.
What changed?
AWS applies security group rule changes to associated resources automatically. The instance still exists with the same software while new inbound HTTP traffic has no allowed path through cloudops-web-sg.
Before you refresh, consider whether the known-good page can still receive a new HTTP request.
- Switch back to the browser tab for http://<instance-public-ip>.
- Refresh the page.
The Apache page no longer loads. This shortfall is intentional because the external request is now blocked before it reaches the instance.
Does the page still load?
- Confirm that cloudops-web-sg shows no inbound rules.
- Refresh the exact public IPv4 URL from earlier in a new browser tab.
Ask for help if the page remains reachable after the rule is gone: help me identify why this EC2 page still loads without an inbound HTTP rule.
Confirm the EC2 host is healthy
A failed browser request does not prove that the server failed. EC2 status checks provide separate evidence about the underlying host and instance.
- Return to the Amazon EC2 console from earlier.
- Choose Instances in the left navigation pane.
- Select cloudops-web-host.
- Choose the Details tab.
The Public IPv4 address field should still contain the address you used in the browser. This proves the instance has retained its public address.
- Choose the Status checks tab.
You should see both EC2 status checks passing. The infrastructure and operating system layers remain healthy despite the browser failure.
What do status checks prove?
EC2 status checks report whether AWS infrastructure can support the instance and whether its operating system remains reachable. Passing checks clear the host layer, but they do not test whether Apache can receive public HTTP traffic.
Isolate the failed network layer
Layered troubleshooting starts at the closest reliable point. The existing Session Manager shell gives you that point inside the host without requiring inbound SSH access.
- Switch back to the Session Manager browser shell from earlier.
Before you inspect Docker, consider whether the container stopped at the same time as the browser failure.
- Verify the current container state by running this command:
docker container ls
What does this check prove?
- The command lists containers that are currently running.
- The row for my_container confirms whether the Apache process remains active.
- The published port confirms that host port 80 still forwards to container port 80.
Good detective work. You should see my_container with a status beginning with Up plus a published mapping from host port 80 to container port 80.
Is the container missing?
- Confirm that you returned to the existing Session Manager shell for cloudops-web-host.
- Check that the command includes the word container before ls.
Ask for help without changing the container state: help me understand why my running container is missing from the Docker container list.
The running container clears the application layer. Next, trace the public subnet through its route table.
- Return to the Amazon VPC console from earlier.
- Choose Route tables in the left navigation pane.
- Select the route table in cloudops-lab-vpc that lists the lab public subnet under Subnet associations.
- Choose the Subnet associations tab.
You should see the lab public subnet associated with this route table. This proves that you are inspecting the path used by cloudops-web-host.
- Choose the Routes tab.
You should see the local route for 10.0.0.0/16 plus a default route for 0.0.0.0/0 targeting the lab internet gateway. The subnet still has its internet route.
The route is intact. The final network gate is the security group attached to the instance.
- Choose Security groups in the left navigation pane.
- Select cloudops-web-sg.
- Choose the Inbound rules tab.
You should see no inbound rules. This is the only unhealthy layer in the request path.
- Choose the Outbound rules tab.
The default outbound allow-all rule should still be present. Only inbound HTTP access was removed.
Your Layer-by-Layer Diagnosis
- The browser cannot reach the Apache page.
- Both EC2 status checks pass.
- The public subnet still routes 0.0.0.0/0 through the internet gateway.
- The container remains Up with host port 80 published.
- The security group has no inbound HTTP rule.
Before the final refresh, consider which result should win: the healthy application or the blocked security group.
- Return to http://<instance-public-ip> in your browser.
- Refresh the page.
The page still fails to load. Your evidence isolates cloudops-web-sg as the failed layer while the route, host, Docker service, and Apache container remain healthy.
That is disciplined incident response: you isolated one failed control without touching the healthy components. Next, you will restore that control and add an EC2 health alarm.
Restore Service and Add a Health Alarm
Your layered diagnosis found one failed control: the security group blocks port 80. The Amazon EC2 host and container stayed healthy throughout the outage.
Now you will restore only the HTTP ingress rule. You will also add an Amazon CloudWatch alarm so infrastructure failures have a visible signal.
In this step, get ready to:
- Restore HTTP access through cloudops-web-sg.
- Confirm the Apache HTTP Server page returns without restarting the host or container.
- Create a status-check alarm for cloudops-web-host.
Restore the HTTP rule
The host already serves the page on port 80. Restoring the missing ingress rule reconnects the browser to that known-good service.
- Return to Security Groups in the AWS Management Console from earlier.
- Select cloudops-web-sg.
- Choose the Inbound rules tab.
- Choose Edit inbound rules.
- Choose Add rule.
- Set Type to HTTP.
- Set Source to Anywhere-IPv4.
- Choose Save rules.
The inbound rules now show TCP port 80 from 0.0.0.0/0. The host still has no inbound SSH rule.
Before you refresh, make a prediction about whether changing only the security rule restores the page.
- Switch back to the failed browser tab from earlier and refresh the page.
That is a clean recovery. You will see It works! again without restarting the instance or my_container.
Page still unreachable?
- Confirm the browser address begins with http://.
- Confirm the restored rule shows TCP port 80.
- Confirm the restored rule uses 0.0.0.0/0 as its source.
If the rule looks correct, help me diagnose why the Apache page is still unreachable.
Open the status-check alarm form
The restored rule fixes today’s network failure. A status-check alarm adds a separate signal for future EC2 infrastructure failures.
What does StatusCheckFailed monitor?
The StatusCheckFailed metric reports whether an EC2 system check or instance check has failed. Its value is 0 for no failure or 1 for a failure.
Using Maximum ensures that a failure value within an evaluation period counts toward the alarm.
- Return to the Amazon EC2 console from earlier.
- Choose Instances in the navigation pane.
- Select cloudops-web-host.
The instance summary still shows the host running with its public IPv4 address.
- Choose the Status Checks tab.
You will see both EC2 status checks passing. This is the healthy baseline that the alarm will monitor.
- Choose Actions.
- Choose Create status check alarm.
- On Manage CloudWatch alarms, choose Create an alarm.
You will see the alarm configuration form for the selected EC2 instance.
Configure and verify the alarm
The alarm will evaluate two consecutive five-minute periods. It will flag a failure when the metric reaches 1.
- Leave the Alarm notification toggle off.
- Set the sampled metric to StatusCheckFailed.
- Set the statistic to Maximum.
The form now tracks the highest status-check value reported during each period.
- Set the period to 300 seconds.
- Set the number of evaluation periods to 2.
- Set the threshold to 1.
The alarm now requires the failure threshold across two evaluation periods.
- Select the greater-than-or-equal comparison that records GreaterThanOrEqualToThreshold.
- Configure missing data to be treated as missing.
- Leave the Alarm action toggle off.
The alarm will observe the instance without triggering an automated EC2 action.
- Enter cloudops-host-status as the alarm name.
- Choose Create.
The alarm is now created. Expect the state to take about ten minutes to settle while two 300-second periods receive status-check data.
Before you check the final state, predict what a healthy instance with passing status checks should report.
- Refresh the alarm details after status-check data arrives.
Your operational signal is working. You will see cloudops-host-status in the OK state while both EC2 status checks pass.
Alarm still waiting for data?
- Confirm both status checks still pass for cloudops-web-host.
- Confirm the alarm monitors StatusCheckFailed for cloudops-web-host.
- Confirm missing data is treated as missing.
If the state still does not settle, help me check my EC2 status alarm configuration.
Your service is reachable again with an EC2 health signal watching the host. Next, you will pause application writes long enough to capture an encrypted recovery snapshot.
Capture a Recovery Point
You restored the Apache HTTP Server page by repairing the failed network layer. The cloudops-host-status CloudWatch alarm now watches your Amazon EC2 host for status-check failures.
That known-good service now needs a recovery point. An Amazon EBS snapshot protects the configured root volume.
Pausing the Docker container first prevents active application writes from crossing the snapshot boundary. You can resume the service as soon as the snapshot request enters pending.
In this step, get ready to:
- Stop my_container for a consistent backup point.
- Request the encrypted standard-tier recovery snapshot.
- Restart the container to restore the public web service.
Pause the container for consistency
Application writes can change files while a snapshot request begins. Stopping my_container freezes the web service at a clean point.
- Switch back to the Session Manager shell connected to cloudops-web-host.
- Stop the container cleanly by running this command:
docker stop my_container
What does this command do?
The command asks Docker to stop my_container cleanly. The terminal returns the container name after the stop completes.
You should see my_container in the terminal output. The public web service is now paused.
Before you inspect the container list, what state do you expect my_container to show?
- Inspect every container on the host by running this command:
docker ps -a
What does this command show?
The command includes running containers plus stopped containers. This proves that my_container still exists after the stop.
You should see a row for my_container with a stopped state. Its original port publishing remains part of the container configuration.
Container still running?
Check that the stop command returned the exact container name my_container.
Confirm that your Session Manager shell is still connected to cloudops-web-host.
Help me diagnose why the container did not stop.
Create the encrypted snapshot
This snapshot can accrue storage charges until you delete it. You remain in control because the cleanup section gives you a direct deletion path.
The attached root volume contains the configured host state. Its existing encryption automatically carries into the new snapshot.
- Return to the Amazon EC2 console from earlier.
- Select Instances in the left navigation pane.
- Select cloudops-web-host from the instance list.
- Select the Storage tab.
- Select the linked root-volume ID from the block devices table.
The volume details should identify an encrypted 8 GiB gp3 volume. This is the disk that holds your configured server state.
- Choose Actions above the volume details.
- Choose Create snapshot from the menu.
- Choose Add tag in the Tags section.
- Enter Name as the tag key.
- Enter cloudops-web-recovery as the tag value.
- Choose Create snapshot to request the recovery point.
What happens after the request?
Snapshot creation is asynchronous. The new standard-tier snapshot enters pending while Amazon EBS transfers the volume data.
The source volume is encrypted. Amazon EBS automatically encrypts the snapshot with the same encryption key.
Snapshot completion can take several hours, so a long pending state is expected. The request itself gives you the safe point needed to resume writes.
- Select Snapshots under Amazon EBS in the left navigation pane.
- Filter the snapshot list with cloudops-web-recovery.
- Select the matching snapshot from the results.
You should see a state of pending or completed. The snapshot details should also show encryption and the standard storage tier.
Don't see the snapshot?
Confirm that the console region remains us-east-1. A regional snapshot appears in the same region as its source volume.
Clear any existing filters from the snapshot list. Search for cloudops-web-recovery again.
Help me find my recovery snapshot.
Resume and verify the service
The recovery point now represents the stopped application state. Restarting the existing container preserves its image plus its original port publishing.
- Switch back to the Session Manager shell for cloudops-web-host.
- Restart the existing container by running this command:
docker start my_container
What does this command do?
The command starts the stopped my_container container. Docker reuses its pinned image plus its existing host-port mapping.
You should see my_container in the terminal output. This confirms that Docker accepted the start request.
Before you inspect the running-container list, do you expect my_container to appear?
- Check the running-container list by using this command:
docker container ls
What does this command show?
The command lists containers that are currently running. Its result proves whether my_container returned to service after the snapshot request.
You should see my_container with a running state. Host TCP port 80 should still be published to container TCP port 80.
Before you refresh the public page, do you expect the Apache response to return?
- Return to the browser tab that showed the Apache page earlier.
- Refresh the public page.
You should see It works! again. Strong recovery work: the original web service is running after a consistent snapshot request.
Page still unavailable?
Confirm that the running-container list includes my_container with host port 80 published.
Check that cloudops-web-sg still allows inbound TCP port 80 from 0.0.0.0/0.
Help me restore the Apache page.
Your encrypted cloudops-web-recovery snapshot is pending or completed. Your public service is running again with its EC2 health alarm still configured.
Secret mission
Diagnose an Application-Level Outage
Create a second outage without changing the network. Compare browser, container, and infrastructure signals to isolate the failed layer and recover the service.
Clean Up Your Resources
Clean Up Your Resources
Choose whether to keep your resources running, pause the lab for later, or delete everything. This AWS lab contains resources in us-east-1 that can continue to incur charges.
Cost warning
The running t3.micro Amazon EC2 instance can incur compute charges. Its public IPv4 address can also incur hourly charges.
The Amazon EBS root volume continues to use storage while the instance exists. The cloudops-web-recovery snapshot continues to use storage until you delete it.
Choose Pause to stop compute usage. Choose Delete to remove every billable resource from this lab.
Resources you used:
- Custom Amazon VPC named cloudops-lab-vpc.
- One public subnet inside cloudops-lab-vpc.
- One internet gateway attached to cloudops-lab-vpc.
- One public route table with a default route to the internet gateway.
- Security group cloudops-web-sg with HTTP access on TCP port 80.
- EC2 instance cloudops-web-host with a public IPv4 address.
- Encrypted 8 GiB gp3 root volume attached to cloudops-web-host.
- Encrypted snapshot cloudops-web-recovery.
- Amazon CloudWatch alarm cloudops-host-status.
- EC2 role CloudOpsLabEc2Role in AWS Identity and Access Management (IAM).
- Instance profile containing CloudOpsLabEc2Role.
Keep everything running
No action needed. Choose this if you want to keep demonstrating the live incident lab.
- Your cloudops-web-host instance stays online.
- Your my_container container continues serving the Apache page.
- Your cloudops-host-status alarm continues monitoring EC2 status-check failures.
- Your instance continues using paid compute capacity.
- Your public IPv4 address continues incurring hourly charges.
- Your root volume continues using EBS storage.
- Your cloudops-web-recovery snapshot continues using EBS snapshot storage.
Pause - I'll come back to this later
Stop the EC2 instance to pause compute usage while preserving its root volume. You can start the instance when you return to the lab.
- Switch back to the Amazon EC2 console from earlier.
- Go to the instance list.
- Select cloudops-web-host.
- Use the instance state controls to stop the selected instance.
- Confirm the stop request.
- Wait until the instance state shows that cloudops-web-host is stopped.
The stopped host no longer serves the Apache page. Its container resumes only after the host starts again.
The root volume remains billable while the instance is stopped. The snapshot also remains billable.
Your Public Address Can Change
The public IPv4 address can change when you start cloudops-web-host again. Read the current address from the instance details before reopening the Apache page.
Delete - I don't want to use this again
Deletion is permanent, so take this option slowly. The order below removes dependent resources before deleting the VPC.
Delete the CloudWatch Alarm
- Switch to Amazon CloudWatch in the AWS Management Console from earlier.
- Go to the alarm list.
- Select cloudops-host-status.
- Delete the selected alarm.
- Confirm the deletion request.
- Verify that cloudops-host-status no longer appears in the alarm list.
Record the Root Volume
The EC2 host owns the volume that contains Docker Engine and my_container. Recording its ID lets you confirm that no storage remains after termination.
- Switch back to the Amazon EC2 console from earlier.
- Go to the instance list.
- Select cloudops-web-host.
- View the storage details for the selected instance.
- Record the root volume ID here: your root volume ID.
Terminate the EC2 Instance
- Return to the instance details for cloudops-web-host.
- Use the instance state controls to terminate the selected instance.
- Confirm the permanent termination.
- Wait until the instance state shows that cloudops-web-host is terminated.
Termination permanently stops the instance. Its public IPv4 address is released as part of removing the host.
Verify the Root Volume Is Gone
- Go to the Amazon EBS volume list in the Amazon EC2 console.
- Search for your root volume ID.
- Delete the volume if it still appears after the instance reaches the terminated state.
- Confirm that no volume with your root volume ID remains.
Delete the Recovery Snapshot
- Go to Amazon EBS Snapshots in the Amazon EC2 console.
- Select cloudops-web-recovery.
- Delete the selected snapshot.
- Confirm the deletion request.
- Verify that cloudops-web-recovery no longer appears in the snapshot list.
The snapshot no longer accumulates storage charges once its deletion completes.
Delete the IAM Role
- Switch to the IAM console in the AWS Management Console from earlier.
- Go to the role list.
- Search for CloudOpsLabEc2Role.
- Select CloudOpsLabEc2Role.
- Delete the selected role.
- Enter the role name if the confirmation screen requests it.
- Confirm that CloudOpsLabEc2Role no longer appears in the role list.
Deleting this console-created role also deletes its matching EC2 instance profile. Its attached managed policy is detached automatically.
Delete the Custom VPC
- Switch to the Amazon VPC console in the AWS Management Console from earlier.
- Go to the VPC list.
- Select cloudops-lab-vpc.
- Delete the selected VPC.
- Confirm the deletion request.
- Wait until cloudops-lab-vpc disappears from the VPC list.
Deleting the VPC from the console also removes its public subnet. It also removes the route table, internet gateway, network ACLs, and cloudops-web-sg after dependent resources are gone.
VPC Won't Delete?
A remaining network interface can block VPC deletion. The terminated instance must finish releasing its network resources first.
- Confirm that cloudops-web-host has reached the terminated state.
- Wait for the instance network resources to disappear.
- Retry deleting cloudops-lab-vpc.
Still blocked? Help me identify the dependent resource.
Nice Work!
Nice Work!
You did it! You built a containerized web service with monitoring and backup protection. You also recovered two controlled outages by changing only the failed layer.
You've learned how to:
- Deploy a public web service on Amazon EC2 inside a custom Amazon VPC. You managed the host through AWS Systems Manager Session Manager without opening SSH access.
- Apply layered troubleshooting across the container, host, route table, and security group. You isolated a missing HTTP ingress rule while the instance and container remained healthy.
- Protect the workload with an Amazon CloudWatch alarm and an encrypted Amazon EBS snapshot. You restored service without unnecessary changes to the host or container.
- Secret Mission: Diagnosed a stopped Docker container while the EC2 status alarm remained healthy. You restarted only the failed container and identified HTTP health checking as the missing application-level signal.
Ready to quiz yourself?