既存Playbookのtaskをroleへ移すAnsibleの移行手順|ファイル配置と参照パスの付け替え

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Ansible > 既存Playbookのtaskをroleへ移すAnsibleの移行手順|ファイル配置と参照パスの付け替え
「Playbookのtasksが増えてきてroleに分けたい。でも files/templates のパスをどう直せばいいか、copy モジュールの src はどう変わるのか、調べても断片的な情報しか出てこない」
こういう場面で手が止まることは珍しくありません。

既存PlaybookをAnsible roleへ移す手順は難しくありませんが、copytemplateモジュールの 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で差分ゼロを確認してから本番適用する


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

task→role移行の全体像|何がどこへ移るのか

移行前後のディレクトリ構造の変化を先に把握しておくと、手順が理解しやすくなります。

移行前:tasksブロックを使った平書きPlaybook

# ディレクトリ構成(移行前) . ├── site.yml ├── files/ │ └── nginx.conf └── templates/ └── vhost.conf.j2

移行後:roleを使ったPlaybook

# ディレクトリ構成(移行後) . ├── 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.ymlfiles/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(移設後)

# 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.conftemplates/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

ハンドラの移設を忘れた場合、「Could not find notify handler 'nginx restart'」というエラーが出ます。

ステップ5:PlaybookのtasksブロックをRoles参照に書き換える

最後に site.yml 本体を書き換えます。tasks: セクションをまるごと削除して roles: セクションに置き換えるだけです。

# site.yml(移行後) - hosts: webservers become: yes roles: - webserver # roles/webserver/ を呼び出す

roleを複数適用したい場合はリスト形式で並べます。

# 複数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'..."}

原因はほぼ2通りです。

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.ymlhandlers: セクションを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を確認
最も注意が必要なのは 参照パスの付け替え(手順4) です。copytemplateモジュールはrole内では files/templates/ ディレクトリを自動探索するため、プレフィックスを残したままにすると二重パスになりエラーになります。

roleへの移設が完了したら、次は defaults/main.yml に変数のデフォルト値を定義して再利用性を高めるステップに進みましょう。Ansible roleの体系的な学習に興味がある方は、下記もご参照ください。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Ansible実践ハンズオンの詳細を見る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。