Build a Cloud Security Monitoring Stack

Set up threat detection, VPC flow logs, and automated alerts on AWS.

Introduction

30 Second Summary

Think about how a building stays secure. There are locked doors, security cameras recording everything, and alarms that go off when something is wrong. Cloud networks need the same layers of protection.

In this project, you will build a cloud security monitoring stack on AWS that segments your network into isolated zones, detects threats using machine learning, and automatically alerts you when suspicious activity occurs.

What You'll Build

A production-style security monitoring stack that mirrors what Security Operations Center (SOC) teams build in real organizations.

By the end of this project, you'll have:

  • A segmented VPC with public and private subnets demonstrating defense-in-depth architecture.
  • Layered firewall rules using Security Groups and Network ACLs, plus VPC Flow Logs capturing all network traffic for forensic analysis.
  • An automated alerting pipeline that uses GuardDuty intrusion detection, EventBridge, and SNS to email you when threats are detected.
  • Secret Mission: Write threat-hunting queries to analyze flow logs like a SOC analyst.

Are there any prerequisites?

You'll need an AWS account and the AWS CLI installed and configured on your machine. Everything else is set up during the project.

Set Up Your Environment

Before you build anything, you need to make sure your tools are ready and pointed at the right place.

Every AWS resource you create lives in a specific region. In this step, you will confirm your AWS CLI is working, set your default region, and verify that Amazon GuardDuty has not been previously enabled so you qualify for the 30-day free trial.

In this step, get ready to:
  • Verify your AWS CLI credentials are working.
  • Set your default region to us-east-1.
  • Confirm GuardDuty has not been previously enabled in your region.
Verify your AWS CLI is configured

The AWS CLI is your command-line tool for interacting with AWS services. Before creating any resources, you need to confirm it can authenticate with your account.

  • Open your terminal by pressing Cmd+Space (macOS) and typing Terminal, then press Enter.
  • Verify your AWS CLI credentials are working by running this command:
aws sts get-caller-identity

What does this command do?

This command asks AWS "who am I?" and returns your account ID, user ARN, and user ID. If it returns a JSON response, your CLI is properly authenticated.

You should see a JSON response containing your Account, UserId, and Arn.

✔️ I see a JSON response with my account details

Your AWS CLI is authenticated and ready to go.

ⓧ I see an error

If you see an error about credentials or tokens, your AWS CLI is not configured. Run the following to set it up:

aws configure

This will prompt you for your AWS Access Key ID, Secret Access Key, default region, and output format. Enter the credentials from your AWS account.

After configuring, run the aws sts get-caller-identity command again to confirm it works.

Set your default region

AWS services run in data centers around the world, grouped into regions. You need all your resources in the same region so they can communicate with each other.

  • Set us-east-1 as your default region by running this command:
aws configure set region us-east-1

Why us-east-1?

The us-east-1 region (N. Virginia) has the broadest AWS service availability. It is the most commonly used region for learning and development.

  • Confirm your region was set correctly by running:
aws configure get region

You should see us-east-1 printed in your terminal.

Not seeing us-east-1?

Make sure you typed the command exactly as shown above. If it still shows a different region, run the set-region command again:

aws configure set region us-east-1

Help me fix my region configuration

Confirm GuardDuty is not already enabled

Amazon GuardDuty offers a 30-day free trial per region for new accounts. If GuardDuty has already been enabled in us-east-1 before, you may not qualify for the free trial.

  • Check whether GuardDuty has any existing detectors in your region by running this command:
aws guardduty list-detectors

What does this command do?

This command lists all GuardDuty detector IDs in your current region. A detector is the resource that represents an active GuardDuty instance.

If the DetectorIds list is empty, GuardDuty has never been enabled here.

You should see a response like this, with an empty list:

{
    "DetectorIds": []
}

✔️ DetectorIds is empty

You qualify for the 30-day free trial. You will enable GuardDuty later in the project.

ⓧ DetectorIds contains an ID

GuardDuty was previously enabled in this region. You can still continue with the project, but you may incur charges after the original trial period ended.

If you want to start fresh with a free trial, you can switch to a different region (like us-west-2) by running:

aws configure set region us-west-2

Then run the list-detectors command again to confirm the new region has no existing detectors:

aws guardduty list-detectors
  • Sign into the AWS Management Console at https://console.aws.amazon.com.
  • In the top-right corner of the console, confirm the region dropdown shows US East (N. Virginia).
  • If it shows a different region, click the dropdown and select US East (N. Virginia).

Your environment is locked and loaded. Next up, you will build a segmented VPC that separates public and private resources.

