【CloudFormation】AWSマルチAZ3層アーキテクチャの構築_ALB

皆様、お世話になっております。鈴木と申します。
前回まででRoute53とACMの設定を行いましたので、今回もCloudformationでALBを作成して暗号化通信を実現していきたいと思います。

1.目次

目次はこちら

2.要件

  • 前回まででACMで証明書を付与したRoute53で作成したドメインを使用してALBの暗号化通信を実現
  • HTTP通信をHTTPS通信にリダイレクトさせる
  • 2つのAZの各プライベートサブネットにあるEC2に負荷分散させる(ラウンドロビンで確認)
  • ヘルスチェック用の実施

Route53のブログはこちら
ACMのブログはこちら

3.ALBについて

AWSのALBとNLBについて

AWSのロードバランサーには、主に2種類のタイプがあります:Application Load Balancer(ALB)Network Load Balancer(NLB)です。

3-1. Application Load Balancer (ALB)

Application Load Balancer(ALB) は、アプリケーション層(レイヤー7)で動作するロードバランサーです。主にHTTPやHTTPSトラフィックを処理し、以下のような機能があります:

  • 高度なルーティング機能:

    • パスベースルーティング: リクエストのパスに基づいて異なるターゲットグループにルーティングできます(例: /imagesimage-service)。
    • ホストベースルーティング: リクエストのホストヘッダーに基づいて異なるターゲットグループにルーティングできます(例: api.example.comapi-service)。
    • クエリ文字列やヘッダーによるルーティング: 特定のクエリ文字列やヘッダーに基づくルーティングが可能です。
  • WebSocketとHTTP/2のサポート: リアルタイム通信や効率的なデータ転送を可能にします。

  • ターゲットグループ: 各ターゲットグループは複数のEC2インスタンスやコンテナで構成され、ALBはこれらにトラフィックを分散します。

  • セキュリティ: AWS Certificate Manager(ACM)との統合により、TLS証明書の管理やHTTPS通信の設定が容易です。

3-2. Network Load Balancer (NLB)との違いについて

特徴 Application Load Balancer (ALB) Network Load Balancer (NLB)
レイヤー アプリケーション層(レイヤー7) ネットワーク層(レイヤー4)
トラフィックの種類 HTTP、HTTPS TCP、UDP、TCP_UDP(TCPとUDPの両方)
ルーティング機能 – パスベースルーティング
– ホストベースルーティング
– クエリ文字列やヘッダーによるルーティング
– 基本的なルーティング(IPアドレスとポートに基づく)
パフォーマンス – 高機能なルーティング
– レイヤー7の処理があるためレイテンシーが高くなる可能性がある
– 高いスループット
– 低レイテンシー
静的IPアドレス 動的IPアドレス 静的IPアドレス
プロトコルサポート HTTP、HTTPS TCP、UDP、TCP_UDP
高可用性 – AWS Certificate Manager(ACM)との統合によるHTTPS設定
– ターゲットグループへのトラフィック分散
– 高い耐障害性と可用性
– ゾーン単位での健康チェック
追加機能 – WebSocketとHTTP/2のサポート – ゾーンヘルスチェック

3-3.要点

  • ALBはアプリケーション層で動作し、HTTP/HTTPSトラフィックの高度なルーティングが可能です。セキュリティ機能が充実しており、ACMとの統合によりHTTPS通信が容易に設定できますが、レイヤー7の処理があるため、レイテンシーが高くなる可能性があります。

  • NLBはネットワーク層で動作し、TCP/UDPトラフィックの高いスループットと低レイテンシーを提供します。静的IPアドレスをサポートし、ネットワークトラフィックの高パフォーマンス処理が求められるシナリオに最適です。

4.構成図

すべての通信を暗号化します。
file

5.ソースコード全体

