2015-10-27 14 views
5

Có cách nào để đảm bảo tính không cần thiết cho các sách phát có sử dụng các biến được tạo ngẫu nhiên không?Idempotence và các biến ngẫu nhiên trong Ansible

Ví dụ, tôi muốn thiết lập crontabs của tôi để kích hoạt email trên nhiều máy chủ tại thời điểm khác nhau, vì vậy tôi tạo ra các số nguyên ngẫu nhiên sử dụng mô-đun set_fact ansible của:

tasks: 
    - set_fact: 
     first_run_30="{{ 30 | random }}" 
    run_once: yes 

Sau đó, áp dụng các biến được tạo ra để crontab của tôi sử dụng ansible như vậy:

- name: Setup cron30job 
    cron: name=cron30job minute={{first_run_30}},{{first_run_30 | int + 30}} job='/bin/bash /cron30job.sh' state=present user=root 
    environment: 
     MAILTO: '[email protected]' 
     MAILFROM: '[email protected]' 

này hoạt động rất tốt, tuy nhiên, nguyên tắc indempotence ansible là, tôi tin rằng, chúng được chia sử dụng chiến lược này vì mỗi lần một vở kịch được làm bạn nhìn thấy một sự thay đổi:

TASK: [Setup cron30job] ***************************************** 
changed: [127.0.0.1] 

Hơn nữa, trong crontab kiểm tra dưới gốc mỗi lần trong ba chạy riêng biệt:

[ansible]# cat /var/spool/cron/root 
#Ansible: cron30job 
5,35 * * * * /bin/bash /sw/test/cron30job.sh 
#Ansible: cron30job 
9,39 * * * * /bin/bash /sw/test/cron30job.sh 
#Ansible: cron30job 
6,36 * * * * /bin/bash /sw/test/cron30job.sh 

Nếu có một cách giải quyết, hoặc có thể indempotence chỉ sẽ không thể trong kịch bản của tôi, tôi muốn biết.

Trả lời

6

Thay vì một giá trị ngẫu nhiên, bạn có thể nhận được một cái gì đó liên quan đến nút, giống như một băm của tên máy chủ hoặc byte cuối cùng của địa chỉ IP.

Đây là một ví dụ:

- name: Get a pseudo-random minute 
    shell: expr $((16#`echo "{{inventory_hostname}}" | md5sum | cut -c 1-4`)) % 30 
    register: minute 
    changed_when: false 
+0

Mặc dù đây là những gợi ý mà thôi, nó có vẻ như là giải pháp hợp lý nhất. Tuy nhiên, tôi cần chỉ ra rằng nhiệm vụ 'Nhận một phút giả ngẫu nhiên' sẽ báo cáo trạng thái' [đã thay đổi] '. Tôi khuyên bạn nên thêm 'changed_when: false' để ngăn điều này xảy ra. Phá vỡ nó trong trường hợp này là tốt bởi vì chúng tôi đảm bảo sự không khoan nhượng đối với crontab và chúng tôi biết rằng giá trị băm sẽ không thay đổi cho mỗi máy, trừ khi bạn thay đổi tên máy chủ cho ip đó (đó là vấn đề của riêng nó). – Jake88

+0

@ Jake88 điểm tốt! –

+0

Điều này thật tuyệt, nhưng tôi có hai vấn đề. Đầu tiên, expr không làm việc với shell mặc định (/ bin/sh) trên debian, mà tôi nghĩ là dấu gạch ngang. thêm 'args: executable:/bin/bash' đã giúp với điều đó. Thứ hai, expr có mã thoát 1 nếu đầu ra là 0. 'failed_when:" minute.rc == 2 hoặc minute.rc == 3' sửa lỗi đó, bằng cách không thất bại trên mã thoát 1. – Berdir

6

Tính đến Ansible phiên bản 2.3, nó có thể khởi tạo bộ tạo số ngẫu nhiên từ một hạt giống. Bằng cách này, bạn có thể tạo số ngẫu nhiên-nhưng-idempotent:

"{{ 59 |random(seed=inventory_hostname) }} * * * * root /script/from/cron" 

Nguồn: random number filter

Tôi đã sử dụng mô hình này để sản xuất cron ngẫu nhiên bắt đầu lần với:

  1. phút khác nhau trên các máy chủ mục tiêu khác nhau
  2. phút khác nhau cho các giờ khác nhau trên cùng một máy chủ (ngẫu nhiên)
  3. cùng một phút trong cùng một ngày và máy chủ khi liên tục chạy Ansible (idempotence)

Yêu cầu Ansible> = 2.3:

cron: 
    name: "{{some_name}}_{{item.day}}" 
    state: present 
    job: "{{some_job}}" 
    weekday: "{{item.day}}" 
    hour: "{{item.hour}}" 
    minute: "{{59|random(seed=inventory_hostname + item.dow)}}" 
    with_items: 
- { day: 0, hour: 3, dow: "sunday" } 
- { day: 1, hour: 7, dow: "monday" } 
- { day: 2, hour: 1, dow: "tuesday" } 
- { day: 3, hour: 5, dow: "wednesday" } 
- { day: 4, hour: 2, dow: "thursday" } 
- { day: 5, hour: 4, dow: "friday" } 
- { day: 6, hour: 7, dow: "saturday" } 
Các vấn đề liên quan