アレイから、あるキーが特定の値であるハッシュを取り出す (Terraform, Ansible, Chef)
やりたい事
terraformにて、以下の様なハッシュ(マップ)のアレイ(リスト)から、nameがn2のattrを取り出す。
キーはユニークとする。
array_01:
- name: n1
attr: attr1
- name: n2
attr: attr2
- name: n3
attr: attr3
なお、ansibleならば、selectattrフィルターが、chef|rubyならばselectメソッドが使用可能。
方法: ワイルドカード指定のindexを使用する。
例
なお、.ftではなく、.tf.jsonを使用
{
"locals": {
"array_01": [
{ "name": "n1", "attr": "attr1" },
{ "name": "n2", "attr": "attr2" },
{ "name": "n3", "attr": "attr3" }
]
},
"output": {
"array_01_name": {
"value": "${ local.array_01.*.name }"
},
"n2_attr": {
"value": "${ local.array_01[ index( local.array_01.*.name, \"n2\" ) ].attr }"
}
}
}
内容を見やすくする為にyqユーティリティを使ってyamlフォーマット化したものも載せておく
$ yq -y . main.tf.json
locals:
array_01:
- name: n1
attr: attr1
- name: n2
attr: attr2
- name: n3
attr: attr3
output:
array_01_name:
value: ${ local.array_01.*.name }
n2_attr:
value: ${ local.array_01[ index( local.array_01.*.name, "n2" ) ].attr }
ここで、local.array_01.*.nameは、local.array_01の要素でキーがname:の値のアレイ(リスト)となり、index( local.array_01.*.name, "n2" ) は、nameがn2である要素番号(0始まり)の1となる。local.array_01[*].nameでも可。
$ terraform apply --auto-approve
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
array_01_name = [
"n1",
"n2",
"n3",
]
n2_attr = attr2
なお、localとoutputのみだからか、terraform initも不要であったし、terraform initを行っても.terraformディレクトリーは作成されなかった。
追記
なお、リソースからワイルドカードによる取得を行った際、要素のタイプが揃わず?indexがエラーとなるケースがあった。terraformかproviderのバグ?
indexに、for文にて作成したリストを与える事で回避した。
indexにfor文で作成したリストを渡して回避した例
{
"locals": {
"array_01": [
{
"name": "n1",
"attr": "attr1"
},
{
"name": "n2",
"attr": "attr2"
},
{
"name": "n3",
"attr": "attr3"
}
]
},
"output": {
"array_01_name": {
"value": "${ local.array_01.*.name }"
},
"n2_attr": {
"value": "${ local.array_01[ index( [ for s in local.array_01 : s.name ], \"n2\") ].attr }"
}
}
}
$ terraform apply --auto-approve
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
array_01_name = [
"n1",
"n2",
"n3",
]
n2_attr = attr2
Ansibleの例
selectattr.yml
- hosts: all
gather_facts: false
vars:
array_01:
- name: n1
attr: attr1
- name: n2
attr: attr2
- name: n3
attr: attr3
tasks:
- debug: msg={{ ( array_01 | selectattr("name", "equalto", "n2") | list )[0].attr }}
- debug: msg={{ ( array_01 | selectattr("name", "==", "n2") | list )[0].attr }}
- debug: msg={{ ( array_01 | json_query("[?name=='n2'].attr"))[0] }}
- json_query には sudo pip install jmespath などが必要
$ ansible-playbook -i localhost, -c local selectattr.yml
PLAY [all] *******************************************************************************************************
TASK [debug] *****************************************************************************************************
ok: [localhost] => {
"msg": "attr2"
}
TASK [debug] *****************************************************************************************************
ok: [localhost] => {
"msg": "attr2"
}
TASK [debug] *****************************************************************************************************
ok: [localhost] => {
"msg": "attr2"
}
PLAY RECAP *******************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Chef(というかRuby)の例
select.rb
require 'yaml'
array_01 = YAML.load(<<~EOS)
- name: n1
attr: attr1
- name: n2
attr: attr2
- name: n3
attr: attr3
EOS
p array_01.select { |e| e['name'] == 'n2' }[0]['attr']
$ ruby select.rb
"attr2"
参考: terraform
- hosts: all
gather_facts: false
vars:
array_01:
- name: n1
attr: attr1
- name: n2
attr: attr2
- name: n3
attr: attr3
tasks:
- debug: msg={{ ( array_01 | selectattr("name", "equalto", "n2") | list )[0].attr }}
- debug: msg={{ ( array_01 | selectattr("name", "==", "n2") | list )[0].attr }}
- debug: msg={{ ( array_01 | json_query("[?name=='n2'].attr"))[0] }}
$ ansible-playbook -i localhost, -c local selectattr.yml
PLAY [all] *******************************************************************************************************
TASK [debug] *****************************************************************************************************
ok: [localhost] => {
"msg": "attr2"
}
TASK [debug] *****************************************************************************************************
ok: [localhost] => {
"msg": "attr2"
}
TASK [debug] *****************************************************************************************************
ok: [localhost] => {
"msg": "attr2"
}
PLAY RECAP *******************************************************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
require 'yaml'
array_01 = YAML.load(<<~EOS)
- name: n1
attr: attr1
- name: n2
attr: attr2
- name: n3
attr: attr3
EOS
p array_01.select { |e| e['name'] == 'n2' }[0]['attr']
$ ruby select.rb
"attr2"
参考: terraform
ワイルドカードに少し触れている。
https://www.terraform.io/docs/configuration-0-11/resources.html
公式のindexの項にはワイルドカードの説明は見つけられなかった。
https://www.terraform.io/docs/configuration/functions/index.html
参考: ansible
Author And Source
この問題について(アレイから、あるキーが特定の値であるハッシュを取り出す (Terraform, Ansible, Chef)), 我々は、より多くの情報をここで見つけました https://qiita.com/hiroyuki_onodera/items/bae949ee259b7697e043著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .