DEV Community

Hands-On Lab Guide: L1 Support Engineer Skills

🛠️ Hands-On Lab Guide: L1 Support Engineer Skills


Lab 1: Windows Server + IIS Setup (Core L1 Skill)

Objective

Launch a Windows Server EC2, install IIS, deploy a test website, and practice troubleshooting.

Step-by-Step

1. Launch a Windows EC2 Instance


AWS Console → EC2 → Launch Instance

Name:              L1-Lab-Windows-IIS
AMI:               Microsoft Windows Server 2022 Base
Instance type:     t3.medium
Key pair:          Create new → "l1-lab-key" → Download .pem
Security Group:    Create new with these rules:
                   - RDP (port 3389) → My IP
                   - HTTP (port 80) → 0.0.0.0/0
                   - HTTPS (port 443) → 0.0.0.0/0

Click "Launch Instance"
Enter fullscreen mode Exit fullscreen mode

2. Connect via RDP


Password:
6xr&;(LfLeaZyayHGSpjA9c@!OgA$xBF
Private IP address
172.31.7.190


1. Select your instance → Click "Connect"
2. Go to "RDP Client" tab
3. Click "Get password" → Upload your .pem key file → Decrypt
4. Download the RDP file
5. Open it with Remote Desktop Connection
6. Enter the decrypted password
7. You're now on a Windows Server!
Enter fullscreen mode Exit fullscreen mode

3. Install IIS (Internet Information Services)

Open PowerShell as Administrator on the Windows Server:

# Install IIS with management tools
Install-WindowsFeature -Name Web-Server -IncludeManagementTools

# Verify IIS is running
Get-Service W3SVC

# Check IIS is serving the default page
Invoke-WebRequest -Uri http://localhost -UseBasicParsing | Select-Object StatusCode
Enter fullscreen mode Exit fullscreen mode

4. Deploy a Test Website


# Navigate to the default website directory
cd C:\inetpub\wwwroot

# Backup the default page
Rename-Item .\iisstart.htm .\iisstart.htm.bak

# Create a custom test page
@"
<!DOCTYPE html>
<html>
<head><title>L1 Lab - Test Application</title></head>
<body>
    <h1>L1 Support Lab - Application Running</h1>
    <p>Server: $(hostname)</p>
    <p>Time: <span id="time"></span></p>
    <p>Status: <span style="color:green;">HEALTHY</span></p>
    <script>
        document.getElementById('time').textContent = new Date().toISOString();
    </script>
</body>
</html>
"@ | Out-File -FilePath .\index.html -Encoding UTF8
Enter fullscreen mode Exit fullscreen mode

5. Verify — Open a browser and navigate to your EC2 Public IP:

http://<your-ec2-public-ip>
Enter fullscreen mode Exit fullscreen mode

You should see your test page. ✅


🔥 Troubleshooting Exercises

Exercise A: Simulate "Website Down" (IIS Stopped)

# Stop IIS
Stop-Service W3SVC

# Now try accessing the website in browser — it fails!
# This simulates a P1 incident: "Website is down"

# How to diagnose:
Get-Service W3SVC  # Shows "Stopped"

# How to fix:
Start-Service W3SVC

# Verify:
Invoke-WebRequest -Uri http://localhost -UseBasicParsing | Select-Object StatusCode
Enter fullscreen mode Exit fullscreen mode

Exercise B: Simulate "Port Blocked"


# Block port 80 in Windows Firewall
New-NetFirewallRule -DisplayName "Block HTTP" -Direction Inbound -LocalPort 80 -Protocol TCP -Action Block

# Website now unreachable from outside, but IIS is running!
# This simulates: "IIS is running but website not accessible"

# Diagnose:
Get-NetFirewallRule -DisplayName "Block HTTP"

# Fix:
Remove-NetFirewallRule -DisplayName "Block HTTP"
Enter fullscreen mode Exit fullscreen mode

Exercise C: Check Event Viewer for Errors


# View recent IIS-related events
Get-EventLog -LogName System -Source "IIS*" -Newest 10

# View application errors
Get-EventLog -LogName Application -EntryType Error -Newest 20

# This is how you find error evidence for incident reports
Enter fullscreen mode Exit fullscreen mode

Lab 2: Linux Server + Log Analysis (Core L1 Skill)

Objective

Launch a Linux EC2, practice essential commands, analyze logs, and simulate issues.

Step-by-Step

1. Launch a Linux EC2 Instance

AWS Console → EC2 → Launch Instance

Name:              L1-Lab-Linux
AMI:               Amazon Linux 2023
Instance type:     t3.micro (save your t3.medium for IIS)
Key pair:          Use same "l1-lab-key"
Security Group:    Allow SSH (port 22) from My IP

Click "Launch Instance"
Enter fullscreen mode Exit fullscreen mode

2. Connect via SSH

From your local terminal (or use EC2 Instance Connect in the browser):

# If using terminal (convert .pem permissions first on Linux/Mac)
ssh -i "l1-lab-key.pem" ec2-user@<your-linux-public-ip>

# Or: AWS Console → Select Instance → Connect → EC2 Instance Connect → Connect
Enter fullscreen mode Exit fullscreen mode

3. Essential L1 Commands — Practice Each One


# ===== SYSTEM INFORMATION =====

# Check who you are
whoami

# Check server hostname
hostname

# Check OS version
cat /etc/os-release

# Check uptime (how long server has been running)
uptime

# ===== CPU & MEMORY =====

# Check CPU usage (press 'q' to exit)
top

# Check memory usage
free -m

# Detailed memory info
cat /proc/meminfo | head -5

# ===== DISK SPACE =====

# Check disk usage (human-readable)
df -h

# Check which directories are using most space
du -sh /var/log/*

# ===== PROCESSES =====

# List all running processes
ps aux

# Find a specific process
ps aux | grep httpd

# Count running processes
ps aux | wc -l

# ===== NETWORK =====

# Check network interfaces
ip addr show

# Check open ports
ss -tlnp

# Test if a remote service is reachable
curl -I http://google.com
Enter fullscreen mode Exit fullscreen mode

4. Log Analysis — The Core L1 Skill


# ===== VIEWING LOGS =====

# View system logs
sudo cat /var/log/messages | tail -50

# Follow logs in real-time (CRITICAL L1 SKILL)
sudo tail -f /var/log/messages
# (Press Ctrl+C to stop)

# Search logs for errors
sudo grep -i "error" /var/log/messages

# Search for specific timestamps
sudo grep "Aug 17" /var/log/messages

# Count how many errors occurred
sudo grep -ic "error" /var/log/messages

# ===== JOURNALCTL (systemd logs) =====

# View recent logs
sudo journalctl -n 50

# View logs since a specific time
sudo journalctl --since "1 hour ago"

# View logs for a specific service
sudo journalctl -u sshd -n 20

# Follow logs live
sudo journalctl -f
Enter fullscreen mode Exit fullscreen mode

5. Simulate and Analyze Errors


# Create a fake application log for practice
sudo bash -c 'cat > /var/log/test-app.log << EOF
2026-08-17 10:00:01 INFO  Application started successfully
2026-08-17 10:00:02 INFO  Database connection established
2026-08-17 10:05:15 WARN  Slow query detected: 3200ms on /api/users
2026-08-17 10:05:16 WARN  Connection pool usage at 85%
2026-08-17 10:10:30 ERROR Database connection timeout after 30000ms
2026-08-17 10:10:31 ERROR java.sql.SQLException: Cannot acquire connection from pool
2026-08-17 10:10:32 ERROR HTTP 500 returned for GET /api/users/123
2026-08-17 10:10:33 ERROR HTTP 500 returned for POST /api/orders
2026-08-17 10:10:34 WARN  Retry attempt 1 for database connection
2026-08-17 10:10:35 WARN  Retry attempt 2 for database connection
2026-08-17 10:10:36 ERROR All retry attempts exhausted. Service degraded.
2026-08-17 10:15:00 INFO  Database connection re-established
2026-08-17 10:15:01 INFO  Service recovered. All endpoints healthy.
EOF'

# Now practice analysis:

# Find all errors
grep "ERROR" /var/log/test-app.log

# Find when errors started
grep "ERROR" /var/log/test-app.log | head -1

# Find when service recovered
grep "recovered" /var/log/test-app.log

# Count errors vs warnings
echo "Errors: $(grep -c 'ERROR' /var/log/test-app.log)"
echo "Warnings: $(grep -c 'WARN' /var/log/test-app.log)"

# Find the root cause pattern
grep -E "timeout|connection" /var/log/test-app.log
Enter fullscreen mode Exit fullscreen mode

[!TIP]
Practice narrating your findings out loud:
"Errors started at 10:10:30. The root cause appears to be database connection timeout. The connection pool was already at 85% utilization at 10:05. This caused HTTP 500 errors on multiple endpoints. Service auto-recovered at 10:15 after database connection was re-established."
This is exactly how you'd communicate during a P1 bridge call.


Lab 3: AWS CloudWatch Monitoring (Monitoring Skill)

Objective

Set up CloudWatch dashboards and alarms for your EC2 instances.

Step-by-Step

1. View Default EC2 Metrics

AWS Console → CloudWatch → Metrics → All metrics

Click: EC2 → Per-Instance Metrics

Find your instances. Select:
  ✅ CPUUtilization
  ✅ NetworkIn
  ✅ NetworkOut
  ✅ StatusCheckFailed

Click "Graphed metrics" tab to see the charts
Enter fullscreen mode Exit fullscreen mode

2. Create a CloudWatch Dashboard


CloudWatch → Dashboards → Create Dashboard

Name: "L1-Lab-Monitoring"

Add Widget → Line chart → Select:
  - EC2 > Per-Instance > CPUUtilization (for both instances)

Add Widget → Number → Select:
  - EC2 > Per-Instance > StatusCheckFailed

Add Widget → Line chart → Select:
  - EC2 > Per-Instance > NetworkIn + NetworkOut

Save Dashboard
Enter fullscreen mode Exit fullscreen mode

3. Create a CloudWatch Alarm (P1 Simulation)


CloudWatch → Alarms → Create Alarm

Select Metric: EC2 → Per-Instance → CPUUtilization
Select your Windows IIS instance

Conditions:
  Threshold type: Static
  Greater than: 80
  Period: 1 minute
  Datapoints: 1 out of 1

Notification:
  Create new SNS topic: "L1-Lab-Alerts"
  Email: your-email@example.com

Alarm name: "High-CPU-IIS-Server"
Description: "CPU above 80% on IIS production server"

Create Alarm
Enter fullscreen mode Exit fullscreen mode

4. Trigger the Alarm (Simulate High CPU)

RDP into your Windows Server and run:

# Simulate CPU load (will spike CPU to ~100%)
# Run this in PowerShell:
$cores = (Get-WmiObject Win32_Processor).NumberOfLogicalProcessors
1..$cores | ForEach-Object {
    Start-Job -ScriptBlock {
        $end = (Get-Date).AddMinutes(3)
        while ((Get-Date) -lt $end) { [math]::Sqrt(12345) | Out-Null }
    }
}

# Watch CPU spike in Task Manager
# Check CloudWatch — the alarm should trigger within 2-3 minutes

# Stop the load after testing:
Get-Job | Stop-Job
Get-Job | Remove-Job
Enter fullscreen mode Exit fullscreen mode

5. Check the Alarm

CloudWatch → Alarms → "High-CPU-IIS-Server"

State should change: OK → In alarm

This is exactly what happens in production.
You'd see this alarm, investigate CPU usage, and open an incident.
Enter fullscreen mode Exit fullscreen mode

[!NOTE]
In real-world L1 support, you'd receive this alarm via email/Slack/PagerDuty, investigate the cause (runaway process? traffic spike? deployment?), and either fix it or escalate.


Lab 4: REST API Troubleshooting with Postman + curl

Objective

Test APIs, understand HTTP status codes, and diagnose API failures.

Step-by-Step (No EC2 needed — use your local machine)

1. Install Postman
Download from: https://www.postman.com/downloads/

2. Test a Public API

Method: GET
URL: https://jsonplaceholder.typicode.com/posts/1

Click Send

Expected:
  Status: 200 OK
  Body: JSON with a post object (userId, id, title, body)
Enter fullscreen mode Exit fullscreen mode

3. Test Different Status Codes

# 200 - Success
GET https://jsonplaceholder.typicode.com/posts/1

# 404 - Not Found
GET https://jsonplaceholder.typicode.com/posts/99999

# Test another API for different codes:
GET https://httpstat.us/200    → Returns 200
GET https://httpstat.us/401    → Returns 401 Unauthorized
GET https://httpstat.us/403    → Returns 403 Forbidden
GET https://httpstat.us/500    → Returns 500 Internal Server Error
GET https://httpstat.us/502    → Returns 502 Bad Gateway
GET https://httpstat.us/503    → Returns 503 Service Unavailable
Enter fullscreen mode Exit fullscreen mode

4. Test POST Request

Method: POST
URL: https://jsonplaceholder.typicode.com/posts
Headers:
  Content-Type: application/json
Body (raw JSON):
{
  "title": "Test from L1 Lab",
  "body": "Testing API creation",
  "userId": 1
}

Click Send

Expected:
  Status: 201 Created
  Body: JSON with id: 101
Enter fullscreen mode Exit fullscreen mode

5. Using curl from Command Line

# GET request
curl -v https://jsonplaceholder.typicode.com/posts/1

# POST request
curl -X POST https://jsonplaceholder.typicode.com/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"Test","body":"Testing","userId":1}'

# Check only status code
curl -s -o /dev/null -w "%{http_code}" https://jsonplaceholder.typicode.com/posts/1

# Check response headers
curl -I https://jsonplaceholder.typicode.com/posts/1

# Test timeout behavior (useful for troubleshooting)
curl --max-time 5 https://httpstat.us/200?sleep=10000
# This will timeout after 5 seconds — simulates API timeout
Enter fullscreen mode Exit fullscreen mode

6. Practice Scenario: "Client reports API not working"

Client says: "The /users endpoint is returning errors"

Your investigation steps:

1. Test the endpoint:
   GET https://jsonplaceholder.typicode.com/users

2. Check status code — is it 200, 401, 500, 503?

3. Check response time — Headers tab in Postman shows duration

4. Check response body — any error messages?

5. Test with different parameters:
   GET https://jsonplaceholder.typicode.com/users/1
   GET https://jsonplaceholder.typicode.com/users?email=Sincere@april.biz

6. Document your findings:
   "Tested /users endpoint at 14:30 UTC. 
    Status: 200 OK. 
    Response time: 245ms. 
    Data returned correctly for all test cases.
    Unable to reproduce client's issue.
    Requesting client to share:
    - Exact URL they're hitting
    - Request headers (especially Authorization)
    - Screenshot of the error
    - Browser/client they're using"
Enter fullscreen mode Exit fullscreen mode

Lab 5: Writing an Incident Report + RCA

Objective

Practice writing a real incident report from the issues you simulated.

Template

# Incident Report

**Incident ID:** INC-2026-0817-001
**Priority:** P2 - High
**Status:** Resolved

## Summary
IIS web server on production EC2 instance became unreachable 
at 10:10 UTC on August 17, 2026. Root cause identified as 
IIS service failure. Service restored at 10:25 UTC.
Total downtime: 15 minutes.

## Timeline
| Time (UTC) | Event |
|------------|-------|
| 10:10 | CloudWatch alarm triggered: StatusCheckFailed |
| 10:12 | L1 engineer acknowledged the incident |
| 10:13 | Client notification sent: "Investigating reported downtime" |
| 10:15 | RDP to server confirmed IIS service stopped |
| 10:16 | Event Viewer checked — unexpected service termination logged |
| 10:18 | IIS service restarted |
| 10:20 | Website verified accessible |
| 10:22 | CloudWatch alarm returned to OK state |
| 10:25 | Client notified: "Service restored, monitoring for stability" |

## Root Cause
The IIS (W3SVC) service stopped unexpectedly due to [cause].
Event Viewer logs showed [specific error details].

## Impact
- All users accessing the web application were affected
- Duration: 15 minutes
- No data loss occurred

## Resolution
IIS service was restarted manually via PowerShell:
`Start-Service W3SVC`

## Preventive Measures
1. Configure IIS service auto-recovery (restart on failure)
2. Add CloudWatch alarm for W3SVC service status
3. Investigate root cause of service termination
4. Add automated health check endpoint monitoring

## Lessons Learned
- Need automated service recovery configuration
- CloudWatch alarm detected issue 2 minutes before client report
- Communication template was used effectively
Enter fullscreen mode Exit fullscreen mode

[!TIP]
Write at least 3 RCA reports using different scenarios from these labs. This is a frequently asked skill in L1 support interviews.


Lab Checklist — Track Your Progress

# Lab Skill Done?
1 Windows EC2 + IIS Server management, IIS administration
2 Linux EC2 + Logs CLI commands, log analysis
3 CloudWatch Monitoring Metrics, dashboards, alarms
4 Postman + curl API testing, status codes
5 Incident Report + RCA Documentation, communication

Quick Reference: Key Commands

Windows (PowerShell)

Get-Service W3SVC                    # Check IIS status
Start-Service W3SVC                  # Start IIS
Stop-Service W3SVC                   # Stop IIS
Restart-Service W3SVC                # Restart IIS
Get-EventLog -LogName System -Newest 20   # Recent system events
Get-Process | Sort-Object CPU -Desc | Select -First 10  # Top CPU processes
Test-NetConnection google.com -Port 443   # Test network connectivity
Enter fullscreen mode Exit fullscreen mode

Linux (Bash)

top                    # CPU/Memory usage (live)
free -m                # Memory usage
df -h                  # Disk space
ps aux                 # Running processes
tail -f /var/log/messages   # Follow logs
grep "ERROR" logfile   # Search for errors
journalctl -f          # Follow system logs
ss -tlnp               # Open ports
curl -I url            # Check HTTP response
systemctl status httpd # Check service status
Enter fullscreen mode Exit fullscreen mode

AWS CLI (Bonus)

# Describe your instances
aws ec2 describe-instances --query 'Reservations[*].Instances[*].[InstanceId,State.Name,PublicIpAddress]' --output table

# Get CloudWatch CPU metric
aws cloudwatch get-metric-statistics \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=YOUR_INSTANCE_ID \
  --start-time 2026-08-17T00:00:00Z \
  --end-time 2026-08-17T23:59:59Z \
  --period 300 \
  --statistics Average
Enter fullscreen mode Exit fullscreen mode

[!IMPORTANT]
Sandbox Time Management: sandbox sessions expire. Prioritize:

  1. Lab 1 (IIS) — takes ~30 min
  2. Lab 2 (Linux) — takes ~20 min
  3. Lab 3 (CloudWatch) — takes ~15 min

Labs 4 and 5 don't need the sandbox. Do them on your local machine anytime.

Top comments (0)