[AWS] Elastic BeanstalkのAutoscalingデプロイポリシー

バッチサイズやデプロイ中のヘルスチェックの動作を設定するオプション

[All at once]、[Rolling]、[Rolling with additional batch]、[Immutable]
・一度に全てのインスタンスへデプロイを反映させる時は”All at once”を選択する。
・デプロイ時にサービスに対しダウンタイムを発生させないようにするためには、”Rolling”を選択し1台ずつデプロイを行わせるようにする。
・全てのインスタンスを新しく構築し直す変更不可なデプロイは、”Immutable”を選択する。

例: Elastic Beanstalk config

ApplicationName: xxx
DateUpdated: 2017-08-18 05:22:49+00:00
EnvironmentName: dev
PlatformArn: arn:aws:elasticbeanstalk:ap-northeast-1::platform/Tomcat 7 with Java
  7 running on 64bit Amazon Linux/2.6.1
settings:
  AWSEBAutoScalingScaleDownPolicy.aws:autoscaling:trigger:
    LowerBreachScaleIncrement: '-1'
  AWSEBAutoScalingScaleUpPolicy.aws:autoscaling:trigger:
    UpperBreachScaleIncrement: '1'
  AWSEBCloudwatchAlarmHigh.aws:autoscaling:trigger:
    UpperThreshold: '90'
  AWSEBCloudwatchAlarmLow.aws:autoscaling:trigger:
    BreachDuration: '10'
    EvaluationPeriods: '1'
    LowerThreshold: '10'
    MeasureName: CPUUtilization
    Period: '10'
    Statistic: Average
    Unit: Percent
  AWSEBLoadBalancerSecurityGroup.aws:ec2:vpc:
    VPCId: null
  aws:autoscaling:asg:
    Availability Zones: Any
    Cooldown: '360'
    Custom Availability Zones: ap-northeast-1a
    MaxSize: '2'
    MinSize: '1'
  aws:autoscaling:launchconfiguration:
    BlockDeviceMappings: null
    EC2KeyName: xxx
    IamInstanceProfile: aws-elasticbeanstalk-ec2-role
    ImageId: ami-xxx
    InstanceType: t2.small
    MonitoringInterval: 5 minute
    RootVolumeIOPS: null
    RootVolumeSize: null
    RootVolumeType: null
    SSHSourceRestriction: tcp,xx,xx,xxx.xxx.xxx.xx/xx
    SecurityGroups: xxx
  aws:autoscaling:updatepolicy:rollingupdate:
    MaxBatchSize: '2'
    MinInstancesInService: '1'
    PauseTime: null
    RollingUpdateEnabled: 'true'
    RollingUpdateType: Health
    Timeout: PT30M
  aws:ec2:vpc:
    AssociatePublicIpAddress: null
    ELBScheme: public
    ELBSubnets: null
    Subnets: null
  aws:elasticbeanstalk:application:
    Application Healthcheck URL: /_health_check.html
  aws:elasticbeanstalk:cloudwatch:logs:
    DeleteOnTerminate: 'false'
    RetentionInDays: '7'
    StreamLogs: 'false'
  aws:elasticbeanstalk:container:tomcat:jvmoptions:
    JVM Options: -Duser.timezone="Asia/Tokyo" -Dhttps.protocols=TLSv1.1,TLSv1.2
    XX:MaxPermSize: 128m
    Xms: 512m
    Xmx: 1024m
  aws:elasticbeanstalk:control:
    DefaultSSHPort: '22'
    LaunchTimeout: '0'
    LaunchType: Migration
    RollbackLaunchOnFailure: 'false'
  aws:elasticbeanstalk:environment:
    EnvironmentType: LoadBalanced
    ExternalExtensionsS3Bucket: null
    ExternalExtensionsS3Key: null
    LoadBalancerType: classic
    ServiceRole: null
  aws:elasticbeanstalk:environment:proxy:
    GzipCompression: 'true'
    ProxyServer: apache
  aws:elasticbeanstalk:healthreporting:system:
    ConfigDocument: '{"Version":1,"CloudWatchMetrics":{"Instance":{"CPUIrq":null,"LoadAverage5min":null,"ApplicationRequests5xx":null,"ApplicationRequests4xx":null,"CPUUser":null,"LoadAverage1min":n...
    HealthCheckSuccessThreshold: Ok
    SystemType: basic
  aws:elasticbeanstalk:hostmanager:
    LogPublicationControl: 'false'
  aws:elasticbeanstalk:managedactions:
    ManagedActionsEnabled: 'false'
    PreferredStartTime: null
  aws:elasticbeanstalk:managedactions:platformupdate:
    InstanceRefreshEnabled: 'false'
    UpdateLevel: null
  aws:elasticbeanstalk:monitoring:
    Automatically Terminate Unhealthy Instances: 'true'
  aws:elasticbeanstalk:sns:topics:
    Notification Endpoint: xxx@xxx.com
    Notification Protocol: email
    Notification Topic ARN: arn:aws:sns:ap-northeast-1:xxx:ElasticBeanstalkNotifications-Environment-dev
    Notification Topic Name: null
  aws:elasticbeanstalk:xray:
    XRayEnabled: 'false'
  aws:elb:healthcheck:
    HealthyThreshold: '5'
    Interval: '10'
    Target: HTTP:80/_health_check.html
    Timeout: '5'
    UnhealthyThreshold: '5'
  aws:elb:listener:443:
    InstancePort: '80'
    InstanceProtocol: HTTPS
    ListenerEnabled: 'true'
    ListenerProtocol: HTTPS
    PolicyNames: null
    SSLCertificateId: arn:aws:acm:ap-northeast-1:xxx:certificate/xxx
  aws:elb:listener:80:
    InstancePort: '80'
    InstanceProtocol: HTTP
    ListenerEnabled: 'true'
    ListenerProtocol: HTTP
    PolicyNames: null
    SSLCertificateId: null
  aws:elb:loadbalancer:
    CrossZone: 'false'
    LoadBalancerHTTPPort: '80'
    LoadBalancerHTTPSPort: '443'
    LoadBalancerPortProtocol: HTTP
    LoadBalancerSSLPortProtocol: HTTPS
    SSLCertificateId: arn:aws:acm:ap-northeast-1:xxx:certificate/xxx
    SecurityGroups: sg-xxx
  aws:elb:policies:
    ConnectionDrainingEnabled: 'false'
    ConnectionDrainingTimeout: '20'
    ConnectionSettingIdleTimeout: '60'

