はじめに
<バージョン>
ansible 2.9.1
以下のPlaybook内のように、test_strという変数の中にある123という数値を
取り出して加算(7を足す)しようと思ったのですが上手くいきませんでした。
(123 + 7 = 130 という計算をしようとしています)
---
- name: int TEST
hosts: localhost
gather_facts: no
vars:
ansible_python_interpreter: /usr/bin/python3
test_str: "aaa 123 bbb"
tasks:
- name: fact
set_fact:
get_number: "{{ test_str.split()[1] | int }}"
- name: debug
debug:
msg: "get_number : {{ get_number + 7 }}"
実行結果1(失敗)
intというfilterを用いて、123という文字列を値に変換しているはずなのに
正しく認識されていないようです
PLAY [int TEST] *****************************************************************************************************************************************************************************
TASK [fact] *********************************************************************************************************************************************************************************
ok: [localhost]
TASK [debug] ********************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "Unexpected templating type error occurred on (get_number : {{ get_number + 7 }}): coercing to Unicode: need string or buffer, int found"}
PLAY RECAP **********************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
原因究明用Playbook
以下、3パターンの方法を調べます。データ型はtype_debugを用いて確認します。
パターン1(結果はdebug1) ←失敗例のパターン
set_factで123という文字列を値に変換する
パターン2a(結果はdebug2a)
set_factでは123という文字列の取り出しのみ行う→他の変数(ここではget_number2a)
に代入するときに値に変換する
パターン2b(結果はdebug2b)
set_factでは123という文字列の取り出しのみ行う→他の変数には代入せずに
値に変換する
---
- name: int TEST
hosts: localhost
gather_facts: no
vars:
ansible_python_interpreter: /usr/bin/python3
test_str: "aaa 123 bbb"
tasks:
- name: fact1
set_fact:
get_number1: "{{ test_str.split()[1] | int }}"
- name: debug1
debug:
msg: "get_number1 : {{ get_number1 }} is {{ get_number1 | type_debug }}"
- name: fact2
set_fact:
get_number2: "{{ test_str.split()[1] }}"
- name: debug2a
debug:
msg: "get_number2a : {{ get_number2a }} is {{ get_number2a | type_debug }}"
vars:
get_number2a: "{{ get_number2 | int }}"
- name: debug2b
debug:
msg: "get_number2b : {{ get_number2 }} is {{ get_number2 | int | type_debug }}"
実行結果2
パターン2bの場合でのみ、正しく値に変換されました。
intというフィルタも万能ではないようです。
PLAY [int TEST] *****************************************************************************************************************************************************************************
TASK [fact1] ********************************************************************************************************************************************************************************
ok: [localhost]
TASK [debug1] *******************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "get_number1 : 123 is unicode"
}
TASK [fact2] ********************************************************************************************************************************************************************************
ok: [localhost]
TASK [debug2a] ******************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "get_number2a : 123 is unicode"
}
TASK [debug2b] ******************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "get_number2b : 123 is int" #正しく整数型(int)に変換されている
}
PLAY RECAP **********************************************************************************************************************************************************************************
localhost : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
修正後Playbook
以上のことから、set_factや変数への代入時にintを使っても値に変換されない
ことがわかったので、これをもとにPlaybookを修正しました。
---
- name: int TEST
hosts: localhost
gather_facts: no
vars:
ansible_python_interpreter: /usr/bin/python3
test_str: "aaa 123 bbb"
tasks:
- name: fact
set_fact:
get_number: "{{ test_str.split()[1] }}"
- name: debug
debug:
msg: "get_number : {{ get_number | int + 7 }}"
実行結果3
想定通り、123 + 7 = 130 という計算を行うことが出来ました。
PLAY [int TEST] *****************************************************************************************************************************************************************************
TASK [fact] *********************************************************************************************************************************************************************************
ok: [localhost]
TASK [debug] ********************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "get_number : 130"
}
PLAY RECAP **********************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0