AWS Security Groups Hands-On Lab 2026: Master Inbound, Outbound & SG References


Introduction: AWS Security Groups Hands-On Lab

If I had to pick one AWS concept that trips up more engineers than anything else, it would be security groups. Not because they’re complicated—they’re actually elegantly simple once you understand them—but because they’re deceptively easy to misconfigure.

This lab teaches you how to work with security groups the right way. You’ll understand the difference between inbound and outbound rules, create security groups from scratch, and master the often-misunderstood SG-to-SG reference pattern that separates junior engineers from seasoned architects.

Here’s something that’ll save you hours of debugging: security groups are stateful. This means if you allow inbound traffic on port 80, the response traffic is automatically allowed out—you don’t need a separate outbound rule for it. This single concept explains about half the “why isn’t this working?” tickets I’ve triaged over the years. Engineers add outbound rules they don’t need, or worse, they restrict outbound traffic and break things they didn’t expect.

Why does this matter? Because in production AWS environments, security groups are your first line of defense. They’re the bouncers at the door of every EC2 instance, RDS database, and Lambda function running in a VPC. I’ve seen a single misconfigured security group take down an entire application—and I’ve seen another expose sensitive data to the internet for three days before anyone noticed.

This lab is built for engineers who’ve launched a few EC2 instances but haven’t really thought deeply about what those security group rules actually do. If you’ve ever wondered why your application can’t connect to a database, or why you can SSH into one instance but not another, this lab will give you the mental model you need.

From an architect’s perspective, security groups aren’t just about blocking bad traffic. They’re about designing systems where the blast radius of any single compromise is as small as possible. A well-designed security group strategy means that even if an attacker gets into one instance, they can’t hop laterally across your infrastructure.

Here’s where beginners usually go wrong: they create one security group that allows everything, attach it to every instance, and call it a day. It works—until it doesn’t. The other common mistake is opening ports to 0.0.0.0/0 (the entire internet) when they only needed access from a specific source. Both of these patterns create unnecessary risk that compounds over time.

Let’s fix that.


Lab Overview

In this hands-on lab, you’ll build a two-tier architecture with properly isolated security groups. You’ll create a web-tier security group that accepts public HTTP traffic, and an app-tier security group that only accepts traffic from the web tier—not from the internet directly.

By the end of this lab, you’ll have gained practical skills in creating and modifying security group rules, implementing SG-to-SG references for inter-tier communication, testing connectivity between EC2 instances using real debugging tools, and identifying common security group misconfigurations before they cause outages.

These skills translate directly to real-world scenarios. Every multi-tier application you’ll ever build on AWS—whether it’s a simple web app or a complex microservices architecture—relies on this exact pattern. Security group knowledge is mission-critical when you’re designing VPC architectures, troubleshooting connectivity issues at 2 AM, passing the AWS Solutions Architect exam, and conducting security reviews of existing infrastructure.


Prerequisites

Before starting this lab, make sure you have an AWS account with EC2 and VPC permissions. You should be comfortable navigating the AWS Console and launching EC2 instances, ideally from completing Lab 1.1 — Launch an EC2 Instance and Lab 1.2 — EC2 Storage Deep Dive (EBS vs Instance Store) in this series.

You’ll need two running EC2 instances in the same VPC (we’ll attach security groups to these), SSH access to at least one instance for testing, and an IAM user or role with permissions such as ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, and ec2:DescribeSecurityGroups.

For secure access best practices, you may also want to review EC2 SSH vs AWS SSM Session Manager, and for identity-based security, IAM Roles for EC2.


What NOT to Do: Common Anti-Patterns

Before we build things the right way, let me show you what failure looks like. I’ve seen these patterns destroy production environments.

Anti-Pattern #1: The “One Ring” Security Group. This is when you create a single security group with ports 22, 80, 443, 3306, 5432, 6379, and everything else wide open, then attach it to every instance in your environment. It works initially because everything can talk to everything. But here’s why it fails at scale: when one instance gets compromised, the attacker has network access to your entire infrastructure. There’s no segmentation, no blast radius reduction. I once watched a team spend 72 hours rebuilding their entire environment because a single compromised web server had direct database access it never needed.

Anti-Pattern #2: The “0.0.0.0/0 Everywhere” Approach. Opening inbound rules to the entire internet “temporarily” for testing. There’s no such thing as temporary in security. These rules get forgotten, and three weeks later you’re explaining to your CISO why your internal API was indexed by Shodan.

