답변:
Ansible 개발자 에 따르면 이를 해결 하는 올바른 방법은 다음과 같은 것을 사용하는 것입니다.
vars_files_locs: ['../path/to/file1', '../path/to/file2', ...]
- include_vars: "{{ item }}"
with_first_found: vars_files_locs
또한 그들은 말합니다 :
위의 방법은 찾은 첫 번째 파일 만 올바르게로드하며
vars_files
language 키워드 를 통해이 작업을 수행하는 것보다 융통성이 있습니다.
include_vars
작업의 역할에 비해 변수의 높은 우선 순위를 줄 것이다 defaults
또는vars
동일한 물리적 서버 (여기서는 가상 머신은 허용되지 않음)에 여러 배치 환경 (라이브, 데모, 샌드 박스)을 작성하고 임의의 svn repos를 배치하는 스크립트를 작성해야하는 설정에서이 문제점이 발생했습니다.
여기에는 (선택적) variable.yml 파일의 디렉토리 트리가 필요합니다.이 트리는 서로 위에 병합되어 누락 된 경우 예외를 발생시키지 않습니다.
가변 병합을 가능하게하여 시작하십시오-이것은 얕은 해시 병합 (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 }
경고 : 모든 환경이 단일 호스트에 존재하므로 모든 플레이 북을 개별적으로 실행해야합니다. 그렇지 않으면 Ansible은 모든 스크립트를 첫 번째 ssh 로그인 사용자로 실행하려고 시도하고 첫 번째 사용자의 변수 만 사용합니다. 모든 스크립트를 순차적으로 실행해야하는 경우 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 }}"
즉, 다음과 같이 대괄호를 사용하여 한 줄에 배열을 쓰는 대신 :
['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 파일이 없어도됩니다.
관련 참조 : /programming//a/39544405/100134