ansible-确保文件内容在服务器之间相同 [英] ansible - ensure content of file is the same across servers

查看:69
本文介绍了ansible-确保文件内容在服务器之间相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用Ansible 2.9.12

Using Ansible 2.9.12

问题:当文件至少存在一个主机时,如何配置Ansible以确保文件的内容在至少3个主机之间相等?

Question: How do I configure Ansible to ensure the contents of a file is equal amongst at least 3 hosts, when the file is present at at least one host?

想象一下,有3位主持人.

Imagine there are 3 hosts.

主机1没有/file.txt .

主机2的/file.txt 内容为 hello .

主机3的/file.txt 内容为 hello .

在运行播放之前,我不知道文件是否存在.因此该文件可能存在于host1,host2或host3上.但是该文件至少存在于其中一台主机上.

Before the play is run, I am unaware whether the file is present or not. So the file could exist on host1, or host2 or host3. But the file exists on at least one of the hosts.

我将如何确保每次Ansible运行时,主机上的文件相等.因此,最后,主机1具有与主机2或主机3相同的文件,并且具有相同的内容.

How would I ensure each time Ansible runs, the files across the hosts are equal. So in the end, Host 1 has the same file with the same contents as Host 2 or Host 3.

我希望对此进行动态设置,而不是指定主机名或组名,例如时间:inventory_hostname == host1 .

I'd like this to be dynamically set, instead of specifying the host names or group names, e.g. when: inventory_hostname == host1.

我不希望检查主机2和3的内容是否相等

I am not expecting a check to see whether the contents of host 2 and 3 are equal

但是,我确实希望以幂等的方式进行设置.

I do however, want this to be setup in an idempotent fashion.

推荐答案

我认为下面的剧作可以完成

The play below does the job, I think

shell> cat pb.yml
- hosts: all
  tasks:
    - name: Get status.
      stat:
        path: /file.txt
      register: status
    - block:
        - name: Create dictionary status.
          set_fact:
            status: "{{ dict(keys|zip(values)) }}"
          vars:
            keys: "{{ ansible_play_hosts }}"
            values: "{{ ansible_play_hosts|
                        map('extract', hostvars, ['status','stat','exists'])|
                        list }}"
        - name: Fail. No file exists.
          fail:
            msg: No file exists
          when: status.values()|list is not any
        - name: Set reference to first host with file present.
          set_fact:
            reference: "{{ status|dict2items|
                           selectattr('value')|
                           map(attribute='key')|
                           first }}"
        - name: Fetch file.
          fetch:
            src: /file.txt
            dest: /tmp
          delegate_to: "{{ reference }}"
      run_once: true
    - name: Copy file if not exist
      copy:
        src: "/tmp/{{ reference }}/file.txt"
        dest: /file.txt
      when: not status[inventory_hostname]

但是,这不会检查现有文件是否同步.我认为同步所有主机会更安全

But, this doesn't check the existing files are in sync. It would be safer to sync all hosts, I think

    - name: Synchronize file
      synchronize:
        src: "/tmp/{{ reference }}/file.txt"
        dest: /file.txt
      when: not status[inventory_hostname]


Q:"致命.在Ansible控制器上找不到或访问'/tmp/test-multi-01/file.txt.但是,/tmp/test-multi-03文件夹中带有file.txt."

A: fetch 模块,将任务委派给另一台主机.将 TASK [Fetch file.] 委派给 test-multi-01 (在本例中为本地主机)时,已更改:[test-multi-03->127.0.0.1] 该文件将从 test-multi-01 中提取,但将存储在/tmp/test-multi-03/file.txt 中.结论是,在创建特定于主机的目录时, fetch 模块会忽略 delegate_to (尚未报告).

A: There is a problem with the fetch module when the task is delegated to another host. When the TASK [Fetch file.] is delegated to test-multi-01 which is localhost in this case changed: [test-multi-03 -> 127.0.0.1] the file will be fetched from test-multi-01 but will be stored in /tmp/test-multi-03/file.txt. The conclusion is, the fetch module ignores delegate_to when it comes to creating host-specific directories (not reported yet).

作为一种解决方法,可以设置 flat:true 并将文件存储在特定目录中.例如,在目录中添加变量 sync_files_dir ,设置访存 flat:true ,然后使用该目录来访存和复制文件

As a workaround, it's possible to set flat: true and store the files in a specific directory. For example, add the variable sync_files_dir with the directory, set fetch flat: true, and use the directory to both fetch and copy the file

- hosts: all
  vars:
    sync_files_dir: /tmp/sync_files
  tasks:
    - name: Get status.
      stat:
        path: /file.txt
      register: status
    - block:
        - name: Create dir for files to be fetched and synced
          file:
            state: directory
            path: "{{ sync_files_dir }}"
          delegate_to: localhost
        - name: Create dictionary status.
          set_fact:
            status: "{{ dict(keys|zip(values)) }}"
          vars:
            keys: "{{ ansible_play_hosts }}"
            values: "{{ ansible_play_hosts|
                        map('extract', hostvars, ['status','stat','exists'])|
                        list }}"
        - debug:
            var: status
        - name: Fail. No file exists.
          fail:
            msg: No file exists
          when: status.values()|list is not any
        - name: Set reference to first host with file present.
          set_fact:
            reference: "{{ status|dict2items|
                           selectattr('value')|
                           map(attribute='key')|
                           first }}"
        - name: Fetch file.
          fetch:
            src: /file.txt
            dest: "{{ sync_files_dir }}/"
            flat: true
          delegate_to: "{{ reference }}"
      run_once: true
    - name: Copy file if not exist
      copy:
        src: "{{ sync_files_dir }}/file.txt"
        dest: /file.txt
      when: not status[inventory_hostname]

这篇关于ansible-确保文件内容在服务器之间相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