Build a Segmented VPC

Your security monitoring stack needs a network to protect. In production, organizations don't throw all their resources onto one flat network.

They segment their infrastructure into zones with different trust levels. In this step, you'll create a VPC (Virtual Private Cloud) with a public subnet and a private subnet. This is the foundation of defense-in-depth architecture.

In this step, get ready to:
  • Create a VPC with public and private subnets using the VPC Console wizard.
  • Verify the Internet Gateway and route tables that control traffic flow.
  • Understand why network segmentation isolates sensitive resources.
Create your VPC with public and private subnets

The VPC Console has a wizard that creates your VPC, subnets, Internet Gateway, and route tables all at once. You'll configure it with specific IP address ranges for each subnet.

  • In the AWS Management Console, navigate to the VPC service by typing VPC in the search bar at the top and selecting VPC.
  • On the VPC Dashboard, click Create VPC.
  • Under Resources to create, select VPC and more.

Why VPC and more?

This option creates your VPC along with subnets, route tables, and an Internet Gateway in one step. The alternative ("VPC only") would require you to create each resource manually. For learning purposes, the wizard gives you a visual preview of the entire network before you build it.

  • Under Name tag auto-generation, clear the pre-filled text and type security-monitoring.
  • For IPv4 CIDR block, enter 10.0.0.0/16.
  • For Number of Availability Zones (AZs), choose 1.
  • For Number of public subnets, choose 1.
  • For Number of private subnets, choose 1.
  • Expand Customize subnets CIDR blocks.
  • For the public subnet CIDR block, enter 10.0.1.0/24.
  • For the private subnet CIDR block, enter 10.0.2.0/24.
  • For NAT gateways, select None.
  • For VPC endpoints, select None.

What do these CIDR blocks mean?

A CIDR block defines a range of IP addresses. 10.0.0.0/16 gives your VPC 65,536 possible addresses (the entire 10.0.x.x range).

The /24 subnets carve out 256 addresses each. 10.0.1.0/24 (public) gets addresses 10.0.1.0 through 10.0.1.255. 10.0.2.0/24 (private) gets 10.0.2.0 through 10.0.2.255.

  • Look at the Preview panel on the right side of the page. You should see a diagram showing your VPC with one public subnet, one private subnet, and an Internet Gateway connected to the public subnet.
  • Click Create VPC.

AWS will take a few seconds to create all the resources. You should see a success banner with a list of created resources including your VPC, subnets, route tables, and Internet Gateway.

Seeing an error about CIDR overlap?

If you see an error about overlapping CIDR blocks, make sure you entered 10.0.1.0/24 and 10.0.2.0/24 (not the same range for both subnets). Each subnet needs its own unique address range within the VPC.

help me fix my VPC CIDR block configuration error

Verify the Internet Gateway and route tables

The wizard created an Internet Gateway and two route tables automatically. Now you'll verify that the public subnet can reach the internet while the private subnet cannot.

  • Click View VPC to navigate to your new VPC's details page.
  • In the left navigation pane, click Route tables.
  • You should see two route tables with names starting with security-monitoring. One is associated with the public subnet, and one with the private subnet.
  • Click the route table associated with the public subnet (its name will contain public).
  • Select the Routes tab at the bottom of the page.

You should see two routes. The first is 10.0.0.0/16 with a target of local (traffic stays within the VPC). The second is 0.0.0.0/0 with a target pointing to your Internet Gateway (igw- prefix). This route sends all internet-bound traffic through the gateway.

  • Go back to Route tables and click the route table associated with the private subnet (its name will contain private).
  • Select the Routes tab again.

This time, you should see only one route: 10.0.0.0/16 with target local. There is no route to 0.0.0.0/0. Resources in this subnet cannot reach the internet directly.

What is an Internet Gateway?

An Internet Gateway connects your VPC to the public internet. A subnet is considered "public" only if its route table has a route that sends internet-bound traffic (0.0.0.0/0) to the gateway.

Your private subnet has no such route. Even if an attacker compromised a resource in the public subnet, they couldn't directly reach anything in the private subnet from the internet. This is network segmentation in action.

Don't see two route tables?

Make sure you're filtering by your new VPC. In the Route tables list, use the search/filter bar and select your security-monitoring-vpc to show only route tables associated with it. Your account may have other route tables from the default VPC.

help me find my VPC route tables in the AWS console

Understand why network segmentation matters

You now have a network split into two trust zones. The public subnet faces the internet. The private subnet is isolated from direct internet access.

Why separate public and private subnets?

