LoginSignup
5
2

More than 1 year has passed since last update.

<Ansible>「win_command」モジュールで文字化けしたときの対処方法

Posted at

はじめに

以前、Ansibleのwin_commandモジュールでコマンドを実行した際、出力結果が文字化けしてしまうということがありました。
その際にansible 2.10.xwin_commandモジュール(ansible.windows.win_command)のoutput_encoding_overrideを使用したことで、文字化けが解決しました。
この記事では、Ansibleのwin_command(ansible.windows.win_command)モジュールのoutput_encoding_overrideの使い方について説明します。
※公式ドキュメントはこちらから確認できます

パラメータ(アーギュメント)

output_encoding_overrideの前に、win_command(ansible.windows.win_command)のパラメータについて簡単に説明します。
使うことは少ないかもしれませんが、win_command(ansible.windows.win_command)にもパラメータは存在します。

パラメータ 選択肢:デフォルト 機能
chdir コマンド実行前に移動するディレクトリのパスを指定する。
creates 作成するファイルのパスを指定する。
指定したファイルが既に存在する場合、この処理は実行されない。
free_form 実際に、この名のパラメータがあるわけではない。
コマンドを指定することが必須となる。
output_encoding_override この記事で扱うパラメータ。
2.9以前のバージョンには存在しない。
[System.Text.Encoding]::GetEncodings()の出力に基づく有効な文字コードを指定する(Encoding.GetEncodings Method)。
これにより、エンコーディングされた出力結果を書き換える。
removes 削除するファイルのパスを指定する。
指定したファイルが存在しない場合、この処理は実行されない。
stdin コマンドの引数を指定する。
標準入力 (stdin) で引数を渡す理由

動作環境

以下の環境で動作を確認しました。
・コントロールノード:RHEL 8.3
・ターゲットノード:Windows Server 2019
どちらもAWSのAmazon EC2を使用しています。

Ansibleのバージョンは2.10.3です。

$ ansible --version
ansible 2.10.3
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /root/.pyenv/versions/3.9.0/lib/python3.9/site-packages/ansible
  executable location = /root/.pyenv/versions/3.9.0/bin/ansible
  python version = 3.9.0 (default, Dec  3 2020, 08:36:30) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]

output_encoding_overrideの使い方

文字化けしたときの状態

文字化けした際、下記のPlaybookを使用していました。
ターゲットノードであるWindows Serverでコマンドw32tm /query /statusを実行させて、コントロールノードであるRHELに結果を表示するという処理内容になっています。

---
- name: '文字化け'
  hosts: windows
  gather_facts: no
  tasks:
  - name: 'コマンド実行'
    ansible.windows.win_command: w32tm /query /status
    register: qiita

  - name: '結果表示'
    debug:
      msg: "{{ qiita }}"
...

実行すると、次のような結果が表示されます。

# ansible-playbook test.yml

PLAY [文字化け] ********************************************************************

TASK [コマンド実行] ******************************************************************
changed: [10.10.10.10]

TASK [結果表示] ********************************************************************
ok: [10.10.10.10] => {
    "msg": {
        "changed": true,
        "cmd": "w32tm /query /status",
        "delta": "0:00:00.078167",
        "end": "2021-08-03 12:12:25.005529",
        "failed": false,
        "rc": 0,
        "start": "2021-08-03 12:12:24.927362",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "?[?C???W?P?[?^?[: 0 (?x?????)\n?K?w: 4 (???駱?? - (S)NTP ?????)\n???x: -23 (?e?B?b?N????? 119.209ns)\n???[?g?x??: 0.0006471s\n???[?g???U: 7.7908155s\n?Q?? ID: 0xA9FEA97B (?\\?[?X IP:  123.45.67.89)\n??I??????????: 2021/08/03 0:06:57\n?\\?[?X: 123.45.67.89,0x9 \n?|?[?????O??u: 9 (512s)\n\n",
        "stdout_lines": [
            "?[?C???W?P?[?^?[: 0 (?x?????)",
            "?K?w: 4 (???駱?? - (S)NTP ?????)",
            "???x: -23 (?e?B?b?N????? 119.209ns)",
            "???[?g?x??: 0.0006471s",
            "???[?g???U: 7.7908155s",
            "?Q?? ID: xxxxxxxxxx (?\\?[?X IP:  123.45.67.89)",
            "??I??????????: 2021/08/03 0:06:57",
            "?\\?[?X: 123.45.67.89,0x9 ",
            "?|?[?????O??u: 9 (512s)",
            ""
        ]
    }
}

