Ansible:每n小时最多运行一次任务

时间:2020-06-22 14:51:31

标签: ansible

我有一个Ansible任务,可以更新LetsEncrypt证书。我只希望该任务每周运行一次,以避免因锤打API而受阻,但是剧本的其余部分需要每天运行-并且在开发过程中将以更多的方式运行(em> way

是否可以对Ansible任务进行速率限制,以便在最近的 n 小时内已运行该任务而将其跳过?

我能想到的最好方法是:如果任务已运行,则触摸文件;如果文件存在且比特定时间戳新,则跳过任务-但Ansible的日期和时间似乎并不大计算。这也使剧本显得很矮胖。

我确实考虑过将标签应用于任务,并在ansible.cfg中将标签默认标记为跳过,然后仅在每周启用一次该标签的情况下运行,但是ansible.cfg似乎覆盖了{{ 1}},而不是相反。

1 个答案:

答案 0 :(得分:1)

选项1

您可以通过CRON执行Bash脚本来运行剧本,例如:

#!/usr/bin/env bash

DAY=$(date +%u)
HOUR=$(date +%k)

# This only runs all tasks (including letsencrypt) if it's 1 AM on Monday, at 
# all other times letsencrypt will be omitted. 
if [[ $(($DAY)) -eq 1 && $(($HOUR)) -eq 1 ]]; then
        echo "ansible-playbook [...]"
else
        echo 'ansible-playbook [...] --tags "!letsencrypt"'
fi

然后,您将必须用letsencrypt标记任务。然后,它将仅在您在脚本中设置的任何特定时间与其他所有任务一起运行,否则将被跳过。 cronjob本身仍然可以每小时运行一次。

选项2

另一种方法是在剧本中使用ansible_date_time。这样,您不需要cronjob拐杖。请参阅以下简单的示例剧本。

- hosts: localhost
  pre_tasks:

    - name: Get current weekday.
      set_fact:
        weekday: "{{ ansible_date_time.weekday }}"

    - name: Get current hour.
      set_fact:
        hour: "{{ ansible_date_time.hour }}"

  tasks:

    - debug:
        msg: "Replace this task with your Let's Encrypt task."
      when:
        - weekday is match("Thursday")
        - hour is match("22")

也许可以看看this post,了解如何使用Ansible和其他可能的输出格式来处理日期/时间。