はじめに
このラボでは、Red Hat Enterprise Linux 上で Ansible を使用する際に遭遇する一般的な問題のトラブルシューティング方法を学びます。初期環境設定から、一般的なプレイブックのエラー、管理対象ホストの接続問題まで、さまざまな問題の特定と解決に関する実践的な経験を積むことができます。演習では、YAML の構文修正、Jinja2 テンプレートの誤りの修正、リモート システムでの問題診断を行います。
まず、RHEL 環境を準備し、効果的なロギングのために Ansible を設定します。次に、ハンズオンのトラブルシューティング シナリオに進み、Ansible のチェックモードを使用してサービス関連の問題を診断し、ファイアウォール設定を修正してホストの到達不能性を解決します。このラボの終わりまでに、堅牢な Ansible 自動化ワークフローを維持するための包括的なスキルセットを習得しているでしょう。
RHEL 環境の準備と Ansible ロギングの設定
このステップでは、Red Hat Enterprise Linux 環境を Ansible 自動化のために準備します。これには、必要なソフトウェアのインストール、専用プロジェクト ディレクトリの作成、Ansible の動作を制御しロギングを有効にするための基本的な設定ファイルのセットアップが含まれます。適切なセットアップは、効果的な自動化とトラブルシューティングの最初のステップです。
Ansible のインストール
まず、Ansible をインストールする必要があります。コアとなる自動化エンジンは
ansible-coreパッケージによって提供されます。sudoを使用してdnfパッケージマネージャーでインストールします。-yフラグは、確認プロンプトに自動的に「yes」と応答します。sudo dnf install -y ansible-coreパッケージとその依存関係がインストールされていることを示す出力が表示されるはずです。
Last metadata expiration check: ... Dependencies resolved. ================================================================================ Package Architecture Version Repository Size ================================================================================ Installing: ansible-core x86_64 <version> <repo> 2.8 M ... Transaction Summary ================================================================================ Install XX Packages Total download size: XX M Installed size: XX M ... Complete!プロジェクト ディレクトリの作成
Ansible プロジェクトを専用ディレクトリに整理することは、ベストプラクティスです。これにより、プレイブック、インベントリ、設定ファイルがきちんと分離されます。ホーム プロジェクト フォルダ内に
ansible_troubleshootingという名前のディレクトリを作成し、そこに移動しましょう。mkdir -p ~/project/ansible_troubleshooting cd ~/project/ansible_troubleshootingこれ以降、このラボのすべてのコマンドは
~/project/ansible_troubleshootingディレクトリ内で実行されます。Ansible インベントリ ファイルの作成
インベントリは、Ansible が管理するホスト(またはノード)をリストするファイルです。単一の LabEx VM で作業しているため、Ansible がローカルマシン自体を管理するように設定します。
inventoryという名前のファイルを作成し、localhostを追加します。ansible_connection=localの部分は、Ansible に SSH を使用せずにコントロール ノード(お使いの VM)で直接コマンドを実行するように指示します。echo "localhost ansible_connection=local" > inventorycatコマンドを使用してファイルの内容を確認できます。cat inventory期待される出力:
localhost ansible_connection=localAnsible ロギングの設定
ansible.cfgファイルを使用すると、特定のプロジェクトの Ansible の動作をカスタマイズできます。プロジェクト ディレクトリに配置すると、その設定はシステム全体のデフォルトを上書きします。ここでは、このファイルを作成して、インベントリの場所を指定し、ロギングを有効にします。ロギングは、すべてのプレイブック実行に関する詳細情報を記録するため、トラブルシューティングに不可欠です。nanoエディターを使用してansible.cfgファイルを作成します。nano ansible.cfg次に、以下の内容を
nanoエディタにコピーして貼り付けます。この設定は、Ansible に現在のディレクトリのinventoryファイルを使用するように指示し、すべてのログ出力をansible.logという名前のファイルに書き込むように指示します。[defaults] inventory = /home/labex/project/ansible_troubleshooting/inventory log_path = /home/labex/project/ansible_troubleshooting/ansible.lognanoでファイルを保存するには、Ctrl+Xを押し、確認のためにYを押し、最後にファイルを書き込むためにEnterを押します。これで環境の準備が整いました。Ansible がインストールされ、ローカルインベントリとロギングが有効になったプロジェクト ディレクトリが設定され、次のステップに進む準備ができました。
プレイブックの YAML 構文とインデント エラーの修正
このステップでは、Ansible プレイブックで最も一般的な 2 つのエラー タイプ、YAML 構文エラーとインデントの誤りを診断および修正する方法を学びます。プレイブックの記述に使用される言語である YAML は、その構造に関して非常に厳格です。1 つのスペースのずれや、引用符で囲まれていない特殊文字でさえ、プレイブックの実行を妨げる可能性があります。実行前にプレイブックを検証するための不可欠なツールである ansible-playbook --syntax-check コマンドを使用します。
意図的にエラーを含むプレイブックの作成
まず、プロジェクト ディレクトリ (
~/project/ansible_troubleshooting) にwebserver.ymlという名前の新しいプレイブック ファイルを作成します。このファイルには、修正する意図的なエラーが含まれています。nanoを使用してファイルを作成します。nano webserver.yml以下の内容をエディタにコピーして貼り付けます。ここでは 2 つの意図的なエラーに注意してください。コロンを含む引用符で囲まれていない文字列と、2 番目のタスクのインデントが正しくありません。
--- - name: Configure Web Server hosts: localhost vars: ## ERROR 1: Unquoted colon in string package_comment: This is a package: httpd tasks: - name: Install httpd package ansible.builtin.dnf: name: httpd state: present ## ERROR 2: Incorrect indentation - name: Create a test index page ansible.builtin.copy: content: "<h1>Welcome to Ansible</h1>" dest: /var/www/html/index.htmlnanoでファイルを保存して終了するには、Ctrl+X、Y、Enterの順に押します。YAML 構文エラー(引用符で囲まれていないコロン)の特定と修正
次に、作成したばかりのプレイブックで構文チェックを実行します。このコマンドはファイルを解析し、タスクを実際に実行せずに構文の問題を報告します。
ansible-playbook --syntax-check webserver.yml期待される出力(エラー):
package_commentの値にコロン (:) が含まれていますが、引用符で囲まれていないため、エラーが表示されます。YAML はコロンをキーと値の区切り文字として解釈するため、構文エラーが発生します。ERROR! We were unable to read either as JSON nor YAML, these are the errors we found: - Syntax Error while loading YAML. did not find expected ':' The error appears to be in '/home/labex/project/ansible_troubleshooting/webserver.yml': line 6, column 41, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: vars: package_comment: This is a package: httpd ^ here解決策: これを修正するには、文字列を二重引用符で囲む必要があります。再度
nanoでファイルを開きます。nano webserver.ymlコロンを含む文字列に引用符を追加するように、
varsの下の行を変更します。## ... (rest of the file) vars: ## FIX: Add quotes around the string with a colon package_comment: "This is a package: httpd" ## ... (rest of the file)エディタを保存して終了します。
YAML インデント エラーの特定と修正
最初のエラーを修正したら、再度構文チェックを実行します。
ansible-playbook --syntax-check webserver.yml期待される出力(エラー): 今回は、Ansible がプレイブックの構造に関連する別のエラーを報告します。
ERROR! A malformed block was encountered. The error appears to be in '/home/labex/project/ansible_troubleshooting/webserver.yml': line 13, column 11, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: ## ERROR 2: Incorrect indentation - name: Create a test index page ^ hereこのエラーは、YAML がインデントを使用して構造を定義するため発生します。リスト内のすべての項目(この場合は
-で始まるタスク)は、同じレベルのインデントを持つ必要があります。2 番目のタスクCreate a test index pageは、インデントが深すぎます。解決策: もう一度ファイルを開いてインデントを修正します。
nano webserver.yml最初のタスクのハイフン (
-) が最初のタスクのハイフンと完全に揃うように、2 番目のタスクの前にある余分なスペースを削除します。## ... (rest of the file) tasks: - name: Install httpd package ansible.builtin.dnf: name: httpd state: present ## FIX: Correct the indentation to align with the previous task - name: Create a test index page ansible.builtin.copy: content: "<h1>Welcome to Ansible</h1>" dest: /var/www/html/index.htmlエディタを保存して終了します。
修正されたプレイブックの検証
最後に、もう一度構文チェックを実行します。
ansible-playbook --syntax-check webserver.yml今回は、コマンドはエラーなしで完了し、プレイブックの名前が表示されて、構文が正しくなったことが確認されます。
期待される出力(成功):
playbook: webserver.yml
Jinja2 引用符とテンプレートパスのエラー解決
このステップでは、Ansible の強力なテンプレート エンジンである Jinja2 に関連するエラーに取り組みます。Jinja2 式が引用符で囲まれることが多い理由と、プレイブックが指定されたテンプレート ファイルを見つけられない場合の問題をデバッグする方法を学びます。これらは、プレイブックが構文チェックを既にパスした後に発生する一般的な実行時エラーです。
Jinja2 テンプレート ファイルの作成
まず、テンプレート ファイルが必要です。静的ファイルとは異なり、テンプレートには Ansible がプレイブック実行中に実際の値に置き換える変数を含めることができます。簡単な HTML テンプレートを作成します。
nanoを使用して、プロジェクト ディレクトリ (~/project/ansible_troubleshooting) にindex.html.j2という名前のファイルを作成します。.j2拡張子は Jinja2 テンプレートの一般的な規約です。nano index.html.j2以下の HTML コンテンツをエディタにコピーして貼り付けます。
{{ welcome_message }}プレースホルダーに注意してください。これは Jinja2 変数です。<h1>{{ welcome_message }}</h1> <p>This page was deployed by Ansible.</p>nanoでファイルを保存して終了します (Ctrl+X、Y、Enter)。プレイブックを修正してテンプレートを使用し、エラーを導入する
次に、
webserver.ymlプレイブックを修正してansible.builtin.templateモジュールを使用します。また、2 つの新しいエラーを導入します。引用符で囲まれていない Jinja2 変数と、正しくないテンプレート パスです。nanoでwebserver.ymlを開きます。nano webserver.ymlファイルの内容全体を以下に置き換えます。
become: trueディレクティブは、Ansible に管理者権限(sudoを使用)でタスクを実行するように指示します。これは、ソフトウェアをインストールしたり、/var/www/htmlのようなシステム ディレクトリにファイルを書き込んだりするために必要です。--- - name: Configure Web Server hosts: localhost become: true vars: package_name: httpd welcome_message: "Welcome to Ansible with Jinja2" tasks: - name: Install httpd package ansible.builtin.dnf: ## ERROR 1: Unquoted Jinja2 variable name: { { package_name } } state: present - name: Create a test index page from template ansible.builtin.template: ## ERROR 2: Incorrect template source path src: index.j2 dest: /var/www/html/index.htmlエディタを保存して終了します。
Jinja2 引用符エラーの特定と修正
これは Jinja2 の問題ですが、YAML の構文エラーとして現れる可能性があります。Ansible がそれをどのように解釈するかを確認するために、構文チェッカーを実行します。
ansible-playbook --syntax-check webserver.yml期待される出力(エラー): YAML の値が
{{で始まると特別な構成として扱われ、文字列として解釈するには引用符で囲む必要があるため、構文エラーが発生します。ERROR! A malformed block was encountered. The error appears to be in '/home/labex/project/ansible_troubleshooting/webserver.yml': line 11, column 19, but may be elsewhere in the file depending on the exact syntax problem. The offending line appears to be: ## ERROR 1: Unquoted Jinja2 variable name: {{ package_name }} ^ here解決策:
webserver.ymlを開き、Jinja2 変数を二重引用符で囲みます。nano webserver.ymlInstall httpd packageタスクを修正します。## ... (rest of the file) tasks: - name: Install httpd package ansible.builtin.dnf: ## FIX: Quote the Jinja2 expression name: "{{ package_name }}" state: present ## ... (rest of the file)保存して終了します。これで構文チェックはパスするはずです。
テンプレート パス エラーの特定と修正
構文が正しくなったので、プレイブックを実行してみます。
ansible-playbook webserver.yml期待される出力(エラー): プレイブックは失敗しますが、今回は構文エラーではなく実行時エラーです。エラー メッセージには、ソース ファイル
index.j2が見つからないことが明確に示されています。TASK [Create a test index page from template] ********************************** fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find or access '/home/labex/project/ansible_troubleshooting/index.j2' on the Ansible Controller."}これは、プレイブックの
srcパラメータがindex.j2を指していますが、作成したファイルの名前がindex.html.j2であるために発生します。解決策: もう一度
webserver.ymlを開き、ファイル名を修正します。nano webserver.ymlCreate a test index page from templateタスクのsrcパラメータを修正します。## ... (rest of the file) - name: Create a test index page from template ansible.builtin.template: ## FIX: Correct template source filename src: index.html.j2 dest: /var/www/html/index.html ## ... (rest of the file)エディタを保存して終了します。
プレイブックの正常な実行
再度プレイブックを実行します。これで、すべてのタスクが正常に完了するはずです。
ansible-playbook webserver.yml期待される出力(成功):
PLAY [Configure Web Server] **************************************************** TASK [Gathering Facts] ********************************************************* ok: [localhost] TASK [Install httpd package] *************************************************** changed: [localhost] TASK [Create a test index page from template] ********************************** changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
チェックモードを使用して管理ホストのサービスエラーをトラブルシューティングする
このステップでは、Ansible の最も強力なトラブルシューティング機能の 1 つであるチェックモードの使用方法を学びます。チェックモード(--check フラグでアクティブ化)を使用すると、プレイブックを実行して、実際にシステム上の何も変更せずに、どのような変更が行われるかを確認できます。これは、プレイブックを安全にテストし、実際の障害を引き起こす前に、不正確なサービス名などの問題を診断するのに非常に役立ちます。
サービスを管理するプレイブックの作成
次に、
httpdWeb サーバーサービスが実行されていることを確認するように設計された新しいプレイブックservice.ymlを作成します。ただし、一般的なエラーをシミュレートするために、意図的に間違ったサービス名を使用します。nanoを使用して、~/project/ansible_troubleshootingディレクトリにservice.ymlファイルを作成します。nano service.yml以下をコピーして貼り付けます。サービス名は
apache2に設定されていますが、これは他の Linux ディストリビューションでは Apache Web サーバーの一般的な名前ですが、RHEL では正しくありません。--- - name: Manage Web Server Service hosts: localhost become: true tasks: - name: Ensure web server service is started ansible.builtin.service: ## ERROR: Incorrect service name for RHEL name: apache2 state: started enabled: truenanoでファイルを保存して終了します (Ctrl+X、Y、Enter)。チェックモードを使用してサービス エラーを特定する
プレイブックを通常どおり実行する代わりに、チェックモードで実行します。これにより、Ansible は変更を加えることはできませんが、システムの状態を確認し、実際に行うであろうことを報告できます。
ansible-playbook --check service.yml期待される出力(エラー): プレイブックは失敗します。エラー メッセージには、
apache2という名前のサービスが見つからなかったことが明確に示されます。これにより、プレイブックのnameパラメータが間違っていることがすぐにわかります。TASK [Ensure web server service is started] ************************************ fatal: [localhost]: FAILED! => {"changed": false, "msg": "Could not find the requested service 'apache2': host"} PLAY RECAP ********************************************************************* localhost : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0正しいサービス名の検索
プレイブックを修正するには、RHEL 上の
httpdパッケージの正しいサービス名を見つける必要があります。これを行う確実な方法は、パッケージによってインストールされたファイルを一覧表示し、通常は/usr/lib/systemd/system/に存在するサービスユニット ファイルを探すことです。rpmコマンドを使用してhttpdパッケージをクエリします。rpm -ql httpd | grep systemd期待される出力: このコマンドは、サービス ファイルを含む
systemd関連ファイルを一覧表示します。/usr/lib/systemd/system/httpd.service /usr/lib/systemd/system/httpd@.service ...出力
httpd.serviceは、正しいサービス名がhttpdであることを示しています。プレイブックの修正とチェックモードでの再実行
正しいサービス名がわかったので、
service.ymlファイルを編集します。nano service.ymlサービス
nameをapache2からhttpdに変更します。## ... (rest of the file) - name: Ensure web server service is started ansible.builtin.service: ## FIX: Correct service name for RHEL name: httpd state: started enabled: trueエディタを保存して終了します。次に、プレイブックをチェックモードで再度実行します。
ansible-playbook --check service.yml期待される出力(チェックモードでの成功): 今回は、プレイブックが
changedステータスを報告するはずです。チェックモードでは、changedは「実際の実行であれば変更が行われた」ことを意味します。これは、プレイブックのロジックが正しくなり、Ansible がhttpdサービスを開始する必要があることを特定したことを示しています。TASK [Ensure web server service is started] ************************************ changed: [localhost] PLAY RECAP ********************************************************************* localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0注意: この特定のコンテナベースの実験環境では、完全な
systemd初期化システムは実行されていません。チェックモードは正しく機能しますが、ansible.builtin.serviceモジュールの通常の実行では引き続き問題が発生する可能性があります。ここで重要な教訓は、チェックモードを使用して、プレイブックのロジックをシステムの構成に対して検証することです。
ファイアウォール設定とホスト到達不能の問題を修正する
この最後のステップでは、ファイアウォールなどの不正確なシステム設定による障害と、Ansible インベントリ ファイルのエラーによる接続の問題という、2 つの重要な実行時エラーに対処します。これらをマスターすることで、自動化における最も一般的な障害のいくつかを解決できるようになります。
パート 1: ファイアウォール設定の修正
サーバー設定における一般的なタスクは、ファイアウォールでポートを開くことです。プレイブックは、ターゲット システムに存在しないファイアウォール サービスを参照すると失敗する可能性があります。
firewalldのインストールと準備まず、RHEL でファイアウォール管理サービスを提供する
firewalldパッケージがインストールされていることを確認します。sudo dnf install -y firewalldfirewalldサービスを開始します。sudo systemctl start firewalldこの演習で使用する
firewalldモジュールが含まれているansible.posixコレクションもインストールする必要があります。ansible-galaxy collection install ansible.posix注意: Ansible のバージョン互換性に関する警告が表示される場合がありますが、この演習ではコレクションは正しく機能します。
ファイアウォール エラーを含むプレイブックの作成
firewall.ymlという新しいプレイブックを作成し、httpサービスを有効にしようとします。ただし、意図的に間違ったサービス名webを使用してエラーを発生させます。nano firewall.yml以下をエディタにコピーして貼り付けます。
--- - name: Configure System Firewall hosts: localhost become: true tasks: - name: Allow web traffic through firewall ansible.posix.firewalld: ## ERROR: 'web' is not a standard firewalld service service: web permanent: true state: enablednanoで保存して終了します (Ctrl+X、Y、Enter)。プレイブックを実行して障害を診断する
プレイブックを実行します。
firewalldがwebという名前のサービスを認識しないため、失敗します。ansible-playbook firewall.yml期待される出力(エラー): エラー メッセージには、
webがサポートされているサービスではないことが明確に示されており、問題に直接誘導されます。TASK [Allow web traffic through firewall] ************************************** fatal: [localhost]: FAILED! => {"changed": false, "msg": "web is not a supported service. This is what I have."} PLAY RECAP ********************************************************************* localhost : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0正しいファイアウォール サービス名の検索
有効な定義済みサービス名のリストを見つけるには、
firewall-cmdコマンドライン ツールを使用できます。firewall-cmd --get-services期待される出力: 利用可能なサービスの長いリストが表示されます。リストを確認して、Web トラフィックの正しいサービスである
httpを見つけます。RH-Satellite-6 ... ftp http https imaps ipp ipp-client ...プレイブックの修正と正常な実行
firewall.ymlを編集し、間違ったサービス名webを正しいhttpに置き換えます。nano firewall.yml修正されたタスクは次のようになります。
## ... (rest of the file) - name: Allow web traffic through firewall ansible.posix.firewalld: ## FIX: Use the correct firewalld service name service: http permanent: true state: enabled保存して終了します。次に、プレイブックを再度実行します。正常に完了するはずです。
ansible-playbook firewall.yml
パート 2: ホスト到達不能エラーのトラブルシューティング
「到達不能」エラーは、Ansible がインベントリにリストされているホストに接続できないことを意味します。これは、多くの場合、ホスト名に単純なタイプミスがあることが原因です。
到達不能なホストのシミュレーション
意図的に
inventoryファイルにタイプミスを導入し、ローカル接続設定を削除します。これにより、Ansible はスペルミスのあるホスト名への実際のネットワーク接続を試行するようになります。nano inventorylocalhostをlocalhossstに変更し、ansible_connection=localを削除します。## ERROR: Intentional typo in hostname, no local connection localhossstエディタを保存して終了します。
インベントリ ホストを使用するようにプレイブックを修正する
まず、ハードコーディングされた
localhostの代わりにインベントリ ホストを使用するようにwebserver.ymlプレイブックを修正する必要があります。プレイブックがhosts: localhostを使用すると、Ansible はそれを特別なケースとして扱い、インベントリ ファイルを完全にバイパスします。nano webserver.ymlhosts行をlocalhostからallに変更します。--- - name: Configure Web Server hosts: all ## Changed from 'localhost' to use inventory hosts become: true ## ... rest of the playbook remains the sameエディタを保存して終了します。
プレイブックを実行してエラーを発生させる
次に、修正されたプレイブックを実行してみます。インベントリにタイプミス
localhossstが含まれているため、失敗します。ansible-playbook webserver.yml期待される出力(エラー): Ansible は失敗し、ホストが
UNREACHABLEであると報告します。エラー メッセージは、ホスト名を解決できなかったことを示しています。PLAY [Configure Web Server] **************************************************** TASK [Gathering Facts] ********************************************************** fatal: [localhossst]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname localhossst: Name or service not known", "unreachable": true} PLAY RECAP ********************************************************************* localhossst : ok=0 changed=0 unreachable=1 failed=0 skipped=0 rescued=0 ignored=0インベントリ ファイルの修正
UNREACHABLEステータスは、ホスト名とネットワーク接続を確認する合図です。この場合、修正はinventoryファイルのタイプミスを修正することです。nano inventorylocalhossstをlocalhostに戻します。## FIX: Corrected hostname localhost ansible_connection=local保存して終了します。
ansible-playbook webserver.ymlを再度実行すると、今度は成功します。オプション:元のプレイブックの復元
今後の演習のためにプレイブックを
hosts: localhostを使用するように戻したい場合は、次のように変更できます。nano webserver.ymlhosts行をlocalhostに戻します。--- - name: Configure Web Server hosts: localhost ## Restored to original become: true ## ... rest of the playbook保存して終了します。このステップは、ハードコーディングされた
localhost(インベントリをバイパスする)を使用することと、インベントリで定義されたホストを使用することの違いを示しています。
まとめ
この実験では、ansible-core をインストールしてロギングを設定することにより、Red Hat Enterprise Linux 環境を Ansible 用に準備し、その後、さまざまな一般的な問題のトラブルシューティングに進みました。プレイブック内のエラーを診断および解決する方法を学びました。たとえば、YAML の構文、インデント、Jinja2 の引用符、および無効なテンプレート パスを修正しました。これらのスキルは、有効で信頼性の高い自動化コードを作成するための基本です。
さらに、管理対象ホスト環境に関連する問題にも取り組みました。Ansible のチェック モードを利用して、実際の変更を行わずにターゲット ノードでの潜在的なサービス障害を安全に特定するためのドライ ランを実行しました。この実験は、ファイアウォール設定を修正してホストの到達不能性を解決することにより、接続の問題に対処して終了しました。これにより、制御ノードから管理対象ホストまでのデバッグに対する包括的なアプローチが提供されました。


