Elastic BeanstalkでELB作成を抑止する


Elastic Beanstalkで管理しているプロダクトを任意のALBでパスルーティングする場合、コスト削減のためにELB作成を抑制することがあります。その時の設定のコツと注意点を書きたいと思います。

  • 基本的に下記名前空間において環境アーキテクチャとサービスロールを設定する必要があります。

名前空間: aws:elasticbeanstalk:environment

  • ELB作成を抑止するためにはEnvironmentTypeSingleInstanceと指定します。 そうすることでELBは作成されずに単一のEC2 Instanceのみが起動する環境を作成できます。
  // EnvironmentType LoadBalanced or SingleInstance
  setting {
    namespace = "aws:elasticbeanstalk:environment"
    name      = "EnvironmentType"
    value     = "SingleInstance"
  }
  • 環境作成時にAuto Scaling Groupも自動で作成されますが、Desired Capacity(必要な容量)Min(インスタンスの最小数)Max(インスタンスの最大数)は強制的に1に設定されます。サーバリソースが高負荷になっても自動でスケールされないという点は注意が必要です。

  • これは名前空間: aws:autoscaling:triggerを明示的に記述しても無視されます。 ELB作成時に使用している下記設定は不要となります。
elastic_beanstalk_environment_front.tf
  setting {
    namespace = "aws:autoscaling:trigger"
    name      = "MeasureName"
    value     = "TargetResponseTime"
  }

  setting {
    namespace = "aws:autoscaling:trigger"
    name      = "Statistic"
    value     = "Average"
  }

  setting {
    namespace = "aws:autoscaling:trigger"
    name      = "Unit"
    value     = "Seconds"
  }

  setting {
    namespace = "aws:autoscaling:trigger"
    name      = "Period"
    value     = "1"
  }

  setting {
    namespace = "aws:autoscaling:trigger"
    name      = "BreachDuration"
    value     = "1"
  }

  setting {
    namespace = "aws:autoscaling:trigger"
    name      = "UpperThreshold"
    value     = "10"
  }

  setting {
    namespace = "aws:autoscaling:trigger"
    name      = "UpperBreachScaleIncrement"
    value     = "1"
  }

  setting {
    namespace = "aws:autoscaling:trigger"
    name      = "LowerThreshold"
    value     = "1"
  }

  setting {
    namespace = "aws:autoscaling:trigger"
    name      = "LowerBreachScaleIncrement"
    value     = "-1"
  }

setting {
  namespace = "aws:ec2:vpc"
  name      = "ELBSubnets"
  value     = var.ELBSubnets
}
  • Elastic Beanstalkが作成したTarget GroupはALBのリスナールールとして指定できないので別途作成してリスナールールに設定することが必要です。
autoscaling_attachment.tf
resource "aws_autoscaling_attachment" "xxxxxxxxxx" {  
  autoscaling_group_name = aws_elastic_beanstalk_environment.xxxxxxxxxx.autoscaling_groups[0]  
  alb_target_group_arn   = aws_lb_target_group.xxxxxxxxxx.arn 
}
lb_target_group.tf
resource "aws_lb_target_group" "xxxxxxxxxx" {
  name     = "xxxxxxxxxx"
  port     = 80
  protocol = "HTTP"
  vpc_id   = data.aws_vpc.xxxxxxxxxx.id

  health_check {
    enabled             = true
    interval            = 30
    path                = "/xxxxxxxxxx"
    port                = "traffic-port"
    protocol            = "HTTP"
    timeout             = 5
    healthy_threshold   = 3
    unhealthy_threshold = 3
    matcher             = 200
  }

  tags = {
    Name        = "xxxxxxxxxx"
    Service     = "xxxxxxxxxx"
    Environment = "xxxxxxxxxx"
    Description = "Managed by Terraform"
  }
}
  • SingleInstanceで作成するEC2 InstanceはPublicIPを付与させない設定のSubnetで起動させてもEIPが付与されてしまいますが、これは仕様です。
  • 限定的なリクエストしか来ないようなプロダクトの商用環境であってもSingleInstanceでの運用が可能かは計測する必要があります。