こういう場面で手が止まることは珍しくありません。
既存PlaybookをAnsible roleへ移す手順は難しくありませんが、
copy・templateモジュールの src パスがrole構造では自動解決される仕様に変わります。ここを理解しないまま移設すると「ファイルが見つからない」エラーが出続けます。この記事では、既存PlaybookのtasksブロックをAnsible roleへ移す手順を解説します。
ansible-galaxy role initによるスケルトン生成、tasks/main.ymlへのtask移設、files/・templates/への再配置と参照パスの付け替え、そしてPlaybookからのrole呼び出しへの書き換えまで、順を追って説明します。動作確認環境: RHEL 9.4 / ansible-core 2.17
この記事のポイント
・copyモジュールのsrcはrole内ではfiles/以下が自動探索され相対パスで指定できる
・ansible-galaxy role initでrole骨格を1コマンドで生成しファイル配置ミスを防げる
・handlers/main.ymlにnotifyハンドラを移設するのを忘れると再起動が実行されなくなる
・移行後はansible-playbook --check --diffで差分ゼロを確認してから本番適用する
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
task→role移行の全体像|何がどこへ移るのか
移行前後のディレクトリ構造の変化を先に把握しておくと、手順が理解しやすくなります。移行前:tasksブロックを使った平書きPlaybook
# ディレクトリ構成(移行前) . ├── site.yml ├── files/ │ └── nginx.conf └── templates/ └── vhost.conf.j2
# ディレクトリ構成(移行後) . ├── site.yml └── roles/ └── webserver/ ├── tasks/ │ └── main.yml ├── files/ │ └── nginx.conf ├── templates/ │ └── vhost.conf.j2 ├── handlers/ │ └── main.yml ├── defaults/ │ └── main.yml └── meta/ └── main.yml
tasks/main.yml・files/・templates/・handlers/main.yml の4か所です。defaults/ と meta/ は雛形のまま残しておけばよく、最初から全部埋める必要はありません。ステップ1:ansible-galaxy role initでroleのスケルトンを生成する
手動でディレクトリを作るとtasks/main.yml の作成漏れなどが起きやすいので、ansible-galaxy role init コマンドを使ってください。必要なディレクトリとファイルが一括で生成されます。# プロジェクトルートで実行する ansible-galaxy role init roles/webserver # 実行後の確認 tree roles/webserver roles/webserver ├── README.md ├── defaults │ └── main.yml ├── files ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── tasks │ └── main.yml ├── templates ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml
files/ と templates/ はディレクトリのみで中身が空の状態で生成されます。次の手順でファイルを配置します。ステップ2:tasks/main.ymlへtaskブロックを移設する
既存Playbookのtasks: セクションに書いていたYAMLを、そのまま roles/webserver/tasks/main.yml に移します。移行前のsite.yml(tasksセクション抜粋)
# site.yml(移行前・抜粋) - hosts: webservers become: yes tasks: - name: nginx設定ファイルを配置する copy: src: files/nginx.conf dest: /etc/nginx/nginx.conf owner: root group: root mode: '0644' notify: nginx restart - name: バーチャルホスト設定を展開する template: src: templates/vhost.conf.j2 dest: /etc/nginx/conf.d/default.conf owner: root group: root mode: '0644' notify: nginx restart handlers: - name: nginx restart service: name: nginx state: restarted
# roles/webserver/tasks/main.yml - name: nginx設定ファイルを配置する copy: src: nginx.conf # ← files/ プレフィックスを削除 dest: /etc/nginx/nginx.conf owner: root group: root mode: '0644' notify: nginx restart - name: バーチャルホスト設定を展開する template: src: vhost.conf.j2 # ← templates/ プレフィックスを削除 dest: /etc/nginx/conf.d/default.conf owner: root group: root mode: '0644' notify: nginx restart
tasks: のインデント(ハイフン)はそのまま使えます。ただし hosts: や become: などのPlaybookレベルのキーは tasks/main.yml には書きません。それらはPlaybook本体に残ります。ステップ3:files/・templates/への再配置と参照パスの付け替え
役割分担を整理しておきましょう。・roles/webserver/files/ ──
copyモジュールが参照する静的ファイル置き場・roles/webserver/templates/ ──
templateモジュールが参照するJinja2テンプレート置き場Ansibleは
copy モジュールの src に相対パスが書かれていると、roles/rolename/files/ を自動で探索します。template モジュールも同様に roles/rolename/templates/ を探します。この自動探索ルールがroleの核心です。1. 静的ファイルをroles/webserver/files/へ移動する
# プロジェクトルートのfiles/からroleのfiles/へ移動 mv files/nginx.conf roles/webserver/files/ # 移動後の確認 ls -la roles/webserver/files/ -rw-r--r--. 1 rocky9-admin rocky9-admin 1284 9月 14 09:22 nginx.conf
2. テンプレートをroles/webserver/templates/へ移動する
mv templates/vhost.conf.j2 roles/webserver/templates/ ls -la roles/webserver/templates/ -rw-r--r--. 1 rocky9-admin rocky9-admin 412 9月 14 09:22 vhost.conf.j2
3. tasks/main.ymlの参照パスを付け替える(重要ポイント)
平書きPlaybookではファイルをfiles/nginx.conf や templates/vhost.conf.j2 のように明示指定していました。roleではファイル名だけを書きます。| モジュール | 移行前(平書きPlaybook) | 移行後(role内) |
|---|---|---|
| copyのsrc | src: files/nginx.conf |
src: nginx.conf |
| templateのsrc | src: templates/vhost.conf.j2 |
src: vhost.conf.j2 |
files/を付けたまま動くのでは?」と思うかもしれませんが、role内で src: files/nginx.conf と書くとAnsibleは roles/webserver/files/files/nginx.conf を探しにいきます。二重パスになるため、必ずプレフィックスを取り除いてください。ステップ4:handlersをroles/webserver/handlers/main.ymlへ移設する
notify: で呼び出しているハンドラも忘れずに移設します。# roles/webserver/handlers/main.yml - name: nginx restart ansible.builtin.service: name: nginx state: restarted
ステップ5:PlaybookのtasksブロックをRoles参照に書き換える
最後にsite.yml 本体を書き換えます。tasks: セクションをまるごと削除して roles: セクションに置き換えるだけです。# site.yml(移行後) - hosts: webservers become: yes roles: - webserver # roles/webserver/ を呼び出す
# 複数roleを順番に適用する例 - hosts: appservers become: yes roles: - common # 全サーバー共通設定 - webserver # Nginx設定 - appserver # アプリケーション設定
移行後の動作確認と典型的なエラー対処
1. --check --diffでドライランを実行する
本番適用の前に変更内容を確認します。ansible-playbook -i inventory site.yml --check --diff # 正常に移設できていれば差分ゼロで終了する PLAY [webservers] ************************************************************* TASK [webserver : nginx設定ファイルを配置する] ********************************** ok: [192.0.2.10] TASK [webserver : バーチャルホスト設定を展開する] ******************************* ok: [192.0.2.10] PLAY RECAP ************************************************************* 192.0.2.10 : ok=2 changed=0 unreachable=0 failed=0
changed=0 が確認できれば、taskの内容が変わっていないことを意味します。changed が出た場合は --diff の出力で差分を確認してください。2. 「Could not find file for copy」が出る場合
TASK [webserver : nginx設定ファイルを配置する] ** fatal: [192.0.2.10]: FAILED! => {"msg": "Could not find or access 'nginx.conf'..."}
・
roles/webserver/files/nginx.conf にファイルが存在しない(ls roles/webserver/files/ で確認する)・
src: files/nginx.conf のまま修正し忘れている(files/ プレフィックスを削除する)3. 「Could not find notify handler」が出る場合
ERROR! The requested handler 'nginx restart' was not found in either the main handlers list nor in the listening handlers list
roles/webserver/handlers/main.yml にハンドラが移設されていない場合に発生します。元の site.yml の handlers: セクションをroleに移設済みか確認してください。本記事のまとめ
既存PlaybookのtaskをAnsible roleへ移す際の要点をまとめます。| 手順 | 実施内容 |
|---|---|
| 1. スケルトン生成 | ansible-galaxy role init roles/rolename でディレクトリを自動作成 |
| 2. tasks移設 | site.ymlのtasksブロックをroles/rolename/tasks/main.ymlへコピー |
| 3. ファイル再配置 | files/ → roles/rolename/files/、templates/ → roles/rolename/templates/ |
| 4. 参照パス修正 | src: files/xxx → src: xxx、src: templates/xxx → src: xxx |
| 5. handlers移設 | site.ymlのhandlersセクションをroles/rolename/handlers/main.ymlへ移動 |
| 6. Playbook更新 | site.ymlのtasks:セクションをroles: - rolenameに置き換え |
| 7. 動作確認 | ansible-playbook --check --diff でchanged=0を確認 |
copy・templateモジュールはrole内では files/・templates/ ディレクトリを自動探索するため、プレフィックスを残したままにすると二重パスになりエラーになります。roleへの移設が完了したら、次は
defaults/main.yml に変数のデフォルト値を定義して再利用性を高めるステップに進みましょう。Ansible roleの体系的な学習に興味がある方は、下記もご参照ください。
Ansible実践ハンズオンの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:Ansibleで複数のAWSリージョンへ同じ構成を展開する|region指定とインベントリ分割の設計
- この記事の属するカテゴリ:Ansibleへ戻る

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