在 ECS 蓝绿部署中,如何处理将流量路由到 HTTPS?

huangapple go评论62阅读模式
英文:

In ecs blue green code deploy, how should I handle routing traffic to https?

问题

以下是您提供的内容的翻译部分:

我正在使用Terraform配置ECS和CI/CD。

有两个目标组,分别是蓝色和绿色:

资源 "aws_lb_target_group" "target_group_blue" {
name = "${local.resource_id}-blue"
port = var.target_group_port
protocol_version = var.target_group_protocol_version
protocol = var.target_group_protocol
vpc_id = var.vpc_id
target_type = "ip"

health_check {
enabled = true
path = var.healthcheck_uri
interval = var.healthcheck_interval
protocol = var.target_group_protocol
healthy_threshold = 5
unhealthy_threshold = 2
timeout = 20
}

tags = local.tags
}

资源 "aws_lb_target_group" "target_group_green" {
name = "${local.resource_id}-green"
port = var.target_group_port
protocol_version = var.target_group_protocol_version
protocol = var.target_group_protocol
vpc_id = var.vpc_id
target_type = "ip"

health_check {
enabled = true
path = var.healthcheck_uri
interval = var.healthcheck_interval
protocol = var.target_group_protocol
healthy_threshold = 5
unhealthy_threshold = 2
timeout = 20
}

tags = local.tags
}

监听器配置如下。
端口80和443用于生产部署,端口8080用于测试流量。

资源 "aws_lb_listener" "http_listener" {
load_balancer_arn = aws_lb.loadbalancer.arn
port = "80"
protocol = "HTTP"

default_action {
type = "forward"
target_group_arn = aws_lb_target_group.target_group_blue.arn
}

生命周期 {
ignore_changes = [default_action]
}

tags = local.tags
}

资源 "aws_lb_listener" "http_test_listener" {
load_balancer_arn = aws_lb.loadbalancer.arn
port = "8080"
protocol = "HTTP"

default_action {
type = "forward"
target_group_arn = aws_lb_target_group.target_group_green.arn
}

生命周期 {
ignore_changes = [default_action]
}

tags = local.tags
}

资源 "aws_lb_listener" "https_listener" {
load_balancer_arn = aws_lb.loadbalancer.arn
port = "443"
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-2016-08"
certificate_arn = var.certificate_arn

default_action {
type = "forward"
target_group_arn = aws_lb_target_group.target_group_blue.arn
}

tags = local.tags
}

代码部署组如下。

资源 "aws_codedeploy_deployment_group" "deployment_group" {
app_name = aws_codedeploy_app.deploy.name
deployment_config_name = aws_codedeploy_deployment_config.config_deploy.deployment_config_name
deployment_group_name = local.resource_id
service_role_arn = aws_iam_role.codedeploy_role.arn

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

blue_green_deployment_config {
deployment_ready_option {
action_on_timeout = "CONTINUE_DEPLOYMENT"
wait_time_in_minutes = 0
}

terminate_blue_instances_on_deployment_success {
  action                           = "TERMINATE"
  termination_wait_time_in_minutes = 5
}

}

deployment_style {
deployment_option = "WITH_TRAFFIC_CONTROL"
deployment_type = "BLUE_GREEN"
}

ecs_service {
cluster_name = aws_ecs_cluster.ecs_cluster.name
service_name = aws_ecs_service.ecs_service.name
}

load_balancer_info {
target_group_pair_info {
prod_traffic_route {
listener_arns = [aws_lb_listener.http_listener.arn]
}

  test_traffic_route {
    listener_arns = [aws_lb_listener.http_test_listener.arn]
  }

  target_group {
    name = aws_lb_target_group.target_group_blue.name
  }

  target_group {
    name = aws_lb_target_group.target_group_green.name
  }
}

}
}

这样,蓝绿目标组替换对于端口80的监听器运行正常。
但是,对于端口443的监听器,目标组替换不会发生。

每当部署时,蓝绿色都会应用于端口80和443的监听器,
我希望它在https域名端点上能够正常工作。

有没有关于此的推荐最佳实践?

英文:

I'm using terraform to configure ECS and CI/CD.

There are two target groups, blue and green:

resource "aws_lb_target_group" "target_group_blue" {
  name             = "${local.resource_id}-blue"
  port             = var.target_group_port
  protocol_version = var.target_group_protocol_version
  protocol         = var.target_group_protocol
  vpc_id           = var.vpc_id
  target_type      = "ip"

  health_check {
    enabled             = true
    path                = var.healthcheck_uri
    interval            = var.healthcheck_interval
    protocol            = var.target_group_protocol
    healthy_threshold   = 5
    unhealthy_threshold = 2
    timeout             = 20
  }

  tags = local.tags
}

