Ansibleのrole命名と変数プレフィックス規約|複数roleを併用しても名前が衝突しない名前空間を作る

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Ansible > Ansibleのrole命名と変数プレフィックス規約|複数roleを併用しても名前が衝突しない名前空間を作る
「複数のroleを組み合わせたら、なぜかサービスの設定値がおかしくなった。調べてみると別のroleで同じ変数名を使っていた…」
Ansibleで構成管理の規模が大きくなると、こうした変数衝突のトラブルが起きやすくなります。Ansibleの変数はPlaybook実行中にグローバルなスコープを持つため、あるrole内で定義した変数が意図せず他のroleに上書きされる事故が発生するのです。

解決策は「命名規約」にあります。role名をプレフィックス(接頭辞)として変数名に付ける規約を徹底すれば、どれだけroleを増やしても名前空間を安全に分離できます。

この記事では、Ansible公式推奨のrole命名規約と変数プレフィックス設計の実践パターンを解説します。Rocky Linux 9 / RHEL 9環境(Ansible 2.16)で動作確認済みの具体的な設定例を交えて進めます。

この記事のポイント

・Ansible変数はPlaybook全体がスコープ—role変数は名前が衝突しやすい
・role名を変数プレフィックスにする(例: nginx_port)のが公式推奨の規約
・defaults/main.ymlでプレフィックスを付けると衝突リスクをほぼゼロにできる
・group_vars・host_varsはroleのdefaultsより優先されるため環境差分の上書きに使う


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

なぜrole変数は衝突するのか|Ansibleの変数スコープを理解する

Ansibleの変数スコープを誤解したまま設計すると、複数roleを組み合わせたときに予期しない動作を引き起こします。まずここを正確に押さえましょう。

Ansibleの変数には「グローバルスコープ」「ホストスコープ」「プレイスコープ」の3層があります。roleのdefaults/main.ymlやvars/main.ymlで定義した変数は基本的にホストスコープに入り、同じPlaybook内で実行されるすべてのroleから参照・上書きできます。

この挙動を示す例を見てください。

# roles/nginx/defaults/main.yml port: 80 # roles/mysql/defaults/main.yml port: 3306

この状態で両方のroleを同一Playbookで呼ぶと、後から読み込まれたroleの値が上書きします。nginxのportが3306になってしまう典型的な衝突です。

Ansibleには「role isolation」の仕組みがありますが(Ansible 2.8以降のprivate_role_vars設定)、デフォルトはオフで完全な分離にはなりません。命名規約によるプレフィックス設計が最も確実な対策です。

Ansible公式が推奨するrole命名規約

1. role名の基本ルール|アンダースコア区切りで一意に

Ansible公式ドキュメント(Best Practices)では、role名に以下のルールを定めています。

・英小文字とアンダースコアのみ使用(ハイフン不可)
・機能を明確に表す名前にする
・十分に説明的な名前を付ける(generic過ぎる名前は避ける)

良い命名例と悪い命名例を比較します。

# NG: 汎用すぎる名前(他roleとの衝突リスクが高い) roles/ web/ db/ app/ # OK: 具体的で一意な名前 roles/ nginx_webserver/ mysql_database/ django_app/

2. Ansible Galaxy形式|namespace.role_name

Ansible Galaxyではrole名に「namespace.role_name」形式を使います。自社内ではnamespaceに会社名や組織名を使うのが一般的です。

# Galaxy形式のrole名(requirements.ymlでの指定例) - name: geerlingguy.nginx version: "3.2.0" # 社内roleの命名例(mycompany=自社namespace) roles/ mycompany.nginx_webserver/ mycompany.mysql_database/ mycompany.app_deploy/

社内でroleを運用する場合も、このnamespace方式を意識してディレクトリを設計しておくと、後からAnsible Galaxyやプライベートリポジトリへの移行がスムーズになります。

変数プレフィックス規約の実践|role名で名前空間を作る

1. defaults/main.ymlへのプレフィックス付け

最も重要な規約は「変数名の先頭にrole名(アンダースコア区切り)をプレフィックスとして付ける」ことです。

先ほどの衝突例を規約通りに修正するとこうなります。

# roles/nginx_webserver/defaults/main.yml nginx_webserver_port: 80 nginx_webserver_user: nginx nginx_webserver_worker_processes: auto nginx_webserver_access_log: /var/log/nginx/access.log # roles/mysql_database/defaults/main.yml mysql_database_port: 3306 mysql_database_root_password: "{{ vault_mysql_root_password }}" mysql_database_max_connections: 200 mysql_database_datadir: /var/lib/mysql

role名(nginx_webserver、mysql_database)が変数名の先頭に付くため、どちらのroleを先に実行しても衝突しません。

2. role内タスクでの変数参照

プレフィックス付きの変数は、role内タスクでそのまま参照します。

# roles/nginx_webserver/tasks/main.yml - name: Nginxをインストールする ansible.builtin.dnf: name: nginx state: present - name: Nginxの設定ファイルを配置する ansible.builtin.template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf owner: root group: root mode: '0644' notify: nginx_webserver reload

# roles/nginx_webserver/templates/nginx.conf.j2 worker_processes {{ nginx_webserver_worker_processes }}; events { worker_connections 1024; } http { access_log {{ nginx_webserver_access_log }}; server { listen {{ nginx_webserver_port }}; } }

テンプレートファイル内でもプレフィックス付き変数名を使うことで、どのroleの設定値を参照しているかが一目でわかります。

3. 複数roleを呼ぶPlaybookの設定例

NginxとMySQLを同一Playbookで管理する実例です。

# site.yml - name: Webサーバーのセットアップ hosts: webservers become: true roles: - role: nginx_webserver vars: nginx_webserver_port: 8080 nginx_webserver_worker_processes: 4 - role: mysql_database vars: mysql_database_max_connections: 500