In a production environment, you place internet-facing resources (load balancers, web servers) in the public subnet. Sensitive resources (databases, application servers, internal APIs) go in the private subnet where they have no direct internet exposure.

Even if an attacker exploits a public-facing service, they still can't directly reach resources in the private subnet from the internet. Each layer an attacker must bypass is another chance to detect and stop them. This layered approach is what security professionals call defense-in-depth.

Your segmented VPC is ready. Next up, you'll add layered firewall rules using Security Groups and Network ACLs to control exactly what traffic can flow between these zones.

Configure Layered Firewall Rules

Your VPC now has a public subnet and a private subnet, each with its own route table. Network segmentation alone is not enough to protect your resources. You need firewall rules that control exactly what traffic can flow into each segment.

AWS gives you two layers of firewall. Security Groups act as stateful firewalls at the instance level. Network ACLs act as stateless firewalls at the subnet level. Using both together creates a defense-in-depth architecture where one layer catches what the other might miss.

In this step, get ready to:
  • Create a Security Group that restricts SSH access to your IP address only.
  • Configure a Network ACL that blocks internet traffic from reaching your private subnet.
  • Understand how these two layers work together for defense-in-depth.
Create a Security Group for the public subnet

A Security Group controls which traffic is allowed to reach resources inside your VPC. You will create one that only permits SSH connections from your personal IP address.

  • In the VPC console, click Security Groups in the left navigation pane.
  • Click Create security group.
  • For Security group name, enter public-sg.
  • For Description, enter Allow SSH from my IP only.
  • For VPC, select security-monitoring-vpc.

Now add the inbound rule that restricts SSH to only your IP address.

  • In the Inbound rules section, click Add rule.
  • For Type, select SSH.
  • For Source, select My IP from the dropdown.
  • Leave the Outbound rules section as-is. The default outbound rule allows all traffic, which is what you want.
  • Click Create security group.

What does My IP do?

When you select My IP as the source, AWS automatically detects your current public IP address and fills in the CIDR block (for example, 203.0.113.25/32).

The /32 suffix means only that single IP address is allowed. This follows the principle of least privilege, where you grant only the minimum access needed.

You should see a green success banner confirming your Security Group was created.

Don't see your VPC in the dropdown?

Make sure you are in the us-east-1 region. Check the region selector in the top-right corner of the AWS Console.

If the VPC still doesn't appear, verify that security-monitoring-vpc was created in the previous step. Help me find my VPC in the console.

Create a custom Network ACL for the private subnet

Network ACLs provide a second line of defense at the subnet level. You will create one that explicitly blocks all internet traffic from reaching your private subnet while still allowing traffic from the public subnet.

  • In the VPC console left navigation, click Network ACLs.
  • Click Create network ACL.
  • For Name, enter private-nacl.
  • For VPC, select security-monitoring-vpc.
  • Click Create network ACL.

Why does a new NACL block everything?

A custom Network ACL starts with only a default deny-all rule (the * rule) for both inbound and outbound traffic. This is the opposite of the default NACL that comes with your VPC, which allows everything.

You will now add explicit rules to allow only the traffic you want.

Now add inbound rules to your new NACL.

  • Select private-nacl from the list.
  • Click the Inbound rules tab.
  • Click Edit inbound rules.
  • Click Add new rule and configure the first rule as follows:
  • Rule number: 100.
  • Type: All traffic.
  • Source: 10.0.1.0/24 (your public subnet CIDR).
  • Allow/Deny: Allow.
  • Click Add new rule again and configure the second rule:
  • Rule number: 200.
  • Type: All traffic.
  • Source: 0.0.0.0/0 (all internet traffic).
  • Allow/Deny: Deny.
  • Click Save changes.

Why does rule ordering matter?

NACL rules are evaluated in ascending order by rule number. The first rule that matches the traffic is applied, and no further rules are checked.

Rule 100 (ALLOW from 10.0.1.0/24) is evaluated before Rule 200 (DENY from 0.0.0.0/0). Traffic from the public subnet matches Rule 100 first and is allowed through. All other traffic hits Rule 200 and is denied.

Now associate this NACL with your private subnet.

  • With private-nacl still selected, click Actions.
  • Click Edit subnet associations.
  • Select the checkbox next to your private subnet (10.0.2.0/24).
  • Click Save changes.

You should see the subnet listed under Subnet associations for your NACL.

Don't see your private subnet in the association list?

Confirm that you selected private-nacl before clicking Actions. If you accidentally selected a different NACL, the subnet associations will differ.

Also verify that your private subnet belongs to security-monitoring-vpc. Only subnets in the same VPC will appear. Help me associate my NACL with the correct subnet.

