Застрял в Code Deploy при попытке выполнить Blue Green Deploy в конвейере CI / CD на ECS - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь выполнить развертывание BlueGreen на ECS. Мой сервис при развертывании на кластере ECS вручную работает нормально и проходит все проверки работоспособности. Но всякий раз, когда я выполняю сине-зеленое развертывание в одной и той же службе в ECS, он застревает в фазе установки до истечения времени ожидания.

После истечения времени ожидания я получаю эту ошибку "Время ожидания для развертывания истекло, пока набор задач замены не исправен . Время ожидания 60 минут. " Я не уверен, что делать сейчас.

Stuck at install phase

Я применил все, проверил балансировщик нагрузки, целевые группы, и все они, кажется, работают нормально, когда я вручную внедряю сервис и тестирую. Пожалуйста, найдите мой код terraform и помогите мне в этом. И дайте мне знать, если вам нужны подробности.

Кластер ECS

resource "aws_ecs_cluster" "production-fargate-cluster" {
  name = "Production-Fargate-Cluster"
}

#Application Load Balancer
resource "aws_alb" "ecs_cluster_alb" {
  name            = var.ecs_cluster_name
  internal        = false
  security_groups = [aws_security_group.ecs_alb_security_group.id]
  subnets         = data.terraform_remote_state.infrastructure.outputs.two_public_subnets

  tags = {
    Name = "${var.ecs_cluster_name} - Application Load Balancer"
  }
}

#First Target group
resource "aws_alb_target_group" "ecs_default_target_group" {

  name = "${var.ecs_cluster_name}-BlueTG"
  port     = var.alb_target_group_port #port 80
  protocol = "HTTP"
  vpc_id   = data.terraform_remote_state.infrastructure.outputs.vpc_id
  target_type = "ip"

  health_check {
    enabled = true
    path = "/actuator/health"
    interval = 30
    healthy_threshold = 3
    unhealthy_threshold = 2
}

  tags = {
      Name = "Blue-TG"
  }

}

#First Load balancer's listener
resource "aws_alb_listener" "ecs_alb_http_listener" {
  load_balancer_arn = aws_alb.ecs_cluster_alb.arn
  port              = var.first_load_balancer_listener_port #80 port
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.ecs_default_target_group.arn
  }

  lifecycle {
    ignore_changes = [default_action]
  }

}



#Second Load balancer's listener
resource "aws_alb_listener" "ecs_alb_http_listener_second" {
  load_balancer_arn = aws_alb.ecs_cluster_alb.arn
  port              = 8080
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_alb_target_group.ecs_default_target_group_second.arn
  }

  lifecycle {
    ignore_changes = [default_action]
  }

}

#Second Target group
resource "aws_alb_target_group" "ecs_default_target_group_second" {

  name = "${var.ecs_cluster_name}-GreenTG"
  port     = 8080
  protocol = "HTTP"
  vpc_id   = data.terraform_remote_state.infrastructure.outputs.vpc_id
  target_type = "ip"

  health_check {
    enabled = true
    path = "/actuator/health"
    interval = 30
    healthy_threshold = 3
    unhealthy_threshold = 2
  }

  tags = {
    Name = "Blue-TG"
  }

}

Служба Fargate ECS

resource "aws_ecs_service" "ecs_service" {
  name            = var.ecs_service_name
  task_definition = aws_ecs_task_definition.task_definition_for_application.arn
  cluster         = data.terraform_remote_state.platform.outputs.ecs_cluster_name
  launch_type     = "FARGATE"

  network_configuration {
    #since we have a load balancer and nat gateway attached we should be deploying in private subnets
    #but I deployed in public subnet just to try some few things
    #you can deploy services in private subnet!! And you should :) 

    subnets          = data.terraform_remote_state.platform.outputs.ecs_public_subnets 
    security_groups  = [aws_security_group.app_security_group.id]
    assign_public_ip = true
  }

  load_balancer {
    container_name   = var.task_definition_name
    container_port   = var.docker_container_port
    target_group_arn = data.terraform_remote_state.platform.outputs.aws_alb_target_group_arn[0] #target group with port 80 is given here
  }
  desired_count = 2

  deployment_controller {
    type = "CODE_DEPLOY"
  }

  lifecycle {
    ignore_changes = [load_balancer, task_definition, desired_count]
  }

}

#Task definition for application
resource "aws_ecs_task_definition" "task_definition_for_application" {
  container_definitions    = data.template_file.ecs_task_definition_template.rendered
  family                   = var.task_definition_name
  cpu                      = var.cpu
  memory                   = var.memory
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"

  execution_role_arn = aws_iam_role.fargate_iam_role.arn
  task_role_arn      = aws_iam_role.ecs_task_execution_role.arn

}

#Role
resource "aws_iam_role" "fargate_iam_role" {
  name = "fargate_iam_role"
  assume_role_policy = data.aws_iam_policy_document.ecs-task-assume-role.json
}

resource "aws_iam_role_policy_attachment" "fargate_iam_role_policy" {
  role = aws_iam_role.fargate_iam_role.name
  policy_arn = data.aws_iam_policy.ecs-task-execution-role.arn
}

