Ansibleのselectattrとmapとlist
最近またAnsibleでAWSの構成を書き始めました。
selectattrとmapが便利
次のような値を with_items で回してサブネットを作るとともに、publicなものを取り出してルートテーブルを作りたくなったのですが、selectattr()とmap()を使うと取り出すことができました。
--- vpc_subnets: - { name: bastion, az: ap-northeast-1a, cidr: 10.0.1.0/28, tier: bastion, public: true } - { name: web1a, az: ap-northeast-1a, cidr: 10.0.10.0/24, tier: web, public: true } - { name: web1c, az: ap-northeast-1c, cidr: 10.0.11.0/24, tier: web, public: true } - { name: db1a, az: ap-northeast-1a, cidr: 10.0.20.0/24, tier: db } - { name: db1c, az: ap-northeast-1c, cidr: 10.0.21.0/24, tier: db }
- name: get public cidr list set_fact: v: '{{ vpc_subnets | selectattr("public", "defined") | selectattr("public", "equalto", true) | map(attribute="cidr") | list}}' - debug: var=v
結果
TASK [vpc : get public cidr list] **********************************************
ok: [localhost]
TASK [vpc : debug] *************************************************************
ok: [localhost] => {
"v": [
"10.0.1.0/28",
"10.0.10.0/24",
"10.0.11.0/24"
]
}
ドキュメント
generator object _select_or_rejectやgenerator object do_mapの中身を見るにはlist
selectattr()やmap()をかました変数をdebugで出力しようとするとオブジェクトになってしまって中身が見られないのですが、listを使ってあげると確認できるのも学びました。便利。
ok: [localhost] => {
"v": "<generator object do_map at 0x1039fd730>"
}
とか
ok: [localhost] => {
"v": "<generator object do_map at 0x1039fd730>"
}
が、listを使うと
ok: [localhost] => {
"v": [
{
"az": "ap-northeast-1a",
"cidr": "10.0.1.0/28",
"name": "bastion",
"public": true,
"tier": "bastion"
},
{
"az": "ap-northeast-1a",
"cidr": "10.0.10.0/24",
"name": "web1a",
"public": true,
"tier": "web"
},
{
"az": "ap-northeast-1c",
"cidr": "10.0.11.0/24",
"name": "web1c",
"public": true,
"tier": "web"
}
]
}
その他のフィルター
他にもいろんなフィルターがあって便利です。 ただ、できるからといっていろいろやりすぎるのは良くないですね。 1ヶ月後の自分が見ても分かるように、できるだけシンプルにわかりやすく記述したいところです。