Compare Security Groups and Network ACLs

You now have two layers of firewall protecting your VPC. Understanding how they differ is essential for designing secure cloud networks.

How do Security Groups and NACLs work together?

Security Groups are stateful and operate at the instance level. If you allow inbound SSH traffic, the response traffic is automatically allowed out without needing a separate outbound rule.

Network ACLs are stateless and operate at the subnet level. You must explicitly allow both inbound and outbound traffic because responses are not automatically permitted.

Together they form defense-in-depth. If someone accidentally opens a Security Group to all traffic, the NACL still blocks unauthorized sources at the subnet boundary. If the NACL rules are too broad, Security Groups still restrict access at the instance level.

Why two layers instead of one?

In production environments, teams change firewall rules frequently. A single misconfiguration can expose sensitive resources. Having both Security Groups and NACLs means a mistake in one layer is caught by the other.

Your layered firewall rules are in place. Next up, you will enable VPC Flow Logs to capture all network traffic for forensic analysis.

Enable VPC Flow Logs

Your network is segmented and your firewall rules are in place. Now you need visibility into what traffic is actually hitting your VPC.

In this step, you will enable VPC Flow Logs. Flow Logs capture metadata about every network connection attempt in your VPC. They record which IP talked to which IP, on what port, and whether the traffic was accepted or rejected by your firewall rules.

In this step, get ready to:
  • Create a CloudWatch Logs log group to store your flow log data.
  • Create an IAM role that gives VPC Flow Logs permission to write to CloudWatch.
  • Enable a VPC Flow Log on your entire VPC that captures all traffic.
Create a CloudWatch Logs log group

Flow log records need a destination. You will create a CloudWatch Logs log group that acts as the central collection point for all network traffic data from your VPC.

  • Open the CloudWatch console at https://console.aws.amazon.com/cloudwatch/.
  • In the left navigation pane, choose Log Management.
  • Choose Actions, then choose Create log group.
  • Enter /vpc/security-flow-logs as the log group name.
  • Leave all other settings as default and choose Create log group.

What is a CloudWatch Logs log group?

A log group is a container that holds related log streams. When VPC Flow Logs publish data to CloudWatch, each network interface in your VPC gets its own log stream inside this group.

The /vpc/ prefix in the name is a naming convention that helps you organize log groups by source. It has no functional effect.

  • Confirm you see /vpc/security-flow-logs listed in your log groups table with a status of Active.

Don't see the log group?

Make sure you are in the us-east-1 region. Check the region selector in the top-right corner of the console. Log groups are region-specific.

help me troubleshoot why my CloudWatch log group isn't appearing

Create an IAM role for VPC Flow Logs

VPC Flow Logs needs permission to write data into your CloudWatch log group. You will create an IAM role that the Flow Logs service can assume. This role grants the specific permissions needed to create log streams and publish log events.

  • Open the IAM console at https://console.aws.amazon.com/iam/.
  • In the left navigation pane, choose Policies.
  • Choose Create policy.
  • Select the JSON tab and replace the contents with the following policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents",
        "logs:DescribeLogGroups",
        "logs:DescribeLogStreams"
      ],
      "Resource": "*"
    }
  ]
}

What does this policy allow?

This policy grants five permissions that VPC Flow Logs needs to deliver data to CloudWatch Logs. It can create log groups and streams, write log events, and describe existing groups and streams.

The Resource: "*" means these permissions apply to any log group. In production, you would scope this to a specific log group ARN.

  • Choose Next.
  • Enter flow-logs-policy as the policy name.
  • Choose Create policy.

Now create the IAM role that uses this policy.

  • In the left navigation pane, choose Roles.
  • Choose Create role.
  • For Trusted entity type, select Custom trust policy.
  • Replace the default trust policy JSON with the following:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "vpc-flow-logs.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

What is a trust policy?

A trust policy defines who can assume (use) this role. Here, you are telling AWS that only the vpc-flow-logs.amazonaws.com service is allowed to assume this role. No users or other services can use it.

  • Choose Next.
  • On the Add permissions page, search for flow-logs-policy and select the checkbox next to it.
  • Choose Next.
  • Enter flow-logs-role as the role name.
  • Choose Create role.
  • Confirm you see a success banner at the top of the page indicating the role was created.

Policy not showing up in the search?

Make sure you are searching for flow-logs-policy exactly. If it still does not appear, go back to Policies in the left navigation and confirm the policy was created successfully.

help me find my IAM policy when creating a role

Create a VPC Flow Log

With the log group and IAM role ready, you can now enable flow logging on your entire VPC. This captures metadata about every connection attempt across all subnets.

  • Open the VPC console at https://console.aws.amazon.com/vpc/.
  • In the left navigation pane, choose Your VPCs.
  • Select the checkbox next to security-monitoring-vpc.
  • Choose Actions, then Create flow log.
  • For Filter, select All. This captures both accepted and rejected traffic.
  • For Maximum aggregation interval, leave the default (10 minutes).
  • For Destination, select Send to CloudWatch Logs.
  • For Destination log group, choose /vpc/security-flow-logs from the dropdown.
  • For IAM role, choose flow-logs-role from the dropdown.
  • For Log record format, keep AWS default format selected.
  • Choose Create flow log.

Why capture ALL traffic?

Capturing both accepted and rejected traffic gives you complete visibility. Accepted traffic shows normal communication patterns. Rejected traffic shows connection attempts that your Security Groups or NACLs blocked.

In a real Security Operations Center, rejected traffic is often the most interesting. It reveals port scans, unauthorized access attempts, and misconfigured applications.

No performance impact

Flow log data is collected outside of the path of your network traffic. Enabling flow logs does not affect network throughput or latency.

  • Confirm you see a success message indicating the flow log was created.
  • Select your VPC and choose the Flow logs tab at the bottom of the page.
  • Verify the flow log shows a status of Active.

Flow logs take a few minutes to start

It takes 2-5 minutes for the first flow log records to appear in CloudWatch Logs. You will verify the records in the next check.

Now verify that flow log data is arriving in CloudWatch.

  • Return to the CloudWatch console at https://console.aws.amazon.com/cloudwatch/.
  • In the left navigation pane, choose Log Management.
  • Choose the /vpc/security-flow-logs log group.
  • Wait 2-5 minutes, then refresh the page. You should see one or more log streams appear.
  • Choose any log stream to view the flow log records inside.

What do flow log records look like?

Each record contains fields like source IP, destination IP, source port, destination port, protocol, number of packets, number of bytes, and the action (ACCEPT or REJECT). This is Layer 4 metadata. It does not capture packet contents.

No log streams appearing after 5 minutes?

Check that your flow log status is Active in the VPC console under the Flow logs tab. If the status shows an error, verify that flow-logs-role has the correct trust policy (vpc-flow-logs.amazonaws.com as the principal) and the flow-logs-policy is attached.

help me debug why my VPC Flow Logs aren't publishing to CloudWatch

Your VPC now has complete network visibility. Every connection attempt is being recorded. Next up, you will enable GuardDuty to apply machine learning and threat intelligence to this data for automated intrusion detection.

Enable GuardDuty for Intrusion Detection

Your network now has layered firewalls and full traffic logging. The next piece of a real security stack is intrusion detection.

Firewalls block known-bad traffic, but sophisticated attackers find ways around rules. Amazon GuardDuty is a managed threat detection service that uses machine learning and threat intelligence feeds to spot suspicious activity that your firewall rules alone would miss.

In this step, get ready to:
  • Enable GuardDuty in your region and start the 30-day free trial.
  • Review the data sources GuardDuty monitors automatically.
  • Generate sample findings to see what a real threat alert looks like.
Enable Amazon GuardDuty

GuardDuty monitors three foundational data sources the moment you enable it: AWS CloudTrail management event logs, VPC Flow Logs, and DNS query logs. You do not need to configure any of these manually.

  • Open the GuardDuty console by navigating to:
  • https://console.aws.amazon.com/guardduty/
  • Select the Amazon GuardDuty - All features option.
  • Click Get started.
  • On the Welcome to GuardDuty page, click Enable GuardDuty.

What just happened?

Enabling GuardDuty created a detector in us-east-1 and started your 30-day free trial. GuardDuty immediately begins analyzing CloudTrail management events, VPC Flow Logs, and DNS query logs for your account.

You did not need to point GuardDuty at your VPC Flow Logs manually. It pulls independent streams of data directly from AWS services.

What is a GuardDuty detector?

A detector is the GuardDuty resource that represents the service enabled in a specific region. Each region gets its own detector. The detector processes your data sources and generates findings when it spots suspicious activity.

Review the GuardDuty dashboard

After enabling GuardDuty, you land on the Summary dashboard. This gives you a high-level view of your account's security posture.

  • In the left navigation pane, click Summary if you are not already on it.

The dashboard shows widgets for total findings, affected resources, and findings over time. Since GuardDuty was just enabled, all values will be zero.

What data sources does GuardDuty monitor?

