🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ansible

Ansibleは、Python で書かれたサーバーの設定を管理するための 構成管理ツールです。

Q&A

解決済

1回答

1736閲覧

Ansibleのj2ファイルでeval的な定義の仕方(変数内の値を変数名として使う)

hakoritenshi

総合スコア41

Ansible

Ansibleは、Python で書かれたサーバーの設定を管理するための 構成管理ツールです。

0グッド

0クリップ

投稿2020/12/01 11:02

編集2020/12/05 16:48

##やりたいこと
①group_vars/server01/vars.mainの〇がついている行のみ抜き出した、varsを作成
②そのvarsをinclude
③そのincludeしたものを元に出力
を汎用化させたい


[0]00_tst.yaml

00_tst.yaml

1--- 2- name: file change 3 hosts: all 4 become: no 5 vars: 6 yyyymmdd: "{{ lookup('pipe','date +%Y%m%d%H%M') }}" 7 roles: 8 - 00_hosts_change

[1]group_vars/server01/vars.main

group_vars/server01/vars.main

1RHEL: 2 hosts: 3 - "1.1.1.1 server01:::〇" 4 - "2.1.1.1 server02:::×" 5 6 tstfile: 7 - "usagi:::〇" 8 - "kappa:::〇"

[2]roles/00_hosts_change/tasks/update_file_choice.yaml

roles/00_hosts_change/tasks/update_file_choice.yaml

1--- 2#------------------------------------------------------------------------------# 3# 値の「〇」がついている値のみ、抜き出して作成。セパレータは「:::」 4#------------------------------------------------------------------------------# 5- name: generate myhost vars file 6 template: 7 src: template/vars.j2 8 dest: "/var/tmp/vars.j2" 9 delegate_to: localhost 10 11#------------------------------------------------------------------------------# 12# yaml再読み込みして変数上書き 13#------------------------------------------------------------------------------# 14- name: include myhost vars file 15 include_vars: "/var/tmp/vars.j2" 16 delegate_to: localhost 17 18#------------------------------------------------------------------------------# 19# ファイル出力 20#------------------------------------------------------------------------------# 21- name: output file 22 template: 23 src: template/file.j2 24 dest: "/var/tmp/hosts"

[3]roles/00_hosts_change/template/vars.j2

roles/00_hosts_change/template/vars.j2

1updateos: 2 {{ j2_vars }}: 3{% for var in j2_vars_list %} 4{% if var.split(':::')[1] == '〇' %} 5 - {{ var.split(':::')[0] }} 6{% endif %} 7{% endfor %}

[4]roles/00_hosts_change/template/file.j2

roles/00_hosts_change/template/file.j2

1{% for var in updateos.hosts %} 2{{ var }} 3{% endfor %}

[5]roles/00_hosts_change/vars/main.yaml

j2_vars: "hosts" j2_vars_list: "{{ RHEL.hosts }}" j2_file_list: "updateos.hosts"

[5]roles/00_hosts_change/tasks/main.yaml

--- - import_tasks: update_file_choice.yaml

##質問内容
[4]roles/00_hosts_change/template/vars.j2のupdateos.hostsを[5]roles/00_hosts_change/vars/main.yamlに定義した変数に変更したいのですが、
方法が分かりません。
j2_file_list内の値(updateos.hosts)の値を変数として使うという風にしたいです。RHELのeval的な感じです。

いい方法は御座いませんでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

comefigo

2020/12/02 14:08

確認ですが、[2]のファイル出力処理のtemplate/file.j2はどのファイルを指しているのでしょうか?
hakoritenshi

2020/12/04 12:29

すみません。以下です。 [4]roles/00_hosts_change/template/vars.j2 ↓ [4]roles/00_hosts_change/template/file.j2
comefigo

2020/12/04 13:19

追加で確認ですが、つまりこんな感じでupdateos.hostsを使わずに {% for var in j2_file_list %} j2_file_listを変数として使えないかということでしょうか? もちろん参照先がupdateos.hostsであること。
hakoritenshi

2020/12/05 12:57

あっております。 ・現状 [4]roles/00_hosts_change/template/file.j2 {% for var in updateos.hosts %} {{ var }} {% endfor %} ↓ ・改変後 [4]roles/00_hosts_change/template/file.j2 {% for var in j2_file_list %} {{ var }} {% endfor %} あっております。 こうやりたい理由は、 varsだけを編集することによって、 各OSファイルを編集できるようにするための テンプレート的なものを作りたいと思っているためです。 現行だと、 [4]roles/00_hosts_change/template/file.j2 も修正しないといけない仕様になっていまして、 いい方法がないかなと悩んでいます。
guest

回答1

0

ベストアンサー

updateos.hostsのhosts配下は可変であるから動的(vars/main.ymlのj2_varsの値に応じて)に呼び出したいということでしょうか?

であれば、以下のような感じでいかがでしょうか?

updateos.hostsのような指定方法は子要素のキーを明示的に指定しなければならない。
updateos['hosts']も同様。
updateos[j2_vars]のように子要素のキーを変数として指定することで動的に指定することができます。
ただし、updateos.j2_varsだと子要素のキーがj2_varsとして解釈されエラーになります。

yaml

1# roles/00_hosts_change/vars/main.yaml 2 3j2_vars: "hosts" 4j2_vars_list: "{{ RHEL.hosts }}" 5j2_file_list: "{{ updateos[j2_vars] }}"

j2_file_listにはリストを代入しているので、そのままループ

yaml

1# roles/00_hosts_change/templates/file.j2 2 3{% for var in j2_file_list %} 4{{ var }} 5{% endfor %}

投稿2020/12/04 13:28

comefigo

総合スコア1051

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hakoritenshi

2020/12/05 13:02 編集

以下は試してみたのですが、 roles/00_hosts_change/vars/main.yaml を読み込む時点では、 "{{ updateos[j2_vars] }}"が作られていないため、 エラーになってしまいます。 ※[2]roles/00_hosts_change/tasks/update_file_choice.yamlで読み込まれる変数のため ```yaml # roles/00_hosts_change/vars/main.yaml j2_vars: "hosts" j2_vars_list: "{{ RHEL.hosts }}" j2_file_list: "{{ updateos[j2_vars] }}" ```
comefigo

2020/12/05 13:35 編集

私の環境では普通に動作しますね。 playbookで00_hosts_changeをなにで読み込んでいますか? - include_role:   name: ../roles/00_hosts_change include_roleで読み込むことで実行時に変数の有無を判定してくれるようになります。
hakoritenshi

2020/12/05 16:44

# ansible-playbook -i inventories/inventory.ini 00_tst.yaml -l server01 でplaybookから呼び出した感じです。 エラーは以下になります。 TASK [00_hosts_change : output file] ******************************************* fatal: [server01]: FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'updateos' is undefined"}
hakoritenshi

2020/12/05 16:53

[2]roles/00_hosts_change/tasks/update_file_choice.yamlの呼び出しは、[5]roles/00_hosts_change/tasks/main.yamlからimport_taskで呼び出した感じです。
comefigo

2020/12/06 02:50

試してないですが、import_taskをinclude_taskに変えて実行されてはいかがでしょうか?
hakoritenshi

2020/12/06 04:30

実行できました! ありがとうざいます!
comefigo

2020/12/06 05:50

無事解決できてよかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問