Ansible: Tôi có thể sử dụng vars_files khi một số tệp không tồn tại


17

Đó là một phần:

vars_files:
  - vars/vars.default.yml
  - vars/vars.yml

Nếu một tập tin vars/vars.ymlkhông tồn tại - đây là một lỗi.

ERROR: file could not read: /.../vars/vars.yml

Làm thế nào tôi có thể tải các biến bổ sung từ tệp này chỉ khi nó tồn tại? (không có lỗi)

Câu trả lời:


27

Nó thực sự khá đơn giản. Bạn có thể nén các mục vars_files khác nhau của mình vào một tuple duy nhất và Ansible sẽ tự động đi qua từng mục cho đến khi tìm thấy một tệp tồn tại và tải nó. Ví dụ:

vars_files:
  - [ "vars/foo.yml", "vars/bar.yml", "vars/default.yml" ]

4
Theo các nhà phát triển Ansible , giải pháp này sẽ tải tất cả các tệp, không chỉ là tệp đầu tiên được tìm thấy.
tjanez

10

Theo các nhà phát triển Ansible , cách thích hợp để giải quyết vấn đề này là sử dụng một cái gì đó như:

vars_files_locs: ['../path/to/file1', '../path/to/file2', ...]

- include_vars: "{{ item }}"
  with_first_found: vars_files_locs

Hơn nữa, họ nói :

Ở trên sẽ chỉ tải đúng tệp đầu tiên được tìm thấy và linh hoạt hơn so với cố gắng thực hiện việc này thông qua vars_filestừ khóa ngôn ngữ.


"chỉ các tập tin đầu tiên tìm thấy" - ý tưởng là để xác định lại một số biến, không phải tất cả trong số họ
Sergey

@Sergey, đọc lại câu hỏi của bạn, tôi thấy rằng những gì bạn muốn có một chút khác biệt. Cảm ơn đã chỉ ra điều này. Tôi sẽ để lại câu trả lời như thể người khác thấy nó hữu ích.
tjanez

1
ngoại trừ việc include_varstrong nhiệm vụ sẽ có độ ưu tiên cao của các biến so với vai trò defaultshoặcvars
Alex F

2

Tôi đã gặp sự cố này trong một thiết lập khi tôi cần tạo nhiều môi trường triển khai (trực tiếp, bản demo, hộp cát) cho cùng một máy chủ vật lý (không cho phép máy ảo ở đây), và sau đó một tập lệnh để triển khai repos svn tùy ý

Điều này đòi hỏi một cây thư mục gồm các tệp biến.yml (tùy chọn), sẽ hợp nhất ontop của nhau và không ném ngoại lệ nếu có bất kỳ trường hợp nào bị thiếu

Bắt đầu bằng cách cho phép hợp nhất biến trong ansible - lưu ý rằng điều này không hợp nhất băm nông (sâu 1 cấp) và không hợp nhất đệ quy sâu

ansible.cfg

[defaults]
hash_behaviour=merge ;; merge rather than replace dictionaries http://docs.ansible.com/ansible/intro_configuration.html###hash-behaviour

Bố cục thư mục ansible

/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

vai trò / triển khai / nhiệm vụ / gồm.yml

Đây là logic chính cho cây thư mục gồm các tệp biến tùy chọn.

;; 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"

nhóm / all.yml

Cấu hình các biến mặc định cho dự án và nhiều người dùng và môi trường khác nhau

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

vai trò / triển khai / vars / main.yml

mặc định dự án

ansible_project:
  node_env:   development
  node_port:  4200
  nginx_port: 4400

vai trò / triển khai / vars / dự án_1.yml

mặc định cho dự án_1

ansible_project:
  node_port:  4201
  nginx_port: 4401

vai trò / triển khai / vars / live / main.yml

mặc định cho môi trường sống, ghi đè mặc định của dự án

ansible_project:
  node_env: production

vai trò / triển khai / vars / live / project_1.yml

