はじめに
パッケージがインストールされていること、設定ファイルが存在すること、サービスが応答することは、それぞれ異なる成果です。ユーティリティのインストールと削除、nginx の設定、稼働状態の宣言、ハンドラーによる変更済み設定の再読み込みを、それぞれ明示的に管理します。両管理対象ノードからの実際の HTTP 応答で、サービスの動作を確認します。
パッケージのインストール済み状態と削除状態を宣言する
このステップでは、小さなユーティリティをインストールして調べ、再利用可能なパッケージの宣言で削除します。
apt モジュールは、管理対象ホストの Ubuntu パッケージを管理します。state: present はインストール、state: absent は削除を要求します。この環境にはパッケージ一覧とキャッシュ済みのダウンロードが用意されているため、update_cache: false を維持してください。一覧の更新や最新バージョンの要求は、不要なネットワーク依存を加えます。本番環境の更新方針は異なる場合があります。
コントローラーのプロジェクトに移動します。
cd /home/labex/project
変数で tree パッケージの望ましい状態を選択する Playbook を作成します。パッケージ操作には、対象での become が必要です。install_recommends: false は、任意の推奨パッケージをインストールしないようにします。
cat > packages.yml <<'YAML'
- name: Declare a utility package state
hosts: all
gather_facts: false
become: true
vars:
utility_state: present
tasks:
- name: Converge the tree package
ansible.builtin.apt:
name: tree
state: "{{ utility_state }}"
update_cache: false
install_recommends: false
YAML
ユーティリティをインストールします。
ansible-playbook packages.yml
tree コマンドはディレクトリツリーを表示します。ここではバージョンオプションで、各管理対象ノードに実行ファイルが本当にインストールされたことを実証します。
ansible all -m ansible.builtin.command -a 'tree --version'
各対象が tree のバージョンを返すはずです。Playbook を繰り返してください。存在するパッケージに、再インストールは不要なはずです。
ansible-playbook packages.yml
次に、再利用可能なタスクを編集せず、追加変数で削除状態を要求します。
ansible-playbook packages.yml -e utility_state=absent
同じ削除状態の要求を繰り返します。今度は、recap の両行が changed=0、failed=0、unreachable=0 を示すはずです。
ansible-playbook packages.yml -e utility_state=absent
パッケージ状態はインストールに関する宣言であり、サービスが稼働し応答している証拠ではありません。次のステップで nginx を配置する間も、tree は削除したままにしてください。
実際の Web サービスを設定して起動する
このステップでは、nginx をインストールし、完全な検証済み設定を配置して、そのサービスを明示的に稼働状態に保ちます。
2 つの管理対象ノードは、別々の SSH 接続先とファイルシステムを持つコンテナーです。systemd は動作していません。service モジュールは、それらで利用可能なサービスマネージャーを使います。これらの対象で systemctl を実行しないでください。systemd の起動方針を保証するのではなく、現在の稼働状態を管理します。
コントローラーに静的ページを作成します。末尾に改行があるため、管理対象の正確なバイト列を予測できます。
printf 'Ansible service ready\n' > page.txt
完全な nginx 設定を記述します。events と http は nginx の最上位コンテキスト、server は Web サイトの定義、listen はポート 8080 の選択、root はドキュメントディレクトリの選択、index は / リクエストに使うページの選択です。これらは Ansible YAML ではなく、nginx の設定です。
cat > nginx-course.conf <<'NGINX'
events {}
http {
server {
listen 8080;
root /var/www/ansible-site;
index index.html;
}
}
NGINX
配置用 Playbook を作成します。apt タスクは policy_rc_d: 101 で、パッケージインストーラーによる暗黙の nginx 起動を防ぎます。後の service タスクが、稼働状態を明示的に宣言します。copy タスクの validate は、コピー先を置き換える前に、一時的な候補ファイル(%s)に対して nginx の設定テストを実行します。
ハンドラーは、handlers の下に記述する名前付きの操作です。変更があった設定タスクは Reload nginx に通知し、これは Play の最後に 1 回実行されます。設定変更がなければ通知はありません。通常の service タスクは started を使用し、無条件に再起動せず、すでに動作中のサービスを稼働状態に保ちます。
cat > web.yml <<'YAML'
- name: Deploy a working web service
hosts: all
gather_facts: false
become: true
tasks:
- name: Install nginx without refreshing the prepared package lists
ansible.builtin.apt:
name: nginx
state: present
update_cache: false
install_recommends: false
policy_rc_d: 101
- name: Prepare the site directory
ansible.builtin.file:
path: /var/www/ansible-site
state: directory
owner: root
group: root
mode: "0755"
- name: Deploy the static page
ansible.builtin.copy:
src: /home/labex/project/page.txt
dest: /var/www/ansible-site/index.html
owner: root
group: root
mode: "0644"
- name: Validate and deploy nginx configuration
ansible.builtin.copy:
src: /home/labex/project/nginx-course.conf
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: "0644"
validate: /usr/sbin/nginx -t -c %s
notify: Reload nginx
- name: Keep nginx running
ansible.builtin.service:
name: nginx
state: started
handlers:
- name: Reload nginx
ansible.builtin.service:
name: nginx
state: reloaded
YAML
構文をチェックし、配置を適用します。
ansible-playbook web.yml --syntax-check
ansible-playbook web.yml
両ノードに nginx がインストールされ、ファイルが届き、正常に起動するはずです。初回の設定変更は、再読み込みハンドラーも実行予定に入れます。パッケージのバージョン確認だけでは、こうしたサービスの動作は何も確認できません。
curl は HTTP クライアントです。--fail は成功でない HTTP ステータスをコマンド失敗として扱い、--silent は進捗出力を省き、--show-error は失敗の詳細を残します。各管理対象ホストで、そのホスト自身のループバックインターフェースに対して実行します。
ansible all -m ansible.builtin.command -a 'curl --fail --silent --show-error http://127.0.0.1:8080/'
各結果に Ansible service ready が含まれるはずです。コントローラーと各対象のループバックインターフェースは別々です。このコマンドはコントローラーではなく、両対象のサービスを確認します。
ハンドラーを通じて設定変更を適用する
このステップでは、稼働中の nginx 設定を変更し、ハンドラーを観察して、HTTP 応答から設定を確認します。
nginx の server_tokens ディレクティブは、応答ヘッダーで nginx のバージョンを公開するかを制御します。コントローラーの設定を次の完全版に置き換え、http 内に server_tokens off を追加します。
cat > nginx-course.conf <<'NGINX'
events {}
http {
server_tokens off;
server {
listen 8080;
root /var/www/ansible-site;
index index.html;
}
}
NGINX
同じ Playbook を適用します。
ansible-playbook web.yml
設定のコピーは両ホストで changed を報告し、Reload nginx に通知するはずです。新しい設定が検証を通過した後、ハンドラーは稼働中のサービスを再読み込みします。その実行によって設定が有効になります。ファイルをコピーしただけでは、プロセスが何を読み込んだかは確認できません。
curl の -I は HTTP ヘッダーを要求します。両ホストの実際のサービス応答を調べます。
ansible all -m ansible.builtin.command -a 'curl --fail --silent --show-error -I http://127.0.0.1:8080/'
両応答は成功の HTTP ステータスを持ち、Server ヘッダーはバージョンの接尾辞がない nginx になるはずです。日付など、他のヘッダーフィールドは変わります。
完全な Playbook を繰り返します。
ansible-playbook web.yml
両ホストが changed=0、失敗または到達不能のタスクなしを報告し、再読み込みハンドラーは実行予定に入らないはずです。静的ページは引き続き利用でき、tree は削除状態、nginx はインストール済みで稼働中のままです。
まとめ
パッケージの存在と不在を宣言し、インストールとサービスの稼働状態を分けて扱い、候補ファイルの検証を伴う完全な nginx 設定を配置しました。変更された設定は再読み込みハンドラーに通知し、実際の HTTP 応答で稼働中の動作を確認しました。変更のない繰り返し実行では、追加の変更や再読み込みを避けられました。