#Security Group
resource "aws_security_group" "app_security_group" {
  name        = "${var.ecs_service_name}-SG"
  description = "Security group for springbootapp to communicate in and out"
  vpc_id      = data.terraform_remote_state.platform.outputs.vpc_id

  ingress {
    from_port   = 80
    protocol    = "TCP"
    to_port     = 8080
    cidr_blocks = [data.terraform_remote_state.platform.outputs.vpc_cidr_block]
  }

  egress {
    from_port   = 0
    protocol    = "-1"
    to_port     = 0
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.ecs_service_name}-SG"
  }

}

#CloudWatch
resource "aws_cloudwatch_log_group" "application_log_group" {
  name = "/ecs/sun-api"
}

Кодовый конвейер

#Code Pipeline
resource "aws_codepipeline" "codepipeline_for_blue_green_deployment" {
  name     = var.pipeline_name
  role_arn = aws_iam_role.codepipeline_roles.arn

  artifact_store {
    location = var.bucket_for_codepipeline
    type     = var.artifact_store_type
  }

  stage {
    name = "github_Source"

    action {
      name             = "github_Source"
      category         = "Source"
      owner            = var.source_stage_owner
      provider         = var.source_stage_provider
      version          = "1"
      output_artifacts = ["SourceArtifact"]

      configuration = {
        PollForSourceChanges = true
        OAuthToken           = var.github_token
        Owner                = var.git_hub_owner
        Repo                 = var.repo_name
        Branch               = var.branch_name
      }
    }

    action {
      name             = "Image"
      category         = "Source"
      owner            = "AWS"
      provider         = "ECR"
      version          = "1"
      output_artifacts = ["MyImage"]
      run_order = 1

      configuration = {
        ImageTag: "latest"
        RepositoryName:"umar-tahir-terraform-repo"

      }
    }
  }

  stage {
    name = "Deploy"

    action {
      name = "Deploy"
      category = "Deploy"
      owner = "AWS"
      provider = "CodeDeployToECS"
      version = "1"
      input_artifacts = ["SourceArtifact","MyImage"]

      configuration ={
        ApplicationName = aws_codedeploy_app.application_deploy.name
        DeploymentGroupName = aws_codedeploy_deployment_group.code_deployment_group.deployment_group_name

        TaskDefinitionTemplateArtifact: "SourceArtifact",
        AppSpecTemplateArtifact: "SourceArtifact",

        TaskDefinitionTemplatePath: "taskdef.json",
        AppSpecTemplatePath: "appspec.yaml",


        Image1ArtifactName: "MyImage",
        Image1ContainerName: "IMAGE1_NAME",



      }
    }
  }
}

Развертывание кода

resource "aws_codedeploy_app" "application_deploy" {
  compute_platform = var.compute_platform
  name             = var.aws_codedeploy_app_name
}

resource "aws_codedeploy_deployment_group" "code_deployment_group" {
  app_name               = aws_codedeploy_app.application_deploy.name
  deployment_group_name  = var.deployment_group_name
  deployment_config_name = var.deployment_config_name
  service_role_arn       = aws_iam_role.codedeploy_role_blue_green.arn

  auto_rollback_configuration {
    enabled = true
    events  = ["DEPLOYMENT_FAILURE"]
  }


  blue_green_deployment_config {

    deployment_ready_option {
      action_on_timeout =  var.action_on_timeout
    }

    terminate_blue_instances_on_deployment_success {
      action = var.terminate_blue_instances_on_deployment_success_action
    }
  }

  ecs_service {
    cluster_name = data.terraform_remote_state.aws_modules_state.outputs.ecs_cluster_name
    service_name = "generalapplication"
  }

  deployment_style {
    deployment_option = var.deployment_option
    deployment_type   = var.deployment_type
  }

  load_balancer_info {
    target_group_pair_info {
      prod_traffic_route {
        listener_arns = [data.terraform_remote_state.aws_modules_state.outputs.listener_arns]
      }

      target_group {
        name = data.terraform_remote_state.aws_modules_state.outputs.green_target_group_name
      }

      target_group {
        name = data.terraform_remote_state.aws_modules_state.outputs.blue_target_group_name
      }
    }
  }
}

appSpe c .yml

version: 0.0
Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: <TASK_DEFINITION>
        LoadBalancerInfo:
          ContainerName: "springboottaskdefinition"
          ContainerPort: 8080
        PlatformVersion: "LATEST"

определение задачи

{
  "taskRoleArn": "arn-xxxx",
  "executionRoleArn": "arn-xxxx",
  "containerDefinitions": [
    {
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/sun-api",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "springboottaskdefinition-LogGroup-stream"
        }
      },
      "portMappings": [
        {
          "hostPort": 8080,
          "protocol": "tcp",
          "containerPort": 8080
        }
      ],
      "image": "<IMAGE1_NAME>",
      "essential": true,
      "name": "springboottaskdefinition"
    }
  ],
  "memory": "1024",
  "family": "springboottaskdefinition",
  "requiresCompatibilities": [
    "FARGATE"
  ],
  "networkMode": "awsvpc",
  "cpu": "512"
}
...