質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.31%
Ansible

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

Q&A

解決済

1回答

1975閲覧

Ansible リスト型の変数の要素数だけループしてselectのチェックをしたい

khaii21

総合スコア67

Ansible

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

0グッド

0クリップ

投稿2023/08/16 02:52

編集2023/08/17 05:46

実現したいこと

commandモジュールにて実行した結果から、任意の文字列(fatal error)を検知したいです。
11行目にてチェックを行いfatal errerとなった場合の処理をしたいです。
該当の変数(hoge_cmd.results)の要素数は今回のケースでは2つですが、1つの場合もあれば10のケースも見込めます。
11行目のselectのチェックを要素数だけloopして実行し、結果を出力したいのですが良いやり方が思いつきません。
リスト型の変数に対して要素数が分かれば実現可能だと考えているのですが、要素数の確認の仕方が分かりません。

下記を利用すれば実現可能だと考えているすが、変数hoge_cmd.resultsの要素数の取得の仕方が分かりません。

when: ( hoge_cmd.results[ {{ item }}]['stdout_lines'] ) | select("regex", "fatal error") | list | length >= 1 with_sequence: start=0 end=要素数

どなたか良い方法をご存知の方がいらっしゃいましたら、ご教授頂けないでしょうか。
宜しくお願い致します。

registerにて実行結果を変数(hoge_cmd)に代入して、selectを使って文字列をカウントします。
変数hoge_cmdはdict型ですが、標準出力結果が含まれているその配下のhoge_cmd.resultsはlist型になります。

msg: "{{ hoge_cmd | ansible.builtin.type_debug }}" "msg": "dict" msg: "{{ hoge_cmd.results | ansible.builtin.type_debug }}" "msg": "list" msg "{{ hoge_cmd.results.stdout_lines | type_debug }}" "msg": "AnsibleUndefined”

hoge_cmd.results抜粋"

