> ## 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.

# Vpc changes alarm remediation

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are the exact AWS Console steps to enable a “VPC Changes” alarm in CloudWatch.

        ***

        ## Prerequisite: Make sure CloudTrail is sending logs to CloudWatch Logs

        1. In the AWS Console, go to **CloudTrail**.
        2. In the left menu, select **Trails**.
        3. Click your **trail name** (or create one if none exist).
        4. Under **CloudWatch Logs**, ensure:
           * **CloudWatch Logs log group** is set (e.g., `/aws/cloudtrail/logs`).
           * If not set:
             * Click **Edit**.
             * In **CloudWatch Logs**, choose **Enabled**.
             * Select or create a **Log group**.
             * Choose or create an IAM role as prompted.
             * Save the changes.

        ***

        ## Step 1: Go to CloudWatch Logs

        1. Open **CloudWatch** in the AWS Console.
        2. In the left menu, choose **Logs** → **Log groups**.
        3. Click the **log group** used by CloudTrail (e.g., `/aws/cloudtrail/logs`).

        ***

        ## Step 2: Create a Metric Filter for VPC Changes

        1. Inside the log group, go to the **Metric filters** tab.

        2. Click **Create metric filter**.

        3. For **Filter pattern**, use a VPC-change pattern, for example:

           ```text theme={null}
           { ($.eventName = "CreateVpc") || ($.eventName = "DeleteVpc") || ($.eventName = "ModifyVpcAttribute") || ($.eventName = "CreateSubnet") || ($.eventName = "DeleteSubnet") || ($.eventName = "CreateRoute") || ($.eventName = "DeleteRoute") || ($.eventName = "ReplaceRoute") || ($.eventName = "CreateRouteTable") || ($.eventName = "DeleteRouteTable") || ($.eventName = "AssociateRouteTable") || ($.eventName = "DisassociateRouteTable") || ($.eventName = "CreateInternetGateway") || ($.eventName = "DeleteInternetGateway") || ($.eventName = "AttachInternetGateway") || ($.eventName = "DetachInternetGateway") || ($.eventName = "CreateNatGateway") || ($.eventName = "DeleteNatGateway") || ($.eventName = "CreateNetworkAcl") || ($.eventName = "DeleteNetworkAcl") || ($.eventName = "CreateNetworkAclEntry") || ($.eventName = "DeleteNetworkAclEntry") || ($.eventName = "ReplaceNetworkAclEntry") || ($.eventName = "ReplaceNetworkAclAssociation") }
           ```

           (You can reduce or expand this list depending on exactly which VPC events you want.)

        4. Click **Next**.

        5. Under **Assign metric**, configure:
           * **Filter name**: `VPC-Changes-Filter`
           * **Metric namespace**: `Security/VPC`
           * **Metric name**: `VPCChanges`
           * **Metric value**: `1`

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

        ***

        ## Step 3: Create a CloudWatch Alarm for This Metric

        1. Still in CloudWatch, in the left menu, select **Alarms** → **All alarms**.
        2. Click **Create alarm**.
        3. Click **Select metric**.
        4. Navigate to the metric:
           * **Custom namespaces** → choose `Security/VPC`.
           * Select the `VPCChanges` metric.
        5. Click **Select metric**.

        ***

        ## Step 4: Configure Alarm Conditions

        1. Under **Specify metric and conditions**:
           * **Statistic**: `Sum`
           * **Period**: `5 minutes` (or your preferred window).
           * **Threshold type**: **Static**.
           * **Whenever `VPCChanges` is**: `>= 1`.
        2. Click **Next**.

        ***

        ## Step 5: Configure Notification (SNS)

        1. Under **Notification**:
           * For **Alarm state trigger**: **In alarm**.
           * **Select an SNS topic**:
             * Choose an existing topic (e.g., `security-alerts`)\
               **or**
             * Click **Create new topic**, name it (e.g., `VPC-Changes-Topic`), and enter one or more email addresses.
        2. Click **Next**.

        ***

        ## Step 6: Name and Create the Alarm

        1. **Alarm name**: `VPC-Changes-Alarm`.
        2. **Alarm description**: `Alerts when VPC configuration changes are detected via CloudTrail.`
        3. Review the settings and click **Create alarm**.

        ***

        Once this is in place, any matching VPC-related CloudTrail event will increment the `VPCChanges` metric and trigger the CloudWatch alarm, sending a notification via SNS.
      </Accordion>

      <Accordion title="Using CLI">
        Below is one way to remediate “VPC Changes Alarm Should Be Enabled” using AWS CLI by:

        1. ensuring CloudTrail is logging to CloudWatch Logs
        2. creating a metric filter for VPC changes
        3. creating a CloudWatch alarm on that metric.

        Adjust names/regions as needed.

        ***

        ### 0. Prerequisites

        * You have a **CloudTrail** trail sending logs to a **CloudWatch Logs log group** (say `/aws/cloudtrail/logs`).
        * You know the **region** and **account ID**.

        If you don’t yet send CloudTrail to CloudWatch Logs, create or update a trail first.

        ***

        ### 1. Confirm / Set CloudTrail → CloudWatch Logs

        If you already have a trail with `CloudWatchLogsLogGroupArn` set, you can skip to step 2.

        Example: create a new trail that sends to `/aws/cloudtrail/logs`:

        ```bash theme={null}
        aws logs create-log-group \
          --log-group-name /aws/cloudtrail/logs \
          --region us-east-1

        # Create an IAM role for CloudTrail to write to CloudWatch Logs (one‑time)
        aws iam create-role \
          --role-name CloudTrail_CloudWatchLogs_Role \
          --assume-role-policy-document file://cloudtrail-cw-trust.json
        ```

        `cloudtrail-cw-trust.json` (example):

        ```json theme={null}
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid": "",
              "Effect": "Allow",
              "Principal": {
                "Service": "cloudtrail.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        }
        ```

        Attach a policy to allow writes to that log group:

        ```bash theme={null}
        aws iam put-role-policy \
          --role-name CloudTrail_CloudWatchLogs_Role \
          --policy-name CloudTrail_CloudWatchLogs_Policy \
          --policy-document file://cloudtrail-cw-policy.json
        ```

        `cloudtrail-cw-policy.json` (replace region/account/log-group if needed):

        ```json theme={null}
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "logs:PutLogEvents",
                "logs:CreateLogStream",
                "logs:DescribeLogStreams"
              ],
              "Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/cloudtrail/logs:*"
            }
          ]
        }
        ```

        Now create the trail:

        ```bash theme={null}
        aws cloudtrail create-trail \
          --name cloudtrail-with-cw \
          --s3-bucket-name my-cloudtrail-bucket \
          --cloud-watch-logs-log-group-arn arn:aws:logs:us-east-1:123456789012:log-group:/aws/cloudtrail/logs \
          --cloud-watch-logs-role-arn arn:aws:iam::123456789012:role/CloudTrail_CloudWatchLogs_Role \
          --is-multi-region-trail
        ```

        Enable logging:

        ```bash theme={null}
        aws cloudtrail start-logging --name cloudtrail-with-cw
        ```

        ***

        ### 2. Create a CloudWatch Logs Metric Filter for VPC Changes

        Pick the relevant VPC events. Common ones include:

        * `CreateVpc`, `DeleteVpc`, `ModifyVpcAttribute`
        * `CreateSubnet`, `DeleteSubnet`, `ModifySubnetAttribute`
        * `CreateRouteTable`, `DeleteRouteTable`, `AssociateRouteTable`, `DisassociateRouteTable`, `ReplaceRouteTableAssociation`
        * `CreateRoute`, `DeleteRoute`, `ReplaceRoute`
        * `CreateInternetGateway`, `DeleteInternetGateway`, `AttachInternetGateway`, `DetachInternetGateway`
        * `CreateNatGateway`, `DeleteNatGateway`
        * `CreateVpcPeeringConnection`, `DeleteVpcPeeringConnection`, etc.

        Sample filter pattern (you can extend):

        ```bash theme={null}
        METRIC_FILTER_NAME="VpcChangeEvents"
        LOG_GROUP_NAME="/aws/cloudtrail/logs"
        NAMESPACE="Security"
        METRIC_NAME="VpcChanges"

        aws logs put-metric-filter \
          --log-group-name "$LOG_GROUP_NAME" \
          --filter-name "$METRIC_FILTER_NAME" \
          --filter-pattern '{ ($.eventName = "CreateVpc") || ($.eventName = "DeleteVpc") || ($.eventName = "ModifyVpcAttribute") || ($.eventName = "CreateSubnet") || ($.eventName = "DeleteSubnet") || ($.eventName = "ModifySubnetAttribute") || ($.eventName = "CreateRoute") || ($.eventName = "DeleteRoute") || ($.eventName = "ReplaceRoute") || ($.eventName = "CreateRouteTable") || ($.eventName = "DeleteRouteTable") || ($.eventName = "AssociateRouteTable") || ($.eventName = "DisassociateRouteTable") || ($.eventName = "ReplaceRouteTableAssociation") || ($.eventName = "CreateInternetGateway") || ($.eventName = "DeleteInternetGateway") || ($.eventName = "AttachInternetGateway") || ($.eventName = "DetachInternetGateway") }' \
          --metric-transformations \
              metricName="$METRIC_NAME",metricNamespace="$NAMESPACE",metricValue=1
        ```

        This will increment the metric `Security/VpcChanges` by 1 every time a matching event appears.

        ***

        ### 3. Create an SNS Topic for Alarm Notifications

        ```bash theme={null}
        TOPIC_NAME="VpcChangesAlarmTopic"

        aws sns create-topic --name "$TOPIC_NAME"
        ```

        Get the ARN:

        ```bash theme={null}
        TOPIC_ARN=$(aws sns list-topics \
          --query "Topics[?ends_with(TopicArn,':$TOPIC_NAME')].TopicArn" \
          --output text)
        ```

        Subscribe an email (or other endpoint):

        ```bash theme={null}
        aws sns subscribe \
          --topic-arn "$TOPIC_ARN" \
          --protocol email \
          --notification-endpoint your-email@example.com
        ```

        Confirm the subscription from your email.

        ***

        ### 4. Create the CloudWatch Alarm on the Metric

        Example: alarm whenever at least 1 VPC change event occurs in a 5‑minute period.

        ```bash theme={null}
        ALARM_NAME="VpcChangesDetected"
        NAMESPACE="Security"
        METRIC_NAME="VpcChanges"
        REGION="us-east-1"

        aws cloudwatch put-metric-alarm \
          --alarm-name "$ALARM_NAME" \
          --alarm-description "Alert on AWS VPC configuration changes" \
          --metric-name "$METRIC_NAME" \
          --namespace "$NAMESPACE" \
          --statistic Sum \
          --period 300 \
          --threshold 1 \
          --comparison-operator GreaterThanOrEqualToThreshold \
          --evaluation-periods 1 \
          --treat-missing-data notBreaching \
          --alarm-actions "$TOPIC_ARN" \
          --region "$REGION"
        ```

        ***

        ### 5. Validate

        * Make a **test VPC change** (e.g., create or modify a subnet).
        * Confirm:
          * CloudTrail logs the event into the log group.
          * The metric `Security/VpcChanges` increments.
          * The `VpcChangesDetected` alarm goes into ALARM state.
          * An SNS notification is received.

        These steps implement an AWS CloudWatch–based alarm that detects VPC configuration changes and satisfies the “VPC Changes Alarm Should Be Enabled” requirement via AWS CLI.
      </Accordion>

      <Accordion title="Using Python">
        To remediate “VPC Changes Alarm Should Be Enabled” in AWS using Python, you typically need:

        1. A CloudTrail that logs management events.
        2. That CloudTrail delivering logs to a CloudWatch Logs log group.
        3. A CloudWatch Logs metric filter that detects VPC-change API calls.
        4. A CloudWatch alarm on that metric.

        Below is a minimal, end‑to‑end example using `boto3`.

        ***

        ## 1. Prerequisites

        * Python 3.x
        * `boto3` installed:
          ```bash theme={null}
          pip install boto3
          ```
        * AWS credentials configured (via `aws configure`, environment variables, or instance profile).
        * An SNS topic ARN to receive the alarm notifications (or create one via console/CLI).

        Assume:

        * Region: `us-east-1`
        * CloudTrail log group: `/aws/cloudtrail/vpc-changes`
        * Metric name: `VPCChangeCount`
        * Namespace: `SecurityMonitoring`
        * Alarm name: `VPC_Changes_Alarm`
        * SNS topic ARN: `arn:aws:sns:us-east-1:123456789012:security-alerts`

        ***

        ## 2. Ensure CloudTrail Is Sending to a CloudWatch Logs Log Group

        If you already have an org/tenant-wide CloudTrail that sends management events to CloudWatch Logs, you can reuse that log group and skip creating a new trail. Otherwise:

        ```python theme={null}
        import boto3

        region = "us-east-1"
        logs_group_name = "/aws/cloudtrail/vpc-changes"

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

        # 2.1 Create CloudWatch Logs log group (idempotent)
        try:
            logs.create_log_group(logGroupName=logs_group_name)
        except logs.exceptions.ResourceAlreadyExistsException:
            pass

        # 2.2 Create IAM role for CloudTrail to write to CloudWatch Logs (if needed)
        role_name = "CloudTrail_CloudWatchLogs_Role"
        assume_role_policy = {
            "Version": "2012-10-17",
            "Statement": [{
                "Effect": "Allow",
                "Principal": {"Service": "cloudtrail.amazonaws.com"},
                "Action": "sts:AssumeRole"
            }]
        }

        try:
            role = iam.create_role(
                RoleName=role_name,
                AssumeRolePolicyDocument=json.dumps(assume_role_policy),
                Description="Role for CloudTrail to write to CloudWatch Logs"
            )["Role"]
        except iam.exceptions.EntityAlreadyExistsException:
            role = iam.get_role(RoleName=role_name)["Role"]

        log_group_arn = f"arn:aws:logs:{region}:{role['Arn'].split(':')[4]}:log-group:{logs_group_name}:*"

        policy_doc = {
            "Version": "2012-10-17",
            "Statement": [{
                "Effect": "Allow",
                "Action": [
                    "logs:CreateLogStream",
                    "logs:PutLogEvents"
                ],
                "Resource": log_group_arn
            }]
        }

        iam.put_role_policy(
            RoleName=role_name,
            PolicyName="CloudTrail_CloudWatchLogs_Policy",
            PolicyDocument=json.dumps(policy_doc)
        )

        # 2.3 Create or update a CloudTrail trail that logs to this log group
        trail_name = "vpc-changes-trail"
        account_id = role["Arn"].split(":")[4]

        try:
            cloudtrail.create_trail(
                Name=trail_name,
                IsMultiRegionTrail=True,
                IsOrganizationTrail=False,
                S3BucketName=f"{account_id}-cloudtrail-logs",  # must exist or be created
                CloudWatchLogsLogGroupArn=f"arn:aws:logs:{region}:{account_id}:log-group:{logs_group_name}",
                CloudWatchLogsRoleArn=role["Arn"],
                IncludeGlobalServiceEvents=True,
                EnableLogFileValidation=True
            )
        except cloudtrail.exceptions.TrailAlreadyExistsException:
            cloudtrail.update_trail(
                Name=trail_name,
                CloudWatchLogsLogGroupArn=f"arn:aws:logs:{region}:{account_id}:log-group:{logs_group_name}",
                CloudWatchLogsRoleArn=role["Arn"]
            )

        # Start logging (if not already)
        cloudtrail.start_logging(Name=trail_name)
        ```

        If you already have a central CloudTrail and log group, just set `logs_group_name` to that existing log group and skip trail creation.

        ***

        ## 3. Create a Metric Filter for VPC Changes

        The filter pattern will match CloudTrail events for VPC‑related API calls.

        Common VPC‑change events:

        * `CreateVpc`, `DeleteVpc`, `ModifyVpcAttribute`
        * `CreateSubnet`, `DeleteSubnet`, `ModifySubnetAttribute`
        * `CreateRouteTable`, `DeleteRouteTable`, `AssociateRouteTable`, `DisassociateRouteTable`, `ReplaceRouteTableAssociation`
        * `CreateRoute`, `DeleteRoute`, `ReplaceRoute`
        * `CreateInternetGateway`, `AttachInternetGateway`, `DetachInternetGateway`, `DeleteInternetGateway`
        * `CreateNatGateway`, `DeleteNatGateway`
        * `CreateVpcPeeringConnection`, `DeleteVpcPeeringConnection`, `AcceptVpcPeeringConnection`, `RejectVpcPeeringConnection`
        * `CreateNetworkAcl`, `DeleteNetworkAcl`, `CreateNetworkAclEntry`, `DeleteNetworkAclEntry`, `ReplaceNetworkAclEntry`
        * etc.

        Example pattern (trim or extend as required):

        ```python theme={null}
        import json
        import boto3

        region = "us-east-1"
        logs_group_name = "/aws/cloudtrail/vpc-changes"

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

        metric_filter_name = "VPCChangesFilter"
        metric_namespace = "SecurityMonitoring"
        metric_name = "VPCChangeCount"

        filter_pattern = (
            '{ ($.eventSource = "ec2.amazonaws.com") && '
            '($.eventName = "CreateVpc" || $.eventName = "DeleteVpc" || '
            '$.eventName = "ModifyVpcAttribute" || '
            '$.eventName = "CreateSubnet" || $.eventName = "DeleteSubnet" || '
            '$.eventName = "ModifySubnetAttribute" || '
            '$.eventName = "CreateRouteTable" || $.eventName = "DeleteRouteTable" || '
            '$.eventName = "AssociateRouteTable" || $.eventName = "DisassociateRouteTable" || '
            '$.eventName = "ReplaceRouteTableAssociation" || '
            '$.eventName = "CreateRoute" || $.eventName = "DeleteRoute" || '
            '$.eventName = "ReplaceRoute" || '
            '$.eventName = "CreateInternetGateway" || $.eventName = "DeleteInternetGateway" || '
            '$.eventName = "AttachInternetGateway" || $.eventName = "DetachInternetGateway" || '
            '$.eventName = "CreateNatGateway" || $.eventName = "DeleteNatGateway" || '
            '$.eventName = "CreateVpcPeeringConnection" || '
            '$.eventName = "DeleteVpcPeeringConnection" || '
            '$.eventName = "AcceptVpcPeeringConnection" || '
            '$.eventName = "RejectVpcPeeringConnection" || '
            '$.eventName = "CreateNetworkAcl" || $.eventName = "DeleteNetworkAcl" || '
            '$.eventName = "CreateNetworkAclEntry" || $.eventName = "DeleteNetworkAclEntry" || '
            '$.eventName = "ReplaceNetworkAclEntry") }'
        )

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

        ***

        ## 4. Create the CloudWatch Alarm on the Metric

        Trigger if at least 1 VPC change occurs in a 5‑minute period:

        ```python theme={null}
        import boto3

        region = "us-east-1"
        cw = boto3.client("cloudwatch", region_name=region)

        metric_namespace = "SecurityMonitoring"
        metric_name = "VPCChangeCount"
        alarm_name = "VPC_Changes_Alarm"
        sns_topic_arn = "arn:aws:sns:us-east-1:123456789012:security-alerts"

        cw.put_metric_alarm(
            AlarmName=alarm_name,
            AlarmDescription="Alarm when any VPC configuration change is detected via CloudTrail",
            Namespace=metric_namespace,
            MetricName=metric_name,
            Statistic="Sum",
            Period=300,  # 5 minutes
            EvaluationPeriods=1,
            Threshold=1.0,
            ComparisonOperator="GreaterThanOrEqualToThreshold",
            ActionsEnabled=True,
            AlarmActions=[sns_topic_arn],
            TreatMissingData="notBreaching"
        )
        ```

        ***

        ## 5. Quick Validation

        1. Make a small VPC change (e.g., create a test subnet).
        2. Wait a few minutes.
        3. Check:
           * CloudWatch Logs: confirm CloudTrail events are arriving.
           * CloudWatch Metrics → `SecurityMonitoring/VPCChangeCount` shows datapoints.
           * CloudWatch Alarms: `VPC_Changes_Alarm` moves to `ALARM` state and sends SNS notification.

        This fully remediates the “VPC Changes Alarm Should Be Enabled” requirement using Python.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # SNS topic to receive VPC change notifications
        resource "aws_sns_topic" "vpc_changes_topic" {
          name = "VPCChangesTopic"
        }

        # Email subscription to the SNS topic
        resource "aws_sns_topic_subscription" "vpc_changes_email" {
          topic_arn = aws_sns_topic.vpc_changes_topic.arn
          protocol  = "email"
          endpoint  = "YOUR_EMAIL_ADDRESS" # replace with the email to receive alerts
        }

        # CloudWatch Logs metric filter on the CloudTrail log group
        resource "aws_cloudwatch_log_metric_filter" "vpc_changes_filter" {
          name           = "VPCChangesFilter"
          log_group_name = "CLOUDTRAIL_LOG_GROUP_NAME" # replace with your CloudTrail log group name

          pattern = "{($.eventName=CreateVpc)||($.eventName=DeleteVpc)||($.eventName=ModifyVpcAttribute)||($.eventName=AcceptVpcPeeringConnection)||($.eventName=CreateVpcPeeringConnection)||($.eventName=DeleteVpcPeeringConnection)||($.eventName=RejectVpcPeeringConnection)||($.eventName=AttachClassicLinkVpc)||($.eventName=DetachClassicLinkVpc)||($.eventName=DisableVpcClassicLink)||($.eventName=EnableVpcClassicLink)}"

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

        # CloudWatch alarm that triggers on VPC change events
        resource "aws_cloudwatch_metric_alarm" "vpc_changes_alarm" {
          alarm_name          = "VPCChangesAlarm"
          namespace           = "CloudTrailMetrics"
          metric_name         = "VPCChanges"
          statistic           = "Sum"
          period              = 300
          evaluation_periods  = 1
          threshold           = 1
          comparison_operator = "GreaterThanOrEqualToThreshold"

          alarm_actions = [
            aws_sns_topic.vpc_changes_topic.arn
          ]

          depends_on = [
            aws_cloudwatch_log_metric_filter.vpc_changes_filter
          ]
        }
        ```

        This remediation creates new resources (SNS topic, SNS email subscription, log metric filter, and CloudWatch alarm); existing resources are not replaced. You must replace `YOUR_EMAIL_ADDRESS` and `CLOUDTRAIL_LOG_GROUP_NAME` with your actual values and confirm the SNS email subscription manually from your inbox.

        To verify, `terraform plan` should show 4 resources to add (`aws_sns_topic`, `aws_sns_topic_subscription`, `aws_cloudwatch_log_metric_filter`, and `aws_cloudwatch_metric_alarm`) and no changes/destroys for existing resources.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
