Ansibleの使い方は、制御ノードへのインストール、ansible.cfgとインベントリの作成、アドホックコマンドでの単発作業、Playbookでの手順化という4段階で覚えると迷いません。この記事では、ansible-core 2.21系を前提に、検証用のサーバー2台へ接続するところから、ping・shell・copyのアドホックコマンド、変数とloopで複数ユーザーを作る最初のPlaybookまでを、そのまま打てるコマンド付きで示します。最後に、アドホックで済ませる作業とPlaybookに書く作業の境界も整理しました。版番号と仕様は2026年10月時点の公式ドキュメントとPyPIで確かめた内容です。
まとめ|Ansibleの使い方はインストール・インベントリ・アドホック・Playbookの4段階
入門で押さえる順番は次のとおりです。
- 制御ノード(Linux・macOS・WSL)にPythonの仮想環境を作り、
ansible-coreを系列固定で入れる。管理対象のサーバーには何も入れない - 作業ディレクトリに
ansible.cfgとinventory.iniを置き、設定をそのディレクトリの中に閉じ込める ansible all -m ansible.builtin.pingが全台でpongを返すまで、Playbookには進まない- 1回きりの確認や再起動はアドホックコマンドで流し、2回以上繰り返す作業や手順書に残す作業はPlaybookに書く
Playbookを2回流して、2回目がchanged=0になれば入門の手順は完了です。
Ansibleを動かす前提:制御ノードと管理対象ノードの要件と検証環境の構成
Ansibleがエージェントを入れずにSSHで動く仕組みと、構成管理ツールとしての長所・短所はAnsibleとは?エージェントレスの仕組みとメリット・デメリット、Red Hat AAPの制約で扱っています。ここからは手を動かす手順だけを書きます。
制御ノードはLinux・macOS・WSLで、管理対象にはPythonとSSHだけを用意
公式のインストールガイドによると、Ansibleを実行する制御ノードはPythonが動くUNIX系のマシンであればよく、Red Hat系・Debian系・Ubuntu・macOSが対象です。WindowsはWSL上のLinuxでのみ制御ノードになれます。ネイティブのWindowsからは実行できません。
管理対象ノードにはAnsibleを入れる必要がありません。要るのは、SSHでログインできるユーザーと、Ansibleが送り込むモジュールを動かすためのPythonの2つだけです。公式のリリースとメンテナンスの表では、ansible-core 2.21系の制御ノードに必要なPythonは3.12〜3.14、管理対象側は3.9〜3.14とされています。古いCentOS 7のようにPythonが3.6止まりのサーバーは、2.21系の管理対象になりません。
以降の例は、制御ノード1台と、AlmaLinuxなどRHEL系の検証サーバー2台(web01・web02)を想定しています。
ansibleとansible-coreの違いとpipでのインストール・バージョン固定
PyPIには2つのパッケージがあります。ansible-coreは組み込みのモジュールとプラグインだけを含む最小構成で、ansibleはコミュニティが選んだコレクション一式を同梱した大きなパッケージです。PyPIのansible-coreでは2.21.5が最新で(2026年10月5日公開)、同梱版のansibleは14.5.0(2026年10月6日公開)でした。14.x系がcore 2.21系に対応します。
# 制御ノードに仮想環境を作り、ansible-coreを2.21系に固定して入れる
python3 -m venv ~/.venvs/ansible
source ~/.venvs/ansible/bin/activate
pip install "ansible-core==2.21.*"
# 入ったバージョンと、使われているPython・設定ファイルの場所を確認する
ansible --version
入門ではcoreだけで足ります。ネットワーク機器やクラウドのモジュールが必要になった時点で、必要なコレクションだけを追加すれば済むためです。系列を2.21.*で固定しておくと、挙動が変わる系列の更新を自分で決めた時期に寄せられます。公式ガイドにはpipx install ansible-coreで入れる方法も載っており、仮想環境の管理を任せたい場合はこちらでも構いません。
ansible.cfgとインベントリの作り方:作業ディレクトリに設定を閉じ込める
インストール直後の状態では、Ansibleは/etc/ansible/hostsをインベントリとして探します。案件ごとに対象サーバーが違うのが普通なので、設定とインベントリは作業ディレクトリに置きます。
ansible.cfgの読み込み順4段階とプロジェクト直下に置く理由
公式の設定リファレンスでは、設定ファイルは次の順で探され、最初に見つかった1つだけが使われます。
- 環境変数
ANSIBLE_CONFIGで指定したファイル - カレントディレクトリの
ansible.cfg - ホームディレクトリの
~/.ansible.cfg /etc/ansible/ansible.cfg
複数のファイルの設定が合算されるわけではありません。ホームに置いた設定が効かないと悩む原因の多くは、カレントディレクトリに別のansible.cfgがあることです。ansible --versionの出力のconfig file行を見れば、どのファイルが使われているかが分かります。もう1つの例外として、誰でも書き込めるディレクトリ(パーミッション777など)に置いたansible.cfgは、第三者に設定を差し込まれる危険があるため読み込まれません。
# 作業ディレクトリの構成
ansible-intro/
├── ansible.cfg
├── inventory.ini
└── users.yml
# ansible.cfg(全項目入りのひな形は ansible-config init --disabled で出力できる)
[defaults]
inventory = ./inventory.ini
remote_user = deploy
forks = 5
並列で接続する台数forksの既定値は5です。host_key_checkingは既定でTrueのままにしておきます。検証でHost key verification failedが出てもFalseにはせず、一度手でSSH接続するかssh-keyscanでknown_hostsに登録して解消します。Falseにした設定ファイルが本番の作業ディレクトリへ持ち込まれると、接続先のすり替えに気付けなくなるためです。
グループ・変数とansible-inventory –graphによる所属確認
インベントリは、接続先のホストをグループ名で束ねたファイルです。書き方は公式のインベントリガイドにINI形式とYAML形式があり、最初は行数の少ないINI形式で十分です。
# inventory.ini
[web]
web01 ansible_host=192.0.2.11
web02 ansible_host=192.0.2.12
[db]
db01 ansible_host=192.0.2.21
[web:vars]
http_port=8080
# グループ構成と、ホストごとに解決される変数を確認する
ansible-inventory --graph
ansible-inventory --host web01
ansible_hostは接続先のIPアドレスで、行頭のweb01は作業で呼ぶための名前です。[web:vars]に書いた変数の適用範囲は、webグループに属する全ホストです。ansible-inventoryコマンドの--graphはグループの木構造を、--hostはそのホストに最終的に渡る変数を表示するので、Playbookを書く前にここで所属と値を確かめます。ホストが増えて変数が多くなったら、group_vars/web.ymlのようにファイルを分けます。
アドホックコマンドの使い方:ping・shell・copyで単発の作業を流す
アドホックコマンドは、Playbookを書かずに1つのモジュールを複数台へ一度に流す使い方です。接続確認、全台の稼働状況の確認、緊急の再起動のように、手順として残すほどではない作業に向いています。
ansibleコマンドの書式と-mを省略したときのcommandモジュール
公式のアドホックコマンドガイドの書式はansible [対象] -m [モジュール] -a "[引数]"です。対象にはインベントリのグループ名、ホスト名、全台を表すallを書きます。
# 全台への接続とPythonの実行を確認する(pongが返れば成功)
ansible all -m ansible.builtin.ping
# -m を省略すると command モジュールでコマンドを実行する
ansible web -a "uptime"
# root権限が要る操作は --become、sudoのパスワード入力が要るなら -K を足す
ansible web -a "/usr/bin/systemctl is-active sshd" --become -K
-mを書かないときの既定モジュールはansible.builtin.commandです。pingで失敗する原因は、ほぼSSH鍵かremote_userの指定のどちらかです。-vvvを付けて流すと、実際に使われたユーザーと鍵が表示されるので、Playbookへ進む前にここで潰します。
shellとcommandの使い分け:パイプやリダイレクトが要るときだけshell
commandモジュールはシェルを通さずにコマンドを実行するため、|や>、$HOMEのような変数展開が使えません。パイプが要るときだけansible.builtin.shellに切り替えます。
# パイプを使うので shell モジュールを指定する
ansible web -m ansible.builtin.shell -a "df -h | grep -v tmpfs"
shellモジュールのリファレンスは、シェルの機能が不要な場面ではcommandを使うよう勧めています。shellは引数がそのまま/bin/shに渡るので、変数を埋め込むと;などで別のコマンドを差し込まれる余地が生まれるためです。変数を渡すときはquoteフィルタで囲みます。どちらのモジュールも状態を判断できず、流すたびにchangedを返す点も覚えておきます。
copy・dnf・serviceモジュールで状態を宣言しchangedを読む
ファイルの配布やパッケージの導入は、コマンドではなく専用モジュールで書きます。モジュールは「こうなっていてほしい状態」を受け取り、すでにその状態なら何もしません。
# ファイルを配る(同じ内容がすでにあれば ok、書き換えたら changed)
ansible web -m ansible.builtin.copy -a "src=./motd dest=/etc/motd mode=0644" --become
# パッケージを入れる(-C を付けると変更せずに結果だけを見る)
ansible web -m ansible.builtin.dnf -a "name=chrony state=present" --become -C
# サービスを起動する
ansible web -m ansible.builtin.service -a "name=chronyd state=started enabled=true" --become
同じコマンドを2回流すと、1回目はCHANGED、2回目はSUCCESS(変更なし)と表示が変わります。何度流しても結果が同じになるこの性質が冪等性で、shellで書いた作業との一番大きな違いです。-C(--check)を付けると、対象ホストを一切変更せずに「変わるかどうか」だけを返します。
setupモジュールでファクトを集めOSやメモリ量を一覧で確認
Ansibleは接続先のOS・IPアドレス・メモリ量などを「ファクト」として集めます。アドホックでansible.builtin.setupを流すと、その中身を確認できます。
# OSの系統とバージョンだけを絞り込んで表示する
ansible all -m ansible.builtin.setup -a "filter=ansible_distribution*"
# メモリ量(MB)を確認する
ansible all -m ansible.builtin.setup -a "filter=ansible_memtotal_mb"
フィルタなしで流すと1台あたり数百行のJSONが出るので、filterで項目を絞ります。ここで確かめたansible_distribution_major_versionのような名前は、Playbookのwhenで「RHEL 9系だけに流す」といった条件分岐にそのまま使えます。
最初のPlaybookを実行する:変数とloopで複数ユーザーを作る手順
アドホックで接続とモジュールの動きを確かめたら、手順をファイルに書きます。題材は「webグループの全台に、運用担当者のユーザーを3人分作る」作業です。
users.ymlの全文とhosts・vars・loop・itemの役割
---
- name: 運用担当者のユーザーを作成する
hosts: web
become: true
vars:
ops_users:
- name: tanaka
uid: 2001
- name: suzuki
uid: 2002
- name: sato
uid: 2003
tasks:
- name: 運用担当者のユーザーを作る
ansible.builtin.user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
groups: wheel
append: true
state: present
loop: "{{ ops_users }}"
loop_control:
label: "{{ item.name }}"
hosts: webはインベントリのwebグループを指し、become: trueで全タスクをroot権限で実行します。varsに書いたリストをloopに渡すと、タスクが要素の数だけ繰り返され、各回の要素を参照するための変数がitemです。公式のループガイドによるとloopは2.5で加わった書き方で、古い記事に多いwith_itemsより推奨されています。loop_controlのlabelは出力を名前だけに絞る表示用の設定で、機密を隠す機能ではない点に注意してください。
値が{{で始まるときは式全体を引用符で囲みます。公式の変数ガイドにある規則で、引用符を外すとYAMLの構文エラーになります。
ansible-playbookで流して2回目にchanged=0を確かめる流れ
# 構文だけを確認する(ホストには接続しない)
ansible-playbook users.yml --syntax-check
# 変更せずに結果を予測する
ansible-playbook users.yml --check
# 1台に絞って適用し、同じコマンドをもう一度流す
ansible-playbook users.yml --limit web01
ansible-playbook users.yml --limit web01
# 残りの台へ適用する
ansible-playbook users.yml
実行の最後に出るPLAY RECAPで、1回目はユーザーを作った分だけchanged=1、2回目はchanged=0になれば正しく書けています。2回目にもchangedが出るなら、どこかでshellやcommandを使っているか、毎回変わる値を渡している状態です。設定ファイルの配布と再起動の連動(handlers)や、--diffでの差分確認、変数の優先順位についてはAnsible Playbookの書き方と実行手順:–checkでのdry-runとhandlersで詳しく扱っています。
ansible-lintで入門者がつまずく書き方を流す前に洗い出す
pip install ansible-lint
ansible-lint users.yml
ansible-lintはPlaybookの書き方を点検するツールで、PyPIでは2026年10月13日公開の26.10.1が最新でした。モジュールをuserのような短縮名で書いている箇所、changed_whenの無いcommandタスク、nameの無いタスクなど、入門段階で入り込みやすい書き方を流す前に指摘します。手元で通るようになったら、同じコマンドをCIにも入れておくと、レビューで書式を指摘する手間が減ります。
アドホックとPlaybookの使い分け:手順書に残す作業はPlaybookへ移す
使い方を覚えた後に迷うのは、どの作業をPlaybookにするかです。ここは条件で決めてしまいます。
アドホックで済ませてよい作業とPlaybookに書くべき作業の境界
| 作業の例 | 向く書き方 | 判断の理由 |
|---|---|---|
| 全台の疎通・稼働時間の確認 | アドホック | 状態を変えず、記録も不要 |
| 障害時の一斉再起動 | アドホック | 1回限りで、手順の再利用がない |
| ユーザー追加・パッケージ導入 | Playbook | サーバー追加のたびに同じ手順を流す |
| 設定ファイルの配布と再起動 | Playbook | 順番と変更時だけの再起動を保証したい |
| 手順書に書いて引き継ぐ作業 | Playbook | 手順書そのものをコードにできる |
境界は「2回目があるか」と「他の人が流すか」の2つです。どちらかに当てはまる作業は、アドホックのコマンドを手順書に貼るのをやめ、Playbookとしてリポジトリに置きます。逆に、shellのコマンドを並べるだけになる作業はPlaybookにしても再実行で安全にならないため、Ansibleに載せるのを見送る判断が必要です。どの運用作業から自動化するかの費用対効果はAnsibleによる運用自動化の進め方で試算式とあわせて整理しています。
入門の次に読む順番:Playbook設計・Vault・Galaxy・Windows管理
入門の4段階を通したら、次は扱う対象に合わせて進みます。
- Playbookを本番で流す:Playbookの書き方と実行手順でhandlers・
--check --diff・tagsを押さえる - パスワードやAPIキーを扱う:Ansible Vaultの使い方で機密変数を暗号化する
- 他人の書いたロールを使う:Ansible Galaxyの使い方で
requirements.ymlによる依存管理を覚える - Windowsサーバーも管理する:AnsibleでWindowsを管理する手順でWinRMとSSHの接続設定を行う
- Terraformで作ったサーバーを管理する:TerraformとAnsibleの連携手順でTerraformの出力をインベントリに取り込む
最優先はVaultです。インベントリや変数ファイルにパスワードを平文で書いたままリポジトリへ入れると、後から履歴ごと消す作業が発生します。
社内にAnsibleを根づかせる段階で外部の支援を入れる判断
1人の担当者が手元で流しているうちは、この記事の範囲で足ります。問題になるのは、書ける人が1人しかいないままPlaybookが増え、その人の異動で誰も直せなくなる場面です。外部に頼る場合は、Playbookを納品物として受け取るだけでなく、インベントリと変数の置き場所、lintとdry-runの手順まで含めて引き継げる形で残してもらうことが条件になります。一創では、既存の手順書の棚卸しからPlaybook化、CIでのansible-lint実行、社内メンバーへの引き継ぎまでをDevOps・CI/CD導入支援として請け負っています。
よくある質問
Ansibleの使い方を学び始めた段階で多い質問に答えます。
WindowsのパソコンからAnsibleを使えますか?
ネイティブのWindowsは制御ノードとしてサポートされていません。Windowsのパソコンから使う場合は、WSLでUbuntuなどのLinuxを動かし、その中にansible-coreを入れます。一方、Windowsサーバーを管理対象として扱うことは可能です。その場合は制御ノードからWinRMかSSHで接続し、ansible.windowsコレクションのモジュールを使います。
Host key verification failedで止まるときはどうしますか?
接続先のホスト鍵が制御ノードのknown_hostsに登録されていないか、サーバーの再構築で鍵が変わったことが原因です。一度手でSSH接続して鍵を確認するか、ssh-keyscanで登録します。host_key_checking = Falseで回避する方法も見かけますが、接続先のすり替えを検知できなくなるので、検証環境の使い捨ての設定以外では使わないでください。
パスワード認証のサーバーにも接続できますか?
接続できます。-k(--ask-pass)を付けると実行時にSSHのパスワードを尋ねられます。ただし制御ノードにsshpassが必要で、台数が増えるほど入力の手間も増える仕組みです。入門の段階でssh-copy-idを使って公開鍵認証に切り替えておくと、CIからの実行にもそのまま移れます。
ansible-coreのバージョンはいつ上げればよいですか?
ansible-coreは約半年ごとに新しい系列が出ます。2.21系は2026年5月に公開され、2027年11月にサポートが終わる予定です。系列を2.21.*のように固定してパッチ版だけを追い、次の系列へは検証環境でPlaybookを流してchanged=0が変わらないことを確かめてから上げます。制御ノードのPythonの対応範囲も系列ごとに変わるので、同時に確認します。
変数はインベントリとPlaybookのどちらに書けばよいですか?
サーバーや環境によって変わる値はインベントリ側(group_vars・host_vars)に、どの環境でも変わらない値はPlaybookのvarsに書きます。同じ名前の変数を両方に書くと、優先順位の高いPlaybook側が勝つため、環境ごとの値が効かなくなる点に注意が必要です。実行時に-eで渡した値はどこに書いた値よりも優先されるため、一時的な上書き以外には使わないようにします。
関連記事
- Ansible Playbookの書き方と実行手順:–checkでのdry-runとhandlers【2.21系】:本記事の次に読む、Playbookを本番で流すための書き方と段階実行。
- Ansibleとは?エージェントレスの仕組みとメリット・デメリット、Red Hat AAPの制約:Ansibleの仕組みと採用判断の前提。
- Ansibleによる運用自動化の進め方:対象作業の選び方と費用対効果・失敗パターン:どの作業から自動化するかを決める判断材料。
- 構成管理とは?CMDB・IaC・ソフトウェア構成管理の違いと運用体制の作り方:Ansibleを運用体制の側から位置付けた記事。
- 構成管理ツールの比較と選び方|Ansible・Terraform・Chef・Puppet・OpenTofuの選定条件:Ansible以外の選択肢との比較。