1ok: [localhost] => { 2 "msg": [ 3      ・ 4      ・ 5 "item": "hoge001.co.jp", 6      ・ 7      ・ 8 "stdout_lines": [ 9 "OK" 10 ] 11 }, 12      ・ 13      ・ 14 "item": "hoge002.co.jp", 15      ・ 16      ・ 17 "stdout_lines": [ 18 "fatal error"
msg: "{{ hoge_cmd.results[0]['stdout_lines'] }}" ok: [localhost] => { "msg": [ "hoge001.co.jp" "OK" ] msg: "{{ hoge_cmd.results[1]['stdout_lines'] }}" "msg": [ "hoge002.co.jp" "fatal error" ] }

該当のソースコード

playbook.yml

1 tasks: 2 - name: "hogeコマンドの実行" 3 ansible.builtin.command: hoge_command "{{ item }}" 4 with_items: 5 - "{{ server_group }}" 6 register: hoge_cmd 7 changed_when: true 8 - name: "hogeコマンドの実行結果" 9 ansible.builtin.debug: 10 msg: "1台もしくは複数台のホストでコマンドが失敗した可能性があります" 11 when: ( hoge_cmd.results[要素数だけループ]['stdout_lines'] ) | select("regex", "fatal error") | list | length >= 1 12 - name: "hogeコマンドの実行結果" 13 ansible.builtin.debug: 14 msg: "{{ hoge_cmd.results }}" 15 - name: "hogeコマンドの実行結果 標準出力" 16 ansible.builtin.debug: 17 msg: "{{ hoge_cmd.results[0]['stdout_lines'] }}"

試したこと

今回のケースでは予め要素数が2つだとわかっていますので下記でselectによるチェックは出来ましたが、
endにあたる要素数の取得の仕方が分かりません。

when: ( hoge_cmd.results[{{ item }}]['stdout_lines'] ) | select("regex", "fatal error") | list | length >= 1 with_sequence: start=0 end=1

標準出力にあたるstdout_linesを下記のようにした場合、template error となりました。

ansible.builtin.debug: msg: "{{ hoge_cmd.results[{{ item }}]['stdout_lines'] }}" with_sequence: start=0 end=1
エラー内容 "template error while templating string: expected token ':', got '

from_jsonフィルターを試してみたのですが、エラーになりました。

msg: "{{ (hoge_cmd.results | ansible.builtin.from_json).stdout_lines }}"
エラー内容 {"msg": "Unexpected templating type error occurred on ({{ (hoge_cmd.results | ansible.builtin.from_json).stdout_lines }}): the JSON object must be str, bytes or bytearray, not list. the JSON object must be str, bytes or bytearray, not list"}

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

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

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

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

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

guest

回答1

0

ベストアンサー

command モジュールのタスクのループの数に関わらず、
以下のような形で実現できそうですがいかがでしょうか。

yaml

1 - name: "hogeコマンドの実行結果" 2 ansible.builtin.debug: 3 msg: "1台もしくは複数台のホストでコマンドが失敗した可能性があります" 4 when: hoge_cmd.results | selectattr('stdout_lines', 'regex', 'fatal error')

投稿2023/08/16 13:13

yabusakadeny

総合スコア186

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

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

khaii21

2023/08/17 05:48 編集

ご確認ありがとうございます。 ご教授頂きました方法で期待した結果が取れました。 ありがとうございます。 もしお分かりでしたら教えて頂けないでしょうか。 下記タスクのtemplate errorが解消できないのですが、 何かお気づきの事がありましたらご指摘頂けますと幸いです。 ``` ansible.builtin.debug: msg: "{{ hoge_cmd.results[{{ item }}]['stdout_lines'] }}" with_sequence: start=0 end=1 ``` 単純に下記にて値を取得できれば期待した結果が取れるのですが エラーになってしまいます。 ``` msg: "{{ hoge_cmd.results.stdout_lines }}" ``` ``` エラー内容 The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'stdout_lines' ``` from_jsonフィルターを試してみたのですが、エラーになりました。 ``` msg: "{{ (hoge_cmd.results | ansible.builtin.from_json).stdout_lines }}" ``` ``` エラー内容 {"msg": "Unexpected templating type error occurred on ({{ (hoge_cmd.results | ansible.builtin.from_json).stdout_lines }}): the JSON object must be str, bytes or bytearray, not list. the JSON object must be str, bytes or bytearray, not list"} ```
yabusakadeny

2023/08/17 09:27

ご提示いただいた方法 (with_sequence) をベースにした場合、以下の書き方でいかがでしょうか。 内側の {{ }} が不要なので取り除いています。 ``` - name: debug ansible.builtin.debug: msg: "{{ hoge_cmd.results[item | int]['stdout_lines'] }}" with_sequence: start=0 end=1 ``` もし、ループ回数を可変にしたい場合は、以下のような書き方もで欲しい出力は得られると思います。 ``` - name: debug ansible.builtin.debug: msg: "{{ item.stdout_lines }}" loop: "{{ hoge_cmd.results }}" ```
khaii21

2023/08/17 12:19 編集

ご確認ありがとうございます。 ご教授頂いた2つのやり方で期待した結果が取得出来ることが確認出来ました。 大変助かりました。 色々伺ってばかりで申し訳ございません。最後にもう一つだけお伺いさせて下さい。 今回のケースでは {{ hoge_cmd.results }} の要素数は2つですが、 Ansibleで要素数を調べる方法がありましたらご教授頂けないでしょうか。 意図としましては今後のスキルアップのために何かしらの方法で要素数を取得して 下記の end=1 について事前に要素数を取得した変数(element_count)に代入して、 下記のように設定したいです。 そもそも実現可能なのか分かっておらず申し訳ございません。 やり方をご存知でしたらご教授頂けますと幸いです。 ``` with_sequence: start=0 end=1 ↓ with_sequence: start=0 end="{{ element_count }}" ```
yabusakadeny

2023/08/17 13:03

リストの要素数を知る場合は、`hoge_cmd.results | length` のようにすると取得できます。
khaii21

2023/08/17 13:54

色々とご確認ありがとうございました。 先程ご教授頂いた内容は現在検証しておりまして、 想定した結果にならないので色々と調べています。 こちらは本件の質問とは違いますので 一旦クローズさせて頂きます。 本当に助かりました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

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

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

質問する

関連した質問