GuardDuty automatically ingests three foundational data sources without any extra setup:

  • AWS CloudTrail management event logs track API calls across your account (who created a resource, who changed permissions).
  • VPC Flow Logs capture network traffic metadata (source/destination IPs, ports, accept/reject actions).
  • DNS query logs reveal if any resource is communicating with known malicious domains.

GuardDuty correlates signals across all three to detect threats that would be invisible in any single data source alone.

Generate sample findings

Real threats may take days or weeks to appear. To understand what GuardDuty alerts look like right now, you can generate sample findings. These simulate every supported threat type with placeholder values.

  • In the left navigation pane, click Settings.
  • Scroll down to the Sample findings section.
  • Click Generate sample findings.
  • In the left navigation pane, click Findings.

You should see a list of findings on the Current findings page. Each one is prefixed with [SAMPLE] to distinguish it from a real threat.

  • Click on any finding to open its detail panel.
  • Review the severity level, the affected resource, and the finding description.
  • Look at findings with different severity levels (High, Medium, Low) to understand how GuardDuty categorizes threats.

What do the severity levels mean?

  • High (7.0 - 8.9) indicates a resource is compromised and actively being used for unauthorized purposes. Immediate investigation is needed.
  • Medium (4.0 - 6.9) indicates suspicious activity that deviates from normal behavior. Investigate promptly.
  • Low (1.0 - 3.9) indicates attempted suspicious activity that did not compromise your network (like a failed port scan).

Finding types to explore

Look for findings related to network reconnaissance (port probes, unusual traffic patterns) and DNS-based threats (communication with known malicious domains). These are the types most relevant to the network security stack you just built.

Don't see any findings after generating?

Sample findings can take a minute or two to appear. Try refreshing the Findings page. Make sure the Status filter at the top is set to Current (not Archived).

If GuardDuty was already enabled in this region from a prior project, you may not qualify for the free trial. Check the Settings page to confirm the trial status.

help me troubleshoot why my GuardDuty sample findings are not showing up

GuardDuty is now watching your account around the clock. In the next step, you will wire up an automated alerting pipeline so that when GuardDuty detects a real threat, you get an email notification immediately.

Build the Alerting Pipeline

You have GuardDuty watching for threats and Flow Logs recording all traffic. But detection without notification is useless.

In real Security Operations Centers, the moment a threat is detected, an alert fires automatically. In this step, you'll wire up that same pattern using Amazon SNS for email delivery and Amazon EventBridge to route GuardDuty findings into your inbox in near real-time.

In this step, get ready to:
  • Create an SNS topic and subscribe your email address.
  • Build an EventBridge rule that catches all GuardDuty findings and emails you a formatted alert.
  • Test the full pipeline end-to-end by generating a sample finding and receiving the email.
Create an SNS topic and subscribe your email

SNS (Simple Notification Service) is a messaging service that can push notifications to email, SMS, or other endpoints. You'll create a topic that acts as the delivery channel for your security alerts.

  • Open the Amazon SNS console at https://console.aws.amazon.com/sns/v3/home.
  • Make sure your region is set to US East (N. Virginia) us-east-1 in the top-right corner.
  • In the left navigation panel, click Topics.
  • Click Create topic.
  • For Type, select Standard.
  • For Name, enter guardduty-alerts.
  • Leave all other settings as defaults and click Create topic.

You should see a success banner and your new topic's details page.

  • On the topic details page, click Create subscription.
  • For Protocol, select Email.
  • For Endpoint, enter the email address where you want to receive security alerts.
  • Click Create subscription.

Confirm your subscription via email

Check your email inbox (and spam/junk folder) for a message from AWS Notifications. Click the Confirm subscription link in that email. Your subscription will remain in a Pending confirmation state until you do this. The alerting pipeline will not work without confirmation.

  • Return to the SNS console and refresh the page.
  • Confirm that your subscription's Status now shows Confirmed.

What is an SNS topic?

Think of an SNS topic as a broadcast channel. Any service can publish a message to it, and all subscribers receive that message instantly. In your case, EventBridge will publish GuardDuty findings to this topic, and your email subscription delivers them to your inbox.

The first 1,000 email notifications per month are free under the SNS free tier.

Subscription stuck in Pending confirmation?

Check your spam or junk folder for the confirmation email from AWS. If you entered the wrong email address, delete the subscription and create a new one with the correct address.

help me troubleshoot my SNS email subscription that is stuck in pending confirmation status

Create an EventBridge rule to route GuardDuty findings to SNS

GuardDuty automatically publishes findings as events to EventBridge in near real-time. You need a rule that catches those events and forwards them to your SNS topic with a readable email format.

