回答:
Ansible開発者によると、これを解決する適切な方法は次のようなものを使用することです:
vars_files_locs: ['../path/to/file1', '../path/to/file2', ...]
- include_vars: "{{ item }}"
with_first_found: vars_files_locs
さらに、彼らは言う:
上記は、最初に見つかったファイルのみを適切にロードし、
vars_files
言語キーワードでこれを行うよりも柔軟です。
include_vars
、タスクでは、ロールと比較して変数の優先順位が高くなります。defaults
またはvars
同じ物理サーバー(ここでは仮想マシンは許可されません)に複数のデプロイメント環境(ライブ、デモ、サンドボックス)を作成する必要があるセットアップでこの問題が発生し、任意のsvnリポジトリをデプロイするスクリプト
これには、(オプションの)variable.ymlファイルのディレクトリツリーが必要でした。これは、互いの上にマージされ、欠落している場合は例外をスローしません。
ansibleで変数のマージを有効にすることから始めます-これは浅いハッシュマージ(1レベルの深さ)を行い、完全な再帰的なマージではないことに注意してください
[defaults]
hash_behaviour=merge ;; merge rather than replace dictionaries http://docs.ansible.com/ansible/intro_configuration.html###hash-behaviour
/group_vars
└── all.yml
/playbooks
├── boostrap.yml
├── demo.yml
├── live.yml
└── sandbox.yml
/roles/deploy/
├── files
├── tasks
│ ├── includes.yml
│ ├── main.yml
└── vars
├── main.yml
├── project_1.yml
├── project_2.yml
├── demo
│ ├── project_1.yml
│ ├── project_2.yml
│ └── main.yml
├── live
│ ├── project_1.yml
│ ├── project_2.yml
│ └── main.yml
└── sandbox
├── project_1.yml
├── project_2.yml
└── main.yml
これは、オプションの変数ファイルのディレクトリツリーのメインロジックです。
;; imports in this order:
;; - /roles/deploy/vars/main.yml
;; - /roles/deploy/vars/{{ project_name }}.yml
;; - /roles/deploy/vars/{{ project_name }}/main.yml
;; - /roles/deploy/vars/{{ project_name }}/{{ project_env }}.yml
- include_vars:
dir: 'vars'
files_matching: "{{ item }}"
depth: 1
with_items:
- "main.yml"
- "{{ project_name }}.yml"
- include_vars:
dir: 'vars/{{ env_name }}'
files_matching: "{{ item }}"
depth: 1
with_items:
- "main.yml"
- "{{ project_name }}.yml"
プロジェクトおよびさまざまなユーザーと環境のデフォルト変数を構成する
project_users:
bootstrap:
env: bootstrap
user: ansible
group: ansible
mode: 755
root: /cs/ansible/
home: /cs/ansible/home/ansible/
directories:
- /cs/ansible/
- /cs/ansible/home/
live:
env: live
user: ansible-live
group: ansible
mode: 755
root: /cs/ansible/live/
home: /cs/ansible/home/ansible-live/
demo:
env: demo
user: ansible-demo
group: ansible
mode: 755
root: /cs/ansible/demo/
home: /cs/ansible/home/ansible-demo/
sandbox:
env: sandbox
user: ansible-sandbox
group: ansible
mode: 755
root: /cs/ansible/sandbox/
home: /cs/ansible/home/ansible-sandbox/
project_env: bootstrap
project_user: "{{ ansible_users[project_env] }}" ;; this will be retroactively updated if project_env is redefined later
プロジェクトのデフォルト
ansible_project:
node_env: development
node_port: 4200
nginx_port: 4400
project_1のデフォルト
ansible_project:
node_port: 4201
nginx_port: 4401
ライブ環境のデフォルト、プロジェクトのデフォルトを上書き
ansible_project:
node_env: production
ライブ環境でのproject_1の最終的なオーバーライド
ansible_project:
nginx_port: 80
環境ごとに個別のプレイブックを構成する
- hosts: shared_server
remote_user: ansible-demo
vars:
project_env: demo
pre_tasks:
- debug: "msg='{{ facter_gid }}@{{ facter_fqdn }} ({{ server_pseudonym }})'"
- debug: var=project_ssh_user
roles:
- { role: deploy, project_name: project_1 }
警告:すべての環境は単一のホストに存在するため、すべてのプレイブックは個別に実行する必要があります。すべてのスクリプトを順番に実行する必要がある場合は、xargsを使用して、それぞれを個別のコマンドとして実行します。
find ./playbooks/*.yml | xargs -L1 time ansible-playbook
- hosts: all
vars_files: vars/vars.default.yml
vars:
optional_vars_file: "{{ lookup('first_found', 'vars/vars.yml', errors='ignore') }}"
tasks:
- when: optional_vars_file is file
include_vars: "{{ optional_vars_file }}"
注:パステスト(ファイル、存在、...)は、ansible-playbookコマンドを実行するときに、絶対パスまたは現在の作業ディレクトリに相対的なパスでのみ機能します。これがルックアップを使用した理由です。ルックアップは、プレイブックディレクトリへの相対パスを受け入れ、ファイルが存在する場合は絶対パスを返します。
または、よりyamlの方法で:
- hosts: webservers
vars:
paths_to_vars_files:
- vars/{{ ansible_hostname }}.yml
- vars/default.yml
tasks:
- include_vars: "{{ item }}"
with_first_found: "{{ paths_to_vars_files }}"
つまり、次のように角括弧で1行に配列を書く代わりに:
['path/to/file1', 'path/to/file2', ...]
次のように、複数行に配列値を書き込むyamlの方法を使用します。
- path/to/file1
- path/to/file2
前述のように、これはという名前のvarsファイルを探し、{{ ansible_hostname }}.yml
存在しない場合はdefault.yml
最新のAnsibleバージョンに基づいた新しい回答-基本的に、が使用されwith_first_found
、skip: true
ファイルが見つからない場合はタスクをスキップする必要があります。
- name: Include vars file if one exists meeting our condition.
include_vars: "{{ item }}"
with_first_found:
- files:
- vars/{{ variable_here }}.yml
skip: true
これにより、フォールバックvarsファイルをそのリストに含める必要がなくなります。
関連を参照してください:https : //stackoverflow.com/a/39544405/100134