roleが別のroleを呼ぶAnsibleの構成|meta/main.ymlのdependenciesと呼び出し順序の決め方

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Ansible > roleが別のroleを呼ぶAnsibleの構成|meta/main.ymlのdependenciesと呼び出し順序の決め方
「roleが増えてきて、どのPlaybookにも最初に common roleを書き忘れないよう管理するのが辛くなってきた。role側で『自分より先にこのroleを実行してほしい』と宣言できれば、Playbookを書く人が依存を意識せずに済むのに」

Ansibleを本格運用するとこういった設計課題が出てきます。その答えが meta/main.ymldependencies ブロックです。roleが自分の依存を宣言することで、Playbookから webapp とだけ書けば common → nginx → webapp の実行順序が自動保証されます。

この記事では、ansible role in roleの実装方法として meta/main.ymldependencies の基本構文、呼び出し順序の制御、重複排除の仕組みを実行ログを交えて解説します。実行環境はRHEL 9.4 / Rocky Linux 9.4です。

この記事のポイント

・meta/main.ymlのdependenciesで依存roleをrole側から宣言できる
・依存roleは宣言した順序で、本体roleより必ず先に実行される
・Ansibleは同一roleの重複実行をデフォルトで自動排除する
・allow_duplicates: trueで変数を変えた複数回実行が可能になる


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

roleが別のroleを呼ぶ設計が必要になる場面

複数のroleを持つAnsibleプロジェクトでは、多くのroleが同じ「前提条件」を必要とします。たとえば次のような状況です。

common role: タイムゾーン設定・必須パッケージインストール・ログローテーション設定を行う
nginx role: Nginxをインストールして設定する(前提: commonが適用済み)
webapp role: アプリケーションをデプロイする(前提: nginxが起動中)

この依存関係をPlaybook側で管理すると次のようになります。

# Playbook側で依存を管理する方式(書き忘れリスクあり) - hosts: webservers roles: - role: common # 忘れやすい - role: nginx # 忘れやすい - role: webapp

この設計の問題は、新しいPlaybookを書く人が commonnginx を追加し忘れる可能性があることです。Playbookが増えるほど漏れのリスクが高まります。

meta/main.ymldependencies を使えば、「このroleを使うなら先にこのroleを実行してほしい」という宣言をrole側に持たせられます。Playbook側は呼び出したいrole名だけ書けばよくなり、依存の書き忘れを構造的に防げます。

meta/main.ymlのdependenciesの書き方

1. role名だけで依存を指定する(最小構成)

最もシンプルな書き方は、依存role名を列挙する形式です。

# roles/webapp/meta/main.yml --- dependencies: - role: common - role: nginx

この記述により、webapp roleを呼び出すと common → nginx → webapp の順で実行されます。Playbook側に commonnginx を列挙する必要はありません。

meta/main.yml にはGalaxy公開用のメタ情報(galaxy_info)も書けますが、ローカル開発では dependencies だけで構いません。依存roleが不要な末端roleは dependencies: [] と明示的に書いておくと意図が伝わりやすくなります。

2. 変数をオーバーライドして依存roleに渡す

依存roleに対して変数を渡したい場合は、role: の下に vars: ブロックを追加します。

# roles/webapp/meta/main.yml --- dependencies: - role: common - role: nginx vars: nginx_port: 8080 nginx_worker_processes: 2

vars: で渡した変数はroleの defaults/main.yml の値をオーバーライドします。ただし host_varsgroup_vars・Playbookのvarsセクションで設定した変数よりは優先順位が低くなります。変数の優先順位が意図と合わない場合は、group_vars 側で上書きして調整するのが実務的なアプローチです。

3. whenで条件付き依存を定義する

環境によって依存roleを実行するかどうかを切り替えたい場合は when を使います。

# roles/webapp/meta/main.yml --- dependencies: - role: common - role: selinux_config when: ansible_selinux.status == "enabled" - role: nginx

