クラウドや仮想化の普及に伴い、数十台から数百台のLinuxサーバーを手動で構築・設定する運用は限界を迎えました。現在、インフラエンジニアの必須技術となっているのが構成管理ツールを用いたIaC(Infrastructure as Code)です。LinuCレベル2(Version 10.0)では、201試験の主題2.04に「構成管理ツール(Ansible)」が正式に追加され、実務直結の重要テーマとして出題されます。
特に記述式問題(コマ問)では、インベントリファイルのセクション記法、YAML形式によるPlaybookの必須ディレクティブ(hosts、tasks、become)、主要モジュール(dnf、systemd、copy、lineinfile)のパラメータ、そしてcommandとshellモジュールの動作差異が頻出します。本記事では、AlmaLinux 9の実機環境で実際にAnsibleを動作させたログに基づき、基礎から実務Playbookの作成手順までを体系的に解説します。
- ホスト名: linuc-node01 (192.168.2.138)
- OS: AlmaLinux 9.8 (x86_64)
- Ansibleバージョン: ansible-core 2.14.18
- Python環境: Python 3.9.25 / Jinja2 3.1.2
| 公式試験の必須出題範囲 | 主題2.04.6「システム構成ツール」(公式重要度4:Ansible、インベントリ、Playbook構文、YAML記法、冪等性) |
|---|---|
| 現場で役立つ実務拡張 | ドライラン(–check)を用いた安全なCI/CDパイプライン運用、become権限昇格の現場設計 |
目次
1. Ansibleのアーキテクチャとエージェントレスの仕組み
Ansibleが他の構成管理ツール(PuppetやChefなど)と大きく異なる最大の特徴は、管理対象サーバーに専用のエージェントソフトウェアを常駐させる必要がない**エージェントレス(Agentless)アーキテクチャ**を採用している点です。

1.1 エージェントレス構成とSSH / Pythonベースの実行原理
Ansibleの全体構造は、指示を発行する「コントロールノード(管理サーバー)」と、設定が適用される「ターゲットノード(管理対象サーバー)」に分かれます。
- コントロールノード: Ansible本体(
ansible、ansible-playbook)がインストールされたLinuxマシン。Windowsをコントロールノードにすることはできません(WSL経由を除く)。 - ターゲットノード: 通常のLinux環境であれば、**SSHサーバー(sshd)**と**Python(2.7または3.5以上)**が導入されていれば、一切の追加ソフトウェアなしで即座に管理下に置くことができます。
タスク実行時、コントロールノード上のAnsibleは必要な処理を小さなPythonスクリプトとして動的に生成し、SSH経由でターゲットノードの/tmp等へ転送して実行します。処理が完了すると、JSON形式で実行結果を回収し、転送したスクリプトを自動的にクリーンアップします。
1.2 構成管理における冪等性(Idempotency)の重要性
構成管理において極めて重要な概念が**冪等性(べきとうせい: Idempotency)**です。「ある操作を1回実行しても、複数回連続して実行しても、得られる結果(最終的なシステムの状態)が常に同一である」という性質を指します。
- シェルスクリプトの場合:
useradd testuserを2回実行すると、「ユーザーは既に存在します」というエラーになりスクリプトが中断します。エラーを防ぐには事前にid testuser等で存在確認を行う複雑な条件分岐が必要です。 - Ansibleの場合:
state: present(存在するべき)と宣言しておけば、ユーザーが存在しない場合は作成(changed)し、既に存在する場合は何もせず正常終了(ok)します。
2. インベントリファイル(Inventory)の設計とホストグループ
管理対象となるターゲットノードの一覧やグループ分け、接続情報を定義するファイルがインベントリ(Inventory)です。デフォルトの参照パスは/etc/ansible/hostsですが、実務ではプロジェクトごとに任意のファイルを-iオプションで指定します。
2.1 INI形式とYAML形式のインベントリ記法
インベントリは、伝統的なINI形式またはYAML形式で記述できます。試験ではシンプルなINI形式が頻出します。
# 個別ホストの列挙
[webservers]
web01.example.com ansible_host=192.168.2.130
web02.example.com ansible_host=192.168.2.131
[dbservers]
db01.example.com ansible_host=192.168.2.132
# グループを束ねる包含グループ(children)
[production:children]
webservers
dbservers
# グループ共通変数の定義(vars)
[webservers:vars]
http_port=80
ansible_user=developer
試験で問われる主要な組み込み接続変数は以下のとおりです。
| 変数名 | 意味・設定内容 |
|---|---|
ansible_host |
実際に接続するターゲットのIPアドレスまたはFQDN |
ansible_user |
SSH接続時に使用するリモートユーザー名 |
ansible_port |
SSH接続ポート番号(デフォルト22以外の場合に指定) |
ansible_ssh_private_key_file |
SSH秘密鍵ファイルのパス |
ansible_connection |
接続プラグイン(ssh、local、docker等) |
2.2 ansible-inventoryコマンドによる構文検証
作成したインベントリの構文エラーやグループ所属関係を確認するには、ansible-inventoryコマンドを使用します。
$ ansible-inventory -i hosts --graph
@all:
|--@production:
| |--@dbservers:
| | |--db01.example.com
| |--@webservers:
| | |--web01.example.com
| |--web02.example.com
|--@ungrouped:
3. アドホックコマンドによる即時実行(ansible)
Playbookを作成するまでもない単発の操作(全台でのサービス状態確認や疎通確認など)には、ansibleコマンドを用いたアドホックコマンド(Ad-hoc Command)を使用します。
3.1 ansibleコマンドの基本構文と主要モジュール
アドホックコマンドの基本構文は以下のとおりです。
$ ansible <ホストパターン> -m <モジュール名> [-a "<モジュール引数>"]
# ping モジュールによる疎通確認(ICMPではなくPython/SSH応答の検証)
$ ansible localhost -m ping -c local
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
# command モジュールによる単発コマンド実行(-m command は省略可能)
$ ansible localhost -m command -a "uptime" -c local
localhost | CHANGED | rc=0 >>
07:11:30 up 19:39, 0 users, load average: 0.00, 0.00, 0.00
3.2 権限昇格(–become / -b)
パッケージの導入やサービス制御などroot権限が必要な処理を行う場合は、特権昇格オプション**-b(または --become)**を付与します。デフォルトではsudoを用いて昇格します。
$ ansible webservers -b -m dnf -a "name=nginx state=present"
4. Playbookの記法と基本構造(ansible-playbook)
複数のタスクを組み合わせ、サーバーのあるべき状態(Desired State)を定義した設計書がPlaybook(プレイブック)です。フォーマットには可読性の高いYAML形式を使用します。

