Ansible入門でよく聞くつまずきです。コマンドのオプションを調べる前に、まず「どのノードに・どのユーザーで・どの鍵で接続するか」という接続設計を固めることが先決です。インベントリの書き方1つで、同じPlaybookが動いたり動かなかったりします。
この記事では、Ansibleの接続設計の全体像を解説します。SSH鍵認証の設定からインベントリ変数の書き方、踏み台サーバー(ProxyJump)経由の構成パターンまで、RHEL 9.4 / Rocky Linux 9 / Ubuntu 24.04 LTSで動作確認した手順を順番に紹介します。
この記事のポイント
・Ansibleの接続はインベントリの変数(ansible_host / ansible_user等)で制御する
・SSH鍵配布はssh-copy-idで行い、known_hostsの確認を先に済ませる
・踏み台経由はansible_ssh_common_argsにProxyJumpを指定するだけ
・ansible pingが全ホストでSUCCESSになれば接続設計は完成
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜ接続設計がAnsibleプロジェクトの土台になるのか
Ansibleの自動化は「コントロールノードからターゲットノードへSSHで入り、Pythonモジュールをリモート実行する」仕組みで動いています。ChefやPuppetのようにエージェントソフトウェアをターゲット側にインストールする必要がなく、ターゲット側にSSHデーモンとPython 3がある環境であれば動作します。この設計の利点は「既存サーバーに手を加えずに管理下に置けること」ですが、裏返すと「SSH接続の設計が確実でないとPlaybookが1行も実行されない」という意味でもあります。インベントリの接続変数が間違っていると、
ansible-playbookを実行してもすべてのタスクがUNREACHABLEで失敗します。接続設計を最初に固める理由は3つあります。
・再実行可能性:鍵と接続変数をインベントリに記録することで、どのエンジニアが実行しても同じ環境に繋がる
・最小権限の実現:接続ユーザーとsudoへのbecome設定を明示することで権限の見える化ができる
・環境分離:本番 / ステージングのインベントリを分けることで誤操作を防げる
Ansibleが接続する仕組み(SSHとインベントリ変数の関係)
1. コントロールノードとターゲットノードの役割
Ansibleの世界では2種類のノードが登場します。・コントロールノード:
ansible / ansible-playbookコマンドを実行するマシン。LinuxまたはmacOSが必要(Windowsは非対応)。・ターゲットノード(マネージドノード):管理される対象のサーバー。SSHデーモンとPython 3があれば対応できる。
コントロールノードからターゲットノードへはSSHで接続し、Python一時モジュール(
/tmp/.ansible/配下に転送)を経由してタスクを実行します。実行後、一時ファイルは削除されます。実務では1台の踏み台サーバー(Bastionホスト)をコントロールノード兼用にするケースが多くあります。VPNや閉域網内に構築したサーバーをコントロールノードにして、ProxyJump経由で外部から操作するパターンも使われます。
2. 静的インベントリファイルの構造と接続変数
インベントリはAnsibleが「誰に・何を実行するか」を決める設定ファイルです。INI形式とYAML形式の2通りで書けます。接続変数はホスト個別(host_vars/)またはグループ単位(group_vars/)で分離して管理するのがベストプラクティスですが、インベントリファイルに直接記述することもできます。代表的な接続変数を確認しておきます。
・ansible_host:接続先のIPアドレスまたはホスト名(DNSで解決できない環境ではIPを直書きする)
・ansible_user:SSH接続に使うOSユーザー名
・ansible_port:SSH待ち受けポート(デフォルトは22)
・ansible_ssh_private_key_file:使用するSSH秘密鍵のパス
・ansible_become:
trueにするとsudoに昇格して実行・ansible_become_user:昇格後のユーザー名(デフォルトはroot)
INI形式のインベントリ例です。
# inventory/hosts.ini [webservers] web01 ansible_host=192.168.10.11 ansible_user=rocky ansible_ssh_private_key_file=~/.ssh/ansible_id_rsa [dbservers] db01 ansible_host=192.168.10.21 ansible_user=rocky ansible_ssh_private_key_file=~/.ssh/ansible_id_rsa [all:vars] ansible_become=true ansible_become_user=root
inventory/hosts.yml)です。all: vars: ansible_become: true ansible_become_user: root children: webservers: hosts: web01: ansible_host: 192.168.10.11 ansible_user: rocky ansible_ssh_private_key_file: ~/.ssh/ansible_id_rsa dbservers: hosts: db01: ansible_host: 192.168.10.21 ansible_user: rocky ansible_ssh_private_key_file: ~/.ssh/ansible_id_rsa
SSH鍵認証でAnsibleを動かす実践手順
1. SSH鍵ペアの生成とターゲットノードへの配布
まずコントロールノードでAnsible専用のSSH鍵ペアを生成します。既存の個人鍵を使い回す方法もありますが、Ansible専用鍵を分けておくと鍵を失効させたり権限を絞ったりする管理がしやすくなります。# コントロールノードで実行 # Ansible専用のED25519鍵ペアを生成(パスフレーズなし) ssh-keygen -t ed25519 -C "ansible-control" -f ~/.ssh/ansible_id_rsa -N "" # 確認 ls -la ~/.ssh/ansible_id_rsa* # 出力例: # -rw------- 1 rocky rocky 399 Aug 5 09:12 /home/rocky/.ssh/ansible_id_rsa # -rw-r--r-- 1 rocky rocky 93 Aug 5 09:12 /home/rocky/.ssh/ansible_id_rsa.pub
ssh-copy-idが使える環境では1コマンドで完了します。# 公開鍵をターゲットノードへ配布 ssh-copy-id -i ~/.ssh/ansible_id_rsa.pub rocky@192.168.10.11 # 手動で配布する場合(ssh-copy-idが使えない環境) # ターゲットノードにログインして以下を実行 mkdir -p ~/.ssh chmod 700 ~/.ssh echo "(公開鍵の内容をペースト)" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
2. インベントリで接続変数を設定する
鍵の配布が終わったら、インベントリファイルに接続変数を書き込みます。複数のターゲットノードで同じ鍵・ユーザーを使う場合は、[all:vars]セクションにまとめて定義するとDRYに保てます。# inventory/hosts.ini の内容 [webservers] web01 ansible_host=192.168.10.11 web02 ansible_host=192.168.10.12 [dbservers] db01 ansible_host=192.168.10.21 [all:vars] ansible_user=rocky ansible_ssh_private_key_file=~/.ssh/ansible_id_rsa ansible_become=true ansible_become_user=root
3. ansible pingで疎通確認
インベントリが完成したら、ansible pingモジュールで全ターゲットへの疎通を確認します。pingモジュールはICMPではなく「SSH接続してPythonモジュールを実行できるか」を確認するAnsible固有のテストです。# 全ホストへのping確認 ansible -i inventory/hosts.ini all -m ping # 正常時の出力例: # web01 | SUCCESS => { # "ansible_facts": { # "discovered_interpreter_python": "/usr/bin/python3" # }, # "changed": false, # "ping": "pong" # } # web02 | SUCCESS => { ... } # db01 | SUCCESS => { ... }
ansible.cfgに以下を追加します。本番環境ではこのオプションは推奨しませんが、テスト環境での初期セットアップ時に使います。# ansible.cfg(ansible-playbookを実行するディレクトリに置く) [defaults] host_key_checking = False inventory = inventory/hosts.ini
Ansibleの接続からPlaybook設計まで体系的に学びたい方へ
接続設計はAnsible自動化の入口にすぎません。インベントリ設計・role構造・Vault連携を実際のサーバーで動かしながら学ぶには、ハンズオン形式のセミナーが最短ルートです。
>> Ansible実践セミナーの詳細はこちら
踏み台サーバー(ProxyJump)経由の接続設計
クラウドや閉域網では、ターゲットノードにインターネットから直接SSHできないケースがほとんどです。踏み台サーバー(Bastionホスト)経由でターゲットに入る構成では、ansible_ssh_common_argsにProxyJumpオプションを指定します。下記のような構成を想定しています。
・コントロールノード(ローカルPC)→ 踏み台サーバー(bastion.example.com:22)→ ターゲットノード(192.168.10.11:22)
# インベントリでProxyJumpを設定する [webservers] web01 ansible_host=192.168.10.11 [all:vars] ansible_user=rocky ansible_ssh_private_key_file=~/.ssh/ansible_id_rsa ansible_ssh_common_args='-o ProxyJump=ec2-user@bastion.example.com'
~/.ssh/configに設定を分離するアプローチもあります。インベントリをコードレビューにさらす際に認証情報を減らせる利点があります。# ~/.ssh/config に踏み台設定を書く方法(インベントリをシンプルに保つ) Host bastion HostName bastion.example.com User ec2-user IdentityFile ~/.ssh/bastion_key Host 192.168.10.* ProxyJump bastion IdentityFile ~/.ssh/ansible_id_rsa # この場合のインベントリはシンプルにできる # [webservers] # web01 ansible_host=192.168.10.11 ansible_user=rocky
# 踏み台経由のping確認(コントロールノードで実行) ansible -i inventory/hosts.ini webservers -m ping # 出力(正常時): # web01 | SUCCESS => { # "ansible_facts": { # "discovered_interpreter_python": "/usr/bin/python3.11" # }, # "changed": false, # "ping": "pong" # }
よくある接続エラーと対処法
ansible pingが通らない場合の切り分けパターンをまとめます。「UNREACHABLE - Failed to connect to the host via ssh」が出る
SSH接続自体が届いていない状態です。まず手動でSSH接続が通るか確認します。
# 手動でSSH接続を試みる ssh -i ~/.ssh/ansible_id_rsa rocky@192.168.10.11 # SSH接続できる場合はインベントリの記述を疑う # 接続できない場合はfirewallまたはセキュリティグループを確認
ssコマンドやncで行えます。詳細な確認方法はLinux ポート確認の全コマンドを参照してください。「Permission denied (publickey)」が出る
SSH鍵の設定が一致していない場合に発生します。以下を順番に確認します。
・
ansible_ssh_private_key_fileで指定したパスに秘密鍵が存在するか・ターゲットノードの
~/.ssh/authorized_keysに対応する公開鍵が含まれているか・
~/.ssh/のパーミッションが700、~/.ssh/authorized_keysが600になっているか「sudo: a terminal is required to read the password」が出る
ansible_become=trueを使う場合にパスワードなしsudoが設定されていないと発生します。ターゲットノードの/etc/sudoers.d/配下にパスワードなしsudoを設定します。# ターゲットノード側の /etc/sudoers.d/ansible の設定例 # visudo コマンドで編集するか、新規ファイルを作成する rocky ALL=(ALL) NOPASSWD:ALL
既存のknown_hostsにある鍵とサーバーの鍵が変わった場合(サーバー再構築後など)に発生します。本番環境では変更後のフィンガープリントを手動で確認してからknown_hostsを更新します。Linuxの名前解決の仕組みについてはLinux DNS 設定の基本を参照してください。
# known_hostsから対象ホストのエントリを削除する ssh-keygen -R 192.168.10.11 # 手動でフィンガープリントを確認してから再接続 ssh -i ~/.ssh/ansible_id_rsa rocky@192.168.10.11 # "Are you sure you want to continue connecting (yes/no)?" に yes で登録
まとめ:Ansible接続設計チェックリスト
接続設計の完成を確認するためのチェックリストをまとめました。| 確認項目 | コマンド・確認方法 |
|---|---|
| コントロールノードにAnsibleがインストール済み | ansible --version |
| Ansible専用SSH鍵ペアを生成済み | ls -la ~/.ssh/ansible_id_rsa* |
| 公開鍵をターゲットノードへ配布済み | ssh-copy-id -i ~/.ssh/ansible_id_rsa.pub user@host |
| インベントリに接続変数を記述済み | ansible-inventory -i hosts.ini --list |
| パスワードなしsudoをターゲットに設定済み | ターゲットでsudo -n whoamiが通ること |
| ansible pingが全ホストでSUCCESS | ansible -i hosts.ini all -m ping |
Ansible実践ハンズオンの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

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