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

# S3 bucket changes alarm remediation

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        Below are concise, console-based steps to enable an S3 bucket changes alarm using CloudWatch and CloudTrail.

        ***

        ### 1. Ensure CloudTrail Is Enabled and Logging to CloudWatch Logs

        1. In the AWS Console, go to **CloudTrail**.
        2. In the left menu, select **Trails**.
        3. If you already have a trail:
           * Click on the trail name.
           * Under **CloudWatch Logs**, confirm:
             * **CloudWatch Logs log group** is set.
             * An IAM role is attached for CloudTrail to send logs to CloudWatch Logs.
           * If not set, click **Edit**, then:
             * Set **CloudWatch Logs** to **Enabled**.
             * Choose or create a **Log group**.
             * Choose or create a suitable **IAM role**.
             * Save changes.
        4. If you **do not** have a trail:
           * Click **Create trail**.
           * Name the trail.
           * For **Storage location**, choose/create an S3 bucket.
           * For **CloudWatch Logs**, set to **Enabled**, and pick/create a log group and IAM role.
           * Ensure **Management events** (Read and Write) are enabled.
           * Create the trail.

        ***

        ### 2. Create a Metric Filter for S3 Bucket Changes

        You will filter CloudTrail events that represent S3 bucket changes (such as PutBucketAcl, PutBucketPolicy, etc.).

        1. Go to **CloudWatch** in the console.

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

        3. Click the **log group** used by CloudTrail (e.g., `/aws/cloudtrail/logs`).

        4. Choose the **Metric filters** tab.

        5. Click **Create metric filter** (or **Add metric filter**).

        6. In **Filter pattern**, use something like:

           ```text theme={null}
           { ($.eventSource = "s3.amazonaws.com") && 
             ($.eventName = "PutBucketAcl" || 
              $.eventName = "PutBucketPolicy" || 
              $.eventName = "PutBucketCors" || 
              $.eventName = "PutBucketLifecycle" || 
              $.eventName = "PutBucketReplication" || 
              $.eventName = "PutBucketVersioning" || 
              $.eventName = "PutBucketWebsite" || 
              $.eventName = "DeleteBucketPolicy" || 
              $.eventName = "DeleteBucketCors" || 
              $.eventName = "DeleteBucketLifecycle" || 
              $.eventName = "DeleteBucketReplication" || 
              $.eventName = "DeleteBucketWebsite") }
           ```

           (Adjust the event list to your policy as needed.)

        7. Click **Next**.

        8. Under **Assign metric**, set:
           * **Filter name**: e.g., `S3BucketChangesFilter`.
           * **Metric namespace**: e.g., `Security/CloudTrail`.
           * **Metric name**: e.g., `S3BucketChanges`.
           * **Metric value**: `1`.

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

        ***

        ### 3. Create a CloudWatch Alarm for S3 Bucket Changes

        1. In **CloudWatch**, go to **Alarms → All alarms**.
        2. Click **Create alarm**.
        3. Click **Select metric**.
        4. Choose **Browse** → go to the namespace you set (e.g., `Security/CloudTrail`) → select the **S3BucketChanges** metric.
        5. Click **Select metric**.
        6. Configure the alarm:
           * **Statistic**: `Sum`.
           * **Period**: e.g., `5 minutes` (or as required).
           * **Threshold type**: `Static`.
           * **Condition**: `Greater/Equal` to `1`.
        7. Click **Next**.
        8. Under **Notification**:
           * Select an existing SNS topic or click **Create new topic**.
           * Enter an **email endpoint** or other subscribers as needed.
        9. Click **Next**, give the alarm a name, e.g., `Alarm-S3BucketChanges`, and optional description.
        10. Click **Next**, then **Create alarm**.

        ***

        Once complete, whenever S3 bucket configuration changes (covered by your filter) occur, CloudTrail logs them, the metric filter increments the `S3BucketChanges` metric, and the CloudWatch alarm triggers and sends a notification.
      </Accordion>

      <Accordion title="Using CLI">
        Below is one concrete way to implement an “S3 bucket changes” CloudWatch alarm using AWS CLI:

        **Goal:** Alarm whenever someone **changes S3 bucket configuration**, such as ACLs/policies.\
        This uses **CloudTrail → CloudWatch Logs → Metric Filter → CloudWatch Alarm**.

        ***

        ## 0. Prerequisites

        * You have an S3 bucket with CloudTrail logs (or will create a new trail).
        * You have (or will create) a CloudWatch Logs log group for CloudTrail.
        * You have an SNS topic ARN to send the alarm notification to (or will create one).

        I’ll include all commands.

        ***

        ## 1. Create / Configure CloudTrail to Send to CloudWatch Logs

        ```bash theme={null}
        # Variables
        REGION="us-east-1"
        TRAIL_NAME="organization-trail"       # or your desired name
        CLOUDTRAIL_BUCKET="my-cloudtrail-bucket-123"
        LOG_GROUP_NAME="/aws/cloudtrail/s3-bucket-changes"
        ROLE_NAME="CloudTrail_CloudWatchLogs_Role"
        ROLE_POLICY_NAME="CloudTrail_CloudWatchLogs_Policy"
        ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
        ```

        ### 1.1 Create the CloudWatch Logs log group (if not exists)

        ```bash theme={null}
        aws logs create-log-group \
          --log-group-name "$LOG_GROUP_NAME" \
          --region "$REGION" 2>/dev/null || true
        ```

        ### 1.2 Create IAM role for CloudTrail to put logs into CloudWatch Logs

        **Trust policy:**

        ```bash theme={null}
        cat > trust-policy.json <<EOF
        {
          "Version": "2012-10-17",
          "Statement": [{
            "Effect": "Allow",
            "Principal": { "Service": "cloudtrail.amazonaws.com" },
            "Action": "sts:AssumeRole"
          }]
        }
        EOF

        aws iam create-role \
          --role-name "$ROLE_NAME" \
          --assume-role-policy-document file://trust-policy.json
        ```

        **Permissions policy:**

        ```bash theme={null}
        cat > cwlogs-policy.json <<EOF
        {
          "Version": "2012-10-17",
          "Statement": [{
            "Effect": "Allow",
            "Action": [
              "logs:CreateLogStream",
              "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:${ACCOUNT_ID}:log-group:${LOG_GROUP_NAME}:*"
          }]
        }
        EOF

        aws iam put-role-policy \
          --role-name "$ROLE_NAME" \
          --policy-name "$ROLE_POLICY_NAME" \
          --policy-document file://cwlogs-policy.json
        ```

        ### 1.3 Create (or update) the CloudTrail trail

        ```bash theme={null}
        # Create S3 bucket for CloudTrail if needed
        aws s3api create-bucket \
          --bucket "$CLOUDTRAIL_BUCKET" \
          --region "$REGION" \
          --create-bucket-configuration LocationConstraint="$REGION" 2>/dev/null || true

        # Create the trail
        aws cloudtrail create-trail \
          --name "$TRAIL_NAME" \
          --s3-bucket-name "$CLOUDTRAIL_BUCKET" \
          --cloud-watch-logs-log-group-arn "arn:aws:logs:${REGION}:${ACCOUNT_ID}:log-group:${LOG_GROUP_NAME}" \
          --cloud-watch-logs-role-arn "arn:aws:iam::${ACCOUNT_ID}:role/${ROLE_NAME}" \
          --is-multi-region-trail

        # Start logging
        aws cloudtrail start-logging --name "$TRAIL_NAME"
        ```

        ***

        ## 2. Create a Metric Filter for S3 Bucket Changes

        We’ll match CloudTrail events that modify bucket configuration (common examples: `PutBucketAcl`, `PutBucketPolicy`, `PutBucketCors`, `PutBucketLifecycleConfiguration`, etc.).

        ### 2.1 Define the metric filter

        ```bash theme={null}
        METRIC_FILTER_NAME="S3BucketChangesFilter"
        METRIC_NAMESPACE="Security/S3"
        METRIC_NAME="S3BucketChangesCount"

        FILTER_PATTERN='{ ($.eventSource = "s3.amazonaws.com") && (
            $.eventName = "PutBucketAcl" ||
            $.eventName = "PutBucketPolicy" ||
            $.eventName = "PutBucketCors" ||
            $.eventName = "PutBucketLifecycleConfiguration" ||
            $.eventName = "PutBucketReplication" ||
            $.eventName = "PutBucketVersioning" ||
            $.eventName = "PutBucketLogging" ||
            $.eventName = "PutBucketEncryption" ||
            $.eventName = "PutBucketPublicAccessBlock" ||
            $.eventName = "DeleteBucketPolicy" ||
            $.eventName = "DeleteBucketCors" ||
            $.eventName = "DeleteBucketLifecycle" ||
            $.eventName = "DeleteBucketReplication" ||
            $.eventName = "DeleteBucketWebsite"
        )}'
        ```

        ### 2.2 Create the metric filter

        ```bash theme={null}
        aws logs put-metric-filter \
          --log-group-name "$LOG_GROUP_NAME" \
          --filter-name "$METRIC_FILTER_NAME" \
          --filter-pattern "$FILTER_PATTERN" \
          --metric-transformations \
              metricName="$METRIC_NAME",metricNamespace="$METRIC_NAMESPACE",metricValue=1
        ```

        ***

        ## 3. Create an SNS Topic for Alarm Notifications (if needed)

        ```bash theme={null}
        SNS_TOPIC_NAME="S3BucketChangesAlarmTopic"
        SNS_TOPIC_ARN=$(aws sns create-topic \
          --name "$SNS_TOPIC_NAME" \
          --query 'TopicArn' \
          --output text)

        # Subscribe an email address
        aws sns subscribe \
          --topic-arn "$SNS_TOPIC_ARN" \
          --protocol email \
          --notification-endpoint you@example.com
        ```

        (You must confirm the subscription email.)

        ***

        ## 4. Create the CloudWatch Alarm

        Alarm if **any** bucket-change event occurs in a 5‑minute period.

        ```bash theme={null}
        ALARM_NAME="S3BucketChangesAlarm"

        aws cloudwatch put-metric-alarm \
          --alarm-name "$ALARM_NAME" \
          --alarm-description "Alarm when S3 bucket configuration is changed" \
          --metric-name "$METRIC_NAME" \
          --namespace "$METRIC_NAMESPACE" \
          --statistic Sum \
          --period 300 \
          --evaluation-periods 1 \
          --threshold 0 \
          --comparison-operator GreaterThanThreshold \
          --treat-missing-data notBreaching \
          --alarm-actions "$SNS_TOPIC_ARN"
        ```

        ***

        ## 5. Validate

        1. Make a bucket change (e.g., modify ACL or bucket policy).
        2. Check:
           * CloudTrail logs show the event.
           * The metric `Security/S3 : S3BucketChangesCount` increases.
           * The `S3BucketChangesAlarm` moves to `ALARM` state and sends an SNS notification.

        This fully enables an alarm on S3 bucket configuration changes using CloudWatch and AWS CLI.
      </Accordion>

      <Accordion title="Using Python">
        To detect S3 bucket configuration changes with CloudWatch, you need:

        1. CloudTrail sending logs to a CloudWatch Logs log group
        2. A CloudWatch Logs metric filter for S3 bucket-change events
        3. A CloudWatch alarm on that metric

        Below is a step‑by‑step guide plus a Python (boto3) example.

        ***

        ## 1. Prerequisites

        * `boto3` installed and configured with credentials/region:
          ```bash theme={null}
          pip install boto3
          aws configure
          ```
        * An existing CloudTrail trail that:
          * Logs management events
          * Delivers to a CloudWatch Logs log group (e.g., `/aws/cloudtrail/main`)

        If CloudTrail is not yet sending to CloudWatch Logs, configure that first (in console or via `boto3.cloudtrail.update_trail` with `CloudWatchLogsLogGroupArn`).

        ***

        ## 2. Recommended metric filter pattern

        This pattern matches S3 bucket configuration changes in CloudTrail logs:

        ```text theme={null}
        { ($.eventSource = "s3.amazonaws.com") &&
          (
            ($.eventName = "PutBucketAcl") ||
            ($.eventName = "PutBucketPolicy") ||
            ($.eventName = "PutBucketCors") ||
            ($.eventName = "PutBucketLifecycle") ||
            ($.eventName = "PutBucketReplication") ||
            ($.eventName = "PutBucketTagging") ||
            ($.eventName = "PutBucketVersioning") ||
            ($.eventName = "PutBucketWebsite") ||
            ($.eventName = "DeleteBucketPolicy") ||
            ($.eventName = "DeleteBucketCors") ||
            ($.eventName = "DeleteBucketLifecycle") ||
            ($.eventName = "DeleteBucketReplication") ||
            ($.eventName = "DeleteBucketTagging") ||
            ($.eventName = "DeleteBucketWebsite")
          )
        }
        ```

        ***

        ## 3. Python script to create metric filter + alarm

        This script will:

        * Create/overwrite a metric filter on the specified CloudWatch Logs log group
        * Create/overwrite a CloudWatch alarm that fires when ≥ 1 S3 bucket change is detected in a 5‑minute period

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

        region = "us-east-1"                 # change as needed
        log_group_name = "/aws/cloudtrail/main"  # your existing CloudTrail log group
        metric_namespace = "SecurityMonitoring"
        metric_name = "S3BucketChanges"
        metric_filter_name = "S3BucketChangesFilter"
        alarm_name = "S3BucketChangesAlarm"
        sns_topic_arn = "arn:aws:sns:us-east-1:123456789012:SecurityAlerts"  # optional, set to None if not using SNS

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

        metric_filter_pattern = (
            '{ ($.eventSource = "s3.amazonaws.com") && '
            '('
            '($.eventName = "PutBucketAcl") || '
            '($.eventName = "PutBucketPolicy") || '
            '($.eventName = "PutBucketCors") || '
            '($.eventName = "PutBucketLifecycle") || '
            '($.eventName = "PutBucketReplication") || '
            '($.eventName = "PutBucketTagging") || '
            '($.eventName = "PutBucketVersioning") || '
            '($.eventName = "PutBucketWebsite") || '
            '($.eventName = "DeleteBucketPolicy") || '
            '($.eventName = "DeleteBucketCors") || '
            '($.eventName = "DeleteBucketLifecycle") || '
            '($.eventName = "DeleteBucketReplication") || '
            '($.eventName = "DeleteBucketTagging") || '
            '($.eventName = "DeleteBucketWebsite")'
            ')'
            '}'
        )

        def create_metric_filter():
            print(f"Creating/updating metric filter '{metric_filter_name}'...")
            logs_client.put_metric_filter(
                logGroupName=log_group_name,
                filterName=metric_filter_name,
                filterPattern=metric_filter_pattern,
                metricTransformations=[
                    {
                        "metricName": metric_name,
                        "metricNamespace": metric_namespace,
                        "metricValue": "1"
                    }
                ]
            )
            print("Metric filter created/updated.")

        def create_alarm():
            print(f"Creating/updating alarm '{alarm_name}'...")
            alarm_kwargs = {
                "AlarmName": alarm_name,
                "AlarmDescription": "Alarm when S3 bucket configuration changes are detected via CloudTrail.",
                "ActionsEnabled": True,
                "MetricName": metric_name,
                "Namespace": metric_namespace,
                "Statistic": "Sum",
                "Period": 300,  # 5 minutes
                "EvaluationPeriods": 1,
                "DatapointsToAlarm": 1,
                "Threshold": 1.0,
                "ComparisonOperator": "GreaterThanOrEqualToThreshold",
                "TreatMissingData": "notBreaching"
            }

            if sns_topic_arn:
                alarm_kwargs["AlarmActions"] = [sns_topic_arn]
                alarm_kwargs["OKActions"] = [sns_topic_arn]

            cw_client.put_metric_alarm(**alarm_kwargs)
            print("Alarm created/updated.")

        if __name__ == "__main__":
            create_metric_filter()
            create_alarm()
            print("Remediation complete: S3 Bucket Changes Alarm enabled.")
        ```

        ***

        ## 4. Summary of remediation steps

        1. Ensure CloudTrail is enabled and sending logs to a CloudWatch Logs log group.
        2. Use the script (or similar boto3 code) to:
           * Add a metric filter on that log group for S3 bucket config‑change events.
           * Create a CloudWatch alarm on that metric (with SNS notifications if desired).
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # SNS topic for alarm notifications
        resource "aws_sns_topic" "s3_bucket_changes_topic" {
          name = "S3BucketChangesTopic"
        }

        # OPTIONAL: subscribe an email endpoint to the SNS topic
        # Replace ALERT_EMAIL_ADDRESS with the destination email (e.g., "user@example.com")
        resource "aws_sns_topic_subscription" "s3_bucket_changes_email" {
          topic_arn = aws_sns_topic.s3_bucket_changes_topic.arn
          protocol  = "email"
          endpoint  = "ALERT_EMAIL_ADDRESS"
        }

        # CloudWatch Logs metric filter on the CloudTrail log group
        # Replace CLOUDTRAIL_LOG_GROUP_NAME with the name of the CloudTrail log group
        resource "aws_cloudwatch_log_metric_filter" "s3_bucket_changes_filter" {
          name           = "S3BucketChangesFilter"
          log_group_name = "CLOUDTRAIL_LOG_GROUP_NAME"

          # Mirrors the filter-pattern from the verified CLI remediation
          pattern = "{($.eventSource=s3.amazonaws.com) && (($.eventName=CreateBucket) || ($.eventName=DeleteBucket) || ($.eventName=PutBucketAcl) || ($.eventName=PutBucketPolicy) || ($.eventName=PutBucketCors) || ($.eventName=PutBucketLifecycle) || ($.eventName=PutBucketReplication) || ($.eventName=PutBucketLogging) || ($.eventName=PutBucketTagging) || ($.eventName=PutBucketWebsite) || ($.eventName=PutBucketVersioning) || ($.eventName=DeleteBucketPolicy) || ($.eventName=DeleteBucketCors) || ($.eventName=DeleteBucketLifecycle) || ($.eventName=DeleteBucketReplication) || ($.eventName=DeleteBucketTagging) || ($.eventName=DeleteBucketWebsite))}"

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

        # CloudWatch alarm for S3 bucket configuration changes
        resource "aws_cloudwatch_metric_alarm" "s3_bucket_changes_alarm" {
          alarm_name          = "S3BucketChangesAlarm"
          alarm_description   = "Alarm for S3 bucket configuration changes"
          namespace           = "CloudTrailMetrics"
          metric_name         = "S3BucketChangesMetric"
          statistic           = "Sum"
          period              = 300
          threshold           = 1
          comparison_operator = "GreaterThanOrEqualToThreshold"
          evaluation_periods  = 1

          alarm_actions = [
            aws_sns_topic.s3_bucket_changes_topic.arn
          ]

          depends_on = [
            aws_cloudwatch_log_metric_filter.s3_bucket_changes_filter
          ]
        }
        ```

        This assumes you already have a CloudTrail trail delivering management events to the `CLOUDTRAIL_LOG_GROUP_NAME` CloudWatch Logs group; that trail configuration is managed separately. No resources above require forced replacement beyond standard Terraform create/update behavior.

        To verify, `terraform plan` should show:

        * `+` create `aws_sns_topic.s3_bucket_changes_topic`
        * `+` create `aws_sns_topic_subscription.s3_bucket_changes_email` (if kept)
        * `+` create `aws_cloudwatch_log_metric_filter.s3_bucket_changes_filter`
        * `+` create `aws_cloudwatch_metric_alarm.s3_bucket_changes_alarm`.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
