- 公開日
- 最終更新日
【入門】Ansibleとは?
この記事を共有する
目次
パーソル&サーバーワークスの髙井です。
AWS を中心としたクラウドインフラの設計・構築・運用を担当しています。
はじめに
Ansible は、サーバーの構成や設定を自動化する構成管理ツールです。
手順書どおりに人が1台ずつ作業する代わりに、「あるべき状態」をファイルに書いておくと、Ansible がその状態になるよう対象サーバーを自動で構成してくれます。
本ブログでは、Ansible の用語・コンポーネント・動作のしくみを整理します。
「Ansible とは何か」「どんな部品が、どんな順番で動くのか」を理解することをゴールにしています。
想定読者
- 「Ansible という名前は聞くが、中で何が動いているのか」を押さえたい方
そもそも Ansible とは
Ansible を一言でいうと、「あるべき状態」を宣言すると、その状態になるよう自動で構成してくれる仕組みです。
「このコマンドを順に実行せよ」という手順の指示ではなく、「最終的にこうなっていてほしい」という状態を書く点が特徴です。
Ansible には、ほかのツールと比べて分かりやすい特徴が2つあります。
「エージェントレス」と「冪等性(べきとうせい)」です。
どちらも後ほど節を分けて説明しますが、先に用語を整理しておきます。
押さえておきたい基本用語
ここを押さえておくと、この後の説明とコード例が読めるようになります。
| 用語 | 意味 |
|---|---|
| Control Node | Ansible を実行する側のサーバー。ここから対象へ指示を送る |
| Managed Node | Ansible に構成される側のサーバー。作業対象 |
| Inventory | 接続対象・接続方式・接続ユーザーを定義するファイル |
| ansible.cfg | Ansible 全体の動作の既定値を書く設定ファイル。 Inventory の場所や接続時の挙動などをまとめる |
| Playbook | 処理手順を YAML で記述したファイル |
| Play | Playbook 内の1つの単位。対象グループと処理内容の組 |
| Task | Play 内の個別処理。1 ステップ |
| Module | Task を実行する部品。「copy」「systemd」などの操作単位 |
| Handler | 変更があったときだけ実行する後処理。サービスの reload など |
| Collection | Module をまとめた配布単位。「ansible.windows」など |
Control Node と Managed Node は役割の呼び名です。
1台のサーバーが Control Node を兼ねつつ、自分自身を Managed Node として構成することもできます。
特徴1:エージェントレス
Ansible は、構成する相手の Managed Node に 専用のエージェント(常駐ソフト)を事前にインストールする必要がありません。
これを「エージェントレス」と呼びます。
多くの構成管理ツールは、対象サーバーに専用のエージェントを常駐させ、それを通して設定を配ります。
Ansible はこの方式を取らず、OS に最初から備わっている標準的なリモート接続のしくみをそのまま使います。
| 対象 OS | 接続方式 | Managed Node 側に必要なもの |
|---|---|---|
| Linux | SSH(Secure Shell) | sshd と Python |
| Windows | WinRM(Windows Remote Management) | WinRM サービス |
エージェントの導入・バージョン管理・展開の承認といった作業が不要になるため、既存の環境へ後から導入しやすいのがエージェントレスの利点です。
「対象サーバーに何も追加インストールせずに自動化を始められる」と考えると分かりやすいです。
特徴2:冪等性
冪等性は少し難しそうな言葉ですが、意味はシンプルです。
同じ Playbook を何度実行しても、対象がすでにあるべき状態なら余計な変更をしないという性質のことです。
Ansible は作業の前に「対象が今どうなっているか」を確認し、足りないところだけを直します。
たとえばファイルを配置する処理は、下記のように動きます。
| 対象の状態 | Ansible の動き | 結果 |
|---|---|---|
| ファイルがない | 配置する | changed(変更あり) |
| 同じ内容のファイルがある | 何もしない | ok(変更なし) |
| 違う内容のファイルがある | 上書きする | changed(変更あり) |
冪等性が重要なのは、「変わったときだけ次の処理をする」という制御ができるからです。
毎回無条件に reload する作りだと、ファイルに変更がなくてもサービスが一瞬止まってしまいます。
実行結果は3つの状態で読む
Ansible を実行すると、Task ごとに結果が表示されます。
基本となるのは下記の3つです。ここを押さえると実行画面が読めるようになります。
| 表示 | 意味 |
|---|---|
| ok | すでにあるべき状態だった。変更しなかった |
| changed | 実際に変更を加えた |
| failed | 失敗した。原則そこで停止する |
冪等性が効いていれば、2回目の実行はすべて「ok」になります。
「changed が出なくなった=狙った状態に収束した」という合図として使えます。
Playbook の構造
Playbook は、処理手順を YAML という形式で書いたファイルです。
プログラムというより、実行できる手順書に近いものだと考えると取っつきやすいです。
全体の骨組みは下記のようになります。
- name: Play の名前
hosts: 対象グループ # Inventory のグループ名
become: true # 権限昇格するか
gather_facts: true # 対象の情報を収集するか
vars:
変数名: 値
pre_tasks:
- name: tasks より前に行う処理
tasks:
- name: あるべき状態へ変更する処理
handlers:
- name: 変更があったときだけ行う後処理
名前(name)には日本語で説明を書けます。
実行するとこの名前がそのまま進捗ログに流れるため、手順書がそのまま実行ログになるイメージです。
コンポーネントの入れ子関係
用語の大きさの関係を整理すると、下記のような入れ子になっています。
Playbook(手順書ファイル1つ)
└─ Play(対象グループ + 処理一式)
└─ Task(1 ステップ)
└─ Module(Task を実行する部品)
Playbook の中に Play があり、Play の中に Task が並び、各 Task は Module という部品を使って動きます。
この関係を押さえておくと、はじめて Playbook を見たときにも構造を追えます。
Task に添える「オプション」でふるまいを調整する
先ほどの骨組みのうち、hosts や become のように、Play や Task に添えてふるまいを調整する指定がいくつかあります。
ここですべてを覚える必要はありません。「Task にはこういう"ふるまいの指定"を添えられる」という雰囲気だけつかんでおけば十分です。
実際の Playbook を読むときに「これはあのオプションか」と思い出せれば大丈夫です。
Play 全体に添えるものとして、下記があります。
| キーワード | どんな指定か |
|---|---|
| hosts | どの対象に実行するかを指定する(Inventory 上のグループ名) |
| become | 権限を昇格して実行する(Linux では sudo に相当) |
| gather_facts | 実行前に対象の OS 情報などを収集する |
個々の Task に添えて、動きを細かく制御するものとして、下記があります。
| キーワード | どんな指定か |
|---|---|
| when | 条件を満たしたときだけその Task を実行する(例:対象が特定の OS のときだけ) |
| loop | 同じ Task を値を変えて繰り返す(例:複数ファイルをまとめて配置する) |
| register | その Task の実行結果を変数に保存し、後続の Task で使う |
| notify | 変更があったとき、後処理(Handler)の実行を予約する |
| no_log | true を指定すると、その Task の引数と結果をログに出さない(パスワードや秘密鍵の保護) |
notify と Handler は組み合わせで効くため、この後の「Handler のしくみ」で改めて説明します。
Handler のしくみ
Handler は「変更があったときだけ動く後処理」です。
Task が実際に変更を起こしたときだけ「notify」で呼び出され、Play の最後にまとめて実行されます。
| Task の結果 | notify | Handler の実行 |
|---|---|---|
| changed | 予約される | Play の最後に実行 |
| ok(変更なし) | 予約されない | 実行されない |
複数の Task が同じ Handler を notify しても、Handler は Play の最後に1回だけ実行されます。
これは先ほどの冪等性と組み合わさり、「変わったときだけ、1回だけ reload する」という無駄のない動きを実現します。
Ansible が動く流れ
ここまでの用語を踏まえて、実行したときの流れを 5 ステップで追います。
まずは全体の流れを下図でつかみ、各ステップの中身はこの後の番号解説で説明します。
[1] 対象を決める ─▶ [2] 手順を読む ─▶ [3] 接続する ─▶ [4] 差分だけ直す ─▶ [5] 結果を返す
(1) 対象を決める
Inventory を読み、どのサーバーに対して実行するかを決めます。
(2) 手順を読む
Playbook を上から順に読み、実行する Task を並べます。
(3) 接続する
対象のサーバーへ接続します(Linux は SSH、Windows は WinRM)。
(4) 差分だけ直す
対象の現在の状態を確認し、あるべき状態と違うところだけ直します。これが冪等性です。
(5) 結果を返す
Task ごとに結果(ok / changed / failed)を返し、実行画面に進捗として表示します。
Playbook は上から順番に処理されます。
途中の Task が「failed」になると、原則そのホストの以降の処理は止まります。
壊れた状態のまま先へ進めない、という安全側の動きになっています。
接続できるかを確かめる ping
本格的に Playbook を流す前に、まず 「対象とちゃんと通信できて、処理を実行できる状態か」を確認しておくと安心です。
Ansible にはそのための ping が用意されています。
ここで注意したいのは、この ping はネットワークの ping(ICMP)とは別物だということです。
Ansible の ping は、下記までを確認します。
| モジュール | 確認する内容 |
|---|---|
| ansible.builtin.ping | SSH で接続でき、対象上で Python が実行できること |
| ansible.windows.win_ping | WinRM で接続でき、対象上で PowerShell が実行できること |
Linux の対象へ接続を確認したいときは、下記で確認できます。
ansible linux_servers -m ansible.builtin.ping
Windows の対象へ接続を確認したいときは、下記で確認できます。
ansible windows_servers -m ansible.windows.win_ping
ネットワーク的に到達できても、対象に Python がない、認証が通らない、といった場合は失敗します。
つまりこの ping は「Ansible が実際にその対象を操作できる状態か」までを一度に確認してくれる点が便利です。
「接続確認が通る → 本番の Playbook を流す」という順番が、作業の基本の流れになります。
まとめ
本ブログの要点は下記のとおりです。
- Ansible は「あるべき状態」を宣言すると、その状態になるよう自動で構成してくれる構成管理ツールです
- エージェントレスのため、対象へ専用ソフトを入れずに SSH・WinRM で構成できます
- 冪等性により、何度実行しても余計な変更をせず、足りないところだけ直します
- 実行結果は ok・changed・failed の3つで読めて、2回目がすべて ok なら状態が収束しています
- Playbook は Play・Task・Module の入れ子で構成され、変更時だけ Handler が後処理を行います
- 本番の前に ping で「接続できて処理を実行できる状態か」を確認しておくと安心です
ここまでで、Ansible の用語・コンポーネント・動作のしくみが一通りつかめたかと思います。
次はこの Ansible を AWS EC2 にインストールして、実際に動かしてみます。
最後までお読みいただきありがとうございました。
参照ドキュメント
- Ansible Documentation
- How Ansible works
- Intro to playbooks
- Handlers: running operations on change
- Windows Remote Management
この記事は私が書きました
髙井 大暉
記事一覧頑張ってインフラエンジニアやってます。