Ansible を使用した RHEL での変数とファクトの管理

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

はじめに

この実験では、Red Hat Enterprise Linux (RHEL) システム上の Ansible Playbook 内で変数、ファクト、およびシークレットを管理するための基本的な手法を学びます。Playbook 変数の使用、組み込みおよびカスタムの Ansible ファクトによるシステム情報の収集、そして Ansible Vault を使用したパスワードなどの機密データの保護を通じて、自動化をより柔軟かつ強力にする方法を探求します。

一連の実践的なステップを通じて、Apache Web サーバーをデプロイおよび設定するための Playbook を構築します。まず、パッケージ名や Web コンテンツの単純な変数を定義し、次にカスタムファクトを活用して Web サーバーの設定を動的に更新します。最後に、Ansible Vault を使用して暗号化されたパスワードを持つ新しいシステムユーザーを安全に作成し、完全な Playbook を実行して、すべての設定が正常に適用されたことを確認します。

Playbook 変数を定義および使用して Apache Web サーバーをデプロイする

このステップでは、Ansible Playbook で変数を使用する方法を学びます。変数は、自動化を柔軟で再利用可能にし、読みやすく保守しやすくするために不可欠です。パッケージ名やファイルパスなどの値をタスクに直接ハードコーディングする代わりに、それらを変数として定義し、Playbook 全体で参照できます。ここでは、変数を使用して Apache Web サーバー (httpd) をインストールし、基本的な Web ページをデプロイする単純な Playbook を作成します。

  1. プロジェクトディレクトリに移動する

    まず、正しい作業ディレクトリにいることを確認します。この実験のすべての作業は、作成済みの ~/project ディレクトリ内で行います。

    cd ~/project

    ansible-core パッケージをインストールします。

    sudo dnf install -y ansible-core
  2. Ansible Playbook を作成する

    次に、Playbook ファイルを作成します。名前は playbook.yml とします。nano などのコマンドラインテキストエディタを使用してファイルを作成および編集できます。

    nano playbook.yml

    このコマンドで nano エディタが開き、空のファイルが表示されます。Playbook の初期部分を追加します。このセクションでは、Play の名前、ターゲットホスト(同じマシン上で実行するため localhost)、および変数を定義する vars セクションを指定します。

    ---
    - name: Deploy Apache using variables
      hosts: localhost
      become: true
      vars:
        web_pkg: httpd
        web_content: "Hello from Ansible Variables"

    Playbook 構造の詳細は以下の通りです。

    • hosts: localhost: Playbook をローカルマシンで実行することを指定します。
    • become: true: タスクに対して特権昇格(sudo と同等)を使用するように Ansible に指示します。これはソフトウェアのインストールに必要です。
    • vars: 変数のキーと値のペアを定義する辞書です。パッケージ名用に web_pkg、テスト Web ページの内容用に web_content を定義しました。
  3. Playbook にタスクを追加する

    次に、vars セクションの下に、これらの変数を使用する tasks を追加します。最初のタスクで Apache パッケージをインストールし、2 番目のタスクで index.html ファイルを作成します。nano エディタで playbook.yml ファイルに以下の tasks ブロックを追加してください。

    tasks:
      - name: Install the latest version of Apache
        ansible.builtin.dnf:
          name: "{{ web_pkg }}"
          state: latest
    
      - name: Create a basic index.html file
        ansible.builtin.copy:
          content: "{{ web_content }}"
          dest: /var/www/html/index.html

    {{ variable_name }} を使用して、先ほど定義した変数を参照している点に注目してください。これは Ansible が変数に使用する Jinja2 テンプレートです。これによりタスク定義が汎用的になります。例えば Nginx をインストールしたい場合、タスク自体ではなく web_pkg 変数を変更するだけで済みます。

  4. Playbook を確認して保存する

    完成した playbook.yml ファイルは以下のようになります。YAML はスペースに非常に敏感なため、内容とインデントを再確認してください。

    ---
    - name: Deploy Apache using variables
      hosts: localhost
      become: true
      vars:
        web_pkg: httpd
        web_content: "Hello from Ansible Variables"
      tasks:
        - name: Install the latest version of Apache
          ansible.builtin.dnf:
            name: "{{ web_pkg }}"
            state: latest
    
        - name: Create a basic index.html file
          ansible.builtin.copy:
            content: "{{ web_content }}"
            dest: /var/www/html/index.html

    nano でファイルを保存するには、Ctrl+X を押し、Y で変更を確定し、最後に Enter を押して playbook.yml という名前で書き込みます。

  5. Playbook の構文をチェックする

    Playbook を実行する前に、構文にエラーがないか確認することをお勧めします。

    ansible-playbook --syntax-check playbook.yml

    構文が正しい場合、以下のように Playbook のファイルパスが出力され、有効であることが確認できます。

    playbook: playbook.yml

    エラーが表示された場合は、nano playbook.yml でファイルを再度開き、修正してください。正しいインデント(通常はスペース 2 つ)に細心の注意を払ってください。

  6. Playbook を実行する

    Playbook を実行します。Ansible は localhost に接続し、変数を読み込んでタスクを実行します。

    ansible-playbook playbook.yml

    各タスクが正常に実行されたことを示す出力が表示されるはずです。changed ステータスは、Ansible がパッケージのインストールやファイルの作成など、システムに変更を加えたことを意味します。

    PLAY [Deploy Apache using variables] *******************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Install the latest version of Apache] ************************************
    changed: [localhost]
    
    TASK [Create a basic index.html file] ******************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

    Playbook を 2 回目に実行すると、パッケージは既にインストールされており、ファイルも正しい内容になっているため、タスクは changed ではなく ok と報告されるはずです。これは Ansible の冪等性(べきとうせい)を示しています。

  7. 設定を手動で検証する

    Playbook は完了しましたが、タスクが期待通りに動作したかを手動で確認できます。まず、httpd パッケージがインストールされたかを確認します。

    rpm -q httpd

    出力にはパッケージ名とバージョンが表示されるはずです。

    httpd-2.4.57-7.el9.x86_64

    次に、index.html ファイルの内容を確認します。

    cat /var/www/html/index.html

    出力は web_content 変数の値と一致するはずです。

    Hello from Ansible Variables

    これで、Ansible Playbook で変数を使用してシステムを設定することに成功しました。