PLAY RECAP *********************************************************************
10.10.10.10                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

結果が文字化けして表示されています。
こちらにも記載があるのですが、Unicode 以外のエンコーディングの多くは不完全で、多くの文字が "?" に変換されるそうです。

文字化けしない状態

文字化けしないように表示するには、下記のように、output_encoding_overrideで文字コードを指定します。
今回はshift_jisを使用しています。

---
- name: '綺麗に出力'
  hosts: windows
  gather_facts: no
  tasks:
  - name: 'コマンド実行'
    ansible.windows.win_command: w32tm /query /status
    args:
      output_encoding_override: shift_jis
    register: qiita

  - name: '結果表示'
    debug:
      msg: "{{ qiita }}"
...

実行します。

# ansible-playbook test.yml

PLAY [綺麗に出力] ********************************************************************

TASK [コマンド実行] ******************************************************************
changed: [10.10.10.10]

TASK [結果表示] ********************************************************************
ok: [10.10.10.10] => {
    "msg": {
        "changed": true,
        "cmd": "w32tm /query /status",
        "delta": "0:00:00.078159",
        "end": "2021-08-03 12:16:22.825437",
        "failed": false,
        "rc": 0,
        "start": "2021-08-03 12:16:22.747277",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "閏インジケーター: 0 (警告なし)\n階層: 4 (二次参照 - (S)NTP で同期)\n精度: -23 (ティックごとに 119.209ns)\nルート遅延: 0.0006471s\nルート分散: 7.7908155s\n参照 ID: 0xA9FEA97B (ソース IP:  123.45.67.89)\n最終正常同期時刻: 2021/08/03 0:15:29\nソース: 123.45.67.89,0x9 \nポーリング間隔: 9 (512s)\n\n",
        "stdout_lines": [
            "閏インジケーター: 0 (警告なし)",
            "階層: 4 (二次参照 - (S)NTP で同期)",
            "精度: -23 (ティックごとに 119.209ns)",
            "ルート遅延: 0.0006471s",
            "ルート分散: 7.7908155s",
            "参照 ID: xxxxxxxxxx (ソース IP:  123.45.67.89)",
            "最終正常同期時刻: 2021/08/03 0:15:29",
            "ソース: 123.45.67.89,0x9 ",
            "ポーリング間隔: 9 (512s)",
            ""
        ]
    }
}

PLAY RECAP *********************************************************************
10.10.10.10                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

文字化けせず、正常に出力されています。
余談ですが、以下のようにすることで、必要な情報のみ表示することもできます。

---
- name: '綺麗に出力'
  hosts: windows
  gather_facts: no
  tasks:
  - name: 'コマンド実行'
    ansible.windows.win_command: w32tm /query /status
    args:
      output_encoding_override: shift_jis
    register: qiita

  - name: '結果表示(最終正常同期時刻)'
    debug:
      msg: "{{ qiita.stdout_lines | select('match', '最終*') | list }}"
...
# ansible-playbook test.yml

PLAY [綺麗に出力] ********************************************************************

TASK [コマンド実行] ******************************************************************
changed: [10.10.10.10]

TASK [結果表示(最終正常同期時刻)] ********************************************************************
ok: [10.10.10.10] => {
    "msg": [
        "最終正常同期時刻: 2021/08/03 0:15:29"
    ]
}

PLAY RECAP *********************************************************************
10.10.10.10                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

あとがき

バージョンが上がることで便利な機能が追加されるのはありがたいです。
今後も便利なものがあれば調べてまとめていきたいです。

5
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
5
2