# Task 157


Trigger a "aws_lambda_function" called test_lambda whenever an EC2 image is created. For the Lambda deployment package, use a `data "archive_file"` with inline source content (do not reference local files). Use `filebase64sha256` on the archive output, not on a local file path.

## Intent

Needs to have an aws_lambda_function defined. Create a aws_cloudwatch_event_rule to trigger on EC2 creation and aws_lambda_permission to have permission to run lambda function. Create a target to trigger the lambda function.

## Reference Terraform solution

terraform {
  required_version = ">= 1.15.0"

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

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

resource "aws_cloudwatch_event_rule" "scan_ami" {
  name          = "EC2CreateImageEvent"
  description   = "EC2 Create Image Event..."
  role_arn      = aws_iam_role.cron.arn
  event_pattern = <<EOF
{
  "source": ["aws.ec2"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventSource": ["ec2.amazonaws.com"],
    "eventName": ["CreateImage"]
  }
}
EOF
}

resource "aws_cloudwatch_event_target" "scan_ami_lambda_function" {
  rule = aws_cloudwatch_event_rule.scan_ami.name
  arn  = aws_lambda_function.cron.arn
}

data "archive_file" "lambda-func" {
  type        = "zip"
  output_path = "${path.module}/lambda_func.zip"

  source {
    content  = "def handler(event, context): return {'statusCode': 200}"
    filename = "lambda_func.py"
  }
}

resource "aws_lambda_function" "cron" {
  function_name = "cron-lambda-function"
  role          = aws_iam_role.cron.arn
  filename      = data.archive_file.lambda-func.output_path
  source_code_hash = data.archive_file.lambda-func.output_base64sha256
  handler       = "lambda_func.handler"
  runtime       = "python3.12"
}

resource "aws_lambda_permission" "cron" {
  function_name = aws_lambda_function.cron.function_name
  action        = "lambda:InvokeFunction"
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.scan_ami.arn
}

data "aws_iam_policy_document" "cron_assume_role" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type = "Service"
      identifiers = [
        "lambda.amazonaws.com",
        "events.amazonaws.com"
      ]
    }
  }
}

resource "aws_iam_role" "cron" {
  name               = "cron_assume_role"
  assume_role_policy = data.aws_iam_policy_document.cron_assume_role.json
}

resource "aws_iam_role_policy_attachment" "cron" {
  role       = aws_iam_role.cron.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}


## OPA Rego validation policy

package terraform.policy

import rego.v1

default allow = false

# Check for CloudWatch event rule for EC2 CreateImage event
ec2_create_image_event_rule_valid(resources) if {
    some resource in resources
    resource.type == "aws_cloudwatch_event_rule"
    contains(resource.change.after.event_pattern, "CreateImage")
    contains(resource.change.after.event_pattern, "ec2.amazonaws.com")
}

# Check for CloudWatch event target for triggering test_lambda
cloudwatch_event_target_for_lambda_valid(resources) if {
    some resource in resources
    resource.type == "aws_cloudwatch_event_target"
    resource.change.after.rule == "EC2CreateImageEvent"
}

# Aggregate all checks
allow if {
    ec2_create_image_event_rule_valid(input.resource_changes)
    cloudwatch_event_target_for_lambda_valid(input.resource_changes)
}

main if {
    allow
}