Task: Infrastructure for an autograder for a CS class. The autograde needs to run students' code stored on GitHub in a specific environment and store the result. Make sure that the autograder prevents the students' code from reaching the internet. Accomplish this using AWS CodeBuild and AWS VPC.

Specification:
have one "aws_codebuild_project" resource
  with "artifacts" argument block
    with "type" argument with value "S3"
    with "location" argument
    with "name" argument
  with "environment" argument block
    with "computer_type" argument
    with "image" argument
    with "type" argument
  with "source" argument block
    with "type" argument with value "GITHUB"
    with "location" argument
  with "vpc_config" argument block
    with "vpc_id" argument
    with "subnets" argument
    with "security_group_ids" argument
have one "aws_vpc" resource
  with "cidr_block" argument
have one "aws_subnet" argument
  with "vpc_id" argument
  with "cidr_block" argument
with one "aws_security_group" resource
  with "vpc_id" argument

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"
}

resource "aws_s3_bucket" "artifact_bucket" {
  bucket_prefix = "artifact-bucket-"
}

resource "aws_codebuild_project" "autograder_build" {
  name         = "autograder_build"
  service_role = aws_iam_role.autograder_build_role.arn

  artifacts {
    type     = "S3"
    location = aws_s3_bucket.artifact_bucket.arn
    name     = "results.zip" # include this
  }

  environment { # arguments required, exact value not specified
    compute_type = "BUILD_GENERAL1_SMALL"
    image        = "aws/codebuild/standard:7.0-24.10.29"
    type         = "LINUX_CONTAINER"
  }

  source {
    type            = "GITHUB"
    git_clone_depth = 1 # good to have, not required
    location        = "github.com/source-location"
  }

  vpc_config {
    vpc_id             = aws_vpc.autograder_vpc.id
    subnets            = [aws_subnet.autograder_vpc_subnet.id]
    security_group_ids = [aws_security_group.autograder_vpc_securitygroup.id]
  }
}

resource "aws_vpc" "autograder_vpc" {
  cidr_block = "10.0.0.0/16" # extra value not specified
}

resource "aws_subnet" "autograder_vpc_subnet" {
  vpc_id     = aws_vpc.autograder_vpc.id
  cidr_block = "10.0.0.0/24" # include this
}

resource "aws_security_group" "autograder_vpc_securitygroup" {
  vpc_id = aws_vpc.autograder_vpc.id
}

resource "aws_iam_role" "autograder_build_role" {
  assume_role_policy = data.aws_iam_policy_document.autograder_build_policy_assume.json
}

data "aws_iam_policy_document" "autograder_build_policy_assume" {
  statement {
    actions = ["sts:AssumeRole"]

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

data "aws_iam_policy_document" "autograder_build_policy" {
  statement {
    effect = "Allow"
    actions = [
      "ec2:DescribeSubnets",
      "ec2:DescribeSecurityGroups",
      "ec2:DescribeVpcs"
    ]
    resources = [
      "*"
    ]
  }

  statement {
    effect  = "Allow"
    actions = ["s3:*"]
    resources = [
      aws_s3_bucket.artifact_bucket.arn,
      "${aws_s3_bucket.artifact_bucket.arn}/*",
    ]
  }
}

resource "aws_iam_policy" "autograder_build_policy" {
  name        = "lambda_policy"
  description = "Grants permissions to Lambda to describe vpc, subnet, security group"

  policy = data.aws_iam_policy_document.autograder_build_policy.json
}

resource "aws_iam_role_policy_attachment" "lambda_policy_attach" {
  role       = aws_iam_role.autograder_build_role.name
  policy_arn = aws_iam_policy.autograder_build_policy.arn
}

Validation policy (checks.rego):
package autograder_high_jail

import rego.v1

codebuild_project_valid(codebuild_project, security_group, subnet, vpc) if {
	some artifact in codebuild_project.expressions.artifacts
	artifact.location
	artifact.type
	artifact.name

	some environment in codebuild_project.expressions.environment
	environment.compute_type
	environment.image
	environment.type

	some source in codebuild_project.expressions.source
	source.type.constant_value == "GITHUB"
	source.location

	some vpc_config in codebuild_project.expressions.vpc_config
	security_group.address in vpc_config.security_group_ids.references
	subnet.address in vpc_config.subnets.references
	vpc.address in vpc_config.vpc_id.references
}

security_group_valid(security_group, vpc) if {
	vpc.address in security_group.expressions.vpc_id.references
}

subnet_valid(subnet, vpc) if {
	subnet.expressions.cidr_block
	vpc.address in subnet.expressions.vpc_id.references
}

vpc_valid(vpc) if {
	vpc.expressions.cidr_block
}

default valid := false

valid if {
	resources := input.configuration.root_module.resources
	some codebuild_project in resources
	codebuild_project.type == "aws_codebuild_project"
	some security_group in resources
	security_group.type == "aws_security_group"
	some subnet in resources
	subnet.type == "aws_subnet"
	some vpc in resources
	vpc.type == "aws_vpc"
	codebuild_project_valid(codebuild_project, security_group, subnet, vpc)
	security_group_valid(security_group, vpc)
	subnet_valid(subnet, vpc)
	vpc_valid(vpc)
}