Anti-Pattern #3: Ignoring Outbound Rules Entirely. The default outbound rule allows all traffic to anywhere. That’s convenient, but it means a compromised instance can exfiltrate data to any destination, download malware from anywhere, and participate in botnets. Tightening outbound rules is defense-in-depth that most teams skip.

Keep these anti-patterns in mind as we build proper security groups below.


Step-by-Step AWS Security Groups Hands-On Lab

Step 1: Navigate to Security Groups

Open the AWS Console and navigate to EC2 → Network & Security → Security Groups.

This is your command center for all security group operations. You’ll see a list of existing security groups, including the default security group that AWS creates automatically for each VPC.

Why this matters: Every VPC gets a default security group that allows all outbound traffic and all inbound traffic from instances using the same security group. This default behavior is convenient for getting started but dangerous in production. We’re going to create purpose-built security groups instead.

What you should see: A table listing security groups with columns for Name, Security Group ID, VPC ID, Description, and Inbound/Outbound rule counts.

Common misconfiguration: Engineers often modify the default security group instead of creating new ones. This works until you need different rules for different instance types—then you’re stuck.


Step 2: Create the Web-Tier Security Group

Click Create security group and configure the following:

  • Security group name: web-sg
  • Description: Security group for web-tier instances - allows HTTP and SSH
  • VPC: Select your target VPC

Why this matters: The naming convention here isn’t arbitrary. When you’re troubleshooting at 3 AM, you want security group names that immediately tell you what they’re for. web-sg is infinitely better than sg-launch-wizard-1.

What you should see: The create form with three sections: Basic details, Inbound rules, and Outbound rules.


Step 3: Configure Inbound Rules for web-sg

In the Inbound rules section, add two rules.

For the first rule, set Type to HTTP, Protocol to TCP, Port range to 80, and Source to 0.0.0.0/0 with a description of “Allow HTTP from internet”.

For the second rule, set Type to SSH, Protocol to TCP, Port range to 22, and Source to My IP with a description of “Allow SSH from admin IP only”.

Click Create security group.

Why this matters: Notice the difference in sources. HTTP traffic comes from anywhere because that’s the point of a web server—it serves the public. But SSH? That should only come from your IP address. Never, ever open SSH to 0.0.0.0/0 in production. I’ve personally witnessed a crypto-mining botnet compromise instances within 8 minutes of SSH being exposed to the internet.

What you should see: The security group created successfully with two inbound rules displayed.

Common misconfiguration: Using 0.0.0.0/0 for SSH “temporarily” and forgetting to remove it. There’s no such thing as temporary in security.


Step 4: Create the App-Tier Security Group

Create another security group with the following settings:

  • Security group name: app-sg
  • Description: Security group for app-tier instances - internal traffic only
  • VPC: Same VPC as web-sg

Leave the inbound rules empty for now. We’ll add them in the next step.

Why this matters: The app tier should have zero direct public access. If an attacker can’t reach it from the internet, that’s one less attack vector to worry about.


Step 5: Configure SG-to-SG Reference (The Important Part)

This is where most engineers miss a critical pattern. Edit app-sg and add an inbound rule, but instead of specifying an IP address or CIDR block, you’ll reference another security group.

Set Type to Custom TCP, Port range to 8080, and for the Source, search for and select web-sg (it will appear as sg-xxxxxxxx | web-sg). Add a description of “Allow traffic from web tier on port 8080”.

Click Save rules.

Why this matters: This is the SG-to-SG reference pattern, and it’s incredibly powerful. Instead of saying “allow traffic from 10.0.1.0/24,” you’re saying “allow traffic from any instance that has web-sg attached.” This is more maintainable because if you add more web instances, they automatically get access—no rule changes needed. It’s also more secure because the rule stays valid even if instance IP addresses change. And it’s more readable because anyone looking at the rule immediately understands the intent.

What you should see: The inbound rule showing web-sg as the source instead of a CIDR block.

Common misconfiguration: Using CIDR blocks when SG references would work. CIDR blocks are static and require updates when instances change.


Step 6: Attach Security Groups to EC2 Instances

Navigate to EC2 → Instances. Select your web-tier instance, click Actions → Security → Change security groups.

Remove any existing security groups and add web-sg. Click Save.

Repeat for your app-tier instance, attaching app-sg instead.