whenfalse と評価された依存roleはスキップされます。ただし when の評価時点で参照する変数が未定義だとエラーになるため、ansible_selinux のようにファクト収集で確実に定義される変数を使うのが安全です。

dependenciesで決まるrole実行順序の仕組み

Ansibleはroleを処理する際、依存関係を再帰的に解決してから本体のroleを実行します。処理の流れは次のとおりです。

1. Playbookwebapp roleを要求する
2. Ansibleが webapp/meta/main.yml を読み込み dependencies リストを取得する
3. 最初の依存 common を処理 → common/meta/main.yml を読み込む(依存なし)→ commonを実行
4. 次の依存 nginx を処理 → nginx/meta/main.yml を読み込む(依存なし)→ nginxを実行
5. webappを実行

dependenciesリストは上から順に処理されるため、順序に意味がある場合は先に実行すべきroleを上に書きます。

依存が深くネストしている場合(roleC → roleB → roleA のチェーン)は深さ優先(DFS)で解決されます。つまり最深部(roleA)から実行され、roleB、roleCの順になります。

# ネストした依存の解決順序の例 # roleC/meta/main.yml dependencies: - role: roleB # roleB/meta/main.yml dependencies: - role: roleA # PlaybookでroleCを指定した場合の実行順序 # 1. roleA(roleBの依存) # 2. roleB(roleCの依存) # 3. roleC(Playbookで指定)

実践例|webappがcommonとnginxを依存として呼ぶPlaybook構成

1. ディレクトリ構成

roles/ ├── common/ │ ├── tasks/ │ │ └── main.yml │ └── meta/ │ └── main.yml # dependencies: [](依存なし) ├── nginx/ │ ├── tasks/ │ │ └── main.yml │ ├── defaults/ │ │ └── main.yml # nginx_port: 80 │ ├── handlers/ │ │ └── main.yml │ └── meta/ │ └── main.yml # dependencies: [common] └── webapp/ ├── tasks/ │ └── main.yml └── meta/ └── main.yml # dependencies: [nginx]

2. 各roleのmeta/main.yml

# roles/common/meta/main.yml --- dependencies: [] # roles/nginx/meta/main.yml --- dependencies: - role: common # roles/webapp/meta/main.yml --- dependencies: - role: nginx vars: nginx_port: 80

3. Playbookの記述

Playbook側は webapp roleだけを記述します。commonnginx を書く必要はありません。

# site.yml --- - hosts: webservers become: true roles: - role: webapp

4. 実行ログで呼び出し順序を確認する

ansible-playbook -i inventory site.yml -v を実行すると、TASKラベルにrole名が含まれ実行順序が確認できます。

PLAY [webservers] ************************************************************ TASK [Gathering Facts] ******************************************************* ok: [web01.example.com] TASK [common : タイムゾーンをAsia/Tokyoに設定する] ************************************ changed: [web01.example.com] TASK [common : 必須パッケージをインストールする] ************************************** changed: [web01.example.com] TASK [nginx : Nginxをインストールする] ******************************************** changed: [web01.example.com] TASK [nginx : Nginx設定ファイルを配置する] ******************************************* changed: [web01.example.com] TASK [webapp : アプリケーションをデプロイする] ****************************************** changed: [web01.example.com] PLAY RECAP ******************************************************************* web01.example.com : ok=6 changed=5 unreachable=0 failed=0

common → nginx → webapp の順に実行されていることが確認できます。Playbook側には webapp しか書いていないにもかかわらず、依存が自動的に解決されています。

重複排除の仕組みとallow_duplicates

Ansibleはデフォルトで同じroleが同じホストに対して複数回実行されることを防ぐ「重複排除」を行います。

たとえば nginx roleと redis roleがどちらも common roleに依存している場合、common は最初の1回だけ実行されます。

# nginx/meta/main.yml dependencies: - role: common # redis/meta/main.yml dependencies: - role: common # site.yml - hosts: app_servers roles: - role: nginx - role: redis # 実行順序: common(1回のみ)→ nginx → redis # 2回目のcommonは重複排除によりスキップされる

