RHEL 上に Ansible Playbook を実装する

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

はじめに

このラボでは、Red Hat Enterprise Linux (RHEL) システムに Apache Web サーバーをデプロイするための完全な Ansible Playbook を実装する方法を学びます。まず、Ansible プロジェクトの基本的なコンポーネントを設定します。これには、管理対象ノードを定義するための静的インベントリファイルの作成と、ansible.cfg ファイルを使用したローカル Ansible 環境の構成が含まれます。

初期設定の後、コアとなるデプロイメントプロセスを自動化するためのマルチタスクプレイブックを作成します。これには、Apache サービスのインストールと起動、カスタム Web ページのデプロイ、および HTTP トラフィックを許可するためのシステムファイアウォールの設定が含まれます。ラボを完了するために、プレイブックに 2 番目のプレイを追加し、コマンドラインから Web サーバーをテストして、デプロイメント全体が成功したことを確認します。

Web サーバー用の静的インベントリファイルを作成する

このステップでは、Ansible インベントリの基本を学びます。インベントリとは、Ansible が管理するサーバー(または「管理対象ノード」)をリスト化したテキストファイルです。Web サーバーのグループに対してシンプルな静的インベントリファイルを作成し、その内容を確認する方法を学びます。

まず、ご自身のシステムに Ansible がインストールされていることを確認する必要があります。デフォルトではインストールされていないため、dnf パッケージマネージャーを使用してインストールします。

  1. ターミナルを開き、基本的な Ansible コマンドラインツールを提供する ansible-core パッケージをインストールします。

    sudo dnf install -y ansible-core

    パッケージがインストールされ、検証されていることを示す出力が表示されるはずです。

    ...
    Installed:
      ansible-core-2.16.x-x.el9.x86_64
    ...
    Complete!
  2. 整理のため、ホームディレクトリ内にこのプロジェクト専用のディレクトリを作成します。ansible-lab という名前にしましょう。

    mkdir -p ~/project/ansible-lab
  3. 新しく作成したプロジェクトディレクトリに移動します。この実験での今後の作業はすべて、この場所から行います。

    cd ~/project/ansible-lab
  4. 次に、最初のインベントリファイルを作成します。インベントリファイルは通常、INI 形式で記述されます。nano テキストエディタを使用して、inventory という名前のファイルを作成します。

    nano inventory
  5. nano エディタ内で、以下の内容を追加します。この設定は [webservers] という名前のグループを定義し、ローカルマシンである localhost をこのグループに追加します。

    • [webservers] はグループ名です。グループは、単一のコマンドで複数のホストを対象とするために使用されます。
    • localhost は管理したいマシンのホスト名です。この場合、LabEx VM 自体です。
    • ansible_connection=local は、Ansible が SSH 経由で接続しようとするのではなく、制御ノード(ご自身の VM)で直接コマンドを実行するように指示する特別な変数です。
    [webservers]
    localhost ansible_connection=local

    nano でファイルを保存するには、Ctrl+O を押し、ファイル名を確認するために Enter を押し、エディタを終了するために Ctrl+X を押します。

  6. インベントリファイルを作成したら、ansible-inventory コマンドを使用してファイルを解析し、含まれるホストのリストを表示できます。-i フラグはインベントリファイルへのパスを指定します。

    ansible-inventory --list -i inventory

    コマンドはインベントリの JSON 形式の表現を出力し、Ansible がファイルを正しく読み取って理解できることを確認します。

    {
      "_meta": {
        "hostvars": {
          "localhost": {
            "ansible_connection": "local"
          }
        }
      },
      "all": {
        "children": ["ungrouped", "webservers"]
      },
      "webservers": {
        "hosts": ["localhost"]
      }
    }

これで、基本的な静的インベントリファイルを作成し、Ansible がそれを正しく解釈できることを確認できました。このインベントリファイルは、次のステップで作成するプレイブックの基盤となります。

ansible.cfg で Ansible 環境を構成する

このステップでは、Ansible 設定ファイルである ansible.cfg を作成します。このファイルを使用すると、Ansible のデフォルトの動作を設定でき、一般的なオプションをコマンドラインで繰り返し入力する手間を省くことができます。プロジェクトディレクトリに ansible.cfg ファイルを配置することで、デフォルトのインベントリファイルのパスなどの設定を定義でき、Ansible はそのディレクトリから実行された際に自動的にそれらを使用します。