Ansible ファクトを使用してシステム情報を表示する

このステップでは、Ansible ファクトについて学びます。ファクトとは、Ansible が管理対象システム(この場合は localhost)について収集する情報のことです。この情報には、オペレーティングシステム、ネットワークインターフェース、メモリなどの詳細が含まれます。デフォルトでは、Ansible はすべての Play の開始時にファクトを収集し、ansible_facts という特別な変数で使用できるようにします。ファクトを使用すると、実行環境に適応する動的な Playbook を作成できます。

  1. プロジェクトディレクトリに移動する

    まず、新しい Playbook を作成する ~/project ディレクトリにいることを確認します。

    cd ~/project
  2. すべてのファクトを表示する Playbook を作成する

    まず、Ansible がシステムについて収集できるすべてのファクトを表示する Playbook を作成しましょう。これにより、利用可能な膨大な情報量を確認できます。nano を使用して display_facts.yml という名前の新しいファイルを作成します。

    nano display_facts.yml

    nano エディタ内で、以下の内容を追加します。この Playbook は localhost をターゲットとし、ansible.builtin.debug モジュールを使用して ansible_facts 変数の内容を出力します。

    ---
    - name: Display all Ansible facts
      hosts: localhost
      tasks:
        - name: Print all available facts
          ansible.builtin.debug:
            var: ansible_facts

    ファイルを保存し、Ctrl+XYEnter を押して nano を終了します。

  3. Playbook を実行する

    結果を確認するために Playbook を実行します。

    ansible-playbook display_facts.yml

    Ansible は大量のデータを収集するため、出力は非常に長くなります。システム詳細を含む大きな JSON 構造が表示されます。これは正常な動作です。

    PLAY [Display all Ansible facts] ***********************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Print all available facts] ***********************************************
    ok: [localhost] => {
        "ansible_facts": {
            "ansible_all_ipv4_addresses": [
                "172.17.0.2"
            ],
            "ansible_all_ipv6_addresses": [
                "fe80::42:acff:fe11:2"
            ],
            "ansible_apparmor": {
                "status": "disabled"
            },
            "ansible_architecture": "x86_64",
            "ansible_bios_date": "01/01/2011",
            "ansible_bios_version": "1.0",
            "ansible_cmdline": {
                "BOOT_IMAGE": "/boot/vmlinuz-5.14.0-427.16.1.el9_4.x86_64",
                "root": "UUID=...",
                "ro": true
            },
            "ansible_date_time": {
                "date": "2024-05-21",
                "day": "21",
                "epoch": "1716298855",
                ...
            },
            "ansible_distribution": "RedHat",
            "ansible_distribution_major_version": "9",
            "ansible_distribution_version": "9.4",
            ...
        }
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  4. 特定のファクトを表示する Playbook を作成する

    すべてのファクトを表示することは調査には役立ちますが、ほとんどの場合、必要な情報は特定のものだけです。別の Playbook display_specific_facts.yml を作成し、いくつかの主要なファクトのみを含むフォーマットされたメッセージを表示しましょう。

    nano display_specific_facts.yml

    以下の内容を追加します。この Playbook は debug モジュールの msg パラメータを使用してカスタム文字列を出力します。ansible_facts['distribution'] のように、ブラケット表記を使用して個々のファクトにアクセスします。

    ---
    - name: Display specific Ansible facts
      hosts: localhost
      tasks:
        - name: Print a summary of system facts
          ansible.builtin.debug:
            msg: >
              The operating system is {{ ansible_facts['distribution'] }}
              version {{ ansible_facts['distribution_major_version'] }}.
              It has {{ ansible_facts['processor_cores'] }} processor cores and
              {{ ansible_facts['memtotal_mb'] }} MB of total memory.

    msg: >> 文字は、複数行の文字列をよりきれいに記述できるようにする YAML の機能です。ファイルを保存して nano を終了します。

  5. 特定のファクトを表示する Playbook を実行する

    新しい Playbook を実行します。

    ansible-playbook display_specific_facts.yml

    出力はよりクリーンで読みやすくなり、要求した情報のみが表示されます。

    PLAY [Display specific Ansible facts] ******************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Print a summary of system facts] *****************************************
    ok: [localhost] => {
        "msg": "The operating system is RedHat version 9. It has 2 processor cores and 3925 MB of total memory."
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

    これは、Ansible ファクトを活用して Playbook が実行環境を認識できるようにし、よりインテリジェントで条件付きの自動化を可能にする方法を示しています。

管理対象ホストからのカスタムファクトを使用して Web サーバーを設定する

このステップでは、カスタムファクトの使用方法を学びます。Ansible は広範な標準ファクトを自動的に収集しますが、独自のファクトを定義することもできます。これらは「ローカルファクト」または「カスタムファクト」と呼ばれます。これは、Ansible がデフォルトで収集しないアプリケーション設定やハードウェア固有のデータなど、管理対象ホストから Playbook に特定の情報を提供できる強力な機能です。

Ansible は、管理対象ホスト上の /etc/ansible/facts.d ディレクトリでカスタムファクトを探します。このディレクトリ内の .fact 拡張子を持つファイルはすべて処理されます。これらのファイルは、単純な INI 形式のテキストファイルまたは JSON ファイルにできます。

  1. カスタムファクトディレクトリを作成する

    まず、Ansible がカスタムファクトファイルを探すディレクトリを作成する必要があります。これはシステムディレクトリであるため、sudo を使用して作成する必要があります。

    sudo mkdir -p /etc/ansible/facts.d

    -p フラグは、ディレクトリが既に存在する場合にコマンドがエラーを返さないようにします。

  2. カスタムファクトファイルを作成する

    次に、Web サーバーのウェルカムメッセージを定義するカスタムファクトファイルを作成しましょう。/etc/ansible/facts.d ディレクトリ内に web_config.fact という名前の INI 形式のファイルを作成します。

    sudo nano /etc/ansible/facts.d/web_config.fact

    以下の内容をファイルに追加します。これは、welcome_message キーを持つ [webserver] セクションを定義します。

    [webserver]
    welcome_message = Welcome to the server configured by Custom Facts!

    ファイルを保存し、Ctrl+XYEnter を押して nano を終了します。

  3. カスタムファクトを使用する Playbook を作成する

    カスタムファクトが配置されたので、このファクトを読み取り、それを使用して Web サーバーのホームページを設定する Playbook を作成できます。~/project ディレクトリに configure_web.yml という名前の新しい Playbook を作成します。

    cd ~/project
    nano configure_web.yml

    以下の内容を Playbook に追加します。この Playbook は、カスタムファクトで定義されたメッセージで /var/www/html/index.html ファイルを更新します。

    ---
    - name: Configure web server using custom facts
      hosts: localhost
      become: true
      tasks:
        - name: Update index.html with custom message
          ansible.builtin.copy:
            content: "{{ ansible_facts.ansible_local.web_config.webserver.welcome_message }}"
            dest: /var/www/html/index.html

    変数 {{ ansible_facts.ansible_local.web_config.webserver.welcome_message }} の詳細を分解します。

    • ansible_facts: すべてのファクトのルート辞書。
    • ansible_local: すべてのカスタムファクトが格納されるキー。
    • web_config: 拡張子を除いたファクトファイル名 (web_config.fact)。
    • webserver: INI ファイルのセクション名 [webserver]
    • welcome_message: 使用したい値のキー。

    ファイルを保存して nano を終了します。

  4. 設定 Playbook を実行する

    設定を適用するために Playbook を実行します。

    ansible-playbook configure_web.yml

    出力には、copy タスクが index.html ファイルを changed したことが表示されるはずです。

    PLAY [Configure web server using custom facts] *********************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Update index.html with custom message] ***********************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  5. 結果を検証する

    最後に、Web ページが正しく更新されたことを検証します。cat コマンドを使用して index.html ファイルの内容を表示します。

    cat /var/www/html/index.html

    出力には、カスタムファクトファイルからのメッセージが表示されるはずです。

    Welcome to the server configured by Custom Facts!

    管理対象ホスト上にカスタムファクトを作成し、それを Playbook 内で使用してサービスを動的に設定することに成功しました。この手法は、自動化をより柔軟でデータ駆動型にするために非常に役立ちます。

