# Task 058


Generate a basic Amazon Kinesis Analytics Application with an input kinesis stream

## Intent

Has one "aws_kinesis_analytics_application" resource with one "aws_kinesis_stream" resource as an input

## Reference Terraform solution

terraform {
  required_version = ">= 1.15.0"

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

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


data "aws_iam_policy_document" "StreamReaderWriter" {
  statement {
    effect = "Allow"
    actions = ["kinesis:DescribeStream",
               "kinesis:GetShardIterator",
               "kinesis:GetRecords"]
    resources = [aws_kinesis_stream.test_stream.arn]
  }
}

data "aws_iam_policy_document" "KinesisAssume" {
  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRole"]
    principals {
      type        = "Service"
      identifiers = ["kinesisanalytics.amazonaws.com"]
    }
  }
}

resource "aws_iam_policy" "StreamReaderWriter" {
  name   = "KinesisStreamReaderWriter"
  policy = data.aws_iam_policy_document.StreamReaderWriter.json
}

resource "aws_iam_role" "kinesis_role" {
  name               = "kinesis_role"
  assume_role_policy = data.aws_iam_policy_document.KinesisAssume.json
}

resource "aws_iam_role_policy_attachment" "attach_kinesis_role" {
  role       = aws_iam_role.kinesis_role.name
  policy_arn = aws_iam_policy.StreamReaderWriter.arn
}

resource "aws_kinesis_stream" "test_stream" {
  name             = "events"
  shard_count      = 1
  retention_period = 168
}


resource "aws_kinesis_analytics_application" "test_application" {
  name = "kinesis-analytics-application-test"

  inputs {
    name_prefix = "test_prefix"

    kinesis_stream {
      resource_arn = aws_kinesis_stream.test_stream.arn
      role_arn     = aws_iam_role.kinesis_role.arn
    }

    parallelism {
      count = 1
    }

    schema {
      record_columns {
        mapping  = "$.test"
        name     = "test"
        sql_type = "VARCHAR(8)"
      }

      record_encoding = "UTF-8"

      record_format {
        mapping_parameters {
          json {
            record_row_path = "$"
          }
        }
      }
    }
  }
}


## OPA Rego validation policy

package terraform.policy

import rego.v1

default has_valid_resources = false

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

has_valid_kinesis_stream if {
        some i
    resource := input.planned_values.root_module.resources[i]
    resource.type == "aws_kinesis_stream"
    resource.values.name
}

has_valid_kinesis_analytics_application if {
        some i
        resource := input.planned_values.root_module.resources[i]
    resource.type == "aws_kinesis_analytics_application"
    resource.values.name
    resource.values.inputs[_].kinesis_stream
}

has_valid_resources if {
        has_valid_iam_role(input.resource_changes)
        has_valid_kinesis_stream
    has_valid_kinesis_analytics_application
}

main if {
    has_valid_kinesis_stream
    has_valid_kinesis_analytics_application
    has_valid_resources
}