前のステップから引き続き、~/project/ansible-lab ディレクトリにいるはずです。

  1. nano テキストエディタを使用して、現在のディレクトリ(~/project/ansible-lab)に ansible.cfg という名前の新しいファイルを作成します。

    nano ansible.cfg
  2. nano エディタ内で、以下の内容を追加します。この設定は、Ansible にデフォルトのインベントリファイルの場所を指示します。

    • [defaults] セクションは ansible.cfg ファイルの標準的な部分であり、ほとんどのデフォルト設定を定義します。
    • inventory = ./inventory という行は、現在のディレクトリ(.)にある inventory ファイルをデフォルトのインベントリとして設定します。
    [defaults]
    inventory = ./inventory

    ファイルを保存するには Ctrl+O を押し、Enter を押し、Ctrl+X で終了します。

  3. デフォルトのインベントリパスを設定したので、Ansible コマンドで -i フラグを使用する必要がなくなりました(~/project/ansible-lab ディレクトリ内にいる限り)。

    これをテストするために、前のステップと同じ ansible-inventory --list コマンドを再度実行しますが、今回は -i inventory の部分を省略します。

    ansible-inventory --list

    前のステップとまったく同じ JSON 出力が表示されるはずです。これは、新しい ansible.cfg の設定のおかげで、Ansible が自動的に inventory ファイルを見つけて使用していることを確認します。

    {
      "_meta": {
        "hostvars": {
          "localhost": {
            "ansible_connection": "local"
          }
        }
      },
      "all": {
        "children": ["ungrouped", "webservers"]
      },
      "webservers": {
        "hosts": ["localhost"]
      }
    }

プロジェクト固有の ansible.cfg を作成することで、ワークフローがより効率的になりました。これは、一貫した動作を保証し、コマンドラインの複雑さを軽減するために、Ansible プロジェクトで一般的に行われるプラクティスです。

Apache サービスをインストールして起動する Playbook を作成する

このステップでは、最初の Ansible Playbook を記述します。Playbook は、管理対象ホストで実行されるタスクのセットを記述した YAML 形式のファイルです。インベントリで定義された localhost マシンに Apache Web サーバー (httpd) をインストールし、そのサービスを開始する Playbook を作成します。

~/project/ansible-lab ディレクトリにいるはずです。

  1. まず、nano テキストエディタを使用して、apache.yml という名前の新しいファイルを作成します。このファイルに Playbook が含まれます。

    nano apache.yml
  2. nano エディタ内で、「プレイ」を定義します。プレイは Playbook の中核となる単位であり、ホストのグループをタスクのセットにマッピングします。apache.yml に以下の内容を追加します。

    • ---: これは YAML ドキュメントの開始を示す標準的なマーカーです。
    • - name: ...: これはプレイの開始です。説明的な名前を付けることはベストプラクティスです。
    • hosts: webservers: これは、インベントリファイル内の webservers グループのすべてのホストでこのプレイを実行するように Ansible に指示します。
    • become: true: これは、タスクを実行するために特権昇格(sudo など)を使用するように Ansible に指示します。これは、ソフトウェアのインストールやサービスの管理などのアクションに必要です。
    • tasks:: このキーワードは、実行されるタスクのリストを開始します。
    ---
    - name: Install and start Apache web server
      hosts: webservers
      become: true
      tasks:
  3. 次に、Playbook にタスクを追加します。各タスクは、Ansible モジュールを呼び出す単一のアクションです。YAML ではインデントが非常に重要なので、タスクが tasks: セクションの下に正しくインデントされていることを確認してください。

    • タスク 1: httpd をインストールする。 このタスクは ansible.builtin.dnf モジュールを使用して、httpd パッケージがインストールされていることを確認します。state: present パラメータは、パッケージが欠落している場合は Ansible がパッケージをインストールし、既にインストールされている場合は何も行わないことを意味します。
    • タスク 2: httpd サービスを開始する。 このタスクは ansible.builtin.service モジュールを使用します。state: started はサービスが実行されていることを保証し、enabled: true はシステム起動時に自動的に開始されることを保証します。

    apache.yml ファイルの tasks: 行の直下に、以下のタスクを追加します。

    - name: Install httpd package
      ansible.builtin.dnf:
        name: httpd
        state: present
    
    - name: Start and enable httpd service
      ansible.builtin.service:
        name: httpd
        state: started
        enabled: true
  4. 完成した apache.yml Playbook は次のようになります。インデントを注意深く確認してください。

    ---
    - name: Install and start Apache web server
      hosts: webservers
      become: true
      tasks:
        - name: Install httpd package
          ansible.builtin.dnf:
            name: httpd
            state: present
    
        - name: Start and enable httpd service
          ansible.builtin.service:
            name: httpd
            state: started
            enabled: true

    ファイルを保存して nano を終了します(Ctrl+OEnterCtrl+X)。

  5. Playbook を実行する前に、--syntax-check フラグを付けた ansible-playbook コマンドを使用して、構文エラーがないか確認することをお勧めします。

    ansible-playbook --syntax-check apache.yml

    構文が正しい場合、コマンドはエラーなしで Playbook のファイル名を表示します。

    playbook: apache.yml
  6. 次に、Playbook を実行します。

    ansible-playbook apache.yml

    Ansible はタスクを実行します。初回実行のため、両方のタスクで changed ステータスが表示され、システムの状態が変更されたことを示します。

    PLAY [Install and start Apache web server] *************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Install httpd package] ***************************************************
    changed: [localhost]
    
    TASK [Start and enable httpd service] ******************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  7. 最後に、curl を使用して localhost からデフォルトの Web ページをリクエストすることで、Apache Web サーバーが実行されていることを確認します。

    curl http://localhost

    デフォルトの Apache Test Page が表示されるはずです。これは、Playbook が正常に機能したことを確認します。

    <html>
      <head>
        <title>Test Page</title>
      </head>
      <body>
        <h1>Test Page</h1>
        <p>This is the default test page for the Apache HTTP server.</p>
      </body>
    </html>