Ansible Vault を使用して暗号化された変数でシステムユーザーを作成する

このステップでは、Ansible Vault を使用してパスワードや API キーなどの機密データを管理する方法を学びます。機密情報を Playbook 内にプレーンテキストで保存することは、大きなセキュリティリスクです。Ansible Vault は、ファイルや個々の変数を暗号化し、シークレットを安全に保つ方法を提供します。これらの暗号化されたファイルを Playbook で使用でき、正しいパスワードを入力すると、Ansible が実行時にそれらを復号化します。

ユーザー名とハッシュ化されたパスワードを含む暗号化ファイルを作成し、Playbook を使用してこれらの資格情報で新しいシステムユーザーを作成します。

  1. プロジェクトディレクトリに移動する

    このタスクのために ~/project ディレクトリにいることを確認します。

    cd ~/project
  2. 暗号化された Vault ファイルを作成する

    ansible-vault create コマンドを使用して、secrets.yml という名前の新しい暗号化 YAML ファイルを作成します。このコマンドは、Vault のパスワードを作成するように求めます。このパスワードは、後でファイルを開いたり、編集したり、使用したりするために必要です。

    まず、作業しやすくするためにエディタを nano に設定します。

    export EDITOR=nano

    次に、Vault ファイルを作成します。

    ansible-vault create secrets.yml

    プロンプトが表示されたら、Vault のパスワードを入力します。この実験では、シンプルにするために labex を Vault パスワードとして使用します。2 回入力する必要があります。

    New Vault password:
    Confirm New Vault password:

    パスワードを確認すると、コマンドは nano テキストエディタで secrets.yml ファイルを開きます。

  3. Vault ファイルにシークレット変数を追加する

    暗号化された secrets.yml ファイルを編集している nano エディタ内で、以下の変数を追加します。新しいユーザーのユーザー名と事前にハッシュ化されたパスワードを定義します。ハッシュ化されたパスワードを使用することは、プレーンテキストのパスワードを保存するよりもはるかに安全です。

    username: myappuser
    pwhash: $6$mysalt$QwMzWSEyCAGmz7tzVrAi5o.8k4d05i2QsfGGwmPtlJsWhGjSjCW6yFCH/OEqEsHk7GMSxqYNXu5sshxPmWyxo0
    • username: 作成したいシステムユーザーの名前。
    • pwhash: 安全にハッシュ化されたパスワード。この特定のハッシュはパスワード AnsibleUserP@ssw0rd に対応しており、ansible.builtin.user モジュールが理解できる形式です。

    ファイルを保存して nano を終了します (Ctrl+XYEnter)。~/project ディレクトリ内の secrets.yml ファイルは現在暗号化されています。cat secrets.yml で表示しようとしても、暗号化されたテキストしか表示されません。

  4. Vault ファイルを使用する Playbook を作成する

    暗号化された secrets.yml ファイルの変数を使用する create_user.yml という名前の新しい Playbook を作成します。

    nano create_user.yml

    以下の内容を追加します。vars_files ディレクティブは、指定されたファイルから変数を読み込むように Ansible に指示します。

    ---
    - name: Create a user from secret variables
      hosts: localhost
      become: true
      vars_files:
        - secrets.yml
      tasks:
        - name: Create the {{ username }} user
          ansible.builtin.user:
            name: "{{ username }}"
            password: "{{ pwhash }}"
            state: present

    この Playbook は、secrets.yml で定義された名前とパスワードハッシュを持つユーザーを作成します。ファイルを保存して nano を終了します。

  5. Vault パスワードを使用して Playbook を実行する

    Vault ファイルを使用する Playbook を実行するには、Vault パスワードを提供する必要があります。--ask-vault-pass フラグを使用して対話的にこれを行うことができます。

    ansible-playbook --ask-vault-pass create_user.yml

    Ansible は Vault パスワードを要求します。labex(ステップ 2 で設定したパスワード)を入力します。

    Vault password:

    正しいパスワードを入力すると、Ansible はメモリ内でファイルを復号化し、Playbook を実行します。ユーザーが作成されたことを示す以下の出力が表示されるはずです。

    PLAY [Create a user from secret variables] *************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Create the myappuser user] ***********************************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  6. ユーザーが作成されたことを検証する

    id コマンドを使用して、myappuser がシステム上に正常に作成されたことを確認できます。

    id myappuser

    ユーザーが存在する場合、ユーザー ID (uid) とグループ ID (gid) の情報が表示されます。

    uid=1002(myappuser) gid=1002(myappuser) groups=1002(myappuser)

    これで、Ansible Vault を使用して自動化タスクの機密データを管理することに成功しました。

