台数が増えるほど手作業は限界になり、冪等性のない手順書はいつか破綻します。
この記事では、Linuxサーバーの構成管理・自動化ツールとして実務で広く使われている ansible-playbook コマンド の使い方を解説します。
インベントリの書き方から playbook の基本構文、変数・ハンドラー・ロールの使い方、GitHub Actions との連携、トラブルシュートまで、実務で使える形でまとめています。
動作確認環境:RHEL 9.4 / AlmaLinux 9.4 / Ubuntu 24.04 LTS(Ansible 2.16)
この記事のポイント
・ansible-playbookはYAMLのplaybookでサーバーを冪等設定できる
・インベントリでホスト一覧を定義してplaybookで操作対象を指定する
・--checkでドライラン、-v/-vvvでデバッグが本番適用前の基本
・ハンドラーで「変更時だけ再起動」を安全に制御できる
・GitHub Actionsと連携してPlaybook検証・デプロイを自動化できる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
Ansibleとansible-playbookコマンドとは
Ansibleは Red Hat が開発するオープンソースの構成管理・自動化ツールです。エージェントレス(管理対象サーバー側に専用ソフトを入れない方式)で動作し、SSH(Linuxの場合)でリモートサーバーに接続して設定を適用します。管理対象のサーバー側には Python が入っていれば追加ソフトウェアは不要という点が、他のツールと比較して導入のハードルを下げています。
ansible-playbook は、Ansibleが提供するコマンドの中核であり、YAML形式で書かれた「playbook」と呼ばれる手順書を読み込んでサーバーへ適用します。コマンド1回で何十台のサーバーを同時に設定でき、何度実行しても同じ結果になる冪等性(べきとうせい)が最大の強みです。
Ansibleには複数のコマンドがありますが、それぞれの役割はこのようになっています。
| コマンド | 役割 |
|---|---|
ansible |
アドホックな単発コマンド実行 |
ansible-playbook |
yamlファイルで定義した手順を実行(本記事のメイン) |
ansible-inventory |
インベントリの確認・デバッグ |
ansible-galaxy |
ロールやコレクションの管理 |
ansible-vault |
機密情報の暗号化 |
Ansibleのインストール方法
1. RHEL 9・AlmaLinux 9・Rocky Linux 9の場合
EPEL リポジトリから Ansible をインストールします。# EPELリポジトリの有効化 sudo dnf install -y epel-release # Ansibleのインストール sudo dnf install -y ansible # バージョン確認 ansible --version
2. Ubuntu 24.04 LTSの場合
Ubuntu では apt もしくは PPA から Ansible をインストールできます。# 公式PPAを追加してからインストール(最新版を使う場合) sudo apt-add-repository --yes --update ppa:ansible/ansible sudo apt install -y ansible # または標準リポジトリから(バージョンは古い場合あり) sudo apt install -y ansible # バージョン確認 ansible --version
3. pipを使ってインストールする場合
DNF/apt が使えない環境や、最新版を使いたい場合は pip でもインストールできます。Python の仮想環境(venv)に閉じ込めると OS 側の Python 環境を汚さずに済みます。# 仮想環境の作成とAnsibleのインストール python3 -m venv ~/ansible-env source ~/ansible-env/bin/activate pip install ansible ansible-lint # バージョン確認 ansible --version ansible-lint --version
[admin@controller ~]$ ansible --version ansible [core 2.16.3] config file = /etc/ansible/ansible.cfg configured module search path = ['/home/admin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python3.11/site-packages/ansible ansible collection location = /home/admin/.ansible/collections:/usr/share/ansible/collections executable location = /usr/bin/ansible python version = 3.11.7 jinja2 version = 3.1.2 libyaml = True
インベントリの書き方
インベントリは、Ansible が操作する対象サーバーの一覧を定義するファイルです。デフォルトパスは/etc/ansible/hosts ですが、-i オプションで任意のファイルを指定するのが実務では一般的です。1. INI形式インベントリの基本
# /etc/ansible/hosts または任意の inventory.ini # 単独のホスト指定 web01.example.com 192.168.10.11 # グループ化 [webservers] web01.example.com web02.example.com [dbservers] db01.example.com ansible_user=dbadmin ansible_port=2222 # グループのグループ(親グループ) [datacenter:children] webservers dbservers
2. YAML形式インベントリ(推奨)
YAML形式はより読みやすく、変数との親和性が高いため実務では推奨されます。# inventory.yml all: children: webservers: hosts: web01.example.com: ansible_user: ec2-user web02.example.com: ansible_user: ec2-user dbservers: hosts: db01.example.com: ansible_user: dbadmin ansible_port: 2222 vars: ansible_ssh_private_key_file: ~/.ssh/id_rsa
3. インベントリの確認
# インベントリ内のホスト一覧を表示 ansible-inventory -i inventory.yml --list # グラフ形式で確認 ansible-inventory -i inventory.yml --graph # 疎通確認(pingモジュール) ansible -i inventory.yml webservers -m ping
playbookの基本構文と作成方法
1. playbookの最小構成
playbook は YAML 形式で記述する「自動化の設計書」です。以下が最小限の構成です。# site.yml --- - name: Webサーバー初期設定 hosts: webservers become: yes # sudo で実行 tasks: - name: Apacheのインストール ansible.builtin.dnf: name: httpd state: present - name: Apacheの起動と自動起動有効化 ansible.builtin.service: name: httpd state: started enabled: yes
・hosts:操作するグループまたはホスト名(インベントリと一致させる)
・become:yes にすると sudo(root 権限)で実行
・tasks:実行するタスクのリスト
・name:タスクの説明文(ログに表示される)
・モジュール名:実際に行う操作(dnf, service, copy 等)
2. when条件でOSごとに処理を切り替える
実務では RHEL 系と Ubuntu 系が混在する環境が少なくありません。when 条件を使うと、OS種別によってモジュールを切り替えられます。tasks: - name: Apacheのインストール(RHEL系) ansible.builtin.dnf: name: httpd state: present when: ansible_os_family == "RedHat" - name: Apacheのインストール(Debian系) ansible.builtin.apt: name: apache2 state: present when: ansible_os_family == "Debian"
ansible_os_family は Gathering Facts で自動取得される変数です。このように同一 playbook でマルチOS環境に対応できます。3. よく使うモジュール一覧
| モジュール | 役割 | 使用例 |
|---|---|---|
ansible.builtin.dnf |
RHEL系パッケージ管理 | Apache, nginxのインストール |
ansible.builtin.apt |
Debian系パッケージ管理 | Ubuntu環境でのインストール |
ansible.builtin.service |
サービス管理 | 起動・停止・自動起動設定 |
ansible.builtin.copy |
ファイルのコピー | 設定ファイルの配布 |
ansible.builtin.template |
テンプレートからファイル生成 | Jinja2変数展開付きの設定配布 |
ansible.builtin.user |
ユーザー管理 | ユーザー作成・削除・グループ追加 |
ansible.builtin.file |
ファイル・ディレクトリ管理 | パーミッション設定・シンボリックリンク |
ansible.builtin.lineinfile |
ファイル内の行編集 | 設定ファイルの特定行変更 |
ansible.builtin.command |
任意コマンドの実行 | 専用モジュールがない処理 |
ansible.builtin.shell |
シェル経由でコマンド実行 | パイプ・リダイレクトを含む処理 |
ansible-playbookコマンドの基本的な使い方
1. 基本実行
# 基本実行 ansible-playbook -i inventory.yml site.yml # SSH鍵を指定して実行 ansible-playbook -i inventory.yml site.yml --private-key=~/.ssh/id_rsa # sudo パスワードを対話的に入力する場合 ansible-playbook -i inventory.yml site.yml --ask-become-pass
2. 実行前のドライラン(--check)
--check オプションは実際には変更を行わず、何が変わるかを事前確認するためのモードです。本番環境への適用前に必ず使う習慣をつけましょう。--diff を組み合わせると、設定ファイルの変更行が diff 形式で表示されるためさらに確認しやすくなります。# ドライラン(変更は行わず確認のみ) ansible-playbook -i inventory.yml site.yml --check # ドライランと差分表示を組み合わせる(より詳細) ansible-playbook -i inventory.yml site.yml --check --diff
3. 特定のホストやグループだけ実行(--limit)
# 特定ホストのみ実行 ansible-playbook -i inventory.yml site.yml --limit web01.example.com # 特定グループのみ実行 ansible-playbook -i inventory.yml site.yml --limit webservers # 複数ホストをカンマ区切りで指定 ansible-playbook -i inventory.yml site.yml --limit "web01.example.com,web02.example.com"
4. 特定タスクだけ実行(タグ機能)
大規模な playbook では、特定のタスクだけを実行したい場面があります。タグ機能を使うと、対象を絞り込めます。# playbook にタグを付ける例 --- - name: Webサーバー設定 hosts: webservers become: yes tasks: - name: Apacheのインストール ansible.builtin.dnf: name: httpd state: present tags: install - name: 設定ファイルのコピー ansible.builtin.copy: src: httpd.conf dest: /etc/httpd/conf/httpd.conf tags: config # installタグのタスクのみ実行 ansible-playbook -i inventory.yml site.yml --tags install # configタグのタスクをスキップ ansible-playbook -i inventory.yml site.yml --skip-tags config
5. 冗長ログでデバッグ(-v / -vvv)
# 標準の詳細ログ ansible-playbook -i inventory.yml site.yml -v # さらに詳細なデバッグ情報(SSH接続情報も表示) ansible-playbook -i inventory.yml site.yml -vvv # 最大詳細ログ(機密情報も表示されるため開発環境限定・本番では使用禁止) ansible-playbook -i inventory.yml site.yml -vvvv
実務でよく使う構成パターン
1. 変数を使って設定値を管理する
ハードコーディングを避け、変数で設定値を管理することで playbook の再利用性が大幅に上がります。# site.yml --- - name: Webサーバー設定 hosts: webservers become: yes vars: http_port: 80 max_clients: 200 server_name: "{{ inventory_hostname }}" tasks: - name: httpdのインストール ansible.builtin.dnf: name: httpd state: present - name: 設定ファイルをテンプレートから生成 ansible.builtin.template: src: httpd.conf.j2 dest: /etc/httpd/conf/httpd.conf owner: root group: root mode: '0644'
・group_vars/all:全グループ共通の変数ファイル
・group_vars/グループ名:グループ別の変数ファイル
・host_vars/ホスト名:ホスト別の変数ファイル
・playbook内のvars:playbook単位の変数
・--extra-vars(-e):コマンドライン引数(最高優先度)
2. ハンドラーで変更があった時だけ再起動する
設定ファイルが変更されたときだけサービスを再起動したい——この要件を安全に実装するのがハンドラーです。--- - name: Apacheの設定と起動 hosts: webservers become: yes handlers: - name: apache再起動 ansible.builtin.service: name: httpd state: restarted tasks: - name: Apacheのインストール ansible.builtin.dnf: name: httpd state: present - name: 設定ファイルのコピー ansible.builtin.copy: src: httpd.conf dest: /etc/httpd/conf/httpd.conf notify: apache再起動 # 変更があった時だけハンドラーを呼び出す
notify で指定した処理が「変更(changed)」になった時のみ、playbook の末尾で1度だけ実行されます。複数のタスクが同じハンドラーを notify しても、1回しか実行されないため、無駄な再起動を防ぎます。3. 実行結果の確認とデバッグ
実サーバー上での実行結果(出力例)を確認しておきます。[admin@controller ~]$ ansible-playbook -i inventory.yml site.yml PLAY [Webサーバー初期設定] **************************************************** TASK [Gathering Facts] ********************************************************* ok: [web01.example.com] ok: [web02.example.com] TASK [Apacheのインストール] ***************************************************** changed: [web01.example.com] changed: [web02.example.com] TASK [Apacheの起動と自動起動有効化] ******************************************** changed: [web01.example.com] changed: [web02.example.com] PLAY RECAP ********************************************************************* web01.example.com : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 web02.example.com : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
・ok:変更なし(すでに正しい状態)
・changed:変更を適用した
・failed:エラーが発生した
・unreachable:SSH接続できなかった
・skipped:条件(when)によりスキップ
4. ローリングデプロイ(serialオプション)
本番に10台のWebサーバーがある状態でPlaybookを実行すると、デフォルトでは全台に一斉に変更が適用されます。万が一障害が発生した場合のリスクを下げるために、serial オプションで1回に更新する台数を絞るのが実務でよく使われるパターンです。# site.yml --- - name: Webサーバーの構成適用 hosts: webservers serial: 2 # 一度に2台ずつ更新 max_fail_percentage: 30 # 30%超失敗で中断 become: yes roles: - nginx
max_fail_percentage を設定しておくと、一定割合以上のサーバーで失敗が発生した時点でPlaybookが中断されます。無言で全台に壊れた設定が広がる事態を防ぐための安全装置です。ロールを使ってplaybookを整理する
playbook が大きくなってきたら、ロール(Role)を使って機能ごとに分割します。ロールは Ansible の推奨する構成管理パターンで、再利用性が大幅に向上します。1. ロールのディレクトリ構造
# ansible-galaxy コマンドでロールの雛形を作成 ansible-galaxy init roles/webserver # 生成されるディレクトリ構造 roles/ └── webserver/ ├── tasks/ │ └── main.yml # メインのタスク定義 ├── handlers/ │ └── main.yml # ハンドラー定義 ├── templates/ │ └── httpd.conf.j2 # Jinja2テンプレート ├── files/ ├── vars/ │ └── main.yml # 変数定義 ├── defaults/ │ └── main.yml # デフォルト変数 ├── meta/ │ └── main.yml # ロールのメタ情報 └── README.md
2. ロールをplaybookから呼び出す
# site.yml(ロール呼び出し版) --- - name: Webサーバーの構成 hosts: webservers become: yes roles: - webserver # roles/webserver/ を自動的に読み込む - firewall # roles/firewall/ も適用
3. ansible-galaxy collectionsでサードパーティ製ロールを活用する
自作ロール以外にも、ansible-galaxy コミュニティが公開している高品質なコレクションを活用できます。# コレクションのインストール(例:Nginx公式コレクション) ansible-galaxy collection install nginxinc.nginx_core # インストール済みコレクション一覧 ansible-galaxy collection list
requirements.yml に記述しておくと、CI/CD環境でも一括インストールできて便利です。CI/CDへの組み込み(GitHub Actions連携)
PlaybookをGitで管理するだけでは不十分です。「誰がいつ実行したかが追跡できない」「lint違反のあるPlaybookが本番に流れてしまう」——こうした問題が手動実行への依存で必ず起きます。GitHub ActionsにPlaybookを組み込むことで、PRのたびに構文チェックが自動で走り、mainブランチへのマージを実行トリガーにできます。1. セルフホストランナーをコントロールノードに使う
GitHubがホストする標準ランナーはNATの外側に位置するため、プライベートなサーバーへのSSH接続ができません。社内ネットワーク内またはVPNアクセス可能なサーバーにセルフホストランナーを配置し、Ansibleのコントロールノードとして使うのが最もシンプルな設計です。セルフホストランナーから対象サーバーへのSSH(22/tcp)疎通は、Linux ポート確認の全コマンドを参考にして事前に確認してください。
2. PRトリガーで構文チェックとlintを自動実行する
# .github/workflows/ansible-syntax-check.yml name: Ansible Syntax Check on: pull_request: paths: - 'playbooks/**' - 'roles/**' - 'inventory/**' jobs: syntax-check: runs-on: self-hosted steps: - uses: actions/checkout@v4 - name: Playbookの構文チェック run: | ansible-playbook playbooks/site.yml --inventory inventory/production/hosts.ini --syntax-check env: ANSIBLE_HOST_KEY_CHECKING: "False" - name: ansible-lintの実行 run: | ansible-lint playbooks/site.yml --profile production
3. mainマージ後にdry-runと本番適用を行う
本番への自動適用は「mainへのpush」をトリガーにして、dry-runと本番適用の2段階に分けます。# .github/workflows/ansible-deploy.yml name: Ansible Deploy on: push: branches: - main jobs: dry-run: runs-on: self-hosted steps: - uses: actions/checkout@v4 - name: SSH鍵の配置 run: | mkdir -p ~/.ssh echo "${{ secrets.ANSIBLE_SSH_PRIVATE_KEY }}" > ~/.ssh/ansible_rsa chmod 600 ~/.ssh/ansible_rsa - name: Vaultパスワードファイル作成 run: printf '%s' "${{ secrets.ANSIBLE_VAULT_PASSWORD }}" > /tmp/vault_pass.txt - name: dry-run(--check --diff) run: | ansible-playbook playbooks/site.yml --inventory inventory/production/hosts.ini --vault-password-file /tmp/vault_pass.txt --check --diff --private-key ~/.ssh/ansible_rsa env: ANSIBLE_HOST_KEY_CHECKING: "False" - name: Vaultパスワードファイル削除 if: always() run: rm -f /tmp/vault_pass.txt deploy: needs: dry-run runs-on: self-hosted environment: production # 承認者によるレビューゲート steps: - uses: actions/checkout@v4 # ... (dry-runと同様にPlaybook本番適用)
printf '%s' を使うことで、echo で発生する末尾改行もなくせます。environment: production にEnvironment protection rulesで承認者を設定しておくと、dry-run完了後に本番適用ジョブが自動開始せず、担当者がGitHub上で承認するまで待機します。よくあるエラーと対処法
1. SSH接続エラー「UNREACHABLE」
# エラー例 fatal: [web01.example.com]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh", "unreachable": true} # 疎通確認 ansible -i inventory.yml web01.example.com -m ping # SSHで直接接続テスト ssh -i ~/.ssh/id_rsa admin@web01.example.com # インベントリの接続情報を確認 ansible-inventory -i inventory.yml --host web01.example.com
・SSH鍵の指定ミス:
ansible_ssh_private_key_file が正しいか確認・known_hostsへの未登録:初回接続時は
ansible_host_key_checking=false を一時的に設定・ファイアウォールのポートブロック:Linux ポート確認の全コマンド で22番ポートの状態を確認
・ユーザー名の誤り:
ansible_user の設定を見直す2. become(sudo)権限エラー
# エラー例 fatal: [web01.example.com]: FAILED! => {"msg": "Missing sudo password"} # 対処1:インタラクティブにパスワードを入力 ansible-playbook -i inventory.yml site.yml --ask-become-pass # 対処2:sudoersでパスワードなしを設定(NOPASSWD) # /etc/sudoers に以下を追加(visudo で編集) # ansibleuser ALL=(ALL) NOPASSWD: ALL
3. モジュールの実行に失敗する「MODULE FAILURE」
# エラー例 fatal: [web01.example.com]: FAILED! => {"changed": false, "msg": "No package matching 'httpd' found available"} # 対処:パッケージリポジトリの確認 # -vvv でより詳細なエラー内容を確認 ansible-playbook -i inventory.yml site.yml -vvv # 手動でパッケージ確認(アドホックコマンド) ansible -i inventory.yml webservers -m shell -a "dnf list available httpd" --become
4. Vault暗号化ファイルの復号に失敗する
ansible-vault で暗号化した変数ファイルを使っているときに「Decryption failed」が出る場合、パスワードの不一致が原因のほぼ全てです。CI/CD環境でGitHubシークレット経由でパスワードを渡す場合は、末尾改行の混入に要注意です。# 問題:echo は末尾に改行を付与するためパスワードが一致しない echo "$VAULT_PASSWORD" > /tmp/vault_pass.txt # NG # 解決:printf '%s' で末尾改行を除去してから書き出す printf '%s' "$VAULT_PASSWORD" > /tmp/vault_pass.txt # OK # 手動でVaultファイルを検証する ansible-vault decrypt group_vars/production/vault.yml --ask-vault-pass
5. 冪等性が担保されていない処理を書いてしまう
command モジュールや shell モジュールは冪等性がないため、毎回実行されます。同じ処理を繰り返してもサーバーの状態が変わらない書き方を意識しましょう。# NGパターン(毎回ユーザーを作ろうとする) - name: ユーザー作成 ansible.builtin.shell: useradd appuser # OKパターン(すでに存在していれば変更なし) - name: ユーザー作成(冪等) ansible.builtin.user: name: appuser state: present shell: /bin/bash
ansible-playbookの主要オプション早見表
| やりたいこと | コマンド・オプション |
|---|---|
| 基本実行 | ansible-playbook -i inventory.yml site.yml |
| ドライラン(変更なし確認) | ansible-playbook -i inventory.yml site.yml --check |
| 差分付きドライラン | ansible-playbook -i inventory.yml site.yml --check --diff |
| 特定ホストのみ実行 | ansible-playbook -i inventory.yml site.yml --limit web01 |
| タグ指定で部分実行 | ansible-playbook -i inventory.yml site.yml --tags install |
| sudo パスワードを対話入力 | ansible-playbook -i inventory.yml site.yml --ask-become-pass |
| 変数をコマンドラインで渡す | ansible-playbook -i inventory.yml site.yml -e "env=production" |
| デバッグログの表示 | ansible-playbook -i inventory.yml site.yml -vvv |
| 並列実行数を制限(デフォルト5) | ansible-playbook -i inventory.yml site.yml -f 2 |
| ステップ実行(タスクごとに確認) | ansible-playbook -i inventory.yml site.yml --step |
| ローリングデプロイ(N台ずつ) | playbook内で serial: N を指定 |
本記事のまとめ
ansible-playbook コマンドは、Linux サーバーの構成管理を「手作業からコード」へ転換する強力なツールです。YAML 形式の playbook でサーバーの「あるべき状態」を定義し、何度実行しても同じ結果になる冪等性が最大の強みです。さらに GitHub Actions と組み合わせることで、構文チェックから本番適用までを自動化し、手動実行の属人化リスクを設計で解消できます。| やること | ポイント |
|---|---|
| インベントリ定義 | ターゲットサーバーをINI/YAML形式でグループ化して管理する |
| 本番適用前の確認 | --check --diffでドライランと変更差分を視覚化する |
| 変更時だけ再起動 | ハンドラー(handlers)でサービス再起動を安全に制御する |
| playbookの整理・再利用 | ロール(roles)で機能ごとに分割して管理する |
| 段階的なデプロイ | serialオプションで一度に更新する台数を制限してリスクを下げる |
| CI/CDへの組み込み | GitHub Actions+セルフホストランナーでPlaybook検証・デプロイを自動化 |
| エラー発生時のデバッグ | -vvvで詳細ログを確認し、原因を特定してから対処する |
手作業で30分かかる初期設定が、ansible-playbook 1回で3分に短縮された——そういう体験が、自動化への確信を生みます。まずは手元の検証環境で試してみてください。
Linux Master Pro Seminar(2日間ハンズオン)では Ansible・systemd・セキュリティ設定まで、
実際のサーバーを触りながら自動化と構成管理を習得できます。
>> セミナー詳細・お申込みはこちら
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 次のページへ:mysqldumpコマンドでMySQLデータベースをバックアップする方法|フルバックアップから特定テーブル・リストアまで
- 前のページへ:pkillコマンドとpgrepコマンドでプロセスを名前で操作する方法|kill・psの代替と実践例
- この記事の属するカテゴリ:Linuxtipsへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます