4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Ansible】文字列から取り出した数値のデータ型が文字列になっている場合の解決策

Last updated at Posted at 2020-03-07

はじめに

<バージョン>
ansible 2.9.1

以下のPlaybook内のように、test_strという変数の中にある123という数値を
取り出して加算(7を足す)しようと思ったのですが上手くいきませんでした。
(123 + 7 = 130 という計算をしようとしています)

int_test1.yml
---
- 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という文字列を値に変換しているはずなのに
正しく認識されていないようです

出力1
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という文字列の取り出しのみ行う→他の変数には代入せずに
 値に変換する

int_test2.yml
---
- 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というフィルタも万能ではないようです。

出力2
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を修正しました。

int_test3.yml
---
- 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 という計算を行うことが出来ました。

出力3
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
4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?