Application Load BalancerのCLI設定取得
Application Load Balancer(以下、ALB)の設定値をAWS CLIコマンドで取得するのに実行するコマンドが多すぎると思ったことはありますか?
ALBの設定パラメーターをCLIで取得するにあたり、ロードバランサーの設定・ターゲットグループの設定・リスナーの設定・リスナールールの設定など、確認したいポイント複数に対してそれぞれのdescribeコマンドを実行する必要があります。
そこで、よく確認する項目だけでも一覧化してALBのデータ確認を効率をするためのpythonコードになります。
また、ターゲット先のEC2やACM(HTTPS証明書)がインスタンスIDやACM ARNで出力されるため、EC2名や証明書名と比べて直感的にわかりにくい箇所をEC2名などの一目見てわかるように変換して出力してくれます。
具体的には以下の項目を一覧化して表示します。
- ALB 設定
— ALB名
— 接続タイプ(内部向け or 外部向け)
— IPアドレスタイプ
— サブネット
— セキュリティグループ
— 属性設定 - リスナー設定
— 接続プロトコル
— 接続ポート
— (使用するデフォルト証明書)(HTTPSのみ)
— 一部のリスナールール - ターゲットグループ設定
— ターゲットグループ名
— ターゲットタイプ
— プロトコル
— 接続ポート
— ヘルスチェック設定
— 属性設定
自分向けに作成しているため「この情報を追加出力したい」などあればアレンジして活用いただければと思います。
前提条件
- Python : ver3.11.4 (細かなバージョン指定はありませんがPythonが実行できる環境が必要)
- boto3 Library : インストール済み
- AWS環境へのReadOnly権限 : データ参照する際に必要になる権限。(名前表示のための EC2をNameタグ/SG Name/ACM 証明書名などELB以外のリソースに対するreadonly権限も必要)
- デフォルトリージョンを指定 : 特定のリージョンを事前指定済みであること
pythonコード
output_alb_status.py
などの名前で下記コードを保存。
import sys import datetime import boto3 from distutils.util import strtobool def main(): if len(sys.argv) < 2: print('invalid argument.' '(example : python3 output_alb_status.py ALBName)') sys.exit(1) alb_name = sys.argv[1] client = boto3.client('elbv2') # get alb general status response = client.describe_load_balancers( Names=[ alb_name ] ) print_alb_parameter(response) print('\n') print_tg_parameter(response) def print_alb_parameter(alb_para: dict): client = boto3.client('elbv2') response = alb_para['LoadBalancers'][0] attribute = client.describe_load_balancer_attributes( LoadBalancerArn=response['LoadBalancerArn'] ) print("###### ALB Parameter ##### ") print(f' LoadBalancerName : {response["LoadBalancerName"]}') print(f' Scheme : {response["Scheme"]}') print(f' IpAddressType : {response["IpAddressType"]}') print(' Subnet1 ') print(f' SubnetID : {response["AvailabilityZones"][0]["SubnetId"]}') print(f' AZ_Name : {response["AvailabilityZones"][0]["ZoneName"]}') print(' Subnet2 ') print(f' SubnetID : {response["AvailabilityZones"][1]["SubnetId"]}') print(f' AZ_Name : {response["AvailabilityZones"][1]["ZoneName"]}') print(' SecurityGroup ') for i, SecurityGroups in enumerate(response['SecurityGroups']): sg_name = return_sg_name(SecurityGroups) print(f' SG{i} : {sg_name}') print() print(' Attribute ') for Attributes in attribute["Attributes"]: if 'deletion_protection.enabled' in Attributes.values(): print(f' DeletProtection: {Attributes["Value"]}') for Attributes in attribute["Attributes"]: if 'idle_timeout.timeout_seconds' in Attributes.values(): print(f' IdleTimeOut : {Attributes["Value"]}') for Attributes in attribute["Attributes"]: if 'routing.http2.enabled' in Attributes.values(): print(f' HTTP2Enable : {Attributes["Value"]}') print() print(' AccessLog ') for Attributes in attribute["Attributes"]: if 'access_logs.s3.enabled' in Attributes.values(): print(f' LogEnable : {Attributes["Value"]}') for Attributes in attribute["Attributes"]: if 'access_logs.s3.bucket' in Attributes.values(): print(f' Backet : {Attributes["Value"]}') for Attributes in attribute["Attributes"]: if 'access_logs.s3.prefix' in Attributes.values(): print(f' Prefix : {Attributes["Value"]}') print() print(' Listener ') print_listener_parameter(response['LoadBalancerArn']) def print_listener_parameter(lb_arn): client = boto3.client('elbv2') listener = client.describe_listeners( LoadBalancerArn=lb_arn ) for i, Listeners in enumerate(listener['Listeners']): print(f' Listener{i} ') print(f' Protocol : {Listeners["Protocol"]}') print(f' Port : {Listeners["Port"]}') if 'Certificates' in Listeners: for Certificates in Listeners['Certificates']: cert_name = return_acm_name(Certificates["CertificateArn"]) print(f' Cert{i} : {cert_name}') else: print(' Cert : None') if 'SslPolicy' in Listeners: print(f' SslPolicy : {Listeners["SslPolicy"]}') print_listener_rule(Listeners["ListenerArn"], i) print() def print_listener_rule(listener_arn, i): client = boto3.client('elbv2') rules = client.describe_rules( ListenerArn=listener_arn ) print() for j, Rule in enumerate(rules['Rules']): print(f' ListerRule {i}-{j}') print(f' Priority : {Rule["Priority"]}') print(' Conditions ') for Condition in Rule["Conditions"]: if 'source-ip' in Condition.values(): print(f' source-ip : {Condition["SourceIpConfig"]}') elif 'host-header' in Condition.values(): print(f' host-header: {Condition["Values"]}') elif 'path-pattern' in Condition.values(): print(f' path-patter: {Condition["Values"]}') elif 'http-header' in Condition.values(): print(f' http-header: {Condition["HttpHeaderConfig"]}') else: print(' Condition Setting: None') print(' Actions ') for Actions in Rule["Actions"]: if 'forward' in Actions.values(): for k, targetgroup in enumerate(Actions['ForwardConfig']['TargetGroups']): tg_response = client.describe_target_groups( TargetGroupArns=[ targetgroup['TargetGroupArn'] ] ) print(f' forward : {tg_response["TargetGroups"][0]["TargetGroupName"]}') print(f' Weight : {targetgroup["Weight"]}') print(f' Stikiness : {Actions["ForwardConfig"]["TargetGroupStickinessConfig"]["Enabled"]}') elif 'redirect' in Actions.values(): print(f' Redirect : {Actions["RedirectConfig"]}') elif 'fixed-response' in Actions.values(): print(f' FixResponse: {Actions["FixedResponseConfig"]}') print() def print_tg_parameter(alb_para): client = boto3.client('elbv2') lb_arn = alb_para['LoadBalancers'][0]['LoadBalancerArn'] tg_para = client.describe_target_groups( LoadBalancerArn=lb_arn ) for i, TargetGroups in enumerate(tg_para["TargetGroups"]): print(f"###### TG Parameter {i} ##### ") print(f' TargetGroupName : {TargetGroups["TargetGroupName"]}') print(f' TargetType : {TargetGroups["TargetType"]}') print(f' Protocol : {TargetGroups["Protocol"]}') print(f' Port : {TargetGroups["Port"]}') print() print(' HealthCheck ') print(f' Protocol : {TargetGroups["HealthCheckProtocol"]}') print(f' Path : {TargetGroups["HealthCheckPath"]}') print(f' Port : {TargetGroups["HealthCheckPort"]}') print(f' Threshold : {TargetGroups["HealthyThresholdCount"]}') print(f' UnHhealtyTH : {TargetGroups["UnhealthyThresholdCount"]}') print(f' Timeout : {TargetGroups["HealthCheckTimeoutSeconds"]}') print(f' Interval : {TargetGroups["HealthCheckIntervalSeconds"]}') print(f' SuccessCode : {TargetGroups["Matcher"]["HttpCode"]}') print() print(' HealthCheckTarget ') tg_instance = client.describe_target_health( TargetGroupArn=TargetGroups["TargetGroupArn"] ) for i, HealthDescriptions in enumerate(tg_instance["TargetHealthDescriptions"]): instance_name = return_instance_name(HealthDescriptions["Target"]["Id"]) print(f' Target {i} : {instance_name}') print(f' Target {i} Health: {HealthDescriptions["TargetHealth"]["State"]}') print() print(' Attribute ') tg_attribute = client.describe_target_group_attributes( TargetGroupArn=TargetGroups["TargetGroupArn"] ) for tg_Attributes in tg_attribute["Attributes"]: if 'deregistration_delay.timeout_seconds' in tg_Attributes.values(): print(f' DerectionDelay : {tg_Attributes["Value"]}') for tg_Attributes in tg_attribute["Attributes"]: if 'slow_start.duration_seconds' in tg_Attributes.values(): print(f' SlowStart : {tg_Attributes["Value"]}') for tg_Attributes in tg_attribute["Attributes"]: if 'load_balancing.algorithm.type' in tg_Attributes.values(): print(f' LbAlgorithm : {tg_Attributes["Value"]}') for tg_Attributes in tg_attribute["Attributes"]: if 'stickiness.enabled' in tg_Attributes.values(): print(f' Stickiness : {tg_Attributes["Value"]}') if strtobool(tg_Attributes["Value"]): for stickinessAttri in tg_attribute["Attributes"]: if 'stickiness.type' in stickinessAttri.values(): print(f' StickinessType : {stickinessAttri["Value"]}') if stickinessAttri["Value"] == "lb_cookie": for stickinessAttri in tg_attribute["Attributes"]: if 'stickiness.lb_cookie.duration_seconds' in stickinessAttri.values(): td = datetime.timedelta(seconds=int(stickinessAttri["Value"])) print(f' StickinessDuration: {td}') elif stickinessAttri["Value"] == "app_cookie": for stickinessAttri in tg_attribute["Attributes"]: if 'stickiness.app_cookie.duration_seconds' in stickinessAttri.values(): td = datetime.timedelta(seconds=int(stickinessAttri["Value"])) print(f' StickinessDuration: {td}') for stickinessAttri in tg_attribute["Attributes"]: if 'stickiness.app_cookie.cookie_name' in stickinessAttri.values(): print(f' StickinessAppName: {stickinessAttri["Value"]}') print() def return_sg_name(sg_id: str): client = boto3.client('ec2') response = client.describe_security_groups( GroupIds=[ sg_id ] ) return (response['SecurityGroups'][0]['GroupName']) def return_acm_name(acm_id: str): client = boto3.client('acm') acm_list = client.list_certificates( CertificateStatuses=[ 'ISSUED' ] ) for CertificateSummaryList in acm_list['CertificateSummaryList']: if acm_id in CertificateSummaryList['CertificateArn']: return (CertificateSummaryList['DomainName']) else: continue return ("None") def return_instance_name(instance_id: str): client = boto3.client('ec2') response = client.describe_instances( InstanceIds=[ instance_id ] ) for Ec2Name in response["Reservations"][0]["Instances"][0]["Tags"]: if 'Name' in Ec2Name.values(): return (Ec2Name["Value"]) else: continue return (instance_id) if __name__ == '__main__': main()
出力イメージ
python3 output_alb_status.py ubukata-alb
でコマンドを実行することで、以下のような設定を取得できます。
※ 出力イメージ用の設定パラメーターは適当です。あくまで出力イメージように設定しているため、パラメーターが適切でない場合があります。
###### ALB Parameter ##### LoadBalancerName : ubukata-alb Scheme : internet-facing IpAddressType : ipv4 Subnet1 SubnetID : subnet-XXXXXXXXXXXXXXXX AZ_Name : ap-northeast-1a Subnet2 SubnetID : subnet-XXXXXXXXXXXXXXXX AZ_Name : ap-northeast-1c SecurityGroup SG0 : ubukata-sg-pub Attribute DeletProtection: false IdleTimeOut : 60 HTTP2Enable : true AccessLog LogEnable : false Backet : Prefix : Listener Listener0 Protocol : HTTPS Port : 443 Cert0 : ubukata.xxxx.xxxx.hoge.jp SslPolicy : ELBSecurityPolicy-TLS13-1-2-2021-06 ListerRule 0-0 Priority : 1 Conditions host-header: ['hoge.example.com'] source-ip : {'Values': ['172.16.0.0/24']} Actions forward : ubukata-tg-1 Weight : 1 Stikiness : False forward : ubukata-tg-2 Weight : 2 Stikiness : False ListerRule 0-1 Priority : 2 Conditions source-ip : {'Values': ['192.168.0.2/32']} Actions FixResponse: {'MessageBody': 'not found', 'StatusCode': '404', 'ContentType': 'text/plain'} ListerRule 0-2 Priority : 3 Conditions path-patter: ['/hoge/test/*'] Actions FixResponse: {'MessageBody': 'sorry', 'StatusCode': '503', 'ContentType': 'text/plain'} ListerRule 0-3 Priority : 4 Conditions http-header: {'HttpHeaderName': 'aa', 'Values': ['hoge']} Actions Redirect : {'Protocol': 'HTTPS', 'Port': '10050', 'Host': '#{host}', 'Path': '/#{path}', 'Query': '#{query}', 'StatusCode': 'HTTP_301'} ListerRule 0-4 Priority : default Conditions Actions forward : ubukata-tg-1 Weight : 1 Stikiness : False Listener1 Protocol : HTTP Port : 80 Cert : None ListerRule 1-0 Priority : default Conditions Actions forward : ubukata-tg-1 Weight : 1 Stikiness : False ###### TG Parameter 0 ##### TargetGroupName : ubukata-tg-1 TargetType : instance Protocol : HTTP Port : 80 HealthCheck Protocol : HTTP Path : / Port : traffic-port Threshold : 5 UnHhealtyTH : 2 Timeout : 5 Interval : 30 SuccessCode : 200 HealthCheckTarget Target 0 : ubukata-windows Target 0 Health: unhealthy Attribute DerectionDelay : 300 SlowStart : 0 LbAlgorithm : round_robin Stickiness : false ###### TG Parameter 1 ##### TargetGroupName : ubukata-tg-2 TargetType : instance Protocol : HTTP Port : 80 HealthCheck Protocol : HTTP Path : /index.html Port : traffic-port Threshold : 5 UnHhealtyTH : 2 Timeout : 5 Interval : 30 SuccessCode : 200 HealthCheckTarget Target 0 : ubukata-ec2-rhel Target 0 Health: healthy Attribute DerectionDelay : 300 SlowStart : 0 LbAlgorithm : round_robin Stickiness : false