4.1 YAML構文の基礎ルール
Playbookを記述する際、構文エラーを防ぐための基本ルールは以下のとおりです。
- タブ文字は厳禁: インデントには必ず半角スペース(通常2文字)を使用します。タブ文字が含まれているとパースエラーになります。
- コロン(:)の後の半角スペース: キーと値の区切り記号「
:」の後には、必ず半角スペースを置く必要があります(例:name: httpd)。 - リスト(配列): ハイフンと半角スペース「
-」で列挙します。
4.2 Playbookの基本骨格と実機検証
1つのPlaybookファイル内には、1つ以上の「Play(対象ホストと実行タスクのセット)」を定義します。
---
- name: Setup Webserver Environment
hosts: webservers
become: true
vars:
web_port: 80
tasks:
- name: Install Apache HTTP Server
ansible.builtin.dnf:
name: httpd
state: present
- name: Deploy Custom Configuration
ansible.builtin.template:
src: httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
owner: root
group: root
mode: '0644'
notify: Restart Apache
- name: Ensure Apache is started and enabled
ansible.builtin.systemd:
name: httpd
state: started
enabled: true
handlers:
- name: Restart Apache
ansible.builtin.systemd:
name: httpd
state: restarted
実機環境で作成したテストPlaybookを実行した結果ログです。
$ ansible-playbook -i localhost, -c local test_playbook.yml
PLAY [Test Playbook] ***********************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [Ensure test file exists] *************************************************
changed: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
4.3 ハンドラー(handlers)と通知(notify)の動作ルール
設定ファイルの変更に伴いデーモンを再起動する場合、タスク内で直接再起動を実行するのではなく、notifyとhandlersを組み合わせます。
notifyが指定されたタスクの実行結果が**changed(変更あり)**となった場合のみ、対応するハンドラーの実行が予約されます(状態が変化せずokだった場合は通知されません)。- 複数のタスクから同一のハンドラー名が通知された場合でも、ハンドラーは**全タスクの実行完了後に「1回だけ」**まとめて実行されます。これにより、設定変更のたびに不要な再起動が何度も繰り返されるのを防ぎます。
5. 頻出モジュール一覧と実務的なタスク定義
LinuC 201試験で問われる主要モジュールと、その主要パラメータをカテゴリ別に整理します。
5.1 パッケージ管理モジュール
| モジュール名 | 主要パラメータ | 設定値と動作 |
|---|---|---|
ansible.builtin.dnf( yum) |
namestate |
name: httpd(パッケージ名)state: present(インストール), latest(最新化), absent(アンインストール) |
ansible.builtin.apt |
namestateupdate_cache |
Debian/Ubuntu系用。update_cache: yesで事前にaptリポジトリ情報を更新可能 |
5.2 サービス管理モジュール
| モジュール名 | 主要パラメータ | 設定値と動作 |
|---|---|---|
ansible.builtin.systemd( service) |
namestateenableddaemon_reload |
name: nginx(サービス名)state: started(起動), stopped(停止), restarted(再起動), reloaded(再読み込み)enabled: true(OS起動時の自動有効化)daemon_reload: yes(unitファイル変更時のsystemd再読込) |
5.3 ファイル・設定管理モジュール
| モジュール名 | 主要パラメータ | 設定値と動作 |
|---|---|---|
ansible.builtin.copy |
src, dest, owner, group, mode |
コントロールノード上のファイルをそのままターゲットへ転送・配置 |
ansible.builtin.template |
src, dest, owner, group, mode |
Jinja2テンプレート(.j2)を変数展開してターゲットへ配置 |
ansible.builtin.file |
path, state, mode, owner |
ディレクトリ作成(state: directory)、シンボリックリンク作成(state: link)、ファイル削除(state: absent) |
ansible.builtin.lineinfile |
path, regexp, line, state |
設定ファイル内の特定行を正規表現(regexp)で検索し、指定行(line)に書き換え・追加 |
6. LinuC 201試験(主題2.04.6 システム構成ツール)重要ポイント総整理
試験本番で迷いやすいコマンド構文、オプション、モジュールの特性差を整理します。
6.1 記述式(コマ問)頻出コマンド・ディレクティブ一覧
| コマンド / ディレクティブ | 書式・オプション | 機能詳細 |
|---|---|---|
ansible |
<pattern> -m <mod> -a "<args>" -i <inv> |
アドホックコマンドの即時実行 |
ansible-playbook |
-i <inv> --syntax-check <playbook.yml> |
Playbookの構文検査(実行せずに構文のみ確認) |
ansible-playbook |
-i <inv> -C <playbook.yml> |
ドライラン(実行シミュレーション、--check) |
ansible-doc |
-l / ansible-doc <module> |
モジュールのドキュメントや引数仕様を表示 |
ansible-inventory |
-i <inv> --list / --graph |
インベントリ構成の確認とツリー表示 |
hosts: |
all / webservers / host1:host2 |
Playの適用対象ホスト・グループの指定 |
become: |
true / false |
特権昇格(sudo)の有効化・無効化 |
notify: |
<handler-name> |
タスク変更時におけるハンドラーの呼び出し |
6.2 commandモジュールとshellモジュールの決定的な違い
どちらも任意のOSコマンドを実行するモジュールですが、試験で最も問われる明確な違いが存在します。
- ansible.builtin.command:
デフォルトの実行モジュール。コマンドを直接プロセスとして起動するため、シェル機能(パイプ|、リダイレクト>、ワイルドカード*、環境変数$VAR、バックグラウンド&)は一切解釈されません。安全性が高い反面、複雑なパイプライン処理は記述できません。 - ansible.builtin.shell:
リモートホストのシェル(/bin/sh)経由でコマンドを実行するため、パイプやリダイレクトを含むすべてのシェル機能が利用可能です。
「grep pattern /var/log/messages | wc -l」のようにパイプを含むコマンドをPlaybookで実行させたい場合、commandモジュールを指定するとパイプ文字が引数として扱われエラーとなります。必ずshellモジュールを指定する必要があります。
7. まとめ:コードによる構成管理(IaC)が運用標準となる
Ansibleの真価は、エージェントレスという導入の容易さと、YAML形式による高い可読性、そして何度実行しても安全な「冪等性」にあります。
インベントリによる対象ホストの管理から、タスク定義、変数とテンプレートの活用、ハンドラーによるスマートな再起動制御までの一連の作法をマスターすることは、LinuC 201試験の突破はもちろん、現代のクラウド・インフラ基盤を支えるエンジニアとしての重要な実践力となります。
次回(第7回)は、エンタープライズLinuxの仮想化中核技術である「KVMによるLinux仮想化サーバーの構築とvirsh管理」(QEMU/KVMアーキテクチャ、仮想ディスク形式、ブリッジネットワーク接続、およびvirshによる仮想マシンのライフサイクル制御)を取り上げます。