You'll now configure the rule step by step through the EventBridge wizard.

  • For Name, enter guardduty-findings-rule.
  • For Event bus, make sure default is selected and Enable the rule on the selected event bus is turned on.
  • For Rule type, select Rule with an event pattern.
  • Click Next.

Now you'll define which events this rule matches.

  • For Event source, select AWS events or EventBridge partner events.
  • Scroll down to the Event pattern section.
  • For Creation method, select Use pattern form.
  • For AWS service, choose GuardDuty.
  • For Event type, choose GuardDuty Finding.
  • Click Next.

What does this event pattern match?

The pattern form creates a rule that matches events where the source is aws.guardduty and the detail-type is GuardDuty Finding. This catches every finding GuardDuty generates, regardless of severity.

Next, you'll set up SNS as the target with a formatted email template.

  • For Target types, select AWS service.
  • For Select a target, choose SNS topic.
  • For Topic, select guardduty-alerts.
  • Expand Additional settings.
  • For Configure target input, choose Input transformer.
  • Click Configure input transformer.

The input transformer lets you extract specific fields from the raw GuardDuty event and format them into a readable email.

  • In the Input path field, paste the following JSON:
{
    "severity": "$.detail.severity",
    "Account_ID": "$.detail.accountId",
    "Finding_ID": "$.detail.id",
    "Finding_Type": "$.detail.type",
    "region": "$.region",
    "Finding_Description": "$.detail.description"
}
  • In the Template field, paste the following:
"You have a severity <severity> GuardDuty finding type <Finding_Type> in the <region> Region."
"Finding Description:"
"<Finding_Description>. "
"For more details open the GuardDuty console at https://console.aws.amazon.com/guardduty/home?region=<region>#/findings?search=id%3D<Finding_ID>"

What does the input transformer do?

The Input path extracts specific values from the raw JSON event (severity, account ID, finding type, etc.). The Template arranges those values into a human-readable email body.

Without this transformer, you'd receive the entire raw JSON event in your email. The transformer gives you a clean summary with a direct link back to the GuardDuty console.

  • Click Confirm.
  • Click Next.
  • On the Configure tags page, leave tags empty and click Next.
  • On the Review and create page, verify your settings and click Create rule.

You should see a success banner confirming your rule was created.

Don't see your SNS topic in the dropdown?

Make sure you're in the same region (us-east-1) where you created the SNS topic. If you still don't see it, try refreshing the page or typing the topic name in the search field.

help me find my SNS topic when creating an EventBridge rule

Test the pipeline end-to-end

The best way to verify your alerting pipeline works is to trigger a sample finding and confirm the email arrives in your inbox.

  • Open the GuardDuty console at https://console.aws.amazon.com/guardduty/.
  • In the left navigation panel, click Settings.
  • Scroll down to Sample findings and click Generate sample findings.
  • Wait 2-5 minutes for the findings to generate and propagate through EventBridge to SNS.
  • Check your email inbox for alert messages from AWS Notifications.

What should the email look like?

You'll receive one or more emails with subject lines like AWS Notification Message. The body will contain the severity level, finding type, region, description, and a direct link to the finding in the GuardDuty console.

Sample findings generate many different finding types at once, so expect multiple emails. In production, you'd only receive alerts for real threats.

✔️ I received the email alerts

Your alerting pipeline is working. GuardDuty detected a threat, EventBridge matched the event, and SNS delivered it to your inbox. This is the same pattern SOC teams use in production environments.

ⓧ I didn't receive any emails

  • Check your spam/junk folder for messages from AWS Notifications.
  • Verify your SNS subscription status shows Confirmed in the SNS console.
  • Confirm your EventBridge rule is Enabled (check the State column in the EventBridge Rules list).
  • Make sure the rule's target is set to guardduty-alerts and the region matches across all services (us-east-1).
  • Wait a few more minutes. Sample findings can take up to 5 minutes to propagate.

help me debug why my GuardDuty sample findings are not triggering email alerts through EventBridge and SNS

Your security monitoring stack is now complete. You have threat detection, traffic logging, and automated alerting all working together. Next up, you'll put your flow log analysis skills to the test in the Secret Mission.

Secret mission

Hunt for Threats in Flow Logs

Your security stack detects threats automatically. But what about proactive threat hunting? In this bonus challenge, you'll write a CloudWatch Logs Insights query that analyzes your VPC Flow Logs to find the noisiest sources of rejected traffic hitting your network. This is exactly what SOC analysts do to identify port-scanning behavior and potential attackers.

Clean Up Your Resources