resource "aws_lb_target_group" "target_group_green" {
  name             = "${local.resource_id}-green"
  port             = var.target_group_port
  protocol_version = var.target_group_protocol_version
  protocol         = var.target_group_protocol
  vpc_id           = var.vpc_id
  target_type      = "ip"

  health_check {
    enabled             = true
    path                = var.healthcheck_uri
    interval            = var.healthcheck_interval
    protocol            = var.target_group_protocol
    healthy_threshold   = 5
    unhealthy_threshold = 2
    timeout             = 20
  }

  tags = local.tags
}

The listener is configured as follows.
Ports 80 and 443 to use for production deployment, and port 8080 to use for testing traffic.

resource "aws_lb_listener" "http_listener" {
  load_balancer_arn = aws_lb.loadbalancer.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.target_group_blue.arn
  }

  lifecycle {
    ignore_changes = [default_action]
  }

  tags = local.tags
}

resource "aws_lb_listener" "http_test_listener" {
  load_balancer_arn = aws_lb.loadbalancer.arn
  port              = "8080"
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.target_group_green.arn
  }

  lifecycle {
    ignore_changes = [default_action]
  }

  tags = local.tags
}

resource "aws_lb_listener" "https_listener" {
  load_balancer_arn = aws_lb.loadbalancer.arn
  port              = "443"
  protocol          = "HTTPS"
  ssl_policy        = "ELBSecurityPolicy-2016-08"
  certificate_arn   = var.certificate_arn

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.target_group_blue.arn
  }

  tags = local.tags
}

The code deploy group is as follows.

resource "aws_codedeploy_deployment_group" "deployment_group" {
  app_name               = aws_codedeploy_app.deploy.name
  deployment_config_name = aws_codedeploy_deployment_config.config_deploy.deployment_config_name
  deployment_group_name  = local.resource_id
  service_role_arn       = aws_iam_role.codedeploy_role.arn

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

  blue_green_deployment_config {
    deployment_ready_option {
      action_on_timeout    = "CONTINUE_DEPLOYMENT"
      wait_time_in_minutes = 0
    }

    terminate_blue_instances_on_deployment_success {
      action                           = "TERMINATE"
      termination_wait_time_in_minutes = 5
    }
  }

  deployment_style {
    deployment_option = "WITH_TRAFFIC_CONTROL"
    deployment_type   = "BLUE_GREEN"
  }

  ecs_service {
    cluster_name = aws_ecs_cluster.ecs_cluster.name
    service_name = aws_ecs_service.ecs_service.name
  }

  load_balancer_info {
    target_group_pair_info {
      prod_traffic_route {
        listener_arns = [aws_lb_listener.http_listener.arn]
      }

      test_traffic_route {
        listener_arns = [aws_lb_listener.http_test_listener.arn]
      }

      target_group {
        name = aws_lb_target_group.target_group_blue.name
      }

      target_group {
        name = aws_lb_target_group.target_group_green.name
      }
    }
  }
}

This way, the blue-green targetgroup replacement works fine for the 80 port listener.
However, targetgroup replacement does not occur for the 443 listener.

Whenever deploy, blue-green is applied to both 80 and 443 listeners,
I want it to work without problems on https domain endpoint.

Are there any recommended best practices for this?

答案1

得分: 1

The listener_arns setting in CodeDeploy is a list. So you could be adding both listeners to that:

在CodeDeploy中,`listener_arns`设置是一个列表。因此,您可以将这两个监听器都添加到其中:

prod_traffic_route {
  listener_arns = [aws_lb_listener.http_listener.arn,
                   aws_lb_listener.https_listener.arn]
}

Then both would be switched over to the new deployment at the same time.

然后,这两个监听器将同时切换到新的部署。

英文:

The listener_arns setting in CodeDeploy is a list. So you could be adding both listeners to that:

      prod_traffic_route {
        listener_arns = [aws_lb_listener.http_listener.arn,
                         aws_lb_listener.https_listener.arn]
      }

Then both would be switched over to the new deployment at the same time.


However, you asked about "best practice", and the best practice for serving HTTPS from the load balancer is to always serve HTTPS. In other words: don't ever allow insecure traffic. If insecure traffic comes in, convert it to secure traffic.

To do that you would configure the HTTP listener to simply issue a redirect to your HTTPS listener, like so:

resource "aws_lb_listener" "http_listener" {
  load_balancer_arn = aws_lb.loadbalancer.arn
  port              = "80"
  protocol          = "HTTP"

  default_action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

Now any requests to your HTTP listener will receive a redirect response that sends them over to the HTTPS listener. After configuring that, you would only need to register the HTTPS listener with CodeDeploy:

      prod_traffic_route {
        listener_arns = [aws_lb_listener.https_listener.arn]
      }

huangapple
  • 本文由 发表于 2023年5月6日 17:08:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76188070.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定