Skip to main content

Internet Gateway Changes Alarm Should Be Enabled

More Info:

AWS VPC Customer/Internet Gateway configuration changes should be monitored using CloudWatch alarms.

Risk Level

Medium

Address

Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • AWS Well Architected Framework
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS AWS
  • CIS Critical Security Controls v8
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • Cloudanix Best Practice
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • Essential 8
  • HIPAA
  • HITRUST CSF
  • ISO 27001
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIS2 Directive
  • NIST CSF
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SOC2
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • UK NCSC Cyber Assessment Framework

Triage and Remediation

Remediation

Using Console

Below are console-only steps to configure a CloudWatch alarm that fires when Internet Gateway (IGW) changes occur, based on CloudTrail logs.


Prerequisites

  1. CloudTrail enabled and logging to CloudWatch Logs.
    • If you already have a CloudTrail trail sending events to a CloudWatch Logs log group, skip to Step 2.
    • If not:
      1. Go to CloudTrail console.
      2. In the left menu, select Trails, then Create trail (or edit an existing trail).
      3. In Log events, choose:
        • Management events: Read/Write events → at least Write.
      4. In CloudWatch Logs, Enable:
        • Choose or create a Log group (e.g., /aws/cloudtrail/main).
        • Set an IAM role as prompted.
      5. Save the trail.

You must know the CloudWatch Logs log group name to proceed.


Step 1 – Create a Metric Filter for IGW Changes

  1. Go to CloudWatch console.

  2. In the left menu, choose Logs → Log groups.

  3. Click the CloudTrail log group (e.g., /aws/cloudtrail/main).

  4. Click the Metric filters tab.

  5. Click Create metric filter.

  6. Under Filter pattern, use a pattern that matches Internet Gateway changes. For example:

    { ($.eventSource = "ec2.amazonaws.com") &&
    ($.eventName = "CreateInternetGateway" ||
    $.eventName = "DeleteInternetGateway" ||
    $.eventName = "AttachInternetGateway" ||
    $.eventName = "DetachInternetGateway") }
  7. Click Next.

  8. Under Assign metric:

    • Filter name: IGWChangesFilter
    • Metric namespace: Security/CloudTrail
    • Metric name: InternetGatewayChanges
    • Metric value: 1
    • Default value: leave blank (or 0).
  9. Click Next, then Create metric filter.


Step 2 – Create an Alarm on the Metric

  1. In the same log group’s Metric filters tab, find IGWChangesFilter.
  2. Click the three dots or the Create alarm link for that metric.
  3. This takes you to the Specify metric and conditions page:
    • Verify Metric namespace: Security/CloudTrail
    • Metric: InternetGatewayChanges
  4. Under Conditions:
    • Statistic: Sum
    • Period: 5 minutes (or as desired)
    • Threshold type: Static
    • Whenever metric is: Greater than
    • Threshold value: 0
  5. Click Next.

Step 3 – Configure Notifications

  1. Under Notification:
    • Alarm state trigger: In alarm
    • Select an SNS topic:
      • Choose an existing topic (e.g., security-alerts), or
      • Click Create new topic, give it a name, and enter your email.
  2. If you created a new topic:
    • After finishing, check your email to Confirm subscription.
  3. Click Next.

Step 4 – Name and Create the Alarm

  1. Alarm name: InternetGatewayChangesAlarm
  2. Alarm description: Alarm when Create/Delete/Attach/Detach Internet Gateway occurs via CloudTrail
  3. Review all settings.
  4. Click Create alarm.

Result

Whenever an Internet Gateway is created, deleted, attached, or detached, CloudTrail logs the event, the metric filter increments InternetGatewayChanges, and the CloudWatch alarm goes In alarm (and sends SNS notification).

Using CLI

Below is a minimal, end‑to‑end example of enabling an “Internet Gateway Changes” CloudWatch alarm using the AWS CLI.

Assumptions:

  • You already have a CloudTrail trail delivering logs to a CloudWatch Logs log group called /aws/cloudtrail/main.
  • You want an SNS notification when an Internet Gateway is created/attached/detached/deleted.

You can adjust names/regions as needed.


1. Create (or choose) an SNS topic

aws sns create-topic \
--name internet-gateway-changes-topic

Note the TopicArn from the output (call it IGW_TOPIC_ARN).

Subscribe your email (or other endpoint):

aws sns subscribe \
--topic-arn IGW_TOPIC_ARN \
--protocol email \
--notification-endpoint you@example.com

