> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Route table changes alarm remediation

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are step‑by‑step instructions (AWS Console only) to create a CloudWatch alarm for route table changes using CloudTrail logs.

        ***

        ## Prerequisites

        1. **CloudTrail must be enabled** and logging management events (at least **Write** events) for EC2.
        2. CloudTrail must be delivering logs to a **CloudWatch Logs log group**.
           * If not configured, in the **CloudTrail console → Trails → your trail → Edit → CloudWatch Logs** and attach/create a log group and an IAM role.

        ***

        ## Step 1: Identify/Create the CloudTrail Log Group

        1. Open **CloudTrail console**.
        2. In the left menu, select **Trails**.
        3. Click your active trail.
        4. Scroll to **CloudWatch Logs** section:
           * Note the **CloudWatch Logs log group name**.
           * If none is configured, enable it:
             * Click **Edit**.
             * Under **CloudWatch Logs**, choose or create a log group (e.g., `/aws/cloudtrail/management`).
             * Choose/create an IAM role as prompted.
             * Save.

        ***

        ## Step 2: Create a Metric Filter for Route Table Changes

        1. Open **CloudWatch console**.

        2. In the left menu, select **Logs → Log groups**.

        3. Click the CloudTrail log group you identified (e.g., `/aws/cloudtrail/management`).

        4. Go to the **Metric filters** tab.

        5. Click **Create metric filter**.

        6. In **Filter pattern**, use a pattern that matches route-table–related API calls, for example:

           ```bash theme={null}
           { ($.eventSource = "ec2.amazonaws.com") && 
             (
               ($.eventName = "CreateRoute") ||
               ($.eventName = "CreateRouteTable") ||
               ($.eventName = "ReplaceRoute") ||
               ($.eventName = "ReplaceRouteTableAssociation") ||
               ($.eventName = "DeleteRoute") ||
               ($.eventName = "DeleteRouteTable") ||
               ($.eventName = "DisassociateRouteTable")
             )
           }
           ```

        7. Click **Next**.

        8. For **Filter name**, enter something like:\
           `RouteTableChangesFilter`

        9. Under **Metric details**:
           * **Metric namespace**: e.g., `Security/NetworkChanges`
           * **Metric name**: e.g., `RouteTableChanges`
           * **Metric value**: `1`
           * **Default value**: leave blank or `0`.

        10. Click **Next**, then **Create metric filter**.

        ***

        ## Step 3: Create a CloudWatch Alarm on That Metric

        1. After creating the filter, you’ll see it listed.\
           Select the filter and click **Create alarm** (or go to **CloudWatch → Alarms → All alarms → Create alarm** and select the metric you just created:\
           `Security/NetworkChanges → RouteTableChanges`).
        2. In the **Specify metric and conditions** step:
           * **Statistic**: `Sum`
           * **Period**: e.g., `5 minutes`
           * **Threshold type**: `Static`
           * **Condition**:
             * **Greater** than
             * **Threshold value**: `0`
           * This means: alarm if at least one route table change occurs in 5 minutes.
        3. Click **Next**.

        ***

        ## Step 4: Configure Alarm Notifications

        1. In **Configure actions**:
           * **Alarm state trigger**: `In alarm`
           * Under **Notification**, choose an **SNS topic** to send alerts to:
             * Select an existing topic (e.g., `security-alerts`), or
             * Click **Create new topic**, provide:
               * Topic name: e.g., `route-table-changes-alerts`
               * Email endpoint(s) (security, ops, etc.).
           * Confirm email subscription(s) if prompted.
        2. (Optional) Add additional actions (e.g., OpsCenter, EC2 action – normally not needed here).
        3. Click **Next**.

        ***

        ## Step 5: Name and Create the Alarm

        1. Provide:
           * **Alarm name**: `RouteTableChangesAlarm`
           * **Alarm description**: e.g., `Alerts on any changes to VPC route tables using CloudTrail events.`
        2. Review all settings.
        3. Click **Create alarm**.

        ***

        ## Step 6: Test the Alarm (Optional but Recommended)

        1. Make a **test route table change** (e.g., add a non-impactful route in a test VPC and remove it).
        2. Wait for the metric to update (typically a few minutes).
        3. Confirm:
           * Alarm transitions to **ALARM** state.
           * Notification (email/SNS) is received.

        This completes enabling a CloudWatch alarm for route table changes using the AWS Console.
      </Accordion>

      <Accordion title="Using CLI">
        Below is a minimal, end‑to‑end way to enable an alarm for Route Table changes in AWS using the AWS CLI.

        Assumptions:

        * You already have a CloudTrail trail sending events to a CloudWatch Logs log group (if not, steps 1–2 cover it).
        * Replace all placeholder values (e.g., `MY_TRAIL`, `my-log-group`, `my-route-table-changes-metric`, `my-route-table-changes-alarm`, etc.) with your own.

        ***

        ### 1. (If needed) Configure CloudTrail to send logs to CloudWatch Logs

        ```bash theme={null}
        # 1.1 Create a log group for CloudTrail if you don’t have one
        aws logs create-log-group --log-group-name /aws/cloudtrail/management

        # 1.2 Attach a role/policy for CloudTrail to write to CloudWatch Logs
        # Create an IAM role and policy separately (if not already present).
        # Example role name: CloudTrail_CloudWatchLogs_Role

        # 1.3 Update / create the trail to send logs to CloudWatch Logs
        aws cloudtrail update-trail \
          --name MY_TRAIL \
          --cloud-watch-logs-log-group-arn arn:aws:logs:REGION:ACCOUNT_ID:log-group:/aws/cloudtrail/management \
          --cloud-watch-logs-role-arn arn:aws:iam::ACCOUNT_ID:role/CloudTrail_CloudWatchLogs_Role
        ```

        ***

        ### 2. Create a CloudWatch Logs Metric Filter for Route Table changes

        The filter will match API calls that modify Route Tables:

        * `CreateRouteTable`
        * `DeleteRouteTable`
        * `AssociateRouteTable`
        * `DisassociateRouteTable`
        * `ReplaceRouteTableAssociation`
        * `ReplaceRouteTableRoute`
        * `CreateRoute`
        * `DeleteRoute`
        * `ReplaceRoute`

        ```bash theme={null}
        aws logs put-metric-filter \
          --log-group-name /aws/cloudtrail/management \
          --filter-name route-table-changes-filter \
          --filter-pattern '{ ($.eventName = "CreateRouteTable") || ($.eventName = "DeleteRouteTable") || ($.eventName = "AssociateRouteTable") || ($.eventName = "DisassociateRouteTable") || ($.eventName = "ReplaceRouteTableAssociation") || ($.eventName = "ReplaceRouteTableRoute") || ($.eventName = "CreateRoute") || ($.eventName = "DeleteRoute") || ($.eventName = "ReplaceRoute") }' \
          --metric-transformations \
              metricName=my-route-table-changes-metric,metricNamespace=Security,metricValue=1
        ```

        This will emit a metric `Security/my-route-table-changes-metric` with value `1` for every matched event.

        ***

        ### 3. Create an SNS topic for notifications (if you don’t have one)

        ```bash theme={null}
        aws sns create-topic --name route-table-changes-topic

        # Capture the TopicArn from the output, e.g.:
        # arn:aws:sns:REGION:ACCOUNT_ID:route-table-changes-topic

        # Optionally subscribe an email
        aws sns subscribe \
          --topic-arn arn:aws:sns:REGION:ACCOUNT_ID:route-table-changes-topic \
          --protocol email \
          --notification-endpoint you@example.com
        ```

        ***

        ### 4. Create a CloudWatch Alarm on the metric

        Alarm if at least 1 route table change occurs in a 5-minute period:

        ```bash theme={null}
        aws cloudwatch put-metric-alarm \
          --alarm-name my-route-table-changes-alarm \
          --alarm-description "Alarm when VPC Route Tables are changed" \
          --metric-name my-route-table-changes-metric \
          --namespace Security \
          --statistic Sum \
          --period 300 \
          --threshold 1 \
          --comparison-operator GreaterThanOrEqualToThreshold \
          --evaluation-periods 1 \
          --alarm-actions arn:aws:sns:REGION:ACCOUNT_ID:route-table-changes-topic \
          --treat-missing-data notBreaching
        ```

        ***

        Once done:

        * Any change to Route Tables (via the listed API calls) will be logged by CloudTrail into the log group.
        * The metric filter will emit a metric per event.
        * The CloudWatch alarm will trigger and send a notification via SNS whenever at least one change is detected in the evaluation period.
      </Accordion>

      <Accordion title="Using Python">
        Below is one straightforward way to remediate this in AWS using Python/boto3:

        Goal:

        * Detect route table changes via CloudTrail
        * Send them to CloudWatch Logs
        * Use a metric filter and CloudWatch Alarm to trigger notifications (e.g., via SNS)

        Assumptions:

        * You have AWS credentials configured.
        * You have `boto3` installed.
        * You have (or will create) an SNS topic and subscription for notifications.

        ***

        ## 1. Enable/Verify CloudTrail With CloudWatch Logs

        CloudTrail must log management events and send them to a CloudWatch Logs log group.

        ```python theme={null}
        import boto3

        region = "us-east-1"
        trail_name = "org-route-table-changes-trail"
        log_group_name = "/aws/cloudtrail/route-table-changes"

        logs = boto3.client("logs", region_name=region)
        ct = boto3.client("cloudtrail", region_name=region)

        # 1a. Create log group if it doesn't exist
        def ensure_log_group():
            try:
                logs.create_log_group(logGroupName=log_group_name)
            except logs.exceptions.ResourceAlreadyExistsException:
                pass

        # 1b. Create or update a trail that sends logs to CloudWatch Logs
        def ensure_trail():
            # Replace with an existing S3 bucket used for CloudTrail
            s3_bucket_name = "my-cloudtrail-logs-bucket"

            # Create or update trail
            trails = ct.describe_trails(trailNameList=[trail_name])["trailList"]
            if not trails:
                ct.create_trail(
                    Name=trail_name,
                    S3BucketName=s3_bucket_name,
                    IsMultiRegionTrail=True,
                    IncludeGlobalServiceEvents=True,
                    IsOrganizationTrail=False,
                    CloudWatchLogsLogGroupArn=f"arn:aws:logs:{region}:YOUR_ACCOUNT_ID:log-group:{log_group_name}",
                    CloudWatchLogsRoleArn="arn:aws:iam::YOUR_ACCOUNT_ID:role/CloudTrail_CloudWatchLogs_Role",
                )
            else:
                ct.update_trail(
                    Name=trail_name,
                    CloudWatchLogsLogGroupArn=f"arn:aws:logs:{region}:YOUR_ACCOUNT_ID:log-group:{log_group_name}",
                    CloudWatchLogsRoleArn="arn:aws:iam::YOUR_ACCOUNT_ID:role/CloudTrail_CloudWatchLogs_Role",
                )

            # Ensure logging is on
            ct.start_logging(Name=trail_name)


        ensure_log_group()
        ensure_trail()
        ```

        Notes:

        * You must have an IAM role (`CloudTrail_CloudWatchLogs_Role`) with the proper trust and permissions for CloudTrail → CloudWatch Logs.
        * Replace `YOUR_ACCOUNT_ID`, bucket name, role ARN as needed.

        ***

        ## 2. Create a Metric Filter for Route Table Changes

        Filter CloudTrail events for route-table–related eventNames on EC2.

        Common relevant events:

        * `CreateRoute`, `DeleteRoute`, `ReplaceRoute`
        * `CreateRouteTable`, `DeleteRouteTable`
        * `AssociateRouteTable`, `DisassociateRouteTable`, `ReplaceRouteTableAssociation`

        ```python theme={null}
        metric_filter_name = "RouteTableChangesFilter"
        metric_namespace = "SecurityMonitoring"
        metric_name = "RouteTableChangeCount"

        filter_pattern = """
        { ($.eventSource = "ec2.amazonaws.com") &&
          (
            $.eventName = "CreateRoute" ||
            $.eventName = "DeleteRoute" ||
            $.eventName = "ReplaceRoute" ||
            $.eventName = "CreateRouteTable" ||
            $.eventName = "DeleteRouteTable" ||
            $.eventName = "AssociateRouteTable" ||
            $.eventName = "DisassociateRouteTable" ||
            $.eventName = "ReplaceRouteTableAssociation"
          )
        }
        """

        logs.put_metric_filter(
            logGroupName=log_group_name,
            filterName=metric_filter_name,
            filterPattern=filter_pattern.strip(),
            metricTransformations=[
                {
                    "metricName": metric_name,
                    "metricNamespace": metric_namespace,
                    "metricValue": "1",
                }
            ],
        )
        ```

        ***

        ## 3. Create an SNS Topic (If Needed)

        ```python theme={null}
        sns = boto3.client("sns", region_name=region)
        topic_name = "route-table-changes-topic"

        topic_arn = sns.create_topic(Name=topic_name)["TopicArn"]

        # Optionally subscribe an email
        sns.subscribe(
            TopicArn=topic_arn,
            Protocol="email",
            Endpoint="security-team@example.com",
        )
        print("Confirm the email subscription from your inbox.")
        ```

        ***

        ## 4. Create a CloudWatch Alarm on the Metric

        Alarm when at least 1 route table change occurs in a 5-minute period.

        ```python theme={null}
        cw = boto3.client("cloudwatch", region_name=region)

        alarm_name = "RouteTableChangesAlarm"

        cw.put_metric_alarm(
            AlarmName=alarm_name,
            AlarmDescription="Alarm when any VPC route table is modified.",
            Namespace=metric_namespace,
            MetricName=metric_name,
            Statistic="Sum",
            Period=300,  # 5 minutes
            EvaluationPeriods=1,
            Threshold=1.0,
            ComparisonOperator="GreaterThanOrEqualToThreshold",
            TreatMissingData="notBreaching",
            AlarmActions=[topic_arn],
        )
        ```

        ***

        ## 5. Validate

        * Make a test change to a route table.
        * Wait a few minutes.
        * Verify:
          * CloudTrail shows the event.
          * Metric in CloudWatch (`SecurityMonitoring/RouteTableChangeCount`) increments.
          * Alarm transitions to ALARM and sends an SNS notification.

        This configuration ensures “Route Table Changes Alarm” is enabled via CloudWatch and fully managed by Python/boto3.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # CloudWatch Logs metric filter for route table changes
        resource "aws_cloudwatch_log_metric_filter" "route_table_changes" {
          name           = "RouteTableChangesFilter"
          log_group_name = "CLOUDTRAIL_LOG_GROUP_NAME" # replace with your CloudTrail log group name

          pattern = "{ ($.eventName = CreateRoute) || ($.eventName = CreateRouteTable) || ($.eventName = ReplaceRoute) || ($.eventName = ReplaceRouteTableAssociation) || ($.eventName = DeleteRouteTable) || ($.eventName = DeleteRoute) || ($.eventName = DisassociateRouteTable) }"

          metric_transformation {
            name      = "RouteTableChangesMetric"
            namespace = "CloudTrailMetrics"
            value     = "1"
          }
        }

        # Optional: SNS topic for alarm notifications (or use an existing one)
        resource "aws_sns_topic" "route_table_changes_notifications" {
          name = "RouteTableChangeNotifications"
        }

        # CloudWatch alarm for the route table changes metric
        resource "aws_cloudwatch_metric_alarm" "route_table_changes" {
          alarm_name          = "RouteTableChangesAlarm"
          alarm_description   = "Monitors for route table changes"
          namespace           = "CloudTrailMetrics"
          metric_name         = "RouteTableChangesMetric"
          statistic           = "Sum"
          period              = 300
          evaluation_periods  = 1
          threshold           = 1
          comparison_operator = "GreaterThanOrEqualToThreshold"

          alarm_actions = [
            aws_sns_topic.route_table_changes_notifications.arn
            # or replace with an existing SNS topic ARN:
            # "ROUTE_TABLE_CHANGES_ALARM_SNS_TOPIC_ARN"
          ]

          depends_on = [aws_cloudwatch_log_metric_filter.route_table_changes]
        }
        ```

        This change will create (or, if the same names already exist and are imported, update) the metric filter `RouteTableChangesFilter` and alarm `RouteTableChangesAlarm`; if they are currently unmanaged by Terraform, importing or replacing them may overwrite existing settings. After adding this, `terraform plan` should show one `aws_cloudwatch_log_metric_filter` and one `aws_cloudwatch_metric_alarm` (and optionally `aws_sns_topic`) to be created or updated with the exact pattern, metric, and threshold described above.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
