[小ネタ] ALB の高度なリクエストルーティングを CloudFormation で設定する

2019.06.30

こんにちは、菊池です。

ちょうど一ヶ月ほど前、以下の記事を書きました。

[小ネタ] ALB の高度なリクエストルーティングを CLI で設定する

この時は、高度なリクエストルーティングがCloudFormationに対応していなかったため、再現性のある構築手順のためにAWS CLIを用いました。ひと月たって、気づけばすでにCloudFromationに対応していたので、テンプレートを作成して構築してみました。

やってみた

今回構築したルールは前回とほぼ同じで以下の通りです。

  • HTTPヘッダに特定の文字列があればターゲットにルーティング
  • それ以外は403を応答(デフォルトアクション)

設定方法は公式ドキュメントを参照します。現時点で、日本語版には未反映でしたので、英語表示で確認しましょう。

ListenerRuleのRuleConditionに、対応している条件が増えています。

テンプレート

テンプレートは以下の通りです。メインはリスナーとリスナールールですが、同時に必要になるSecurityGroup、TargetGroup、ALBも合わせて作成しています。TLSの証明書のみパラメータで指定が必要です。

AWSTemplateFormatVersion: '2010-09-09'
Description: public security group and alb

Parameters:
  certificate:
    Type: String

Resources:
  albSecuritygroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupName: alb-sg
      GroupDescription: alb-sg
      Tags:
        - Key: Name
          Value: alb-sg
      VpcId: vpc-xxxxxxxxxxxxxxxx
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '443'
        ToPort: '443'
        CidrIp: 0.0.0.0/0

  albTargetGroup:
    Type: AWS::ElasticLoadBalancingV2::TargetGroup
    Properties:
      HealthCheckIntervalSeconds: 30
      HealthCheckPath: /healthcheck
      HealthCheckPort: 80
      HealthCheckProtocol: HTTP
      HealthCheckTimeoutSeconds: 6
      HealthyThresholdCount: 3
      Name: alb-tg
      Port: 80
      Protocol: HTTP
      UnhealthyThresholdCount: 3
      TargetType: ip
      VpcId: vpc-xxxxxxxxxxxxxxxx
  alb:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: alb
      Scheme: internet-facing
      SecurityGroups:
        - !Ref albSecuritygroup
      Subnets:
        - subnet-xxxxxxxxxxxxxxxx
        - subnet-xxxxxxxxxxxxxxxx
      Tags:
        - Key: Name
          Value: alb
      Type: application

  alblistnener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      DefaultActions:
        - Type: fixed-response
          FixedResponseConfig:
            StatusCode: 403
            MessageBody: Not authorized Access.
            ContentType: text/plain
      Certificates:
        - CertificateArn: !Ref certificate
      LoadBalancerArn: !Ref alb
      Port: 443
      Protocol: HTTPS

  lisnerRule:
    Type: AWS::ElasticLoadBalancingV2::ListenerRule
    Properties:
      Actions:
      - Type: forward
        TargetGroupArn:
          !Ref albTargetGroup
      Conditions:
      - Field: http-header
        HttpHeaderConfig:
          HttpHeaderName: x-pre-shared-key
          Values:
            - PRESHAREDKEY
      ListenerArn: !Ref alblistnener
      Priority: 10

上記テンプレートを実行すると、狙った通りにリスナールールが設定されました。

さいごに

今回は以上です。

求める機能がある時には対応していなくても、翌月には(あるいは翌日には)対応されるっといったことがAWSではよくあります。どれも手段にすぎませんので、最初に決めた方法に固執せず、柔軟に受け入れてよりよい実装に向けていくことが重要ですね。