Ansible Shell モジュール

AnsibleBeginner
オンラインで実践に進む

はじめに

この実験では、Ansible の Shell モジュールを使用してリモートホストでシェルコマンドを実行する方法を学びます。既存の Ansible モジュールでカバーされていないシェルコマンドを実行する場合や、実行に対してより柔軟性と制御を必要とする場合に、Shell モジュールは便利です。

単純なシェルコマンドの実行

このステップでは、Ansible の Shell モジュールを使用してリモートホストで単純なシェルコマンドを実行します。

まず、/home/labex/project/simple_shell_command.yml ファイルを完成させます。
以下の内容をプレイブックファイルに追加します。

- name: Execute a Simple Shell Command
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Execute ls -l command
      shell: ls -l
      register: command_output

    - name: Display command output
      debug:
        var: command_output.stdout_lines
  • hosts: localhost: この Ansible プレイブックを実行するターゲットホストは localhost です。
  • gather_facts: false: ホスト情報の収集を無効にします。
  • shell: ls -l: 実行するコマンドを指定します。

要するに、このプレイブックの目的は、ローカルホストで ls -l コマンドを実行し、そのコマンドの出力を表示することです。

次に、Ansible プレイブック内のコマンドの出力を表示します。

ansible-playbook /home/labex/project/simple_shell_command.yml

出力例:

[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

PLAY [Execute a Simple Shell Command] ******************************************

TASK [Execute ls -l command] ***************************************************
changed: [localhost]

TASK [Display command output] **************************************************
ok: [localhost] => {
    "command_output.stdout_lines": [
        "total 16",
        "-rwxrwxrwx 1 labex root 285 Mar  8 13:33 complex_shell_commands.yml",
        "-rwxrwxrwx 1 labex root 221 Mar  8 13:33 handle_command_failure.yml",
        "-rwxrwxrwx 1 labex root 222 Mar  8 13:33 pass_variables.yml",
        "-rwxrwxrwx 1 labex root 266 Mar  8 13:36 simple_shell_command.yml"
    ]
}

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

ここで "command_output.stdout_lines":[...] は、ターゲットホストでの ls -l の出力です。

シェルコマンドに変数を渡す

このステップでは、Ansible プレイブックからの変数を Shell モジュールを使って実行するシェルコマンドに渡す方法を学びます。

まず、/home/labex/project/pass_variables.yml ファイルを完成させます。
以下の内容をプレイブックファイルに追加します。

- name: Pass Variables to Shell Commands
  hosts: localhost
  gather_facts: false
  vars:
    directory_path: /home/labex

  tasks:
    - name: Execute ls command with a variable
      shell: ls "{{ directory_path }}"
      register: variable_command_output

    - name: Display variable command output
      debug:
        var: variable_command_output.stdout_lines
  • hosts: localhost: この Ansible プレイブックを実行するターゲットホストは localhost です。
  • vars: directory_path という名前の変数を定義し、その値を /home/labex とします。
  • shell: ls "{{ directory_path }}": ls コマンドを実行して、directory_path という名前の変数が表すディレクトリの内容を出力します。

要するに、このプレイブックは、ローカルホストでディレクトリパス(/home/labex)を表す変数を使って ls コマンドを実行し、そのコマンドの出力を表示します。

次に、Ansible プレイブック内のコマンドの出力を表示します。

ansible-playbook /home/labex/project/pass_variables.yml

出力例:

[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

PLAY [Pass Variables to Shell Commands] ****************************************

TASK [Execute ls command with a variable] **************************************
changed: [localhost]

TASK [Display variable command output] *****************************************
ok: [localhost] => {
    "variable_command_output.stdout_lines": [
        "Code",
        "Desktop",
        "golang",
        "project"
    ]
}

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

ここで "variable_command_output.stdout_lines": [...] は、ターゲットホストでの ls /home/labex の出力です。

コマンドの失敗を処理する

このステップでは、Shell モジュールを使用してシェルコマンドを実行する際に、コマンドの失敗をどのように処理するかを学びます。シェルコマンドが非ゼロの終了ステータスを返し、失敗を示すケースを処理します。

まず、/home/labex/project/handle_command_failure.yml ファイルを完成させます。
以下の内容をプレイブックファイルに追加します。

- name: Handle Command Failure
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Execute a failing command
      shell: failing-command
      register: failing_command_output
      ignore_errors: yes

    - name: Handle command failure
      debug:
        msg: "The command failed. Performing fallback action."
      when: failing_command_output.failed
  • hosts: localhost: この Ansible プレイブックを実行するターゲットホストは localhost です。
  • shell: failing-command: この行では、shell モジュールを使用して failing-command コマンドを実行します。このコマンドの出力はキャプチャされ、failing_command_output 変数に格納されます。failing-command スクリプトは存在しないため、このコマンドは必ず失敗します。
  • ignore_errors: yes: この行は、Ansible に failing-command の実行中に発生するエラーを無視するよう指示します。これにより、コマンドが失敗してもプレイブックの実行を続けることができます。
  • debug: このモジュールは、debug モジュールを使用して「The command failed. Performing fallback action.」というメッセージを表示します。このメッセージは、failing_command_output.failed 条件が満たされた場合、つまり前のコマンドの実行が失敗した場合にのみ表示されます。

要するに、このプレイブックは失敗すると予想されるコマンドを実行し、実行中に発生するエラーを無視し、コマンドの失敗ステータスに基づいてコマンドが失敗したこととフォールバックアクションが実行されることを示すメッセージを表示します。

次に、Ansible プレイブック内のコマンドの出力を表示します。

ansible-playbook /home/labex/project/handle_command_failure.yml

出力例:

[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

PLAY [Handle Command Failure] **************************************************

TASK [Execute a failing command] ***********************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "failing-command", "delta": "0:00:00.009169", "end": "2024-03-08 13:46:22.701946", "msg": "non-zero return code", "rc": 127, "start": "2024-03-08 13:46:22.692777", "stderr": "/bin/sh: line 1: failing-command: command not found", "stderr_lines": ["/bin/sh: line 1: failing-command: command not found"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [Handle command failure] **************************************************
ok: [localhost] => {
    "msg": "The command failed. Performing fallback action."
}

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

"msg": "The command failed. Performing fallback action." が表示されていることは、この failing-command コマンドの実行が失敗したことを示しています。

複雑なシェルコマンドの実行

このステップでは、Shell モジュールを使用してより複雑なシェルコマンドを実行します。コマンドのリダイレクト、パイプライン、および複雑なコマンド構造の使い方を探ります。

まず、/home/labex/project/complex_shell_commands.yml ファイルを完成させます。
以下の内容をプレイブックファイルに追加します。

- name: Execute Complex Shell Commands
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Execute complex command
      shell: ls -l /home/labex | grep 'project' > /home/labex/output.txt
      register: complex_command_output

    - name: Display complex command output
      debug:
        var: complex_command_output.stdout_lines
  • hosts: localhost: この Ansible プレイブックを実行するターゲットホストは localhost です。
  • shell: ls -l /home/labex の出力を /home/labex/output.txt ファイルにリダイレクトし、grep を使用して project に関する内容をフィルタリングします。

要するに、このプレイブックはローカルホストで複雑なシェルコマンドを実行し、出力をフィルタリングしてファイルにリダイレクトし、その後コマンド実行の出力を表示します。

次に、Ansible プレイブックコマンドを実行します。

ansible-playbook /home/labex/project/complex_shell_commands.yml

出力例:

[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'

PLAY [Execute Complex Shell Commands] ******************************************

TASK [Execute complex command] *************************************************
changed: [localhost]

TASK [Display complex command output] ******************************************
ok: [localhost] => {
    "complex_command_output.stdout_lines": []
}

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

最後に、/home/labex/output.txt ファイルの内容を表示します。

cat /home/labex/output.txt

出力例:

drwxr-xr-x 1 labex labex 4096 Mar 8 13:49 project

まとめ

おめでとうございます!Ansible Shell モジュールの実験を無事に完了しました。Shell モジュールを使ってリモートホストでシェルコマンドを実行し、コマンドに変数を渡し、コマンドの失敗を処理し、複雑なシェルコマンドを実行する方法を学びました。

Shell モジュールは、Ansible プレイブックでシェルコマンドを実行する際に大きな柔軟性と制御性を提供します。ただし、任意のシェルコマンドを実行するとセキュリティ上の問題が生じる可能性があるため、使用する際は注意が必要です。常にコマンドを信頼できることを確認し、ユーザーから提供された入力を適切にサニタイズしてください。

これで Shell モジュールについて十分に理解できたので、さまざまな自動化タスクを実行し、リモートホストを効率的に管理するために活用することができます。Ansible スクリプト作成を楽しんでください!