Why this matters: An instance can have multiple security groups attached, and the rules are additive. But for clean architecture, one security group per tier keeps things manageable.


Step 7: Test Connectivity and Understand Outbound Rules

SSH into your web-tier instance and test connectivity to the app-tier instance:

# Test if port 8080 is reachable
curl http://<app-tier-private-ip>:8080

# Alternative: Use netcat to test port connectivity
nc -zv <app-tier-private-ip> 8080

# Check if ICMP is allowed (ping)
ping -c 3 <app-tier-private-ip>

What you should see: The nc command should return “Connection to 8080 port [tcp/*] succeeded!” if everything is configured correctly. The curl command might time out if nothing is listening on 8080, but that’s a different problem than connectivity.

Note: Ping likely won’t work unless you explicitly allow ICMP in the security group. This surprises a lot of engineers.

Understanding Outbound Rules (Often Overlooked)

By default, every security group allows all outbound traffic to 0.0.0.0/0. This is why your instances can reach the internet, download packages, and call external APIs without you configuring anything.

But what happens when you restrict outbound rules? Things break in ways that confuse people.

Real-world outbound failures I’ve debugged:

First, package managers stop working. If you remove the default outbound rule and don’t explicitly allow HTTPS (443) outbound, apt update, yum install, and pip install all fail with timeout errors. Your instances can’t reach package repositories.

Second, API calls time out silently. An application calling an external API (Stripe, Twilio, any SaaS) will hang indefinitely if outbound HTTPS isn’t allowed. The logs often just show “connection timeout” with no indication that the security group is the culprit.

Third, DNS resolution breaks. If you restrict outbound UDP port 53, DNS queries fail. Everything that relies on domain names stops working, including your package managers and API calls, even if you allowed HTTPS.

Fourth, NTP sync fails. If you block outbound UDP port 123, your instances can’t sync time. This causes TLS certificate validation failures, log timestamp drift, and authentication issues with time-sensitive tokens.

When to restrict outbound rules: High-security environments often lock down outbound traffic to specific destinations. If you do this, make sure you explicitly allow DNS (UDP 53), HTTPS (TCP 443) to required endpoints, NTP (UDP 123) if not using VPC-provided time sync, and any specific ports your application needs.

Test from your instance:

# Verify outbound internet access
curl -I https://aws.amazon.com

# Check DNS resolution
nslookup google.com

# Test specific outbound port
nc -zv api.stripe.com 443

Real Lab Experiences (Architect Insights)

Let me share some war stories that’ll save you pain down the road.

I once spent four hours troubleshooting why a new microservice couldn’t connect to RDS. The security group rules looked perfect. Turned out, the RDS instance was in a different VPC entirely. Security groups don’t cross VPC boundaries—that’s what VPC peering or Transit Gateway is for. Always verify VPC IDs first.

Another time, a production outage lasted two hours because someone added a rule allowing traffic from 10.0.0.0/8 instead of 10.0.1.0/24. That one extra subnet accidentally exposed an internal service to development instances running untested code. One rogue process hammered the service and brought it down.

The scariest one? An engineer opened port 3306 (MySQL) to 0.0.0.0/0 “just for testing” and forgot about it. Three weeks later, the database was ransomware’d. The data was gone. No backup strategy in place. That company doesn’t exist anymore.

My advice to junior engineers touching production security groups: never make changes directly. Always use Infrastructure as Code (Terraform, CloudFormation) with peer review. And always ask yourself: “What’s the minimum access required?”

Validation & Testing

To confirm your security groups are working correctly, run these tests from your web-tier instance:

# Test 1: Verify connectivity to app tier on port 8080
nc -zv <app-private-ip> 8080
# Expected: Connection succeeded

# Test 2: Attempt connection on unauthorized port
nc -zv <app-private-ip> 3306
# Expected: Connection timed out or refused

# Test 3: From app tier, verify outbound internet access
curl -I https://aws.amazon.com
# Expected: HTTP/2 200 (if outbound rules allow)

Success looks like: Authorized connections complete instantly. Unauthorized connections hang until timeout.

Failure looks like: Even authorized connections timeout, or unauthorized connections succeed.


Troubleshooting Guide

Problem: Connection times out even with correct rules.
Check if the security group is actually attached to the instance. Run aws ec2 describe-instances --instance-id <id> --query 'Reservations[].Instances[].SecurityGroups' to verify.

Problem: Rules look correct but traffic is blocked.
Security groups are stateful, but NACLs are not. Check if a NACL is blocking return traffic: aws ec2 describe-network-acls --filters "Name=vpc-id,Values=<vpc-id>".

Problem: SG reference doesn’t work.
Verify both security groups are in the same VPC. SG references don’t work cross-VPC.

Problem: Instance can’t download packages or reach external APIs.
Check outbound rules. The default allows all outbound, but if someone modified it, you may be missing HTTPS (443) or DNS (53) outbound access.

Problem: Ping works but application traffic doesn’t.
ICMP (ping) and TCP are different protocols with different rules. Allowing ICMP doesn’t allow TCP, and vice versa.

Useful debugging commands:

# Check instance network configuration
ip addr

# Verify what's listening on the instance
ss -tulnp

# Check for host-based firewall rules
sudo iptables -L -n

# Describe security group rules via CLI
aws ec2 describe-security-groups --group-ids &lt;sg-id>

# Trace route to identify where traffic stops
traceroute &lt;destination-ip>

AWS Best Practices (Solutions Architect Level)

Principle of Least Privilege: Every security group rule should answer the question: “What’s the minimum access required for this component to function?” If you can’t justify a rule, delete it.

Layered Security: Security groups are your first layer, but don’t stop there. Use NACLs as a second layer for subnet-level controls. This defense-in-depth approach means a misconfiguration in one layer doesn’t expose everything.

Blast Radius Reduction: Design security groups so that compromising one tier doesn’t grant access to others. The SG-to-SG pattern you learned today is key to this.

Naming and Tagging: Use consistent naming conventions like <environment>-<tier>-sg (e.g., prod-web-sg, dev-app-sg). Add tags for Environment, Owner, and CostCenter.

Operational Excellence: Document your security group strategy. When you’re troubleshooting at 3 AM, good documentation is the difference between a 10-minute fix and a 2-hour nightmare.

Scaling Patterns: SG references scale automatically. When you add instances to your auto-scaling group, they inherit access through the shared security group—no rule updates needed.

Regular Audits: Use AWS Config rules like vpc-sg-open-only-to-authorized-ports to continuously monitor for overly permissive security groups.

For deeper guidance, review the official AWS documentation on Security Group Rules and VPC Security Best Practices.


AWS Security Groups Interview Questions

If you’re preparing for AWS interviews or the Solutions Architect exam, expect questions like these. I’ve included the thought process behind each answer—that’s what interviewers really want to see.

Q1: What’s the difference between security groups and NACLs?

Security groups operate at the instance level and are stateful, meaning return traffic is automatically allowed. NACLs operate at the subnet level and are stateless, requiring explicit rules for both inbound and outbound traffic. Security groups only support allow rules, while NACLs support both allow and deny rules. In practice, security groups are your primary tool; NACLs are a secondary defense layer.

Q2: Can you attach multiple security groups to a single EC2 instance?

Yes, and this is actually a common pattern. When you attach multiple security groups, the rules are aggregated—traffic is allowed if any of the attached security groups permits it. This lets you create modular, reusable security groups (like a “bastion-access-sg” that you attach to instances needing SSH from a bastion host).

Q3: What happens if you delete a security group that’s referenced by another security group?

AWS prevents you from deleting it. You’ll get an error saying the security group is being referenced. You must first remove the reference, then delete the security group. This is a safety mechanism that prevents you from accidentally breaking connectivity.

Q4: How would you troubleshoot an EC2 instance that can’t connect to an RDS database in the same VPC?

I’d check these in order: first, verify the RDS security group allows inbound traffic from the EC2 instance’s security group (or CIDR). Second, confirm both resources are in the same VPC. Third, check if there’s a NACL blocking traffic at the subnet level. Fourth, verify the RDS instance is in an available state and the endpoint is correct. Fifth, test from the EC2 instance using nc -zv <rds-endpoint> 3306 to isolate whether it’s a network issue or application issue.

Q5: Why would you use a security group reference instead of a CIDR block?

SG references are dynamic and maintain correct access even when instances scale up/down or get replaced with new IP addresses. CIDR blocks are static and require manual updates. SG references are also self-documenting—seeing “allow from web-sg” is clearer than “allow from 10.0.1.0/24” because it communicates intent.

Q6: A security group has no outbound rules. What traffic can leave instances using this security group?

None. If there are no outbound rules, all outbound traffic is blocked. This is different from the default security group, which allows all outbound traffic. This trips people up because they assume outbound is always allowed.

Q7: Can security group rules reference security groups in a different VPC?

No. Security group references only work within the same VPC. For cross-VPC communication, you’d use VPC peering or Transit Gateway, and reference CIDR blocks or use prefix lists.


Frequently Asked Questions (FAQs): AWS Security Groups Hands-On Lab

What is a security group in AWS?

A security group acts as a virtual firewall for your EC2 instances, controlling inbound and outbound traffic at the instance level. Unlike traditional firewalls that you install on a server, security groups are managed through AWS and applied at the hypervisor level. Each security group contains rules that specify which traffic is allowed, and by default, all inbound traffic is denied while all outbound traffic is allowed.

Are AWS security groups stateful or stateless?

AWS security groups are stateful. This means when you allow inbound traffic on a specific port, the response traffic is automatically allowed to flow back out without needing a separate outbound rule. For example, if you allow inbound HTTP on port 80, the web server’s responses go back to clients automatically. This is fundamentally different from Network ACLs, which are stateless and require explicit rules for both directions.

How many security groups can I attach to an EC2 instance?

You can attach up to five security groups to a single EC2 instance by default. This limit can be increased by contacting AWS support, though it’s rarely necessary. When multiple security groups are attached, their rules are combined—traffic is allowed if permitted by any of the attached groups.

What is an SG-to-SG reference and when should I use it?

An SG-to-SG reference (security group to security group reference) allows you to create rules that permit traffic from instances associated with another security group, rather than specifying IP addresses. You should use this pattern whenever traffic flows between tiers of an application (web to app, app to database) because it automatically accommodates scaling and IP changes without requiring rule updates.

Can I use security groups with other AWS services besides EC2?

Absolutely. Security groups protect RDS databases, ElastiCache clusters, Lambda functions in VPCs, EFS mount targets, ELB/ALB load balancers, and many other VPC-enabled AWS services. The configuration works the same way—you define inbound and outbound rules based on protocol, port, and source/destination.

Why can’t I ping my EC2 instance even though security groups look correct?

Ping uses ICMP protocol, not TCP or UDP. You need an explicit inbound rule allowing ICMP (specifically “Echo Request”) from the source you’re pinging from. Many engineers forget this because they associate “connectivity” with TCP ports, but ICMP is a separate protocol that requires its own rule.

What’s the difference between 0.0.0.0/0 and My IP in security group rules?

The CIDR 0.0.0.0/0 represents the entire IPv4 internet—any IP address can match this rule. “My IP” is an AWS Console convenience that automatically detects your current public IP address and uses it as the source. Always use “My IP” or specific CIDR ranges for sensitive ports like SSH (22) and RDP (3389), and reserve 0.0.0.0/0 only for intentionally public services like HTTP/HTTPS.

Do security group changes take effect immediately?

Yes. Security group rule changes take effect immediately without requiring instance restarts or any propagation delay. This is both powerful and dangerous—a misconfigured rule change can instantly break production connectivity.

How do I audit security groups for overly permissive rules?

Use AWS Config with managed rules like vpc-sg-open-only-to-authorized-ports to continuously monitor for dangerous configurations. You can also use AWS Security Hub, which aggregates findings from multiple security services, or third-party tools like Prowler. For manual auditing, the CLI command aws ec2 describe-security-groups exports all rules for review.


Conclusion & Next Steps

You’ve just completed one of the most important foundational labs in AWS networking. You now understand how inbound and outbound rules control traffic flow, why SG-to-SG references are superior to CIDR blocks for dynamic environments, how to test and validate security group configurations, and what separates good security group hygiene from dangerous shortcuts.

Security groups are foundational to everything you’ll build on AWS. The patterns you practiced today—isolated tiers, minimal access, SG references—will serve you whether you’re building a simple web app or architecting a multi-region enterprise platform.

Ready to level up? In the next lab, we’ll tackle the often-confused relationship between Security Groups and Network ACLs. You’ll learn when to use each, how they interact, and why getting this wrong causes some of the most confusing connectivity issues in AWS.

👉 Next Lab: Lab 1.4 — Network ACLs vs Security Groups {link}


Related Posts:


Last updated: 2025 | Part of the AWS Hands-On Lab Series on thedevopstooling.com

Similar Posts

Leave a Reply