この挙動はほとんどの場面で正しいですが、変数を変えながら同じroleを複数回実行したい場合は問題になります。たとえば複数のVirtualHostを設定するために同じ nginx_vhost roleを繰り返し呼びたい場合です。

そのような場合は allow_duplicates: true を設定します。

# roles/nginx_vhost/meta/main.yml --- allow_duplicates: true dependencies: []

これにより、依存定義内やPlaybook内で同じroleを変数を変えながら複数回呼び出せます。

# webapp/meta/main.yml(nginx_vhostをVirtualHost数だけ呼ぶ例) --- dependencies: - role: nginx_vhost vars: vhost_name: app1 vhost_port: 80 - role: nginx_vhost vars: vhost_name: app2 vhost_port: 8080

allow_duplicates: false(デフォルト)の場合、2番目の nginx_vhost は「すでに実行済み」としてスキップされます。変数が違っていても判断基準はrole名のみであるため注意が必要です。

よくある落とし穴とエラー対処法

1. 循環依存(roleAとroleBが互いに依存している)

症状: roleAがroleBに依存し、roleBがroleAに依存すると、Ansibleはエラーを出して停止します。

ERROR! A circular dependency was detected for role: roleA

対処: 共通の依存は第3のrole(common)に切り出し、roleAroleB が両方そのroleに依存する設計に変えます。重複排除が働くため common は1回だけ実行されます。

2. 変数を変えても同じroleが2回目にスキップされる

症状: 同じrole名で変数を変えて複数回依存定義しても、2回目以降がスキップされる。

対処: 繰り返し実行が必要なroleの meta/main.ymlallow_duplicates: true を追加します。ただし冪等性の設計に注意し、変数が変わることで実際に異なる処理になることを確認してから設定しましょう。

3. dependenciesのwhenに未定義変数を使う

症状: when 条件の評価時点で変数がまだ定義されておらず、エラーまたは意図しない評価になる。

対処: when にはファクト変数(gather_facts が収集するもの)か、インベントリや group_vars で確実に定義されている変数だけを使います。Playbookの varsset_fact で設定した変数は依存解決の時点では使えない場合があるため要注意です。

4. meta/main.ymlの場所またはYAMLインデントが誤っている

症状: meta/main.yml を作成したつもりだが、期待した依存roleが実行されない。

# 正しいパス roles/webapp/meta/main.yml # YAMLの正しいインデント(スペース2つ) --- dependencies: - role: common # スペース2つでインデント vars: nginx_port: 80 # スペース6つ(2+4) # 構文チェックで事前確認 ansible-playbook --syntax-check site.yml

YAML構文エラーは --syntax-check で事前に検出できます。meta/main.yml が存在しない場合はそのroleに依存は設定されていないものとして扱われます。

本記事のまとめ

やりたいこと 設定方法
roleが別のroleを依存として宣言する roles/xxx/meta/main.ymldependencies: ブロック
依存roleに変数を渡す 依存定義内の vars: nginx_port: 80 形式
同一roleを複数回実行する meta/main.ymlallow_duplicates: true を追加
依存roleを条件付きで実行する 依存定義内に when: ansible_xxx == "..." を追加
実行順序を確認する ansible-playbook -v の実行ログでTASKラベルを確認
構文エラーを事前に検出する ansible-playbook --syntax-check site.yml
meta/main.ymldependencies を使いこなすことで、「このroleを使うなら○○を事前に適用する」という暗黙の前提をPlaybook側ではなくrole自体に閉じ込められます。Playbookから webapp とだけ書けば common → nginx → webapp の順序が自動保証される設計は、チーム開発での書き忘れや実行順序ミスを構造的に防ぎます。

重複排除の仕組みを理解した上で allow_duplicates を適切に使い、循環依存を避ける設計を心がけることが、メンテナブルなansible role in role設計の基本です。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Ansible実践ハンズオンの詳細を見る >>

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

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

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

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

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

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

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

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

この記事を書いた人

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

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

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