Posted at

ansibleのelb_target_group_factsの検索は全一致になるらしい(というか boto3 elbv2のdescribe_load_balancersが全一致)


TL;DR



  • elbv2のdescribe_load_balancersは存在しないELBを検索しようとするとLoadBalancerNotFoundException

  • 検索したいload balancer nameを1つずつfor文で回すしかない


経緯

AWSのALBの情報を取得するansibleを書いていたのですが、elbv2describe_load_balancersの仕様にはまったのでメモ。


問題点

ansibleのALBの情報取得をするelb_application_lb_factsで以下のように書いたのですが、

- elb_application_lb_facts:

aws_access_key: hoge
aws_secret_key: fuga
region: ap-northeast-1
names:
- "alb-blue"
- "alb-green"
register: alb_result

load balancerの情報を取得できない。。

"load_balancers": []

実際のlibraryを確認してみると、LoadBalancerNotFoundが発生した場合は空で返すとのこと。

つまり検索候補のうち、片方が存在しない名前のLoad Balancerの場合、エラーを吐くらしい。きつい。

https://github.com/ansible/ansible/blob/stable-2.7/lib/ansible/modules/cloud/amazon/elb_application_lb_facts.py#L222

一応自分でpythonで以下のように試してみたのですが、

import boto3

access_key = 'hoge'
secret_key = 'fuga'
client = boto3.client(
'elbv2',
region_name='ap-northeast-1',
aws_access_key_id = access_key,
aws_secret_access_key = secret_key
)
response = client.describe_load_balancers(
Names=[
'alb-blue',
'alb-green'
]
)
print(response)

やっぱりLoadBalancerNotFoundExceptionが出てしまう。避けられない仕様らしい。

botocore.errorfactory.LoadBalancerNotFoundException: An error occurred (LoadBalancerNotFound) when calling the DescribeLoadBalancers operation

結局以下のように無理やりloopにして対応しました。

- set_fact: 

alb_list: []

- elb_application_lb_facts:
aws_access_key: hoge
aws_secret_key: fuga
region: ap-northeast-1
names:
- "{{ item }}"
register: alb_result
with_items:
- "alb-blue"
- "alb-green"

- set_fact:
alb_list: "{{ alb_list }} + {{ item['load_balancers'] }}"
when: item['load_balancers'] | length > 0
with_items: "{{ alb_result['results'] }}"


結論

elbv2のdescribe_load_balancersは全一致しか許さない、という鬼仕様でした。

今回はansibleのyml側で制御する方法を取ったのですが、

elb_application_lb_factsを多用するのであれば、custom moduleを作成して、

python内部でfor文を回した方が保守性が良くなりそうです。