Clean Up Your Resources

Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Most resources in this project are free (VPC, subnets, Security Groups, NACLs, Internet Gateway, EventBridge rule, SNS topic). VPC Flow Logs incur minimal data ingestion charges (pennies for this project's traffic level). The main cost risk is GuardDuty: it is free for 30 days, but will start charging after the trial ends if you do not disable it.

Cost warning

Amazon GuardDuty charges begin after the 30-day free trial expires. If you do not plan to continue using GuardDuty, disable it now to avoid unexpected charges. You can check your remaining trial days in the GuardDuty console under Settings.

Resources you used:

  • VPC (security-monitoring-vpc), public subnet, private subnet, Internet Gateway, route tables, Security Group (public-sg), Network ACL (private-nacl).
  • VPC Flow Log publishing to CloudWatch Logs.
  • CloudWatch Logs log group (/vpc/security-flow-logs).
  • Amazon GuardDuty (enabled in us-east-1, 30-day free trial).
  • SNS topic (guardduty-alerts) with email subscription.
  • EventBridge rule (guardduty-findings-rule).
  • IAM role (flow-logs-role).

Keep everything running

No action needed. Choose this if you are still actively building or want to continue monitoring your account with GuardDuty.

  • GuardDuty continues its 30-day free trial. Monitor the Usage page in the GuardDuty console to track cost estimates as the trial progresses.
  • VPC Flow Logs continue capturing traffic. Charges are minimal (pennies) for low-traffic environments.
  • The SNS topic, EventBridge rule, VPC, and all networking components remain active at no cost.

Pause - I'll come back to this later

Disable GuardDuty to stop the free trial clock and prevent post-trial charges. Keep the VPC and Flow Logs so you can resume later.

  • Open the GuardDuty console at https://console.aws.amazon.com/guardduty/.
  • In the navigation pane, choose Settings.
  • In the Suspend GuardDuty section, choose Suspend GuardDuty, then confirm your action.
  • Your existing findings remain intact. You can re-enable GuardDuty later from the same Settings page.
  • Leave the VPC, Flow Logs, SNS topic, and EventBridge rule in place. Flow Log charges remain minimal.

Delete - I don't want to use this again

Remove all project resources completely. Follow these steps in order.

Step 1: Disable GuardDuty.

Step 2: Delete the VPC Flow Log.

  • Open the VPC console at https://console.aws.amazon.com/vpc/.
  • In the navigation pane, choose Your VPCs.
  • Select security-monitoring-vpc and choose the Flow logs tab.
  • Select the flow log, choose Actions, then Delete flow logs.
  • Type delete when prompted, then choose Delete.

Step 3: Delete the CloudWatch Logs log group.

  • Open the CloudWatch console at https://console.aws.amazon.com/cloudwatch/.
  • In the navigation pane, choose Logs, then Log groups.
  • Select /vpc/security-flow-logs, choose Actions, then Delete log group(s).
  • Confirm the deletion.

Step 4: Delete the EventBridge rule.

  • Open the EventBridge console at https://console.aws.amazon.com/events/.
  • In the navigation pane, choose Rules.
  • Select guardduty-findings-rule, choose Actions, then Delete.
  • Choose Delete to confirm.

Step 5: Delete the SNS topic.

Step 6: Delete the VPC (and all associated networking resources).

  • Return to the VPC console at https://console.aws.amazon.com/vpc/.
  • In the navigation pane, choose Your VPCs.
  • Select security-monitoring-vpc and choose Actions, then Delete VPC.
  • The console will show the resources it will delete for you (subnets, route tables, Security Groups, NACLs, Internet Gateway).
  • Type delete when prompted, then choose Delete.

Step 7: Delete the IAM role.

  • Open the IAM console at https://console.aws.amazon.com/iam/.
  • In the navigation pane, choose Roles.
  • Search for flow-logs-role, select it, then choose Delete.
  • Type the role name to confirm, then choose Delete.

Nice Work!

Nice Work!

You just built a real security monitoring stack from scratch. This is the same layered architecture that Security Operations Center teams deploy to protect production environments.

You've learned how to:

  • Build a segmented network with defense-in-depth architecture, using a VPC with public and private subnets and layered firewalls (Security Groups and NACLs).
  • Enable VPC Flow Logs for complete network traffic visibility and activate GuardDuty for AI-powered intrusion detection.
  • Wire up an automated alerting pipeline using EventBridge and SNS that emails you in real time when threats are detected.
  • Write threat-hunting queries in CloudWatch Logs Insights to analyze flow logs and identify suspicious traffic patterns like a SOC analyst.

Ready to quiz yourself?