ghi đè cuối cùng cho dự án_1 trong môi trường sống

ansible_project:
  nginx_port: 80

playbooks / demo.yml

Cấu hình Playbook riêng cho từng môi trường

- 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 }

CẢNH BÁO: Bởi vì tất cả các môi trường sống trên một máy chủ duy nhất, tất cả các playbook phải được chạy riêng lẻ, nếu không Ansible sẽ cố gắng chạy tất cả các tập lệnh với tư cách là người dùng đăng nhập ssh đầu tiên và chỉ sử dụng các biến cho người dùng đầu tiên. Nếu bạn cần chạy tất cả các tập lệnh một cách tuần tự, thì hãy sử dụng xargs để chạy từng tập lệnh dưới dạng các lệnh riêng biệt.

find ./playbooks/*.yml | xargs -L1 time ansible-playbook

1
- 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 }}"

Lưu ý: Các kiểm tra đường dẫn (là tệp, tồn tại, ...) chỉ hoạt động với các đường dẫn hoặc đường dẫn tuyệt đối liên quan đến thư mục làm việc hiện tại khi chạy lệnh ansible-playbook. Đây là lý do chúng tôi sử dụng tra cứu. tra cứu chấp nhận các đường dẫn liên quan đến thư mục playbook và trả về đường dẫn tuyệt đối khi tệp tồn tại.


0

Hoặc theo một cách yaml hơn:

- 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 }}"

Đó là, thay vì viết một mảng trên một dòng bằng dấu ngoặc vuông, như:

['path/to/file1', 'path/to/file2', ...]

Sử dụng cách yaml để viết các giá trị mảng trên nhiều dòng, như:

- path/to/file1
- path/to/file2

Như đã đề cập, điều này tìm kiếm một tệp vars có tên {{ ansible_hostname }}.ymlvà nếu nó không tồn tại sử dụngdefault.yml


Câu trả lời này sử dụng cùng một mã với mã này ngoại trừ nó sử dụng một dữ liệu khác. Cụ thể {{ ansible_hostname }}.ymltên tập tin thay vì ../path/to/file1. Vấn đề ở đây là gì? Người ta có thể thêm một số lượng không giới hạn tên tập tin đầu vào.
techraf

@Techraf: Ok, tôi đã thêm một số giải thích / khuếch đại về lý do tại sao một câu trả lời mới được gửi. Đó là bởi vì các bình luận về lỗi máy chủ không hỗ trợ các đoạn mã nhiều dòng và tôi chỉ đưa ra một điểm rằng các mảng yaml thường được (tốt nhất là?) Được viết trên nhiều dòng. Tôi cũng sẽ ổn nếu câu trả lời trước đó được chỉnh sửa và định dạng mảng nhiều dòng được hiển thị, vì tôi thấy điều đó thường xuyên hơn. Sau đó, câu trả lời của tôi có thể bị xóa.
Donn Lee

Cả hai ký hiệu được chỉ định trong tài liệu Ansible trong chương cơ bản YAML . Thực tế là bạn thấy một cái thường xuyên hơn cái kia chưa làm cho câu trả lời mới này.
techraf

0

Ghép các mảnh khác nhau lại với nhau ... bao gồm các mệnh đề với mệnh đề khi đúng khi tệp tồn tại. I E

vars:
  file_to_include: /path/to/file
tasks:
  - include_vars: "{{ file_to_include }}"
    when: file_to_include is exists

0

Câu trả lời mới dựa trên các phiên bản Ansible mới nhất về cơ bản, bạn nên sử dụng with_first_found, cùng với skip: trueviệc bỏ qua nhiệm vụ nếu không tìm thấy tệp nào.

- name: Include vars file if one exists meeting our condition.
  include_vars: "{{ item }}"
  with_first_found:
    - files:
        - vars/{{ variable_here }}.yml
      skip: true

Điều này làm cho nó để bạn không phải có một tệp vars dự phòng trong danh sách đó.

Xem liên quan: /programming//a/39544405/100134

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.