ELBを作成する場合の注意点について

ELBを作成する際の注意点について、まとめていきます。 特に言及していないプロパティはAWSの例通りでいいと思います。

AccessLoggingPolicy

  • S3BucketPrefix
ELBのログ用バケットを1つにする場合はS3BucketPrefixを指定して、
ELB毎にディレクトリを分けます。

ELB毎にログ用バケットを作成するとELBを作成する度にバケットを作成しないといけないので、
あまりオススメはしません。
  • バケット
    以下のように作成します。
    PrincipalについてはTokyoリージョンなら582318560864です。
    "ELBLogsBucketPolicy": {
      "Type" : "AWS::S3::BucketPolicy",
      "Properties" : {
        "Bucket"         : { "Ref": "ELBLogsBucket" },
        "PolicyDocument" : {
          "Id": "Policy1461927670460",
          "Version": "2012-10-17",
          "Statement": [
            {
              "Sid"      : "Stmt1461927665605",
              "Action"   : ["s3:PutObject"],
              "Effect"   : "Allow",
              "Resource" : {"Fn::Join":[
                   "",
                   [
                      "arn:aws:s3:::",
                      { "Ref":"ELBLogsBucketName" },
                      "/*"
                   ]
                ]
              },
              "Principal": {
                "AWS": [{ "Fn::FindInMap": [ "ELB", "Principal", "Tokyo"]}]
              }
            }
          ]
        }
      }
    },
    "ELBLogsBucket": {
      "Type" : "AWS::S3::Bucket",
      "Properties" : {
        "AccessControl": "LogDeliveryWrite",
        "BucketName"   : { "Ref": "ELBLogsBucketName" },
        "Tags": [
          { "Key": "Name", "Value": { "Ref": "AWS::StackName" } }
        ]
      }
    }

ちなみにログは以下のようになります。
ヘルスチェックが失敗する場合はbackend:portのステータスを見ます。

timestamp elb client:port backend:port request_processing_time backend_processing_time response_processing_time elb_status_code backend_status_code received_bytes sent_bytes "request" "user_agent" ssl_cipher ssl_protocol
2016-06-11T19:03:38.356123Z ELBWeb $CLIENT:44651 $BACKEND:80 0.000058 0.001017 0.000022 200 200 0 3770 GET https://$PUBLIC_IP:443/ HTTP/1.1 $UA ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2

※internal ELBの場合はVPC内の2つのIPからアクセスが来ますので、VPC内からのHTTPを許可します。

AvailabilityZones

通常のケースですと、ロードバランサーはVPC内にありますので、
指定してはいけません。  
その代わりに、Subnetsプロパティを指定します。
コンソールから作成する際もAZではなく、サブネットを指定するようになっています。

HealthCheck

AutoScalingのHealthCheckGracePeriodが300の場合は
300秒以内にIn Serviceになるようにします。
そうしないとインスタンスが増えていってしまいます。
※HealthCheckTypeがELBの場合

Listeners

以下で問題ないです。
HTTPSで受けて、HTTPでインスタンスに流します。
SSLCertificateIdはACMで証明書を事前に作成しておく必要があります。
※自前で証明書を管理すると期限切れや、中間証明書が正しく設定されない可能性があります。
※「このサイトは安全に接続できません。」画面を見ることはなくなります

AWS Certificate Manager(簡単に SSL/TLS 証明書を作成、管理、配置) | AWS

json

  • Resources
    "ELBWeb": {
      "Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      "Properties": {
        "AccessLoggingPolicy": {
          "EmitInterval"  : "5",
          "Enabled"       : "true",
          "S3BucketName"  : { "Ref": "ELBLogsBucketName" },
          "S3BucketPrefix": "ELBWeb"
        },
        "ConnectionDrainingPolicy": {
          "Enabled": "true",
          "Timeout": "300"
        },
        "ConnectionSettings": {
          "IdleTimeout": "60"
        },
        "CrossZone": "true",
        "HealthCheck": {
          "HealthyThreshold"  : "2",
          "Interval"          : "30",
          "Target"            : "HTTP:80/",
          "Timeout"           : "10",
          "UnhealthyThreshold": "2"
        },
        "LoadBalancerName": "ELBWeb",
        "Listeners": [
          {
            "InstancePort"    : "80",
            "InstanceProtocol": "HTTP",
            "LoadBalancerPort": "443",
            "Protocol"        : "HTTPS",
            "SSLCertificateId": {
              "Fn::Join":[
                 "",
                 [
                    "arn:aws:acm:ap-northeast-1:",
                    { "Ref":"AWS::AccountId" },
                    ":certificate/",
                    "XXXXXXXXXXXXXXXXXX"
                 ]
              ]
            }
          }
        ],
        "Scheme": "internet-facing",
        "Subnets": [
          { "Ref": "PublicSubnet1a" },
          { "Ref": "PublicSubnet1c" }
        ],
        "SecurityGroups": [
          { "Ref": "SGELB" }
        ],
        "Tags": [
          { "Key": "Name", "Value": { "Ref": "AWS::StackName" } }
        ]
      }
    }
  • Outputs ELBWebはAutoScalingGroupのLoadBalancerNamesに使用します。
    ELBWEBDNSNameはRoute53のCNAMEレコード作成時に使用します。
  "Outputs" : {
    "ELBWeb" : {
      "Value" : { "Ref" : "ELBWeb" }
    },
    "ELBWEBDNSName" : {
      "Value" : { "Fn::GetAtt" : [ "ELBWeb", "DNSName" ] }
    }
  }