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
}

module "lambda_neo4j_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                                    = var.dns_updater_lambda_name
  lambda_description                             = "Lambda for updating Neo4j cluster DNS records"
  lambda_function_timeout                        = "300"
  use_container_image                            = true
  lambda_function_reserved_concurrent_executions = "1"

  iam_managed_policy_attachments = [
    aws_iam_policy.update_route53_record_policy.arn
  ]

  lambda_function_environment_variables = {
    ENVIRONMENT    = var.environment
    HOSTED_ZONE_ID = var.route53_zone_id
    NEO4J_URL      = "neo4j+s://dev-neo4j-cluster.dev.theorchard.io"
    RECORD_NAME    = "${aws_route53_record.non_production_route53_record.fqdn}."
  }
}

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.dev_orchard.arn]
  }
}

resource "aws_iam_policy" "update_route53_record_policy" {
  name        = "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 "aws_cloudwatch_event_rule" "lambda_periodic_trigger" {
  name                = "${var.environment}-${var.dns_updater_lambda_name}-periodic-trigger"
  description         = "Event for periodically triggering the Lambda to update Neo4j DNS records"
  schedule_expression = "rate(1 minute)"
}

resource "aws_cloudwatch_event_target" "lambda_periodic_trigger_target" {
  rule      = aws_cloudwatch_event_rule.lambda_periodic_trigger.name
  target_id = "${var.environment}-${var.dns_updater_lambda_name}-periodic-trigger-target"
  arn       = module.lambda_neo4j_dns_update.lambda_arn
}

resource "aws_lambda_permission" "allow_cloudwatch_scheduled_execution" {
  statement_id  = "AllowScheduledExecutionFromCloudWatch"
  action        = "lambda:InvokeFunction"
  function_name = module.lambda_neo4j_dns_update.lambda_name
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.lambda_periodic_trigger.arn
}

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

  query = "logs(\"service:${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",
  ]
}

