# Launch template ============================================================

resource "aws_launch_template" "this" {
  name_prefix   = "${var.name}-"
  image_id      = var.ami_id
  instance_type = var.instance_type
  key_name      = var.key_name
  user_data     = var.user_data

  vpc_security_group_ids = var.security_group_ids

  dynamic "iam_instance_profile" {
    for_each = var.iam_instance_profile_arn != null ? [var.iam_instance_profile_arn] : []
    content {
      arn = iam_instance_profile.value
    }
  }

  metadata_options {
    http_endpoint               = "enabled"
    http_tokens                 = var.metadata_http_tokens
    http_put_response_hop_limit = 1
  }

  monitoring {
    enabled = true
  }

  block_device_mappings {
    device_name = "/dev/xvda"
    ebs {
      volume_size           = var.root_volume_size
      volume_type           = "gp3"
      encrypted             = true
      kms_key_id            = var.root_volume_kms_key_id
      delete_on_termination = true
    }
  }

  lifecycle {
    create_before_destroy = true
  }

  tags = local.tags
}

# Auto Scaling Group =========================================================

resource "aws_autoscaling_group" "this" {
  name                = var.name
  vpc_zone_identifier = var.vpc_zone_identifier
  min_size            = var.min_size
  max_size            = var.max_size
  desired_capacity    = var.desired_capacity
  health_check_type   = var.health_check_type
  target_group_arns   = var.target_group_arns

  launch_template {
    id      = aws_launch_template.this.id
    version = aws_launch_template.this.latest_version
  }

  dynamic "tag" {
    for_each = local.asg_tags
    content {
      key                 = tag.value.key
      value               = tag.value.value
      propagate_at_launch = tag.value.propagate_at_launch
    }
  }

  dynamic "warm_pool" {
    for_each = var.warm_pool_enabled ? [true] : []
    content {
      min_size = var.warm_pool_min_size

      instance_reuse_policy {
        reuse_on_scale_in = true
      }
    }
  }

  lifecycle {
    ignore_changes = [desired_capacity]
  }
}

# Lifecycle hooks ------------------------------------------------------------

resource "aws_autoscaling_lifecycle_hook" "this" {
  for_each = var.lifecycle_hooks

  name                    = each.key
  autoscaling_group_name  = aws_autoscaling_group.this.name
  lifecycle_transition    = each.value.lifecycle_transition
  heartbeat_timeout       = each.value.heartbeat_timeout
  default_result          = each.value.default_result
  notification_target_arn = each.value.notification_arn
}

# Scaling policies ===========================================================

resource "aws_autoscaling_policy" "this" {
  for_each = var.scaling_policies

  name                   = each.key
  autoscaling_group_name = aws_autoscaling_group.this.name
  policy_type            = "TargetTrackingScaling"

  target_tracking_configuration {
    predefined_metric_specification {
      predefined_metric_type = each.value.predefined_metric_type
    }
    target_value = each.value.target_value
  }

  estimated_instance_warmup = each.value.cooldown
}

