我有一个Ansible任务,可以更新LetsEncrypt证书。我只希望该任务每周运行一次,以避免因锤打API而受阻,但是剧本的其余部分需要每天运行-并且在开发过程中将以更多的方式运行(em> way
是否可以对Ansible任务进行速率限制,以便在最近的 n 小时内已运行该任务而将其跳过?
我能想到的最好方法是:如果任务已运行,则触摸文件;如果文件存在且比特定时间戳新,则跳过任务-但Ansible的日期和时间似乎并不大计算。这也使剧本显得很矮胖。
我确实考虑过将标签应用于任务,并在ansible.cfg
中将标签默认标记为跳过,然后仅在每周启用一次该标签的情况下运行,但是ansible.cfg
似乎覆盖了{{ 1}},而不是相反。
答案 0 :(得分: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本身仍然可以每小时运行一次。
另一种方法是在剧本中使用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和其他可能的输出格式来处理日期/时间。