Vault パスワードファイルを使用して設定を適用する Playbook を実行する

このステップでは、Ansible に Vault パスワードを提供するより自動化された方法を学びます。前のステップでは、--ask-vault-pass を使用して対話的にパスワードを入力しました。これは安全ですが、パスワードを入力するユーザーが存在しない CI/CD パイプラインなどの自動化環境には適していません。

解決策は、Vault パスワードファイルを使用することです。これは、Vault パスワードを含む単純なテキストファイルです。Playbook を実行するときにこのファイルを参照すると、Ansible は自動的にそこからパスワードを読み取ります。セキュリティのため、このパスワードファイルの権限を制限し、許可されたユーザーのみが読み取れるようにすることが重要です。

  1. プロジェクトディレクトリに移動する

    Playbook と Vault ファイルがある ~/project ディレクトリにいることを確認します。

    cd ~/project
  2. Vault パスワードファイルを作成する

    Vault パスワードを保存するファイルを作成しましょう。名前は vault_pass.txt とします。echo コマンドを使用してファイルを作成し、パスワード (labex) を書き込むことができます。

    echo "labex" > vault_pass.txt

    cat でファイルの内容を確認できます。

    cat vault_pass.txt

    出力は以下の通りです。

    labex
  3. パスワードファイルを保護する

    プレーンテキストファイルにパスワードを保存するのは危険です。ファイルを保護するためにファイル権限を制限する必要があります。chmod コマンドでファイル権限を変更できます。権限を 600 に設定します。これは、ファイルの所有者(この場合は labex ユーザー)のみが読み取りおよび書き込み権限を持つことを意味します。システム上の他のユーザーはアクセスできません。

    chmod 600 vault_pass.txt

    ls -l コマンドを使用して新しい権限を確認できます。

    ls -l vault_pass.txt

    出力は -rw------- で始まり、制限された権限が確認できるはずです。

    -rw-------. 1 labex labex 6 May 21 14:30 vault_pass.txt
  4. Playbook を変更してユーザーをグループに追加する

    create_user.yml Playbook を変更して、追加のアクションを実行しましょう。myappuserwheel グループに追加します。多くのシステムでは、これにより管理(sudo)権限が付与されます。これは、既存の設定を変更する Playbook の実行を示します。

    まず、create_user.yml Playbook を編集用に開きます。

    nano create_user.yml

    ansible.builtin.user タスクを変更して、groups および append パラメータを含めます。

    ---
    - name: Create a user from secret variables
      hosts: localhost
      become: true
      vars_files:
        - secrets.yml
      tasks:
        - name: Create the {{ username }} user and add to wheel group
          ansible.builtin.user:
            name: "{{ username }}"
            password: "{{ pwhash }}"
            state: present
            groups: wheel
            append: true
    • groups: wheel: ユーザーを追加するグループを指定します。
    • append: true: ユーザーが所属している可能性のある他のグループから削除せずに、このグループに追加されるようにします。

    ファイルを保存して nano を終了します。

  5. Vault パスワードファイルを使用して Playbook を実行する

    Playbook を再度実行します。今回は --ask-vault-pass の代わりに、--vault-password-file オプション(または短いエイリアスの --vault-pass-file)を使用してパスワードファイルへのパスを指定します。

    ansible-playbook --vault-password-file vault_pass.txt create_user.yml

    Ansible は vault_pass.txt から直接パスワードを読み取るため、パスワードを要求せずに実行されます。ユーザーの設定が変更されたことを示す出力が表示されるはずです。

    PLAY [Create a user from secret variables] *************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Create the myappuser user and add to wheel group] ************************
    changed: [localhost]
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

    changed ステータスは、Ansible がユーザーを wheel グループに追加して変更したことを確認します。

  6. ユーザーのグループ所属を確認する

    最後に、myappuserwheel グループのメンバーであることを確認します。groups コマンドで確認できます。

    groups myappuser

    出力には、ユーザーのプライマリグループ (myappuser) と wheel グループの両方が表示されるはずです。

    myappuser : myappuser wheel

    これで、Vault パスワードファイルを使用して Playbook を非対話的に実行することに成功しました。これは安全なワークフローを自動化するための重要なスキルです。

