module "dns_updater_secrets" {
  source   = "git@github.com:theorchard/terraform-secrets-manager.git//?ref=1.5.1"
  for_each = var.dns_updater_secret_names

  application_family = var.application_family
  environment        = var.environment
  secret_name        = each.value
  service_name       = var.dns_updater_lambda_name
}

# temporary grant read access to the secrets manager secrets
module "secrets_manager_policy" {
  source = "git@github.com:theorchard/terraform-iam-policy-templates.git//documents/secretsmanager/secrets_list?ref=0.3.0"

  secrets = [
    "${var.environment}/${var.dns_updater_lambda_name}/NEO4J_USERNAME",
    "${var.environment}/${var.dns_updater_lambda_name}/NEO4J_PASSWORD",
  ]
  action_types = ["read"]
}

resource "aws_iam_policy" "secrets_manager_access_policy_for_lambda" {
  name        = "SecretsManager-${var.environment}-${var.dns_updater_lambda_name}-policy"
  description = "Access to Secrets Manager for Neo4j DNS updater Lambda"
  policy      = module.secrets_manager_policy.policy.json
}

module "lambda_neo4j_networking_dns_update" {
  source = "git@github.com:theorchard/terraform-lambda.git//?ref=4.2.0"

  datadog_advanced_enabled                       = true
  environment                                    = var.environment
  application_family                             = var.application_family
  lambda_name                                    = "networking-${var.dns_updater_lambda_name}"
  lambda_description                             = "Lambda for updating Neo4j cluster DNS records in the networking account"
  lambda_function_timeout                        = "300"
  use_container_image                            = true
  lambda_function_reserved_concurrent_executions = "1"
  vpc_id                                         = module.vpc_info.vpc_id
  vpc_subnet_ids                                 = module.vpc_info.default_private_subnet_ids
  cloudwatch_event_enabled                       = true
  cloudwatch_event_schedule                      = "rate(1 minute)"

  iam_managed_policy_attachments = [
    aws_iam_policy.update_route53_record_policy.arn,
    aws_iam_policy.assume_cross_account_neo4j_dns_update_role_policy.arn,
    aws_iam_policy.secrets_manager_access_policy_for_lambda.arn,
  ]

  lambda_function_environment_variables = {
    ENVIRONMENT           = var.environment
    HOSTED_ZONE_ID        = data.aws_route53_zone.networking_route53_zone.zone_id
    NEO4J_URL             = "neo4j+s://qa-neo4j-5-cluster.theorchard.io"
    RECORD_NAME           = "qa-neo4j-5-cluster.theorchard.io."
    ROUTE_53_IAM_ROLE_ARN = data.aws_iam_role.cross_account_neo4j_dns_update_role.arn
    EXTERNAL_ID           = "MVbfR8vaLnItbX9nE7"
  }
}

data "aws_iam_policy_document" "lambda_update_neo4j_route53_record_policy" {
  statement {
    effect = "Allow"

    actions = [
      "autoscaling:DescribeAutoScalingGroups",
      "ec2:DescribeInstances",
      "route53:ListHostedZones",
    ]

    resources = ["*"]
  }

  statement {
    effect = "Allow"

    actions = [
      "route53:ChangeResourceRecordSets",
      "route53:GetHostedZone",
      "route53:ListResourceRecordSets"
    ]

    resources = [data.aws_route53_zone.route53_zone.arn]
  }
}

resource "aws_iam_policy" "update_route53_record_policy" {
  name        = "${var.environment}_lambda_neo4j_dns_update_policy"
  description = "Access to update DNS records with instance private IPs"
  policy      = data.aws_iam_policy_document.lambda_update_neo4j_route53_record_policy.json
}

resource "datadog_monitor" "dns_record_updated_monitor_v5" {
  name    = "Neo4j ${upper(var.environment)} V5 DNS record has been updated"
  type    = "log alert"
  message = "{{#is_warning}}DNS record for Neo4j ${upper(var.environment)} V5 cluster has been updated with new node information\nNotify: ${var.dns_lambda_notification_endpoints}{{/is_warning}}"

  query = "logs(\"service:networking-${var.dns_updater_lambda_name} env:${var.environment} \\\"DNS record updated for Neo4j ${var.environment} v5\\\"\").index(\"*\").rollup(\"count\").last(\"15m\") >= 10"

  monitor_thresholds {
    critical = 10
    warning  = 1
  }

  include_tags = true

  tags = [
    "environment:${var.environment}",
    "service_name:${var.service_name}",
    "application_family:devops",
  ]
}
