Как объединить два файла в один файл с помощью Ansible на удалённом сервере

Вопрос или проблема

Мне нужно объединить два файла без дублирующихся записей в них. Есть ли способ сделать это с помощью модулей Ansible.
Например, у меня есть два файла /etc/hosts1 и /etc/hosts2. Мне нужно, чтобы был один файл /etc/hosts со всеми записями, присутствующими как в /etc/hosts1, так и в /etc/hosts2, без дублирующихся записей.
Как я могу этого добиться.
Пример будет очень полезен.

- name: Объединить два файла
  assemble:
    src: /etc/hosts1
    dest: /etc/hosts2

Вышеуказанный модуль assemble не сработает.

Это работает. Он читает содержимое всех файлов и сокращает полученный массив строк до уникальных значений. Затем создается новый файл с этими строками.

- hosts: localhost
  gather_facts: no
  vars:
    hostsfiles:
      - /tmp/hosts1
      - /tmp/hosts2
  tasks:
  - name: чтение файлов
    command: awk 1 {{ hostsfiles | join(' ') }}
    register: hosts_contents
  - name: создать файл hosts
    copy:
      dest: /tmp/hosts
      content: "{{ hosts_contents.stdout_lines | unique | join('\n') }}"

Я использую awk 1 вместо cat, чтобы добавить потенциально отсутствующие переносы строк в конце исходных файлов.

Используйте slurp для получения содержимого файла, оператор ~ для объединения и copy для сохранения отсортированного содержимого.

# lookup('ansible.builtin.file') читает файл только на контролере, используйте slurp вместо этого.
- name: Извлечение содержимого файлов на удаленном хосте
  ansible.builtin.slurp:
    src: "{{ item }}"
  register: _file_content
  loop:
    - /etc/hosts
    - /etc/resolv.conf

- name: Декодирование base64, объединение, сортировка и вывод в файл назначения.
  ansible.builtin.copy:
    content: "{{ ((_file_content.results.0.content | b64decode) ~ (_file_content.results.1.content | b64decode) ) | split('\n') | sort | unique | join('\n')  }}"
    dest: /tmp/nicely-sorted-file

Ответ или решение

Объединение файлов без дублирующихся записей с использованием Ansible может быть реализовано, если корректно воспользоваться его модулями и функциями. Ниже приведена инструкция, как это можно сделать, а также пример плейбука Ansible, который поможет вам достичь желаемого результата.

Теория:

Ansible предоставляет мощные инструменты для автоматизации задач управления конфигурацией и выполнения различных операций на удалённых серверах. В вашем случае, задача заключается в объединении содержимого двух файлов в один, исключая при этом дублирующиеся строки. Ansible обладает рядом модулей, таких как command, slurp и copy, которые могут быть эффективно использованы для решения вашей задачи.

Используя модуль slurp, мы можем считать содержимое файла с удалённого сервера, преобразовать его из формата base64 и объединить с содержимым другого файла. Затем, при помощи модуля copy, можно легко записать отсортированные и уникализированные строки в конечный файл.

Пример:

Рассмотрим пример плейбука Ansible, который иллюстрирует, как можно объединить два файла /etc/hosts1 и /etc/hosts2 на удалённом сервере, избегая дублирования строк:

- name: Объединение файлов на удалённом сервере
  hosts: удалённые_серверы # определите вашу группу хостов
  gather_facts: no
  tasks:
    - name: Чтение содержимого файла /etc/hosts1
      ansible.builtin.slurp:
        src: /etc/hosts1
      register: hosts1_content

    - name: Чтение содержимого файла /etc/hosts2
      ansible.builtin.slurp:
        src: /etc/hosts2
      register: hosts2_content

    - name: Создание объединённого файла без дубликатов
      ansible.builtin.copy:
        dest: /etc/hosts # определите расположение конечного файла
        content: "{{ (hosts1_content.content | b64decode + '\n' + hosts2_content.content | b64decode) | split('\n') | unique | join('\n') }}"

Применение:

Этот плейбук делает следующее:

  1. Чтение содержимого: Сначала с помощью модуля slurp считывается содержимое обоих файлов. Полученное содержимое регистрируется в переменных hosts1_content и hosts2_content. slurp создаёт данные в формате base64, поэтому его результат необходимо декодировать.

  2. Объединение и Удаление Дубликатов: При помощи функции b64decode содержимое каждого файла декодируется из base64 в обычный текст, после чего они объединяются. Фильтр split('\n') используется для создания списка строк, которые затем сортируются и уникализируются с помощью unique, после чего результат соединяется в одну строку с помощью join('\n').

  3. Сохранение конечного файла: Окончательное содержимое записывается в файл /etc/hosts с помощью модуля copy, что позволяет перестроить файл с уникальными строками обоих файлов.

Заключение:

Использование данного подхода позволяет полностью автоматизировать процесс объединения файлов на удалённых серверах с помощью Ansible, минимизируя вероятность возникновения ошибок, связанных с дублированием строк. Это особенно полезно в окружениях, требующих высокой степени надёжности и воспроизводимости конфигурации. Таким образом, вы сможете сэкономить время и избежать ручного вмешательства, что может быть особенно важно в масштабных инфраструктурах.

Эта техника показывает, как могут быть использованы возможности Ansible для решения специфичных задач на высоком уровне автоматизации, что является ключевым аспектом в современных процессах DevOps и управления конфигурациями. Надеемся, что данный пример и объяснение помогут вам успешно реализовать вашу задачу.

Оцените материал
Добавить комментарий

Капча загружается...