こんにちは、CI部 柿﨑です。
最近はバドミントンのスマッシュがキレイに打てるようになってきており、楽しくて仕方ありません。
今回はALBのリスナールールの優先度に焦点を当てていきたいと思います。
※本ブログの執筆時点(2022年7月)での情報となりますので今後、変更されることが予想されます。
ALBのリスナールールの優先度について
勘違いしていたこと
ALBのリスナールールを複数設定するとマネコン上では以下のとおりに優先度が1, 2, 3, 4
と表示されます。
このことから優先度の設定は1, 2, 3, 4
のように数字を切り詰めた状態でしか設定できず、ネットワークACLのルールのように10, 20, 30, 40
と設定することができないと思っていました。
事実
マネコン上では優先度の設定は1, 2, 3, 4
のように数字を切り詰めた状態で設定することとなります。(正確には優先度を数値で設定できない)
しかし、AWS CLIでは以下のように優先度を10, 20, 30, 40
と設定することが可能でした。
※AWS CLIだけでなく、CloudFormationやboto3でも同様の設定が可能です。
aws elbv2 set-rule-priorities --rule-priorities RuleArn=<リスナールールARN>,Priority=10 RuleArn=<リスナールールARN>,Priority=20 RuleArn=<リスナールールARN>,Priority=30 RuleArn=<リスナールールARN>,Priority=40
set-rule-priorities — AWS CLI 1.25.34 Command Reference
ただし、上記のような設定を入れてもマネコン上では1, 2, 3, 4
のように数字を切り詰めた状態で表示されます。
この状態でAWS CLIを使用してリスナールールの状態を取得すると、システム側では優先度の情報が保持されていることが分かります。
[cloudshell-user@ip-10-0-10-1 ~]$ aws elbv2 describe-rules --listener-arn <リスナーARN> { "Rules": [ { "RuleArn": "<リスナールールARN>", "Priority": "10", ~~~~~省略~~~~~ }, { "RuleArn": "<リスナールールARN>", "Priority": "20", ~~~~~省略~~~~~ }, { "RuleArn": "<リスナールールARN>", "Priority": "30", ~~~~~省略~~~~~ }, { "RuleArn": "<リスナールールARN>", "Priority": "40", ~~~~~省略~~~~~ } ] } [cloudshell-user@ip-10-0-10-1 ~]$
describe-rules — AWS CLI 1.25.34 Command Reference
このことからマネコン上で表示されている優先度の数値はシステム側の設定値を表示しているのではなく、単にリスナールールの順番のようなものを表示していることが分かります。
疑問1
Q.AWS CLIで優先度を10, 20, 30, 40
と設定した状態で、マネコンから優先度の入れ替えを行うとどうなるか?
A.入れ替えるリスナールールの優先度の中で数字が大きい優先度を基準に新たに番号が割り当てられる。
リスナールールの名前と優先度がtest1:10, test2:20, test3:30, test4:40
となっているときに、test1:10
とtest4:40
を入れ替えるとtest4:40, test2:41, test3:42, test1:43
となります。
さらにtest1:10, test2:20, test3:30, test4:100
の状態からtest3:30
とtest4:100
を入れ替えるとtest1:10, test2:20, test4:100, test3:101
になります。
疑問2
Q.リスナールールの優先度の値はどこまで設定可能なのか?
A.本ブログの執筆時点(2022年7月)では50000
まで設定可能。
※リスナールール数の上限はデフォルト100
ですのでご注意ください。
Application Load Balancer のクォータ - Elastic Load Balancing
以下のようにAWS CLIで優先度を高く設定してみたところ、エラーの中で上限値を教えてくれました。
※私が探した限りではCloudFormationのドキュメントにも記載されていました。
AWS::ElasticLoadBalancingV2::ListenerRule - AWS CloudFormation
[cloudshell-user@ip-10-0-154-145 ~]$ aws elbv2 set-rule-priorities --rule-priorities RuleArn=<リスナールールARN>,Priority=100000 An error occurred (ValidationError) when calling the SetRulePriorities operation: 1 validation error detected: Value '100000' at 'rulePriorities.4.member.priority' failed to satisfy constraint: Member must have value less than or equal to 50000 [cloudshell-user@ip-10-0-154-145 ~]$
さらに疑問1との合わせ技でリスナールールの名前と優先度がtest1:10, test2:20, test3:30, test4:50000
となっているときに、test3:30
とtest4:50000
をマネコン上の設定で入れ替えようとすると、システム側ではtest3:50001
を割り当てようとするため50000
の上限値に抵触しました。
今回の調査を行うに至った背景
ALBのリスナールールではHTMLの固定レスポンスを設定することができ、Sorryページを簡単に実装することが可能です。
ALB で Sorry ページを実装する方法と運用上の考慮点 - サーバーワークスエンジニアブログ
そこで1年ほど前に正常時はALBからWEBサーバーへリクエストを送り、
異常時にLambdaがリスナールールの優先度を変更してSorryページの固定レスポンスを返す仕組みを作りました。
このときは単体のALBにつき単体のターゲットグループを設定するため、単純にリスナールールの優先度を入れ替えるだけで問題ありませんでした。
しかし、最近になり単体のALBに複数のターゲットグループを設定した状態で、特定のターゲットグループで異常が発生した際にSorryページの固定レスポンスを返す必要が出てきました。
この状態で優先度の番号を1, 2, 3, 4
と数字を切り詰めると、リスナールールの優先度の制御が複雑化します。
そこでネットワークACLのルールのように優先度の番号を10, 20, 30, 100
と設定し、
Sorryページの固定レスポンスを優先度100
、異常の発生したリスナールールを一時的に優先度101
以上にするような制御ができないか、と考えたのが発端となります。
以上となります。