# Task 118


Create an IAM policy document that allows the 's3.amazonaws.com' service to publish to an SNS topic for S3 event notifications. Specify the actions as 'SNS:Publish' and set the resource to the ARN of the SNS topic 's3-event-notification-topic'. Apply a condition to allow this action only if the source ARN is similar to the ARN of the specified S3 bucket. Create an SNS topic named 's3-event-notification-topic' with the generated IAM policy. Set up an S3 bucket named 'your-bucket-name' and configure it to send notifications to the SNS topic for 's3:ObjectCreated:*' events with a filter for '.log' suffix.

## Intent

Data "aws_iam_policy_document"
has one "effect"
has one "principals" 
has one "actions"
has one "resources"

Resource "aws_sns_topic" 
has one "name"
uses the JSON output

Resource "aws_s3_bucket" 
has one "bucket"

Resource "aws_s3_bucket_notification" 
has one "bucket"
configures a "topic" notification with:
"topic_arn"
"events"
"filter_suffix"

## Reference Terraform solution

terraform {
  required_version = ">= 1.15.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

provider "aws" {
    region = "us-west-1"
}

data "aws_iam_policy_document" "topic" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["s3.amazonaws.com"]
    }

    actions   = ["SNS:Publish"]
    resources = ["arn:aws:sns:*:*:s3-event-notification-topic"]

    condition {
      test     = "ArnLike"
      variable = "aws:SourceArn"
      values   = [aws_s3_bucket.bucket.arn]
    }
  }
}
resource "aws_sns_topic" "topic" {
  name   = "s3-event-notification-topic"
  policy = data.aws_iam_policy_document.topic.json
}

resource "aws_s3_bucket" "bucket" {
  bucket = "your-bucket-name"
}

resource "aws_s3_bucket_notification" "bucket_notification" {
  bucket = aws_s3_bucket.bucket.id

  topic {
    topic_arn     = aws_sns_topic.topic.arn
    events        = ["s3:ObjectCreated:*"]
    filter_suffix = ".log"
  }
}


## OPA Rego validation policy

package terraform.policy

import rego.v1

default has_aws_iam_policy_document_topic = false
default has_aws_sns_topic = false
default has_aws_s3_bucket = false
default has_aws_s3_bucket_notification = false

has_aws_iam_policy_document_topic if {
    policy := input.planned_values.root_module.resources[_]
    policy.type == "aws_iam_policy_document"
}

has_aws_sns_topic if {
    topic := input.planned_values.root_module.resources[_]
    topic.type == "aws_sns_topic"
    topic.name == "topic"
    topic.values.name == "s3-event-notification-topic"
}

has_aws_s3_bucket if {
    bucket := input.planned_values.root_module.resources[_]
    bucket.type == "aws_s3_bucket"
    bucket.name == "bucket"
    bucket.values.bucket == "your-bucket-name"
}

has_aws_s3_bucket_notification if {
    notification := input.planned_values.root_module.resources[_]
    notification.type == "aws_s3_bucket_notification"
    notification.name == "bucket_notification"
    notification.values.topic[0].events[0] == "s3:ObjectCreated:*"
    notification.values.topic[0].filter_suffix == ".log"
}

valid_configuration if {
    has_aws_iam_policy_document_topic
    has_aws_sns_topic
    has_aws_s3_bucket
    has_aws_s3_bucket_notification
}

main if {
    valid_configuration
}