Web サーバーとユーザー設定を検証する

この最後のステップでは、専用の検証 Playbook を作成して学習を統合します。これまでは、catidgroups などの標準的な Linux コマンドを使用して Playbook の結果を手動で確認してきました。より強力で再現可能なアプローチは、Ansible 自体を使用してシステムの状態を監査および検証することです。

この Playbook はテストスイートとして機能し、Web サーバーがインストールされているか、Web ページの内容が正しいか、システムユーザーが適切なグループ所属で存在するかをプログラムで確認します。これは、Ansible が設定管理だけでなく、コンプライアンスや状態検証にも使用できることを示しています。

  1. プロジェクトディレクトリに移動する

    まず、~/project ディレクトリにいることを確認します。

    cd ~/project
  2. 検証 Playbook を作成する

    verify_config.yml という名前の新しい Playbook を作成しましょう。この Playbook には、前のステップで適用した設定を確認する一連のタスクが含まれます。

    nano verify_config.yml
  3. 設定を検証するタスクを追加する

    nano エディタ内で、以下の内容を追加します。この Playbook は、特定の条件が真であることをアサートするように設計された複数のタスクで構築します。アサーションが失敗すると、Playbook は停止してエラーを報告し、何が問題かを即座に伝えます。

    ---
    - name: Verify system configuration
      hosts: localhost
      become: true
      tasks:
        - name: Check if httpd package is installed
          ansible.builtin.dnf:
            list: httpd
          register: httpd_pkg_info
    
        - name: Assert that httpd is installed
          ansible.builtin.assert:
            that:
              - httpd_pkg_info.results | length > 0
            fail_msg: "Apache (httpd) package is not installed."
            success_msg: "Apache (httpd) package is installed."
    
        - name: Read the content of the index.html file
          ansible.builtin.slurp:
            src: /var/www/html/index.html
          register: index_file
    
        - name: Assert that the web page content is correct
          ansible.builtin.assert:
            that:
              - "'Custom Facts' in (index_file.content | b64decode)"
            fail_msg: "Web page content is incorrect."
            success_msg: "Web page content is correct."
    
        - name: Check if myappuser exists
          ansible.builtin.getent:
            database: passwd
            key: myappuser
          register: user_info
    
        - name: Assert that myappuser exists
          ansible.builtin.assert:
            that:
              - user_info.ansible_facts.getent_passwd['myappuser'] is defined
            fail_msg: "User 'myappuser' does not exist."
            success_msg: "User 'myappuser' exists."
    
        - name: Query the wheel group members
          ansible.builtin.getent:
            database: group
            key: wheel
          register: wheel_group_info
    
        - name: Assert that myappuser is in the wheel group
          ansible.builtin.assert:
            that:
              - "'myappuser' in (wheel_group_info.ansible_facts.getent_group['wheel'][2] | default('') | split(','))"
            fail_msg: "User 'myappuser' is not in the wheel group."
            success_msg: "User 'myappuser' is in the wheel group."

    ここで使用されている主要なモジュールを確認します。

    • ansible.builtin.dnf (list): パッケージをチェックし、結果を register します。
    • ansible.builtin.slurp: リモートホストからファイルの内容全体を「吸い上げ」ます。内容は安全な転送のために base64 エンコードされます。
    • ansible.builtin.getent: passwdgroup などのシステムデータベースを安全にクエリする方法です。結果は ansible_facts に保存されるため、user_info.ansible_facts.getent_passwd などのキーを通じて返されたデータにアクセスします。
    • ansible.builtin.assert: 検証の核心です。指定された条件が真かどうかをチェックします。そうでない場合、Play は失敗します。カスタムの成功および失敗メッセージを提供します。
    • b64decode: slurp モジュールから取得した base64 コンテンツをデコードするために使用される Jinja2 フィルタです。

    passwd データベースと group データベースを個別にクエリしていることに注意してください。これにより、ユーザー存在チェックと wheel グループ所属チェックが getent によって返される実際のデータと一致します。

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

  4. 検証 Playbook を実行する

    検証 Playbook を実行します。Vault ファイルを使用していないため、パスワードを提供する必要はありません。

    ansible-playbook verify_config.yml

    前のステップがすべて正しく完了していれば、Playbook は正常に実行され、各アサーションのカスタム成功メッセージが表示されます。

    PLAY [Verify system configuration] *********************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [localhost]
    
    TASK [Check if httpd package is installed] *************************************
    ok: [localhost]
    
    TASK [Assert that httpd is installed] ******************************************
    ok: [localhost] => {
        "changed": false,
        "msg": "Apache (httpd) package is installed."
    }
    
    TASK [Read the content of the index.html file] *********************************
    ok: [localhost]
    
    TASK [Assert that the web page content is correct] *****************************
    ok: [localhost] => {
        "changed": false,
        "msg": "Web page content is correct."
    }
    
    TASK [Check if myappuser exists] ***********************************************
    ok: [localhost]
    
    TASK [Assert that myappuser exists] ********************************************
    ok: [localhost] => {
        "changed": false,
        "msg": "User 'myappuser' exists."
    }
    
    TASK [Query the wheel group members] *******************************************
    ok: [localhost]
    
    TASK [Assert that myappuser is in the wheel group] *****************************
    ok: [localhost] => {
        "changed": false,
        "msg": "User 'myappuser' is in the wheel group."
    }
    
    PLAY RECAP *********************************************************************
    localhost                  : ok=9    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

    おめでとうございます!Ansible を使用して変数を定義し、システムファクトを収集し、Vault でシークレットを管理し、最後にシステムの状態を自動化された方法で検証することに成功しました。

まとめ

この実験では、RHEL システムを設定するために Ansible Playbook 内でさまざまな種類のデータを管理する方法を学びました。まず、標準的な Playbook 変数を定義および使用して、Apache Web サーバーを柔軟にインストールおよび設定しました。続いて、Ansible の組み込みファクトを活用してシステム情報を表示する方法を探求し、動的でホストを認識する自動化タスクを作成するための基盤を提供しました。

さらに、管理対象ホストからのカスタムファクトを作成および利用して、Web サーバーをさらに設定しました。機密情報を安全に処理するために、Ansible Vault を使用してユーザーパスワードを暗号化し、この暗号化された変数で新しいシステムユーザーを作成し、Vault パスワードファイルを使用して Playbook を非対話的に実行しました。最後に、Web サーバーと新しいシステムユーザーの両方が正しく設定されていることを検証し、学習したすべての概念が正常に適用されたことを確認しました。