ALBのパスベースルーティングで複数のターゲットグループにトラフィックを転送する

ALBのパスベースルーティングで複数のターゲットグループにトラフィックを転送する

ALBのパスベースルーティング用構成

ALBはパスベースルーティングに対応しています。

1 つのターゲットグループにリクエストを転送するデフォルトルールを持つリスナーがある場合、URL に基づいて別のターゲットグループにリクエストを転送するルールを追加できます。

パスベースのルーティングの追加

今回は2つのEC2インスタンスを用意し、URLに応じて、トラフィックを振り分けます。

構築する環境

Diagram of fowarding traffic to multiple target groups with Path-based routing in ALB.

2つのALBターゲットグループを作成し、それぞれのグループにEC2インスタンスを1つずつ配置します。
2つのインスタンスにApacheをインストールして、Webサーバとして動作させます。

CloudFormationテンプレートファイル

上記の構成をCloudFormationで構築します。以下のURLにCloudFormationテンプレートを配置してます。

https://github.com/awstut-an-r/awstut-fa/tree/main/029

テンプレートファイルのポイント解説

今回の構成は、以下のページと概ね同様です。

あわせて読みたい
プライベートサブネット内のインスタンスをALBにアタッチする 【プライベートサブネット内のインスタンスをALBにアタッチする構成】 プライベートサブネット内に設置されたインスタンスを、ALBにアタッチする方法を確認します。 AWS...

プライベートサブネットのEC2インスタンスをALBにアタッチする方法や、プライベートサブネット内のEC2インスタンでyumを実行する方法については、上記のページをご確認ください。
異なる点はパスベースルーティングを使用している点です。ですから本ページでは、それに関する内容にフォーカスします。

パスベースルーティングを行う場合、以下の2つのリソースがポイントとなります。

  • ターゲットグループ
  • リスナールール

順番に確認します。

ターゲットグループ

今回の構成では、2つのインスタンスを別のグループに分けます。ですからターゲットグループを2つ作成する点がポイントになります。

Resources:
  ALBTargetGroup1:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      VpcId: !Ref VPC
      Name: !Sub "${Prefix}-ALBTargetGroup1"
      Protocol: HTTP
      Port: !Ref HTTPPort
      HealthCheckProtocol: HTTP
      HealthCheckPath: /
      HealthCheckPort: traffic-port
      HealthyThresholdCount: !Ref HealthyThresholdCount
      UnhealthyThresholdCount: !Ref UnhealthyThresholdCount
      HealthCheckTimeoutSeconds: !Ref HealthCheckTimeoutSeconds
      HealthCheckIntervalSeconds: !Ref HealthCheckIntervalSeconds
      Matcher:
        HttpCode: !Ref HttpCode
      Targets:
        - Id: !Ref Instance1
      TargetType: instance

  ALBTargetGroup2:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      Name: !Sub "${Prefix}-ALBTargetGroup2"
      ...
Code language: YAML (yaml)

パスベースルーティングを行うためには、特別な設定は不要です。今回は全く同じ設定で、2つのターゲットグループを作成します。

リスナールール

リスナールールで、URLと対応するターゲットグループを設定します。