トリガーのしきい値例

・MeasureName: CPU利用率
・UpperThreshold: CPU平均利用率 < 90% -> インスタンス増加
・LowerThreshold: CPU平均利用率 > 10% -> インスタンス減少
・Unit: 単位=%
・BreachDuration: 上記が10分継続した場合、Autoscalingが起動
・IgnoreHealthCheck: デプロイ時にHealthCheckは無視する

Rollingを指定したデプロイ時ダウンタイムを発生させない設定例

1. しきい値等変更作業

Autoscalingの設定、インスタンス台数の設定を変更する。
ダウンタイムを避けるためインスタンスを1台追加し、計2台で一時的に稼働させる。

・実行時間: 2分30秒
・ダウンタイム: 無

AWSEBCloudwatchAlarmHigh.aws:autoscaling:trigger:
  UpperThreshold: '90'
AWSEBCloudwatchAlarmLow.aws:autoscaling:trigger:
  BreachDuration: '10'
  LowerThreshold: '10'
  MeasureName: CPUUtilization
  Statistic: Average
  Unit: Percent
aws:autoscaling:asg:
  MaxSize: '4'
  MinSize: '2'
aws:autoscaling:updatepolicy:rollingupdate:
  MaxBatchSize: '2'
  MinInstancesInService: '2'
aws:elasticbeanstalk:command:
  BatchSizeType: Percentage
  IgnoreHealthCheck: 'true'

2. 新しいアプリケーションのデプロイ

2台のインスタンスへ対して、1つずつ順にデプロイされる。
その間、サイトが遅くなる可能性はあるものの、サービスのダウンタイムは発生しない。

・実行時間: 約6分30秒
・ダウンタイム: 無

3. インスタンス数を戻す

デプロイの為に追加したインスタンスの台数を減らす。
実行時間: 約2分

aws:autoscaling:asg:
  MaxSize: '4'
  MinSize: '1'
aws:autoscaling:updatepolicy:rollingupdate:
  MaxBatchSize: '2'
  MinInstancesInService: '2'

参考site

デプロイポリシーと設定
Elastic Beanstalk 環境設定のローリング更新
すべての環境に対する汎用オプション