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より優先されるため環境差分の上書きに使う
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜ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
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名で名前空間を作る
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
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 }}; } }
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
実際の実行例を確認します(--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
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
衝突パターンと回避策|よくあるミスと修正例
複数roleを運用してきた現場でよく起きる衝突パターンを整理します。パターン1: 汎用的な変数名によるサイレント上書き
version、port、user、config_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
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_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_vars の name オプションを使うと、読み込んだ変数をすべて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名プレフィックス付きに変更し、タスクファイルとテンプレートを順次更新していきましょう。
Ansible実践ハンズオンの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:AnsibleがAWSの認証情報を解決する仕組み|AWS CLIのプロファイル・環境変数・IAMロールの優先順位
- この記事の属するカテゴリ:Ansibleへ戻る

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