Playbookのvarsブロックでrole変数を上書きするときも、プレフィックスがあるためどの変数がどのroleのものかが明確です。

実際の実行例を確認します(--checkフラグでドライラン)。

$ ansible-playbook -i inventory/production site.yml --check -v PLAY [Webサーバーのセットアップ] ***************************** TASK [nginx_webserver : Nginxをインストールする] *** ok: [web01.example.com] TASK [nginx_webserver : Nginxの設定ファイルを配置する] *** changed: [web01.example.com] TASK [mysql_database : MySQLをインストールする] *** ok: [web01.example.com] PLAY RECAP *** web01.example.com : ok=3 changed=1 unreachable=0 failed=0

タスク名にもrole名が自動で付与されるため、どのroleのタスクが実行されているかが出力から追えます。
Ansible設計を現場レベルで体系的に学びたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Ansible実践ハンズオンの詳細を見る >>

変数優先順位の設計|defaults・vars・group_vars・host_varsの使い分け

Ansibleの変数には優先順位があり、上位の変数が下位を上書きします。設計時に押さえておくべき主要な優先順位は次の通りです(数字が大きいほど優先度が高い)。

・1位(最低): role defaults(roles/<role>/defaults/main.yml)
・2位: group_vars(inventory/group_vars/)
・3位: host_vars(inventory/host_vars/)
・4位: role vars(roles/<role>/vars/main.yml)
・5位(最高): Playbookのvars:ブロック

この優先順位を踏まえた設計指針は次の通りです。

defaults/main.yml = デフォルト値の置き場
最も低い優先度を持つため「変更を許容するデフォルト値」をここに置きます。外部から上書きされることを前提とした設計です。

vars/main.yml = 変更させたくない内部定数の置き場
roleの内部ロジックで使う定数(パッケージ名・サービス名など)はここに置きます。group_varsやhost_varsより優先されるため、外部から変更されません。

group_vars・host_vars = 環境ごとの上書き専用
本番・ステージング・開発環境の差分を吸収するために使います。プレフィックス付きの変数名を使えば、どのroleの設定を上書きしているかが明確になります。

# inventory/group_vars/production.yml # 本番環境固有の設定(プレフィックスで対象roleが一目でわかる) nginx_webserver_port: 443 nginx_webserver_worker_processes: 8 mysql_database_max_connections: 1000

プレフィックス規約があることで、group_vars内の変数が「どのroleに属するか」を文脈なしに読み取れます。チームでAnsibleを運用するときの読みやすさが大きく向上します。

衝突パターンと回避策|よくあるミスと修正例

複数roleを運用してきた現場でよく起きる衝突パターンを整理します。

パターン1: 汎用的な変数名によるサイレント上書き
versionportuserconfig_file のような汎用的な変数名は衝突の温床です。roleAが port: 80 を定義し、roleBが port: 5432 を定義すると、後から実行されたroleの値が全体に影響します。

# NG: 衝突する変数定義 port: 80 # roles/nginx/defaults/main.yml port: 5432 # roles/postgresql/defaults/main.yml # OK: プレフィックスで分離 nginx_port: 80 # roles/nginx/defaults/main.yml postgresql_port: 5432 # roles/postgresql/defaults/main.yml

パターン2: コミュニティroleとの変数名衝突
Ansible Galaxyから取得したコミュニティroleは独自の変数名を持っています。取り込む前に変数名の一覧を確認しましょう。

# コミュニティroleのdefaults変数名一覧を確認する $ grep "^[a-z]" roles/geerlingguy.nginx/defaults/main.yml | cut -d: -f1 nginx_worker_processes nginx_worker_connections nginx_keepalive_timeout nginx_listen_ipv6

コミュニティroleは <role_short_name>_ プレフィックスを持つことが多いため、自社roleも同様の規約を守れば衝突を防げます。

パターン3: include_varsによる意図しない上書き
ansible.builtin.include_vars でYAMLファイルを動的に読み込むとき、プレフィックスなしの変数名を含むファイルは全スコープを汚染します。name オプションで辞書変数に格納するのが安全な使い方です。

# NG: プレフィックスなしで読み込む - name: 設定ファイルを読み込む ansible.builtin.include_vars: file: config.yml # 変数名にプレフィックスがない場合は危険 # OK: nameオプションでnamespace化する(Ansible 2.8+) - name: 設定ファイルをnamespace付きで読み込む ansible.builtin.include_vars: file: config.yml name: nginx_webserver_config # 辞書変数の中にキーが格納される

include_varsname オプションを使うと、読み込んだ変数をすべて1つの辞書変数の中に格納できます。これがAnsibleネイティブな名前空間の作り方です。

本記事のまとめ

Ansibleのrole命名と変数プレフィックス規約を整理します。

設計ポイント 推奨パターン
role名の形式 英小文字とアンダースコアのみ(例: nginx_webserver)
変数プレフィックス role名を先頭に付ける(例: nginx_webserver_port)
デフォルト値の置き場 defaults/main.yml(外部上書きを許容する変数)
内部定数の置き場 vars/main.yml(外部から変更させない変数)
環境差分の管理 group_vars・host_varsでプレフィックス付き変数を上書き
include_varsの安全な使い方 nameオプションで辞書変数に格納してnamespace化

role名を変数プレフィックスにするルールを1つ徹底するだけで、複数roleの衝突事故はほぼゼロにできます。既存のPlaybookを改修する場合は、まずdefaults/main.ymlの変数名をrole名プレフィックス付きに変更し、タスクファイルとテンプレートを順次更新していきましょう。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Ansible実践ハンズオンの詳細を見る >>

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

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

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

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

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

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

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

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

この記事を書いた人

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

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

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