YAML形式にて記述しております。
Route53、ACM、ALBを同じファイルで記述しているため、ALB部分のみを抜粋しております。
またALBのアクセスログも取得するため、そちらも記述しております。
こちらで説明予定です。

 # ALB 作成
  LoadBalancerResource:
    Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
    Properties:
      Name: "naoki-alb"
      Scheme: "internet-facing"
      Type: "application"
      Subnets:
        - !Ref Subnet1Id
        - !Ref Subnet2Id
      SecurityGroups:
        - !Ref SecurityGroupId
      IpAddressType: "ipv4"
      Tags:
        - Key: "Name"
          Value: "naoki-alb"
      LoadBalancerAttributes:
        - Key: "access_logs.s3.enabled"
          Value: "true"
        - Key: "access_logs.s3.bucket"
          Value: !Ref S3BucketName
        - Key: "access_logs.s3.prefix"
          Value: "alb-logs"

  # ターゲットグループ作成
  TargetGroupResource:
    Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
    Properties:
      Name: "naoki-tg-web"
      VpcId: !Ref VpcId
      Protocol: "HTTP"
      Port: 80
      TargetType: "instance"
      Targets:
        - Id: !Ref InstanceId1
          Port: 80
        - Id: !Ref InstanceId2
          Port: 80
      HealthCheckEnabled: true
      HealthCheckIntervalSeconds: 30
      HealthCheckPath: "/mnt/efs/healthcheck.html"
      HealthCheckPort: "traffic-port"
      HealthCheckProtocol: "HTTP"
      HealthCheckTimeoutSeconds: 5
      HealthyThresholdCount: 5
      UnhealthyThresholdCount: 2
      Matcher:
        HttpCode: "200"
      Tags:
        - Key: "Name"
          Value: "naoki-tg-web"

  # HTTPS リスナー作成
  HttpsListener:
    Type: "AWS::ElasticLoadBalancingV2::Listener"
    Properties:
      LoadBalancerArn: !Ref LoadBalancerResource
      Port: 443
      Protocol: "HTTPS"
      Certificates:
        - CertificateArn: !Ref SubdomainCertificate
      DefaultActions:
        - Type: "forward"
          TargetGroupArn: !Ref TargetGroupResource

  # HTTP リスナー作成(HTTPS へのリダイレクト)
  HttpListener:
    Type: "AWS::ElasticLoadBalancingV2::Listener"
    Properties:
      LoadBalancerArn: !Ref LoadBalancerResource
      Port: 80
      Protocol: "HTTP"
      DefaultActions:
        - Type: "redirect"
          RedirectConfig:
            Protocol: "HTTPS"
            Port: "443"
            StatusCode: "HTTP_301"

6.ソースコード詳細

6-1.ALB作成

まずはALBの作成の詳細を下記にて記載します。
アクセスログのところは今後の構築で使用するため有効化しております。
またデフォルトでラウンドロビン形式となるため今回下記には指定していません。

使用するオプション 設定値 説明
Type AWS::CertificateManager::Certificate デフォルトの定義
DomainName !Sub "${SubdomainName}" サブドメインを指定
ValidationMethod DNS 検証方法をDNSで指定
DomainValidationOptions
DomainName
!Sub "${SubdomainName}" 検証サブドメインを指定
DomainValidationOptions
ValidationDomain
!Sub "ホストドメイン名" サブドメインのホストゾーンであるドメインを指定
Tags Key: ‘Name’
Value: ‘naoki-acm’
タグのキーと値を設定
LoadBalancerAttributes Key: "access_logs.s3.enabled
"Value: "true"
アクセスログを有効化
LoadBalancerAttributes Key: "access_logs.s3.bucket"
Value: !Ref S3BucketName
保管先S3を指定
LoadBalancerAttributes Key: "access_logs.s3.prefix"
Value: "alb-logs"
S3のプレフィックスを指定
  # ALB 作成
  LoadBalancerResource:
    Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
    Properties:
      Name: "naoki-alb"
      Scheme: "internet-facing"
      Type: "application"
      Subnets:
        - !Ref Subnet1Id
        - !Ref Subnet2Id
      SecurityGroups:
        - !Ref SecurityGroupId
      IpAddressType: "ipv4"
      Tags:
        - Key: "Name"
          Value: "naoki-alb"
      LoadBalancerAttributes:
        - Key: "access_logs.s3.enabled"
          Value: "true"
        - Key: "access_logs.s3.bucket"
          Value: !Ref S3BucketName
        - Key: "access_logs.s3.prefix"
          Value: "alb-logs"

6-2.ターゲットグループ作成

事前にEC2にて/mnt/efsにヘルスチェック用のPHPファイルを作成しているためヘルスチェック先はそちらを指定しております。

