locals {
  role_name = "cp9-${var.session_name}-gcp-regional"
}

data "aws_caller_identity" "current" {}

data "aws_route53_zone" "regional" {
  zone_id      = var.route53_zone_id
  private_zone = false

  lifecycle {
    postcondition {
      condition     = trimsuffix(self.name, ".") == trimsuffix(var.route53_zone_name, ".")
      error_message = "route53_zone_id must resolve to route53_zone_name in target_account."
    }
  }
}

resource "terraform_data" "contract" {
  input = {
    audience                  = var.audience
    regional_endpoint_host    = var.regional_endpoint_host
    service_account_unique_id = var.service_account_unique_id
    target_account            = var.target_account
  }

  lifecycle {
    precondition {
      condition     = data.aws_caller_identity.current.account_id == var.target_account
      error_message = "The active AWS account does not match target_account."
    }
    precondition {
      condition     = var.permissions_boundary_arn == "arn:aws:iam::${var.target_account}:policy/cp9-developer-boundary"
      error_message = "permissions_boundary_arn must be the target account cp9-developer-boundary policy."
    }
    precondition {
      condition     = var.developer_power_policy_arn == "arn:aws:iam::${var.target_account}:policy/cp9-developer-power"
      error_message = "developer_power_policy_arn must be the target account cp9-developer-power policy."
    }
    precondition {
      condition     = can(regex("^arn:aws:acm-pca:${var.aws_region}:${var.target_account}:certificate-authority/[0-9a-fA-F-]+$", var.pca_arn))
      error_message = "pca_arn must be a certificate authority in the target account and region."
    }
    precondition {
      condition     = length(local.role_name) <= 64
      error_message = "The session name produces an AWS role name longer than 64 characters."
    }
  }
}

data "aws_iam_policy_document" "trust" {
  statement {
    sid     = "ExactGoogleRuntimeIdentity"
    effect  = "Allow"
    actions = ["sts:AssumeRoleWithWebIdentity"]

    principals {
      type        = "Federated"
      identifiers = ["accounts.google.com"]
    }

    condition {
      test     = "StringEquals"
      variable = "accounts.google.com:aud"
      values   = [var.service_account_unique_id]
    }
    condition {
      test     = "StringEquals"
      variable = "accounts.google.com:oaud"
      values   = [var.audience]
    }
    condition {
      test     = "StringEquals"
      variable = "accounts.google.com:sub"
      values   = [var.service_account_unique_id]
    }
  }
}

resource "aws_iam_role" "runtime" {
  name                 = local.role_name
  assume_role_policy   = data.aws_iam_policy_document.trust.json
  permissions_boundary = var.permissions_boundary_arn
}

resource "aws_iam_role_policy_attachment" "runtime" {
  role       = aws_iam_role.runtime.name
  policy_arn = var.developer_power_policy_arn
}

resource "aws_route53_record" "regional" {
  zone_id = data.aws_route53_zone.regional.zone_id
  name    = var.regional_endpoint_host
  type    = "A"
  ttl     = 60
  records = [var.gcp_public_ip]
}

resource "tls_private_key" "regional" {
  algorithm   = "ECDSA"
  ecdsa_curve = "P256"
}

resource "tls_cert_request" "regional" {
  private_key_pem = tls_private_key.regional.private_key_pem
  dns_names       = [var.regional_endpoint_host]

  subject {
    common_name = var.regional_endpoint_host
  }
}

resource "aws_acmpca_certificate" "regional" {
  certificate_authority_arn   = var.pca_arn
  certificate_signing_request = tls_cert_request.regional.cert_request_pem
  signing_algorithm           = "SHA256WITHRSA"
  template_arn                = "arn:aws:acm-pca:::template/EndEntityCertificate/V1"

  validity {
    type  = "DAYS"
    value = 5
  }

  depends_on = [terraform_data.contract]
}
