Ansible 时间戳,在整个播放期间对所有节点都是相同的
Ansible timestamp which is the same for all nodes during the whole play
我想要一个时间戳变量,它在所有主机上都是相同的。
(我将其包含在目录名称中:它在所有主机上必须相同)
我最初的想法是在 group_vars/all.yml 中添加一个声明,因为那
优先级比较高,应该分享一下。
group_vars/all.yml:
my_timestamp: "{{ ansible_date_time.date }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"
尝试时,主机之间的值不同,导致我的目录结构不一致。
我怀疑这是因为变量只是延迟评估,当引用的 ansible_date_time
对象在每个主机上已经具有不同的值时,具体取决于执行到达变量引用并解析值的确切时刻。
当我尝试在我的剧本中 set_fact
开始时,同样的问题发生了。
site.yml:
---
# This playbook performs the deployment
- name: Prepare playbook settings
hosts: all
tasks:
- name: Generate my timestamp
set_fact:
my_timestamp: "{{ ansible_date_time.date }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"
问题是:如何设置一个恒定的共享时间戳,在整个剧本执行期间在所有节点上都相同? clean Ansible 生成一致、恒定时间戳的方法是什么?不作为命令行参数传递,打印到文件并读回值等。
我在使用 Ansible 2.9.23。
你的基本问题是,使用或不使用 set_fact
,你正在解析一个值,该值填充在为每个主机收集的事实中。由于与您的目标的 ssh 连接永远不会同时发生,每个主机将有不同的值
解决方案是对所有这些使用来自一台主机的一个时间戳。一种方法是从控制器 (localhost
) 获取它,但您可以决定从其他地方获取它(例如,在部署游戏期间使用 set_facts
和 run_once
获取您组中的第一个主机).
这里是使用控制器的想法。适应自己的要求
---
- name: Make sure we gather facts from localhost
hosts: localhost
- name: Make my actual deployment
hosts: all
vars:
# declare timestamp using localhost values
my_timestamp: >-
{{
hostvars['localhost'].ansible_date_time.date
}}{{
hostvars['localhost'].ansible_date_time.hour
}}{{
hostvars['localhost'].ansible_date_time.minute
}}{{
hostvars['localhost'].ansible_date_time.second
}}
tasks:
- name: Make sure timestamp value is the same everywhere
debug:
var: my_timestamp
#... rest of your tasks...
正如@Zeitounator 的回答完美指出的那样,变量是按主机设置的,并且是在评估时设置的。
另一种似乎有效的方法是 运行 set_fact
任务一次,因此它只评估一次 (run_once
)。喜欢:
- hosts: all
gather_facts: true
tasks:
- name: save timestamp in var
my_timestamp: "{{ ansible_date_time.date }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"
run_once: true
- name: show my_timestamp
debug:
var: my_timestamp
由于 my_timestamp
设置了一次,现在每个主机上都会显示相同的时间戳。
我采纳了 Zeitounator 的建议,最后使用了一个中间变量。在接受 Zeitounator 的回答的同时,我为任何对实际解决方案感兴趣的人发布了一个代码示例。
---
# This playbook deploys our infrastrucure to each host type
- name: Prepare playbook settings
hosts: localhost
tasks:
- name: Generate my timestamp
set_fact:
my_timestamp_local: "{{hostvars['localhost'].ansible_date_time.date}}{{ hostvars['localhost'].ansible_date_time.hour }}{{ hostvars['localhost'].ansible_date_time.minute }}{{hostvars['localhost'].ansible_date_time.second }}"
cacheable: yes
- name: Show generated timestamp
debug:
var: hostvars['localhost']['my_timestamp_local']
- name: apply common configuration to all nodes
hosts: all
vars:
my_timestamp: "{{hostvars['localhost']['my_timestamp_local']}}"
roles:
- common
- name: apply foo node specific configuration
hosts: foo_nodes
vars:
my_timestamp: "{{hostvars['localhost']['my_timestamp_local']}}"
roles:
- foo
- name: apply bar node specific configuration
hosts: bar_nodes
vars:
my_timestamp: "{{hostvars['localhost']['my_timestamp_local']}}"
roles:
- bar
我想要一个时间戳变量,它在所有主机上都是相同的。 (我将其包含在目录名称中:它在所有主机上必须相同)
我最初的想法是在 group_vars/all.yml 中添加一个声明,因为那 优先级比较高,应该分享一下。
group_vars/all.yml:
my_timestamp: "{{ ansible_date_time.date }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"
尝试时,主机之间的值不同,导致我的目录结构不一致。
我怀疑这是因为变量只是延迟评估,当引用的 ansible_date_time
对象在每个主机上已经具有不同的值时,具体取决于执行到达变量引用并解析值的确切时刻。
当我尝试在我的剧本中 set_fact
开始时,同样的问题发生了。
site.yml:
---
# This playbook performs the deployment
- name: Prepare playbook settings
hosts: all
tasks:
- name: Generate my timestamp
set_fact:
my_timestamp: "{{ ansible_date_time.date }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"
问题是:如何设置一个恒定的共享时间戳,在整个剧本执行期间在所有节点上都相同? clean Ansible 生成一致、恒定时间戳的方法是什么?不作为命令行参数传递,打印到文件并读回值等。
我在使用 Ansible 2.9.23。
你的基本问题是,使用或不使用 set_fact
,你正在解析一个值,该值填充在为每个主机收集的事实中。由于与您的目标的 ssh 连接永远不会同时发生,每个主机将有不同的值
解决方案是对所有这些使用来自一台主机的一个时间戳。一种方法是从控制器 (localhost
) 获取它,但您可以决定从其他地方获取它(例如,在部署游戏期间使用 set_facts
和 run_once
获取您组中的第一个主机).
这里是使用控制器的想法。适应自己的要求
---
- name: Make sure we gather facts from localhost
hosts: localhost
- name: Make my actual deployment
hosts: all
vars:
# declare timestamp using localhost values
my_timestamp: >-
{{
hostvars['localhost'].ansible_date_time.date
}}{{
hostvars['localhost'].ansible_date_time.hour
}}{{
hostvars['localhost'].ansible_date_time.minute
}}{{
hostvars['localhost'].ansible_date_time.second
}}
tasks:
- name: Make sure timestamp value is the same everywhere
debug:
var: my_timestamp
#... rest of your tasks...
正如@Zeitounator 的回答完美指出的那样,变量是按主机设置的,并且是在评估时设置的。
另一种似乎有效的方法是 运行 set_fact
任务一次,因此它只评估一次 (run_once
)。喜欢:
- hosts: all
gather_facts: true
tasks:
- name: save timestamp in var
my_timestamp: "{{ ansible_date_time.date }}{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}{{ ansible_date_time.second }}"
run_once: true
- name: show my_timestamp
debug:
var: my_timestamp
由于 my_timestamp
设置了一次,现在每个主机上都会显示相同的时间戳。
我采纳了 Zeitounator 的建议,最后使用了一个中间变量。在接受 Zeitounator 的回答的同时,我为任何对实际解决方案感兴趣的人发布了一个代码示例。
---
# This playbook deploys our infrastrucure to each host type
- name: Prepare playbook settings
hosts: localhost
tasks:
- name: Generate my timestamp
set_fact:
my_timestamp_local: "{{hostvars['localhost'].ansible_date_time.date}}{{ hostvars['localhost'].ansible_date_time.hour }}{{ hostvars['localhost'].ansible_date_time.minute }}{{hostvars['localhost'].ansible_date_time.second }}"
cacheable: yes
- name: Show generated timestamp
debug:
var: hostvars['localhost']['my_timestamp_local']
- name: apply common configuration to all nodes
hosts: all
vars:
my_timestamp: "{{hostvars['localhost']['my_timestamp_local']}}"
roles:
- common
- name: apply foo node specific configuration
hosts: foo_nodes
vars:
my_timestamp: "{{hostvars['localhost']['my_timestamp_local']}}"
roles:
- foo
- name: apply bar node specific configuration
hosts: bar_nodes
vars:
my_timestamp: "{{hostvars['localhost']['my_timestamp_local']}}"
roles:
- bar