Web ページをデプロイするタスクを追加する

このステップでは、Playbook を拡張して、より現実的な Web サーバー構成を実行します。カスタム index.html ページをデプロイするタスクを追加します。これにより、Ansible のファイル管理モジュールを使用してファイルを管理する方法が示されます。

~/project/ansible-lab ディレクトリにいるはずです。

  1. まず、Playbook がデプロイする簡単な HTML ファイルを作成します。nano を使用して、現在のディレクトリに index.html という名前のファイルを作成します。

    nano index.html
  2. ファイルに以下の HTML コンテンツを追加します。これがカスタム Web ページのコンテンツになります。

    <h1>Welcome to the Ansible-managed Web Server!</h1>
    <p>This page was deployed using an Ansible Playbook.</p>

    nano を保存して終了します(Ctrl+OEnterCtrl+X)。

  3. 次に、apache.yml Playbook を更新して新しいタスクを追加します。YAML フォーマットのエラーを回避するために、既存の apache.yml ファイルを削除し、以下に示す完全なコンテンツで新しいファイルを作成することをお勧めします。

    重要: 正しい YAML フォーマットを確保し、インデントエラーを回避するために、既存の apache.yml ファイルを削除し、以下に示す完全なコンテンツで新しいファイルを作成してください。

    rm apache.yml
    nano apache.yml
  4. Playbook に新しいタスクを追加します。このタスクは、index.html ファイルを Web サーバーのドキュメントルート(/var/www/html/)にコピーします。

    • タスク:index.html をデプロイする。 このタスクは ansible.builtin.copy モジュールを使用します。src はコントロールノード上のソースファイル(index.html)を指定し、dest は管理対象ホスト上の宛先パスを指定します。
  5. 以下の完全な apache.yml Playbook コンテンツをコピーして貼り付けます。これにより、正しい YAML フォーマットとインデントが保証されます。

    ---
    - name: Install and start Apache web server
      hosts: webservers
      become: true
      tasks:
        - name: Install httpd package
          ansible.builtin.dnf:
            name: httpd
            state: present
    
        - name: Deploy custom index.html
          ansible.builtin.copy:
            src: index.html
            dest: /var/www/html/index.html
    
        - name: Start and enable httpd service
          ansible.builtin.service:
            name: httpd
            state: started
            enabled: true

    nano を保存して終了します。

  6. ファイルを保存して nano を終了し(Ctrl+OEnterCtrl+X)、更新された Playbook を実行します。

    ansible-playbook apache.yml

    今回は、新しいタスクが実行されているのが表示されるはずです。「Install httpd」および「Start httpd」タスクは、それらの望ましい状態が既に満たされているため ok と報告されるはずです。「Deploy custom index.html」タスクは changed と報告されます。

    PLAY [Install and start Apache web server] *************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Install httpd package] ***************************************************
    ok: [localhost]
    
    TASK [Deploy custom index.html] ************************************************
    changed: [localhost]
    
    TASK [Start and enable httpd service] ******************************************
    ok: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  7. 最後に、curl を再度使用して、カスタム Web ページが現在提供されていることを確認します。

    curl http://localhost

    出力は、index.html ファイルのコンテンツになっているはずです。

    <h1>Welcome to the Ansible-managed Web Server!</h1>
    <p>This page was deployed using an Ansible Playbook.</p>

Web サーバーのデプロイをテストするための 2 つ目の Play を実装する

この最後のステップでは、Playbook に 2 番目のプレイを追加します。単一の Playbook ファイルには複数のプレイを含めることができ、それらは順次実行されます。これは、異なるホストを対象とするタスクや、異なる目的を持つタスクを整理するのに役立ちます。最初のプレイで構成された Web サーバーをテストするために、コントロールノード(localhost)でのみ実行される新しいプレイを追加します。

~/project/ansible-lab ディレクトリにいるはずです。

  1. Playbook に 2 番目のプレイを追加します。2 番目のプレイを追加する際に正しい YAML フォーマットを確保するために、既存の apache.yml ファイルを削除し、以下に示す完全な 2 つのプレイを含む新しいファイルを作成することをお勧めします。

    重要: 2 番目のプレイを追加する際に YAML のインデントエラーを回避するために、既存の apache.yml ファイルを削除し、以下に示す完全な 2 つのプレイを含む新しいファイルを作成してください。

    rm apache.yml
    nano apache.yml
  2. Playbook に 2 番目のプレイを追加します。2 番目のプレイにより、異なるホストを対象とするタスクや、異なる目的を持つタスクを整理できます。

    • name: Test web server: 新しいプレイの説明的な名前です。
    • hosts: localhost: このプレイは、コントロールノード自体である localhost で実行されます。
    • become: false: このテストでは root 権限は必要ないため、明示的に特権昇格を無効にします。
    • タスク:Web コンテンツを確認する。 このタスクは ansible.builtin.uri モジュールを使用して、Web サーバーに HTTP リクエストを行います。サーバーがステータスコード 200(OK)を返し、返されたコンテンツに「Ansible-managed」という文字列が含まれていることを確認します。これにより、これまで手動で行っていた curlgrep のチェックが自動化されます。
  3. 以下に、両方のプレイを含む完全な apache.yml Playbook コンテンツをコピーして貼り付けます。

    ---
    - name: Install and start Apache web server
      hosts: webservers
      become: true
      tasks:
        - name: Install httpd package
          ansible.builtin.dnf:
            name: httpd
            state: present
    
        - name: Deploy custom index.html
          ansible.builtin.copy:
            src: index.html
            dest: /var/www/html/index.html
    
        - name: Start and enable httpd service
          ansible.builtin.service:
            name: httpd
            state: started
            enabled: true
    
    - name: Test web server from localhost
      hosts: localhost
      become: false
      tasks:
        - name: Verify web server is serving correct content
          ansible.builtin.uri:
            url: http://localhost
            return_content: yes
            status_code: 200
          register: result
          failed_when: "'Ansible-managed' not in result.content"

    nano を保存して終了します(Ctrl+OEnterCtrl+X)。

  4. 完全な Playbook を実行します。Ansible は最初のプレイを実行し、すべてのタスクが既に望ましい状態(ok)にあることを確認してから、2 番目のプレイに進んでテストを実行します。

    ansible-playbook apache.yml

    出力には、両方のプレイが実行されていることが表示されます。すべてのタスクは ok ステータスで正常に完了するはずです。

    PLAY [Install and start Apache web server] *************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Install httpd package] ***************************************************
    ok: [localhost]
    
    TASK [Deploy custom index.html] ************************************************
    ok: [localhost]
    
    TASK [Start and enable httpd service] ******************************************
    ok: [localhost]
    
    PLAY [Test web server from localhost] ******************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Verify web server is serving correct content] ****************************
    ok: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

2 番目のプレイを追加することで、サービスを構成するだけでなく、デプロイが成功したことを確認するための組み込みテストも含まれる、より堅牢な自動化ワークフローを作成しました。

まとめ

この実験では、ansible-core パッケージをインストールし、プロジェクトディレクトリを構造化することによって、RHEL 環境を Ansible 自動化のために準備する方法を学びました。管理対象ノードのグループを定義するために基本的な静的インベントリファイルを作成し、ローカル接続で localhost を指定しました。また、カスタムインベントリを指すように ansible.cfg ファイルを使用して Ansible 環境を構成し、Playbook を実行するためのクリーンで整理されたワークスペースを確立しました。

次に、Apache Web サーバーのデプロイを自動化するための包括的な Ansible Playbook を作成しました。これには、ansible.builtin.dnf モジュールを使用して httpd パッケージをインストールするタスクと、ansible.builtin.service モジュールを使用してサービスが開始され有効になっていることを確認するタスクの作成が含まれていました。Playbook は、ansible.builtin.copy モジュールを使用してカスタム index.html Web ページをデプロイするように拡張されました。最後に、同じ Playbook 内に 2 番目のプレイを実装してデプロイを検証しました。ansible.builtin.uri モジュールを使用して新しくデプロイされた Web サーバーへの接続をテストし、完全なセットアップと検証ワークフローを示しました。