Task: Generate a Kinesis Firehose Delivery Stream with a OpenSearch Serverless Destination

Specification:
Has one "aws_iam_role" resource, one "aws_s3_bucket" resource, one "aws_opensearchserverless_security_policy" resource, and one "aws_kinesis_firehose_delivery_stream" resource with an "opensearchserverless_configuration" block

Terraform configuration (main.tf):
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.75"
    }
  }

  required_version = ">= 1.9.0"
}

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

data "aws_region" "current" {}

data "aws_caller_identity" "current" {}

resource "aws_iam_role" "firehose_role" {
  name = "firehose_opensearch_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect = "Allow",
        Principal = {
          Service = "firehose.amazonaws.com"
        },
        Action = "sts:AssumeRole"
      }
    ]
  })
}

resource "aws_iam_policy" "firehose_policy" {
  name        = "firehose_opensearch_s3_policy"
  description = "Policy for Kinesis Firehose to access S3 and OpenSearch Serverless"

  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect = "Allow",
        Action = [
          "s3:PutObject",
          "s3:PutObjectAcl",
          "s3:GetBucketLocation",
          "s3:ListBucket",
          "s3:GetObject"
        ],
        Resource = [
          aws_s3_bucket.januarysixth.arn,
          "${aws_s3_bucket.januarysixth.arn}/*"
        ]
      },
      {
        Effect = "Allow",
        Action = [
          "es:ESHttpPut",
          "es:ESHttpPost",
          "es:ESHttpGet"
        ],
        Resource = [
          "arn:aws:es:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:collection/${aws_opensearchserverless_collection.test_collection.name}/*",
        ]
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "firehose_policy_attach" {
  role       = aws_iam_role.firehose_role.name
  policy_arn = aws_iam_policy.firehose_policy.arn
}

resource "aws_s3_bucket" "januarysixth" {
  bucket = "januarysixth"
}
resource "aws_opensearchserverless_security_policy" "example" {
  name = "example"
  type = "encryption"
  policy = jsonencode({
    "Rules" = [
      {
        "Resource" = [
          "collection/example"
        ],
        "ResourceType" = "collection"
      }
    ],
    "AWSOwnedKey" = true
  })
}

resource "aws_opensearchserverless_collection" "test_collection" {
  name = "example"
  depends_on = [aws_opensearchserverless_security_policy.example]
}

resource "aws_kinesis_firehose_delivery_stream" "test_stream" {
  name        = "terraform-kinesis-firehose-test-stream"
  destination = "opensearchserverless"

  opensearchserverless_configuration {
    collection_endpoint = aws_opensearchserverless_collection.test_collection.collection_endpoint
    role_arn            = aws_iam_role.firehose_role.arn
    index_name          = "test"

    s3_configuration {
      role_arn           = aws_iam_role.firehose_role.arn
      bucket_arn         = aws_s3_bucket.januarysixth.arn
      buffering_size     = 10
      buffering_interval = 400
      compression_format = "GZIP"
    }
  }
}

Validation policy (checks.rego):
package terraform.validation

import future.keywords.in

default has_valid_resources = false

has_valid_iam_role(resources) { 
	some resource in resources 
    resource.type == "aws_iam_role" 
    contains(resource.change.after.assume_role_policy,"firehose.amazonaws.com") 
}

has_valid_bucket {
    some i
    resource := input.planned_values.root_module.resources[i]
    resource.type == "aws_s3_bucket"
}

has_valid_opensearchserverless_collection {
    some i
    resource := input.planned_values.root_module.resources[i]
    resource.type == "aws_opensearchserverless_collection"
    resource.values.name
}

has_valid_firehose_delivery_stream {
	some i
	resource := input.planned_values.root_module.resources[i]
    resource.type == "aws_kinesis_firehose_delivery_stream"
    resource.values.name
    resource.values.destination == "opensearchserverless"
    resource.values.opensearchserverless_configuration[_].s3_configuration
	role := input.configuration.root_module.resources[i]
    role.expressions.opensearchserverless_configuration[_].role_arn
    role.expressions.opensearchserverless_configuration[_].collection_endpoint
}

has_valid_resources {
	has_valid_iam_role(input.resource_changes)
	has_valid_bucket
	has_valid_opensearchserverless_collection
    has_valid_firehose_delivery_stream
}