#############################################
# CVE-2016-5195 (Dirty COW) lab — single EC2 VM on an old vulnerable kernel.
# Author-from-scratch; stage only. NEVER `tofu apply` here (director gates apply).
#############################################

# Default VPC / subnet of the region (no custom networking needed for a single VM).
data "aws_vpc" "default" {
  default = true
}

data "aws_subnets" "default" {
  filter {
    name   = "vpc-id"
    values = [data.aws_vpc.default.id]
  }
}

# --- Ephemeral, per-run SSH key pair (minted in-stack, destroyed with the stack). ---
resource "tls_private_key" "lab" {
  algorithm = "RSA"
  rsa_bits  = 4096
}

resource "aws_key_pair" "lab" {
  key_name   = "cve-${lower(replace(var.cve_id, "_", "-"))}-${var.lab_run_id}"
  public_key = tls_private_key.lab.public_key_openssh
}

resource "local_file" "private_key" {
  content         = tls_private_key.lab.private_key_pem
  filename        = "${path.module}/lab_ssh_key.pem"
  file_permission = "0600"
}

# --- Security group: SSH only, from the operator CIDR (never 0.0.0.0/0 by default). ---
resource "aws_security_group" "lab" {
  name_prefix = "cve-${var.lab_run_id}-"
  description = "CVE-2016-5195 lab: SSH from operator only"
  vpc_id      = data.aws_vpc.default.id

  ingress {
    description = "SSH from operator"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.allowed_ssh_cidr]
  }

  egress {
    description = "all egress (needed to fetch the pinned kernel debs at first boot)"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = { Name = "cve-${var.lab_run_id}-sg" }
}

# --- cloud-init user_data with embedded baseline/control/probe payloads. ---
locals {
  user_data = templatefile("${path.module}/../cloud-init/user_data.yaml.tftpl", {
    cve_actor              = var.actor_user
    baseline_sh_b64        = filebase64("${path.module}/../files/cve-baseline.sh")
    baseline_service_b64   = filebase64("${path.module}/../files/cve-baseline.service")
    control_sh_b64         = filebase64("${path.module}/../files/cve-control.sh")
    control_service_b64    = filebase64("${path.module}/../files/cve-control.service")
    cowprobe_c_b64         = filebase64("${path.module}/../files/cowprobe.c")
  })
}

resource "aws_instance" "lab" {
  ami                         = var.ami_id
  instance_type               = var.instance_type
  key_name                    = aws_key_pair.lab.key_name
  subnet_id                   = data.aws_subnets.default.ids[0]
  vpc_security_group_ids      = [aws_security_group.lab.id]
  associate_public_ip_address = true
  # gzip+base64: cloud-init decompresses gzip user_data transparently. Keeps the
  # embedded baseline/control/probe payloads under the 16 KiB user_data limit.
  user_data_base64 = base64gzip(local.user_data)

  # Xen instance -> root presented as /dev/xvda; old generic initramfs has the driver.
  root_block_device {
    volume_size = 20
    volume_type = "gp2"
    delete_on_termination = true
  }

  tags = {
    Name = "cve-2016-5195-dirtycow-lab"
  }
}