Confirm the subscription from your email.


2. Create a CloudWatch Logs metric filter for Internet Gateway changes

Replace:

  • LOG_GROUP_NAME with your CloudTrail log group (e.g. /aws/cloudtrail/main).
aws logs put-metric-filter \
--log-group-name "/aws/cloudtrail/main" \
--filter-name "InternetGatewayChanges" \
--filter-pattern '{ ($.eventSource = "ec2.amazonaws.com") && ( ($.eventName = "CreateInternetGateway") || ($.eventName = "AttachInternetGateway") || ($.eventName = "DetachInternetGateway") || ($.eventName = "DeleteInternetGateway") ) }' \
--metric-transformations \
metricName="InternetGatewayChangesCount",metricNamespace="Security",metricValue="1"

This creates a metric:

  • Namespace: Security
  • Name: InternetGatewayChangesCount
  • Increments by 1 when any of the above events occurs.

3. Create a CloudWatch alarm on that metric

Replace:

  • REGION with your region (e.g. us-east-1).
  • IGW_TOPIC_ARN with the SNS TopicArn from step 1.
aws cloudwatch put-metric-alarm \
--alarm-name "InternetGatewayChangesAlarm" \
--alarm-description "Alarm when Internet Gateway is created/attached/detached/deleted" \
--metric-name "InternetGatewayChangesCount" \
--namespace "Security" \
--statistic Sum \
--period 300 \
--evaluation-periods 1 \
--threshold 1 \
--comparison-operator GreaterThanOrEqualToThreshold \
--treat-missing-data notBreaching \
--alarm-actions IGW_TOPIC_ARN \
--region us-east-1

This triggers if at least one IGW change occurs in a 5‑minute period.


4. Verify

  • Generate a test event (e.g., create/attach an Internet Gateway).
  • Check:
    • CloudWatch → Logs: metric filter is matched.
    • CloudWatch → Alarms: alarm goes to ALARM state.
    • SNS: notification email is received.

This completes enabling the Internet Gateway Changes alarm using AWS CLI.

Using Python

Below are the steps and example Python (boto3) code to detect and alarm on Internet Gateway changes using AWS CloudWatch:


1. Prerequisites

  1. You must have:

    • CloudTrail enabled and recording management events.
    • A CloudWatch Logs log group where CloudTrail is delivering events.
      Example name below: /aws/cloudtrail/management
  2. Install and configure boto3:

pip install boto3
aws configure

2. Decide What to Alert On

We want to monitor CloudTrail events for Internet Gateway changes, e.g.:

  • CreateInternetGateway
  • DeleteInternetGateway
  • AttachInternetGateway
  • DetachInternetGateway

The CloudWatch Logs metric filter will look for these in eventName.


3. Python Script Overview

The script will:

  1. Create (or update) a CloudWatch Logs metric filter that:

    • Matches CloudTrail events for the above operations.
    • Publishes a custom metric (e.g. InternetGatewayChanges) in a namespace (e.g. Security).
  2. Create (or update) a CloudWatch alarm that:

    • Triggers whenever the metric is ≥ 1 in a recent period.
    • Sends notification to an SNS topic (you must have one, or create it).

4. Example Python Code

Replace:

  • YOUR_LOG_GROUP_NAME with your CloudTrail log group (e.g. /aws/cloudtrail/management)
  • YOUR_SNS_TOPIC_ARN with an SNS topic ARN for notifications
  • Adjust region/profile as needed.
import boto3
from botocore.exceptions import ClientError

region = "us-east-1"
log_group_name = "/aws/cloudtrail/management" # <-- CHANGE THIS
metric_filter_name = "InternetGatewayChangesFilter"
metric_namespace = "Security"
metric_name = "InternetGatewayChanges"
alarm_name = "InternetGatewayChangesAlarm"
sns_topic_arn = "arn:aws:sns:us-east-1:123456789012:SecurityAlerts" # <-- CHANGE THIS

logs_client = boto3.client("logs", region_name=region)
cw_client = boto3.client("cloudwatch", region_name=region)

def create_or_update_metric_filter():
# Filter pattern for CloudTrail Internet Gateway events
# Matches events where eventSource is ec2.amazonaws.com and eventName is one of the specified operations.
filter_pattern = (
'{ ($.eventSource = "ec2.amazonaws.com") && '
'($.eventName = "CreateInternetGateway" || '
'$.eventName = "DeleteInternetGateway" || '
'$.eventName = "AttachInternetGateway" || '
'$.eventName = "DetachInternetGateway") }'
)

