5分でできる
3台以上のLinuxサーバーを管理していて、毎回アップデートのたびに1台ずつSSHでログインしてコマンドを打っているなら——その気持ち、よくわかります。Ansibleはこの問題を最もシンプルな方法で解決します:各マシンにSSH接続してコマンドを実行する、それだけです。追加のエージェントインストールも、バックグラウンドで動くデーモンも、余分なポート開放も一切不要です。
コントロールノードにAnsibleをインストールする(CentOS Stream 9)
# EPELリポジトリを有効化
sudo dnf install epel-release -y
# Ansibleをインストール
sudo dnf install ansible -y
# バージョン確認
ansible --version
最初のインベントリファイルを作成する
インベントリファイルは管理したいサーバーのリストです。プロジェクトディレクトリにhosts.iniファイルを作成します:
[webservers]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11
[dbservers]
db1 ansible_host=192.168.1.20
[all:vars]
ansible_user=admin
ansible_ssh_private_key_file=~/.ssh/id_rsa
最初のコマンドを実行する
# 全サーバーに接続確認のpingを実行
ansible all -i hosts.ini -m ping
# webserversグループのuptimeを確認
ansible webservers -i hosts.ini -m command -a "uptime"
# 全マシンのディスク使用量を確認
ansible all -i hosts.ini -m command -a "df -h /"
各マシンから"ping": "pong"が返ってきたら——接続成功です。自動化の準備が整いました。
Ansibleはどのように動作するのか?
「自動化ツール」と聞くと、各サーバーに追加のサービスをインストールしなければならないと思いがちです。Ansibleは違います:毎日サーバー接続に使っているSSHを唯一の通信手段として使います。
アーキテクチャは2つの要素で構成されます:
- Control Node: Ansibleをインストールするマシン(ラップトップまたはジャンプサーバー)。これが1台あれば十分です。
- Managed Nodes: 管理対象のサーバー。SSHとPython 3があれば十分で、最近のほとんどのLinuxディストリビューションに標準搭載されています。
Ansibleコマンドを実行すると、次の順序で処理が行われます:
- インベントリファイルを読み込み、接続先のマシンを特定する
- 各managed nodeにSSH接続する(
-fオプションで並列実行) - Pythonモジュールを一時的に
/tmpにアップロードする - モジュールを実行し、結果を取得後、一時ファイルを即座に削除する
すべての処理はSSH経由で行われ、実行完了後はmanaged nodeに何も残りません。これがAnsibleがエージェントレスと呼ばれる理由です。
実践的なPlaybookを書く
アドホックコマンドは1回限りの素早いタスクに適しています。複数の手順を順番に実行する必要がある場合はPlaybookが必要です——「何を、どのマシンで、どの順番で行うか」を記述するYAMLファイルです。
例:webserversにNginxをインストールするPlaybook
---
- name: Nginxのインストールと設定
hosts: webservers
become: yes # sudoで実行
vars:
nginx_port: 80
tasks:
- name: nginxをインストール
dnf:
name: nginx
state: present
- name: nginx起動とブート時自動起動を有効化
systemd:
name: nginx
state: started
enabled: yes
- name: ファイアウォールでポート80を開放
firewalld:
port: "{{ nginx_port }}/tcp"
permanent: yes
state: enabled
immediate: yes
- name: index.htmlページを作成
copy:
content: "<h1>Server {{ inventory_hostname }} — Deployed by Ansible</h1>"
dest: /var/www/html/index.html
owner: nginx
group: nginx
mode: '0644'
handlers:
- name: nginxをリロード
systemd:
name: nginx
state: reloaded
# playbookを実行
ansible-playbook -i hosts.ini deploy_nginx.yml
# ドライラン:実際に適用せずに変更内容を確認
ansible-playbook -i hosts.ini deploy_nginx.yml --check --diff
--check --diffパラメータは、playbookが何を変更するか確認したい時に非常に便利です——実際にシステムに手を加えることなく、どのファイルのどの行が変更されるかを詳細に表示します。
実体験:1週間で5台のサーバーを移行した話
CentOS 8がEOLを迎えた時、1週間で5台のサーバーをRocky Linuxへ移行しなければなりませんでした。最初は手作業でやろうと思っていました——1台ずつSSHでログインして、Excelのチェックリストに従って作業する方法です。ところが3台目を終えた頃からミスが出始めました:このサーバーはテスト後にSELinuxを有効に戻し忘れた、あのサーバーは違うバージョンのPHPをインストールしてしまった、別のサーバーはJSTのタイムゾーン設定が抜けていた…
その時点で作業を止め、移行プロセス全体をAnsible playbookとして書くことにしました。作成とテストに約2時間かかりましたが——残り2台のサーバーはplaybookで各8分で完了し、完全に統一された状態で、ミスゼロでした。
そのplaybookはその後、新しいサーバーのプロビジョニング時に何度も再利用されました——手順を思い出す必要もなく、チェックリストも不要で、ansible-playbook provision.ymlを実行するだけです。
教訓:サーバーが2〜3台しかない場合でもplaybookを書きましょう。初回の作成コストは、手作業で4番目のステップを間違えた時のデバッグコストより遥かに低いです。
Rolesでコードを整理する
playbookが50タスクを超えてきたら、Rolesに分割することをお勧めします——プロジェクト間での再利用と共有を容易にする標準的なディレクトリ構造です。
# 新しいroleを初期化
ansible-galaxy init roles/nginx
作成後のディレクトリ構造:
roles/nginx/
├── tasks/
│ └── main.yml # メインのタスク
├── handlers/
│ └── main.yml # ハンドラー(サービスの再起動/リロード)
├── templates/
│ └── nginx.conf.j2 # 動的変数を含むJinja2テンプレート
├── vars/
│ └── main.yml # 固定変数
└── defaults/
└── main.yml # デフォルト変数(オーバーライド可能)
playbookでroleを使うとずっとスッキリします:
---
- name: Setup web server stack
hosts: webservers
become: yes
roles:
- common # timezone, hostname, sysctl
- nginx
- php-fpm
- firewall
実践的なTips
1. Ansible Vaultで機密情報を保護する
# パスワード/APIキーを含むファイルを暗号化
ansible-vault encrypt secrets.yml
# 暗号化されたファイルの内容を確認
ansible-vault view secrets.yml
# vaultを使用してplaybookを実行
ansible-playbook site.yml --ask-vault-pass
# またはパスワードファイルを使用(CI/CDに適している)
ansible-playbook site.yml --vault-password-file ~/.vault_pass
2. 多数のサーバーがある場合の高速化
# デフォルトではAnsibleは5ホストを並列実行
# インフラが十分大きければ20に増やす
ansible-playbook -i hosts.ini site.yml -f 20
# またはansible.cfgで設定
[defaults]
forks = 20
3. 本番環境で使用する前にplaybookの品質を確認する
# ansible-lintをインストール
pip install ansible-lint
# プロジェクト全体をlint
ansible-lint
# クイック構文チェック
ansible-playbook deploy.yml --syntax-check
4. プロジェクトにansible.cfgファイルを作成して毎回-iを指定しなくて済むようにする
[defaults]
inventory = hosts.ini
remote_user = admin
private_key_file = ~/.ssh/id_rsa
host_key_checking = False
forks = 10
[privilege_escalation]
become = True
become_method = sudo
このansible.cfgファイルがあれば、コマンドはこれだけになります:
ansible-playbook deploy_nginx.yml
AnsibleはDevOpsの上級者でなくても使えます。シンプルなインベントリファイルといくつかのアドホックコマンドから始めてみましょう——数日後には手動で1台ずつSSHログインしたくなくなっているはずです。それは良い兆候です。