使用するオプション 設定値 説明
Type AWS::ElasticLoadBalancingV2::TargetGroup デフォルトの定義
Name naoki-tg-web ターゲットグループ名
VpcId !Ref VpcId VPCIDを指定
Protocol HTTP プロトコルを指定
Port 80 プロトコルの番号を指定
TargetType instance インスタンスをターゲットに指定
Targets Id: !Ref InstanceId1Id
Port: 80
Id: !Ref InstanceId2Id
Port: 80
インスタンスIDを指定
HealthCheckEnabled true ヘルスチェックを有効化
HealthCheckIntervalSeconds 30 間隔(秒)
HealthCheckPath /healthcheck.php ヘルスチェックパスを指定
HealthCheckPort traffic-port トラフィックポートを指定(TCP)
HealthCheckProtocol HTTP ヘルスチェックのポートを指定
HealthCheckTimeoutSeconds 5 タイムアウトを指定(秒)
HealthyThresholdCount 5 正常なしきい値を指定
UnHealthyThresholdCount 2 非正常のしきい値を指定
HttpCode 200 成功コードを指定
Tags Key: ‘Name’
Value: ‘naoki-tg-web’
タグのキーと値を設定

6-3.HTTPSリスナー作成

続いてHTTPS通信を受信できるようにリスナーを作成します。

使用するオプション 設定値 説明
Type AWS::ElasticLoadBalancingV2::Listener デフォルトの定義
LoadBalancerArn !Ref LoadBalancerResource ALBのARNを指定
Port 443 ポートを指定
Protocol HTTPS プロトコルを指定
CertificateArn !Ref SubdomainCertificate ACM(証明書)のARNを指定
Type forward リスナーが受け取るトラフィックをターゲットグループに転送
TargetGroupArn !Ref TargetGroupResource ターゲットグループのARNを指定
  # HTTPS リスナー作成
  HttpsListener:
    Type: "AWS::ElasticLoadBalancingV2::Listener"
    Properties:
      LoadBalancerArn: !Ref LoadBalancerResource
      Port: 443
      Protocol: "HTTPS"
      Certificates:
        - CertificateArn: !Ref SubdomainCertificate
      DefaultActions:
        - Type: "forward"
          TargetGroupArn: !Ref TargetGroupResource

6-4. HTTP リスナー作成(HTTPS へのリダイレクト)

続いてHTTP通信をHTTPSへリダイレクトできるようにリスナーを作成します。

使用するオプション 設定値 説明
Type AWS::ElasticLoadBalancingV2::Listener デフォルトの定義
LoadBalancerArn !Ref LoadBalancerResource ALBのARNを指定
Port 80 ポートを指定
Protocol HTTP プロトコルを指定
Type redirect リダイレクトを指定
Protocol HTTPS リダイレクト先プロトコルを指定
Port 443 リダイレクト先ポートを指定
StatusCode HTTP_301 ステータスコードを指定

7.テスト

7-1.テスト内容

今回はいくつかのテストを実施していきたいと思います。

  • EC2の内容をWEBサーバーで表示できるか(ALB→EC2→NAT構成)
  • ラウンドロビンで1号機・2号機を表示可能かどうか
  • Route53で作成したドメイン経由でWEBサーバーへアクセスし暗号化通信をできているか

7-2.EC2の内容をWEBサーバーで表示できるか?(ALB→EC2→NAT構成)

実際にEC2にALBを紐づけてまずはALBのDNS経由でアクセスしていきます。
下記赤枠のDNSからWEBサーバーで検索をかけていきます。
file

そうすると下記でアクセスを確認できました。
file

7-3.ラウンドロビンで1号機・2号機を表示可能かどうか

こちらでページの更新(F5)をしていきます。
file

これで2号機の内容も表示させることが出来ましたのでラウンドロビン方式でできていることを確認できました。

7-4.Route53で作成したドメイン経由でWEBサーバーへアクセスし暗号化通信をできているか

最後にRoute53で証明書を付与したドメインでアクセスした際にHTTPSでの通信ができるのかを確認します。
下記でRoute53で作成したドメインを確認します。
file

ちなみにACMで証明書を発行できていることをACMのコンソール画面でも念のため表示しておきます。
file

こちらで検索をかけると…
file

HTTPSで通信できていることを確認しました。
最後にHTTPで通信するようにすると,,,
file

file
HTTPSへリダイレクトされていることを確認することが出来ました。

8.感想

Route53から一連の流れでの構築となりました。
ALBは資格試験ではよく出てきた内容でしたので構築時はそこまで戸惑うことは少なかったように感じます。
次回はここでも少し出てきましたが、ALBのアクセスログやVPCフローログについて投稿していきます。

Last modified: 2024-08-01

Author