try:
logs_client.put_metric_filter(
logGroupName=log_group_name,
filterName=metric_filter_name,
filterPattern=filter_pattern,
metricTransformations=[
{
"metricName": metric_name,
"metricNamespace": metric_namespace,
"metricValue": "1"
}
]
)
print(f"Metric filter '{metric_filter_name}' created/updated.")
except ClientError as e:
print("Error creating/updating metric filter:", e)
raise

def create_or_update_alarm():
# Alarm if at least 1 matching event occurs in a 5-minute period
try:
cw_client.put_metric_alarm(
AlarmName=alarm_name,
AlarmDescription="Alarm when Internet Gateway configuration changes occur",
Namespace=metric_namespace,
MetricName=metric_name,
Statistic="Sum",
Period=300, # 5 minutes
EvaluationPeriods=1,
Threshold=1,
ComparisonOperator="GreaterThanOrEqualToThreshold",
TreatMissingData="notBreaching",
AlarmActions=[sns_topic_arn],
OKActions=[sns_topic_arn],
ActionsEnabled=True
)
print(f"Alarm '{alarm_name}' created/updated.")
except ClientError as e:
print("Error creating/updating alarm:", e)
raise

if __name__ == "__main__":
create_or_update_metric_filter()
create_or_update_alarm()

5. Validation Steps

  1. Confirm CloudTrail is logging to the specified log group:

    • In the CloudTrail console, open your trail → “CloudWatch Logs” section.
  2. Run the script:

    python create_igw_alarm.py
  3. In the AWS console:

    • CloudWatch → Logs → Log groups → select your group → “Metric filters”
      Confirm InternetGatewayChangesFilter exists.
    • CloudWatch → Alarms
      Confirm InternetGatewayChangesAlarm exists and is in OK state.
  4. Test:

    • Create or delete an Internet Gateway (or attach/detach it).
    • After a few minutes, the alarm should go to ALARM and send an SNS notification.

This setup remediates “Internet Gateway Changes Alarm Should Be Enabled” by programmatically ensuring both the metric filter and the alarm are in place.

Using Terraform
# Metric filter to publish a metric when Internet Gateway changes occur
resource "aws_cloudwatch_log_metric_filter" "internet_gateway_changes" {
name = "internet-gateway-changes-filter"
log_group_name = "/aws/cloudtrail/LOG_GROUP_NAME" # replace with your CloudTrail log group name

# Matches Create/Delete/Attach/Detach Internet Gateway API calls
pattern = <<EOF
{ ($.eventSource = "ec2.amazonaws.com") &&
(($.eventName = "CreateInternetGateway") ||
($.eventName = "DeleteInternetGateway") ||
($.eventName = "AttachInternetGateway") ||
($.eventName = "DetachInternetGateway")) }
EOF

metric_transformation {
name = "InternetGatewayChanges"
namespace = "VPC/ChangeMonitoring" # replace with your desired namespace if needed
value = "1"
}
}

# CloudWatch alarm on the Internet Gateway changes metric
resource "aws_cloudwatch_metric_alarm" "internet_gateway_changes_alarm" {
alarm_name = "internet-gateway-changes-alarm"
alarm_description = "Alarm when VPC Internet Gateway configuration changes are detected"
namespace = aws_cloudwatch_log_metric_filter.internet_gateway_changes.metric_transformation[0].namespace
metric_name = aws_cloudwatch_log_metric_filter.internet_gateway_changes.metric_transformation[0].name
statistic = "Sum"
period = 300
evaluation_periods = 1
threshold = 1
comparison_operator = "GreaterThanOrEqualToThreshold"

treat_missing_data = "notBreaching"

alarm_actions = [
"ARN_OF_SNS_TOPIC_OR_OTHER_ACTION", # replace with your SNS topic ARN or other action
]

dimensions = {
# Add dimensions here only if your metric filter sets them; otherwise omit this block
}
}

Substitute:

  • LOG_GROUP_NAME with your CloudTrail log group name.
  • ARN_OF_SNS_TOPIC_OR_OTHER_ACTION with the SNS topic (or other) ARN to notify.

This change does not force replacement of any dependent VPC resources; it only creates/updates CloudWatch resources. After updating Terraform, terraform plan should show creation (or in-place update) of aws_cloudwatch_log_metric_filter.internet_gateway_changes and aws_cloudwatch_metric_alarm.internet_gateway_changes_alarm with the specified threshold and configuration.

Additional Reading: