# Task 128


Create a custom Virtual Private Cloud (VPC) with CIDR block 10.0.0.0/16. Create two subnets in us-east-1a and us-east-1b. Finally create an EC2 instance in each subnet using the latest Amazon Linux 2 AMI, with t2.micro instance type and an attached EBS volume of 50 GB.

## Intent

Create a VPC, 2 subnets, and ec2 instance in each subnet with latest Amazon Linux 2 AMI, with t2.micro instance type and an attached EBS volume of 50 GB.

## 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_ami" "latest_amazon_linux_2" {
  most_recent = true

  owners = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }

  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }
}

# Create a Virtual Private Cloud (VPC)
resource "aws_vpc" "my_vpc" {
  cidr_block = "10.0.0.0/16"
}

data "aws_availability_zones" "azs" {
    state = "available"
}

resource "aws_subnet" "subnet_a" {
  vpc_id            = aws_vpc.my_vpc.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = data.aws_availability_zones.azs.names[0]
}

resource "aws_subnet" "subnet_b" {
  vpc_id            = aws_vpc.my_vpc.id
  cidr_block        = "10.0.2.0/24"
  availability_zone = data.aws_availability_zones.azs.names[1]
}

# Create an EC2 instance in Subnet A
resource "aws_instance" "ec2_instance_a" {
  ami           = data.aws_ami.latest_amazon_linux_2.id
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.subnet_a.id

  root_block_device {
    volume_size = 50
  }
}

# # Create an EC2 instance in Subnet B
resource "aws_instance" "ec2_instance_b" {
  ami           = data.aws_ami.latest_amazon_linux_2.id
  instance_type = "t2.micro"
  subnet_id     = aws_subnet.subnet_b.id

  root_block_device {
    volume_size = 50
  }
}


## OPA Rego validation policy

package terraform.policy

import rego.v1

default allow = false

allow if {
    count(aws_instances) == 2
    subnet_a_exists(input.resource_changes)
    subnet_b_exists(input.resource_changes)
}

aws_instances contains resource if {
    resource := input.resource_changes[_]
    resource.type == "aws_instance"
    check_ami(resource)
    check_instance_type(resource)
    check_root_block_device(resource)
}

subnet_a_exists(resources) if {
    some resource in resources
    resource.type == "aws_subnet"
    resource.change.after.availability_zone == "us-east-1a"
    resource.change.after.cidr_block == "10.0.1.0/24"
}

subnet_b_exists(resources) if {
    some resource in resources
    resource.type == "aws_subnet"
    resource.change.after.availability_zone == "us-east-1b"
    resource.change.after.cidr_block == "10.0.2.0/24"
}

check_aws_instance(resources) if {
    some resource in resources
    resource.type == "aws_instance"
    check_ami(resource)
    check_instance_type(resource)
    check_root_block_device(resource)
}

check_ami(aws_instance) if {
    aws_instance.change.after.ami != null
    aws_instance.change.after.ami != ""
}

check_instance_type(aws_instance) if {
    aws_instance.change.after.instance_type == "t2.micro"
}

check_root_block_device(aws_instance) if {
    aws_instance.change.after.root_block_device[0].volume_size == 50
}

main if {
    allow
}