Resources:
  ALBListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - TargetGroupArn: !Ref ALBTargetGroup1
          Type: forward
      LoadBalancerArn: !Ref ALB
      Port: !Ref HTTPPort
      Protocol: HTTP

  ALBListenerRule1:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - TargetGroupArn: !Ref ALBTargetGroup1
          Type: forward
      Conditions:
        - Field: path-pattern
          PathPatternConfig:
            Values:
              - /instance1/*
      ListenerArn: !Ref ALBListener
      Priority: 1

  ALBListenerRule2:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
        - TargetGroupArn: !Ref ALBTargetGroup2
          Type: forward
      Conditions:
        - Field: path-pattern
          PathPatternConfig:
            Values:
              - /instance2/*
      ListenerArn: !Ref ALBListener
      Priority: 2
Code language: YAML (yaml)

前提として、リスナーリソースにデフォルトアクション、つまりデフォルトのトラフィック送信先を設定する必要があります。DefaultActionsプロパティで設定可能です。今回はALBTargetGroup1を設定します。
TargetGroupArnプロパティで、対象のターゲットグループを指定します。関連づけるURLは、Conditionsプロパティで設定できます。Fieldプロパティで「path-pattern」を、PathPatternConfigプロパティでURLを指定します。
以上をまとめると、今回は以下の通りに設定します。

  • /:ALBTargetGroup1(Instance1)
  • /instance1/:ALBTargetGroup1(Instance1)
  • /instance2/:ALBTargetGroup2(Instance2)

(参考) インスタンス初期化

2つのEC2インスタンスをWebサーバとして設定しますが、これをUserDataで実施します。

Resources:
  Instance1:
    Type: AWS::EC2::Instance
    Properties:
      UserData: !Base64 |
        #!/bin/bash -xe
        yum update -y
        yum install -y httpd
        systemctl start httpd
        systemctl enable httpd
        echo 'path: "/"' >> /var/www/html/index.html
        ec2-metadata -i >> /var/www/html/index.html

        mkdir /var/www/html/instance1
        echo 'path: "/isntace1/"' >> /var/www/html/instance1/index.html
        ec2-metadata -i >> /var/www/html/instance1/index.html

  Instance2:
    Type: AWS::EC2::Instance
    Properties:
      UserData: !Base64 |
        #!/bin/bash -xe
        yum update -y
        yum install -y httpd
        systemctl start httpd
        systemctl enable httpd

        mkdir /var/www/html/instance2
        echo 'path: "/isntace2/"' >> /var/www/html/instance2/index.html
        ec2-metadata -i >> /var/www/html/instance2/index.html
Code language: YAML (yaml)

yumでApacheをインストール・起動後、各ディレクトリにHTMLファイルを作成し、設置します。
注意するべき点は、コンテンツを配置する位置です。先述のURLに対応する位置に配置する必要があります。

パスパターンはリクエストのルーティングに使用されますが、変更はしません。例えば、ルールにパスパターン /img/* がある場合、ルールは /img/picture.jpg のリクエストを /img/picture.jpg のリクエストとして、指定されたターゲットグループに転送します。

Application Load Balancer のリスナー

上記に従い、ドキュメントルートから見た、URLに対応する位置に、HTMLファイルを配置します。

環境構築

CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。

CloudFormationスタックを作成し、スタック内のリソースを確認する

CloudFormationスタックを作成します。スタックの作成および各スタックの確認方法については、以下のページをご確認ください。

あわせて読みたい
CloudFormationのネストされたスタックで環境を構築する 【CloudFormationのネストされたスタックで環境を構築する方法】 CloudFormationにおけるネストされたスタックを検証します。 CloudFormationでは、スタックをネストす...

各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。

  • ALB:fa-029-ALB
  • ターゲットグループ1:fa-029-ALBTargetGroup1
  • ターゲットグループ2:fa-029-ALBTargetGroup2
  • インスタンス1:i-06542b7318333fd34
  • インスタンス2:i-0d3bdfef3f2f83533

AWS Management Consoleからも、リソースの作成状況を確認します。まずALBを確認します。

The ALB has been created successfully.

ALBが作成されました。

次にリスナールールを確認します。ルールの確認は、リスナーのページからアクセスできます。

Access the listener rules page.
Listener Rules.

次にターゲットグループを確認します。

ALB Target Group 1
ALB Target Group 2

各ターゲットグループにインスタンスが登録されていることがわかります。

動作確認

準備が整いましたので、ALBにアクセスします。

まずルートページ(「/」)です。

Go to the root page of ALB.

インスタンス1から応答がありました。デフォルトアクションで設定した通り、ターゲットグループ1に登録されているインスタンス1に、トラフィックがルーティングされたということです。

次に「/instance1/」にアクセスします。

Path-based routing 1

こちらもインスタンス1から応答がありました。リスナールールの1行目に従って、ターゲットグループ1にルーティングされました。

最後に「/instance2/」にアクセスします。

Path-based routing 2

こちらはインスタンス2から応答がありました。リスナールールの2行目に従って、ターゲットグループ2にルーティングされました。

まとめ

ALBのパスベースルーティングで、複数のターゲットグループにトラフィックを転送する方法を確認しました。