Ошибка Terraform - ECS использует спотовые экземпляры для размещения контейнеров - PullRequest
0 голосов
/ 13 июля 2020

Извините за длинный пост, но надеюсь, что он предоставит хороший фон. Не знаю, ошибка это или мой код неправильный. Я хочу создать кластер ECS со спотовыми инстансами EC2 с помощью шаблона запуска и ASG. Мой код выглядит следующим образом:

Для службы ECS, кластера, определения задачи:

resource "aws_ecs_cluster" "main" {
  name = "test-ecs-cluster"
}

resource "aws_ecs_service" "ec2_service" {
  for_each = data.aws_subnet_ids.all_subnets.ids
  name                              = "myservice_${replace(timestamp(), ":", "-")}"
  task_definition                   = aws_ecs_task_definition.task_definition.arn
  cluster                           = aws_ecs_cluster.main.id
  desired_count                     = 1
  launch_type                       = "EC2"
  health_check_grace_period_seconds = 10

  load_balancer {
    container_name   = "test-container"
    container_port   = 80
    target_group_arn = aws_lb_target_group.alb_ec2_ecs_tg.id
  }

  network_configuration {
    security_groups  = [aws_security_group.ecs_ec2.id]
    subnets          = [each.value]
    assign_public_ip = "false"
  }

  ordered_placement_strategy {
    type  = "binpack"
    field = "cpu"
  }
}

resource "aws_ecs_task_definition" "task_definition" {
  container_definitions    = data.template_file.task_definition_template.rendered
  family                   = "test-ec2-task-family"
  execution_role_arn       = aws_iam_role.ecs_task_exec_role_ec2_ecs.arn
  task_role_arn            = aws_iam_role.ecs_task_exec_role_ec2_ecs.arn
  network_mode             = "awsvpc"
  memory                   = 1024
  cpu                      = 1024
  requires_compatibilities = ["EC2"]

  lifecycle {
    create_before_destroy = true
  }
}

data "template_file" "task_definition_template" {
  template = file("${path.module}/templates/task_definition.json.tpl")
  vars = {
    container_port = var.container_port
    region         = var.region
    log_group      = var.cloudwatch_log_group
  }
}

Шаблон запуска:

resource "aws_launch_template" "template_for_spot" {
  name = "test-spor-ecs-launch-template"
  disable_api_termination = false
  instance_type = "t3.small"
  image_id = data.aws_ami.amazon_linux_2_ecs_optimized.id
  key_name = "FrankfurtRegion"
  user_data = data.template_file.user_data.rendered
  vpc_security_group_ids = [aws_security_group.ecs_ec2.id]
  monitoring {
    enabled = var.enable_spot == "true" ? false : true
  }
  block_device_mappings {
    device_name = "/dev/sda1"
    ebs {
      volume_size = 30
    }
  }
  iam_instance_profile {
    arn = aws_iam_instance_profile.ecs_instance_profile.arn
  }
  lifecycle {
    create_before_destroy = true
  }
}

data "template_file" "user_data" {
  template = file("${path.module}/user_data.tpl")
  vars = {
    cluster_name = aws_ecs_cluster.main.name
  }
}

ASG с политикой масштабирования:

resource "aws_autoscaling_group" "ecs_spot_asg" {
  name = "test-asg-for-ecs"
  max_size = 4
  min_size = 2
  desired_capacity = 2
  termination_policies = [
    "OldestInstance"]
  vpc_zone_identifier = data.aws_subnet_ids.all_subnets.ids
  health_check_type = "ELB"
  health_check_grace_period = 300

  mixed_instances_policy {
    instances_distribution {
      on_demand_percentage_above_base_capacity = 0
      spot_instance_pools = 2
      spot_max_price = "0.03"
    }
    launch_template {
      launch_template_specification {
        launch_template_id = aws_launch_template.template_for_spot.id
        version = "$Latest"
      }
      override {
        instance_type = "t3.large"
      }
      override {
        instance_type = "t3.medium"
      }
      override {
        instance_type = "t3a.large"
      }
      override {
        instance_type = "t3a.medium"
      }
    }
  }
  lifecycle {
    create_before_destroy = true
  }
}

resource "aws_autoscaling_policy" "ecs_cluster_scale_policy" {
  autoscaling_group_name = aws_autoscaling_group.ecs_spot_asg.name
  name = "test-ecs-cluster-scaling-policy"
  policy_type = "TargetTrackingScaling"
  adjustment_type = "ChangeInCapacity"

  target_tracking_configuration {
    target_value = 70
    customized_metric_specification {
      metric_name = "ECS-cluster-metric"
      namespace = "AWS/ECS"
      statistic = "Average"
      metric_dimension {
        name = aws_ecs_cluster.main.name
        value = aws_ecs_cluster.main.name
      }
    }
  }
}

РЕДАКТИРОВАТЬ: я получаю:

Ошибка: InvalidParameterException: создание службы не было идемпотентным. «test-ec2-service-qaz»

в строке 5 ecs.tf в ресурсе «aws_ecs_service» «ec2_service»: 5: ресурс «aws_ecs_service» «ec2_service» {

EDIT2: изменено Имя ecs_service на name = "myservice_${replace(timestamp(), ":", "-")}", по-прежнему возникает та же ошибка.

Читал из других проблем, что это связано с жизненным циклом использования с оператором create_before_destroy в ecs_service, но это не объявлено в моем коде. Может это что-то связано с чем-то другим, не могу сказать что.

1 Ответ

0 голосов
/ 27 августа 2020

Спасибо @Marko E и @karnauskas на github с name = "myservice_${each.value}" смогли развернуть три службы ECS. С поправкой на обработку подсетей я смог развернуть все "вещи" по мере необходимости. Подсети:

data "aws_subnet_ids" "all_subnets" {
  vpc_id = data.aws_vpc.default.id
}

data "aws_subnet" "subnets" {
  for_each = data.aws_subnet_ids.all_subnets.ids
  id = each.value
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...