在 crontab 中拥有多个 MAILTO 环境变量的可靠方法

Ansbile way of having multiple MAILTO environment varialbes in crontab

我必须在 Ansible 中创建 crontab,这样呈现的 crontab 应该有多个 MAILTO,这是基于以下 cron 任务。例如,最终的 crontab 可能如下所示

MAILTO=person1@domain.com
#Ansible: TEST 1
0 * * * * ls -ahl > /dev/null

MAILTO=person2@domain.com
#Ansible: TEST 2
1 * * * * ls -ahl > /dev/null

MAILTO 是一个环境变量,如果我多次指定它,它就会被覆盖 使用 env.

的剧本示例
- cron:
    env: true
    name: MAILTO
    job: person1@domain.com
    state: "present"
    insertbefore: "TEST 1"
- cron:
    name: "TEST 1"
    job: "ls -ahl > /dev/null"
    state: "present"
    minute: "0"
    hours: "5,2"
- cron:
    env: true
    name: MAILTO
    job: person2@domain.com
    state: "present"
    insertbefore: "TEST 2"
- cron:
    name: "TEST 2"
    job: "ls -ahl > /dev/null"
    state: "present"
    minute: "1"
    hours: "4,2"

但运气不好,我也尝试过使用 cronvar

- cronvar:
    name: MAILTO
    value: person1@domain.com
    state: "present"
    insertbefore: "TEST 1"
- cron:
    name: "TEST 1"
    job: "ls -ahl > /dev/null"
    state: "present"
    minute: "0"
    hours: "5,2"
- cronvar:
    name: MAILTO
    value: person2@domain.com
    state: "present"
    insertbefore: "TEST 2"
- cron:
    name: "TEST 2"
    job: "ls -ahl > /dev/null"
    state: "present"
    minute: "1"
    hours: "4,2"

又一次不走运

有人能指出实现此目标的方法吗?

因为 cronvar 是为了向文件添加变量,这些文件是唯一的,而且我对 that comment that having multiple MAILTO is something possible on all the implementation of crontab, so it is likely that it is not going to be supported by Ansible, I guess your best bet is to resort to a plain old lineinfile 不是很确定。

其中的 not-so-nice 部分当然是您必须创建一个主机、播放或任务变量来保存 crontab 文件的路径。
我快速浏览了文档,但似乎没有提供用户实际的 crontab 的事实,而且由于它似乎是 the cron module code itself 的一部分,我不确定是否有找到它的好方法来自 Ansible 本身。

另一方面,确定应在何处添加行的部分似乎是未来的证据,因为它已明确记录为预期行为:

When crontab jobs are managed: the module includes one line with the description of the crontab entry "#Ansible: <name>" corresponding to the “name” passed to the module, which is used by future ansible/module calls to find/check the state. The “name” parameter should be unique, and changing the “name” value will result in a new cron task being created (or a different one being removed).

来自文档:https://docs.ansible.com/ansible/2.9/modules/cron_module.html

有了这一切,给定剧本:

- hosts: all
  gather_facts: no
  vars:
    cron_file: /etc/crontabs/root
  
  tasks:
    - cron:
        name: "TEST 1"
        job: "ls -ahl > /dev/null"
        state: "present"
        minute: "0"
        hour: "5,2"
      register: cron

    - lineinfile:
        path: "{{ cron_file }}"
        insertbefore: '#Ansible: TEST 1'
        line: 'MAILTO=person1@domain.com'

    - cron:
        name: "TEST 2"
        job: "ls -ahl > /dev/null"
        state: "present"
        minute: "1"
        hour: "4,2"
    
    - lineinfile:
        path: "{{ cron_file }}"
        insertbefore: '#Ansible: TEST 2'
        line: 'MAILTO=person2@domain.com'

这产生了回顾:

PLAY [all] *********************************************************************************************************

TASK [cron] ********************************************************************************************************
changed: [localhost]

TASK [lineinfile] **************************************************************************************************
changed: [localhost]

TASK [cron] ********************************************************************************************************
changed: [localhost]

TASK [lineinfile] **************************************************************************************************
changed: [localhost]

PLAY RECAP *********************************************************************************************************
localhost                  : ok=4    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

而在/etc/crontabs/root的Alpine中用来测试:

MAILTO=person1@domain.com
#Ansible: TEST 1
0 5,2 * * * ls -ahl > /dev/null
MAILTO=person2@domain.com
#Ansible: TEST 2
1 4,2 * * * ls -ahl > /dev/null

最后但同样重要的是,重新运行完全相同的剧本表明幂等性得到尊重:

PLAY [all] *********************************************************************************************************

TASK [cron] ********************************************************************************************************
ok: [localhost]

TASK [lineinfile] **************************************************************************************************
ok: [localhost]

TASK [cron] ********************************************************************************************************
ok: [localhost]

TASK [lineinfile] **************************************************************************************************
ok: [localhost]

PLAY RECAP *********************************************************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0