Сегодня про автоматизацию начальной настройки Linux сервера посредством Ansible🎺. От установки locales, timezone, параметров SSH сервера… до создания и настройки окружения нового пользователя👨💻: Oh-My-Zsh, Neovim и Tmux. Будет интересно😉.
Подписывайтесь на наш телеграм @r4ven_me📱, чтобы не пропустить новые публикации на сайте😉. А если есть вопросы или желание пообщаться по тематике – заглядывайте в Вороний чат @r4ven_me_chat🧐.
Для примеров из статьи в качестве управляющего хоста использовалась система с Linux Mint 22. Ansible playbook разработан под Deb based дистрибутивы и протестирован на Debian 12 и Ubuntu 24.
Дорогие читатели, прошу обратить ваше внимание на тот факт, что материалы на моём сайте носят рекомендательный характер. Все действия вы выполняете на свой страх и риск. Всегда делайте бэкапы важных файлов, перед настройкой виртуалок делайте снапшоты, а перед внесением изменений на продуктивных серверах всегда проверяйте их на тестовом стенде. Благодарю за понимание.
В каждой из статей довольно много подробностей и рутинных действий. Поэтому идея автоматизировать процесс родилась сама собой. В этой заметке я расскажу про мою Ansible role, которая сводит количество выполняемых действий из статей выше — к одной команде. Если конечно соблюдены необходимые условия😉.
Коротко перечислю, что делает playbook:
1) Конфигурация сервера:
Замена пароля root пользователя
Установка временнОй зоны (timezone)
Установка hostname
Добавление хостов в файл hosts
Настройка локализации
Обновление и установка пакетов
Конфигурация SWAP (если его нет) в файле
Ограничение количества хранимых системных журналов journald
Конфигурация SSH сервера
Отключение использования IPv6 в системе и в фаерволе UFW
Открытие заданного списка сетевых портов в UFW
черт, а я тут ufw пользуюсь..😳
2) Настройка окружения пользователя:
Создание нового пользователя с указанием пароля, оболочки и списка групп
Добавление публичного SSH ключа авторизации в ~/.ssh
Установка пакетов пользователя (отдельный список)
Скачивание и применение конфигурации для Zsh, Neovim, Tmux
Если вам не нужно выполнять все перечисленные действия, то плейбук подразумевает выборочную конфигурацию с помощью указания флагов (см. ниже) или через теги задач.
Подготовка
Для запуска плейбука нам понадобятся:
Целевые Linux сервер(ы) с Debian/Ubuntu на борту
Возможностью удаленного подключения к этим серверам по SSH
Установленный и настроенный Ansible на управляющей машине-клиенте
Если у вас еще нет такого набора, то возможно найдете полезными эти мои материалы:
Последнюю статью крайне рекомендую, если вы новичок в Ansible👆.
Если же вам лень читать длинные полотна и вы просто хотите поскорее приступить к автоматизации, то необходимый минимум, это: файлы ansible.cfg и inventory.yml.
Далее мы скачаем файлы проекта из моего репозитория на GitHub (понадобится утилита git) и скопируем нужную роль в рабочую директорию ansible, в моем случае это ~/ansible:
~ — это alias домашней директории пользователя.
# установка git
sudo apt install -y git
# клонирование репозитория во временную папку
git clone https://github.com/r4ven-me/ansible /tmp/ansible
# копирование роли в рабочую папку
cp -r /tmp/ansible/roles/linux-base-config ~/ansible/roles/
# очистка
rm -rf /tmp/ansible
# переход в рабочую папку
cd ~/ansible/
Состав роли выглядит так:
ls -l --tree --sort=type ./roles/linux-base-config
Ниже приведены спойлеры для каждого файла роли, под которыми указано его содержимое на момент написания статьи с комментариями на русском языке👇.
Если вы не хотите особо вникать во все файлы, то изучите только defaults/main.yml, содержащий переменные, которые необходимо отредактировать в соответствии с вашими предпочтениями.
defaults/main.yml — файл с переменными по умолчанию
---
### Обработчики
- name: Enable swap on startup # Включает swap при загрузке системы
ansible.builtin.lineinfile:
path: "/etc/fstab" # Файл конфигурации монтирования
regexp: "^/swap" # Проверяет наличие строки, начинающейся с /swap
line: '/swap none swap sw 0 0' # Добавляет строку для монтирования swap
state: present # Убеждается, что строка присутствует в файле
- name: Reload sysctl # Применяет настройки sysctl
ansible.builtin.shell: "sysctl -p"
ignore_errors: true # Игнорирует ошибки при выполнении
- name: Restart journald service # Перезапускает systemd-journald
ansible.builtin.systemd_service:
name: systemd-journald # Имя службы
state: restarted # Перезапуск службы
- name: Restart ufw service # Перезапускает UFW (брандмауэр)
ansible.builtin.systemd_service:
name: ufw # Имя службы
state: restarted # Перезапуск службы
enabled: true # Включает службу при загрузке
- name: Restart sshd service # Перезапускает SSH-сервер (имя определяется в зависимости от ОС)
ansible.builtin.systemd_service:
name: >-
{%- if ansible_facts['distribution'] == 'Debian' -%}
sshd
{%- elif ansible_facts['distribution'] == 'Ubuntu' -%}
ssh
{%- else -%}
ssh
{%- endif -%}
daemon_reload: true # Перечитывает конфиг systemd при изменениях
state: restarted # Перезапуск службы
- name: Reboot system # Перезагружает систему
ansible.builtin.shell: "sleep 5 && reboot"
async: 1 # Запускает команду асинхронно
poll: 0 # Не ожидает завершения команды
- name: Delete ufw rule for default ssh port # Удаляет правило UFW для порта 22
community.general.ufw:
rule: allow # Тип правила (разрешить)
port: 22 # Порт, который удаляется
proto: tcp # Протокол (TCP)
delete: true # Удаление правила
when: server_config == true and ansible_facts['user_id'] == "root" # Условия выполнения
- name: Wait for online # Ожидает, пока сервер станет доступным
ansible.builtin.wait_for_connection:
connect_timeout: 15 # Тайм-аут на подключение
sleep: 5 # Пауза перед следующей попыткой
delay: 40 # Задержка перед началом ожидания
timeout: 300 # Общее время ожидания
become: false # Выполнение от непривилегированного пользователя
vars:
ansible_port: "{{ server_ssh_port }}" # Обновление значения порта подключения
ansible_user: "{{ user_name }}" # Обновление значения пользователя подключения
meta/main.yml — метаданные о роли
---
### Метаинформация о роли
galaxy_info:
author: Ivan Cherniy # Автор роли
description: Basic configuration for linux server # Описание роли
company: r4ven.me # Название компании или проекта
license: GPL-2.0 # Лицензия, по которой распространяется роль
min_ansible_version: 2.1 # Минимальная версия Ansible для работы роли
platforms: # Поддерживаемые платформы
- name: Debian
versions:
- 12 # Поддерживаемая версия Debian
- name: Ubuntu
versions:
- 24 # Поддерживаемая версия Ubuntu
galaxy_tags: [] # Теги для поиска в Ansible Galaxy (не заданы)
dependencies: [] # Зависимости (если есть другие роли, которые требуется установить)
tasks/main.yml — основной файл задач
---
### Файл задач для базовой настройки сервера
- name: Check flags # Проверяет, установлен ли хотя бы один из флагов
ansible.builtin.debug:
msg: "At least one of the flags should be set to true:
server_config | user_config | server_reboot" # Выводит сообщение, если флаги не установлены
changed_when: true # Помечает задачу как изменённую (для корректного триггера обработчиков)
when: (server_config and user_config and server_reboot) != true # Проверяет, что хотя бы один флаг установлен
tags:
- check_flags # Метка для запуска этой задачи отдельно
- import_tasks: server_config.yml # Импорт задач настройки сервера
when: server_config == true and ansible_facts['user_id'] == "root" # Выполняется, если server_config установлен в true и пользователь root
tags:
- server_config # Метка для удобного запуска этой части задач
- import_tasks: user_config.yml # Импорт задач настройки пользователя
when: user_config == true # Выполняется, если user_config установлен в true
tags:
- user_config # Метка для запуска этой части задач
- name: Init reboot handlers # Инициализирует обработчики для перезагрузки сервера
ansible.builtin.debug:
msg: "Running handlers..." # Выводит сообщение о запуске обработчиков
notify: # Запускает обработчики при изменениях
- Reboot system # Перезагружает систему
- Delete ufw rule for default ssh port # Удаляет правило UFW для стандартного порта SSH
- Wait for online # Ждёт, пока сервер снова станет доступным
when: server_reboot == true # Выполняется, если server_reboot установлен в true
changed_when: true # Помечает задачу как изменённую
tags:
- reboot # Метка для запуска этой части задач
tasks/server_config.yml — файл задач по настройке сервера
---
### Конфигурация сервера
- name: Change root password # Устанавливает пароль для root
ansible.builtin.user:
name: "root" # Имя пользователя
password: "{{ server_root_password }}" # Новый пароль
tags:
- root # Метка для фильтрации задач
- name: Set timezone # Устанавливает часовой пояс
community.general.timezone:
name: "{{ server_timezone }}" # Часовой пояс из переменной
tags:
- timezone
- name: Change hostname # Изменяет имя хоста
ansible.builtin.lineinfile:
path: "/etc/hostname" # Файл с именем хоста
regexp: "^.*$" # Заменяет всю строку
line: "{{ server_hostname }}" # Новое имя хоста
tags:
- hostname
- name: Set hosts # Добавляет записи в /etc/hosts
ansible.builtin.lineinfile:
path: "/etc/hosts" # Файл hosts
line: "{{ item }}" # Строка с записью
state: present # Убеждается, что строка присутствует
loop: "{{ server_hosts }}" # Перебирает список хостов
tags:
- hosts
- name: Config locales # Устанавливает локали
community.general.locale_gen:
name: "{{ item }}" # Название локали
state: present # Убеждается, что локаль установлена
loop: "{{ server_locales }}" # Перебирает список локалей
tags:
- locales
- name: Update system and install pkgs # Обновляет систему и устанавливает пакеты
block:
- name: Cache update and system upgrade # Обновляет кэш пакетов и выполняет обновление
ansible.builtin.apt:
upgrade: true # Выполняет обновление системы
update_cache: true # Обновляет кэш пакетов
- name: Install pkgs # Устанавливает необходимые пакеты
ansible.builtin.apt:
name: "{{ server_pkgs }}" # Список пакетов
state: present # Убеждается, что пакеты установлены
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu' # Выполняется только для Debian и Ubuntu
tags:
- pkgs
- name: Config SWAP # Настраивает файл подкачки
block:
- name: Checking if swap partition exists # Проверяет, существует ли swap
ansible.builtin.shell: "swapon -s | grep -q /"
register: swap_status # Сохраняет статус выполнения команды
ignore_errors: true # Игнорирует ошибки
changed_when: false # Не помечает задачу как изменённую
failed_when: false # Не считает ошибку критической
- name: Make swap file # Создаёт файл подкачки
ansible.builtin.command: "{{ item }}"
loop:
- "dd if=/dev/zero of=/swap bs=1M count={{ server_swap_size }}" # Создаёт файл
- "chmod 600 /swap" # Устанавливает права доступа
- "mkswap /swap" # Форматирует файл подкачки
- "swapon /swap" # Включает swap
when: swap_status.rc != 0 # Выполняется, если swap отсутствует
notify: Enable swap on startup # Запускает задачу включения swap при загрузке
tags:
- swap
- name: Disable ipv6 in system # Отключает IPv6 в системе
ansible.builtin.lineinfile:
path: "/etc/sysctl.conf" # Файл конфигурации sysctl
regexp: "^{{ item.key }}" # Ищет строку по ключу
line: "{{ item.key }} = {{ item.value }}" # Добавляет или заменяет строку
state: present # Убеждается, что строка присутствует
create: true # Создаёт файл, если он отсутствует
loop:
- {key: "net.ipv6.conf.all.disable_ipv6", value: "1"}
- {key: "net.ipv6.conf.default.disable_ipv6", value: "1"}
- {key: "net.ipv6.conf.lo.disable_ipv6", value: "1"}
notify: Reload sysctl # Перезапускает sysctl для применения изменений
tags:
- ipv6
- name: Disable ipv6 in UFW # Отключает IPv6 в UFW (брандмауэре)
ansible.builtin.lineinfile:
path: /etc/default/ufw # Файл конфигурации UFW
regexp: "^IPV6=yes" # Ищет строку с включённым IPv6
line: "IPV6=no" # Отключает IPv6
tags:
- ipv6
- name: Allow ports from list in UFW # Разрешает список портов в UFW
community.general.ufw:
rule: allow # Разрешает соединения
port: "{{ item }}" # Номер порта
proto: tcp # Протокол TCP
state: enabled # Включает UFW
loop: "{{ server_ufw_ports }}" # Перебирает список портов
notify:
- Restart ufw service # Перезапускает UFW
tags:
- ufw
- name: Config journald # Настраивает systemd-journald
ansible.builtin.lineinfile:
path: /etc/systemd/journald.conf # Файл конфигурации
regexp: "^{{ item.key }}=" # Ищет строку с параметром
line: "{{ item.key }}={{ item.value }}" # Добавляет или заменяет параметр
backup: true # Создаёт резервную копию файла перед изменением
loop: "{{ server_journald_params }}" # Перебирает параметры конфигурации
notify: Restart journald service # Перезапускает journald после изменений
tags:
- journald
- name: Config SSH daemon # Настраивает SSH-сервер
ansible.builtin.lineinfile:
path: /etc/ssh/sshd_config # Файл конфигурации SSH
regexp: "^{{ item.key }}" # Ищет параметр по ключу
line: "{{ item.key }} {{ item.value }}" # Добавляет или изменяет параметр
validate: "/usr/sbin/sshd -t -f %s" # Проверяет конфигурацию перед сохранением
backup: true # Создаёт резервную копию файла
loop: "{{ server_ssh_params }}" # Перебирает параметры SSH
notify:
- Restart sshd service # Перезапускает SSH после изменений
tags:
- sshd
tasks/user_config.yml — файл задач по настройке пользователя
---
### Конфигурация пользователя
- name: Create user with shell, groups and password # Создаёт пользователя с оболочкой, группами и паролем
ansible.builtin.user:
name: "{{ user_name }}" # Имя пользователя
shell: "{{ user_shell }}" # Оболочка пользователя (например, /bin/zsh)
groups: "{{ user_groups }}" # Список групп, в которые добавляется пользователь
append: true # Добавляет пользователя в группы, не заменяя текущие
password: "{{ user_password }}" # Устанавливает пароль
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu' # Выполняется только для Debian/Ubuntu
tags:
- user # Метка для удобного запуска
- name: Create ssh directory # Создаёт каталог .ssh для пользователя
ansible.builtin.file:
path: "{{ user_home }}/.ssh/" # Путь к каталогу
state: directory # Убеждается, что это директория
owner: "{{ user_name }}" # Назначает владельца
group: "{{ user_name }}" # Назначает группу
mode: "0700" # Устанавливает права доступа (только владелец)
tags:
- ssh
- name: Add user ssh public key # Добавляет SSH-ключ пользователя
ansible.builtin.lineinfile:
path: "{{ user_home }}/.ssh/authorized_keys" # Файл с авторизованными ключами
line: "{{ user_ssh_pubkey }}" # Публичный ключ SSH
create: true # Создаёт файл, если он отсутствует
owner: "{{ user_name }}" # Назначает владельца
group: "{{ user_name }}" # Назначает группу
mode: "0600" # Устанавливает права (чтение и запись только владельцу)
tags:
- ssh
- name: Install user pkgs # Устанавливает пакеты для пользователя
ansible.builtin.apt:
name: "{{ user_pkgs }}" # Список пакетов для установки
state: present # Убеждается, что пакеты установлены
update_cache: true # Обновляет кэш перед установкой
when: ansible_distribution == 'Debian' or ansible_distribution == 'Ubuntu' # Только для Debian/Ubuntu
tags:
- user_pkgs
- name: Create dots dir # Создаёт каталоги для dot-файлов
ansible.builtin.file:
path: "{{ item }}" # Путь к создаваемой директории
state: directory # Убеждается, что это директория
owner: "{{ user_name }}" # Назначает владельца
group: "{{ user_name }}" # Назначает группу
recurse: true # Рекурсивно создаёт вложенные каталоги
loop:
- "{{ user_home }}/.local/share/nvim/site/autoload/" # Папка для nvim-плагинов
- "{{ user_home }}/.config/nvim/" # Папка для конфигурации Neovim
- "{{ user_home }}/.config/tmux/" # Папка для конфигурации tmux
tags:
- dots
- name: Download dot files # Загружает dot-файлы из репозитория
ansible.builtin.shell:
cmd: "sudo -u {{ user_name }}
curl -fsSL https://raw.githubusercontent.com/{{ item.key }}
-o {{ user_home }}/{{ item.value }}" # Скачивает файл и сохраняет в указанное место
loop:
- {key: "r4ven-me/dots/main/.zshrc", value: ".zshrc"} # Конфигурация Zsh
- {key: "junegunn/vim-plug/master/plug.vim", value: ".local/share/nvim/site/autoload/plug.vim"} # Установщик плагинов Neovim
- {key: "r4ven-me/dots/main/.config/nvim/init.vim", value: ".config/nvim/init.vim"} # Основной конфиг Neovim
- {key: "r4ven-me/dots/main/.config/nvim/plugins.vim", value: ".config/nvim/plugins.vim"} # Список плагинов Neovim
- {key: "r4ven-me/dots/main/.config/tmux/tmux.conf", value: ".config/tmux/tmux.conf"} # Конфигурация tmux
tags:
- dots
- name: Apply config for dot files # Применяет настройки dot-файлов
ansible.builtin.shell: "sudo -u {{ user_name }} {{ item }}"
loop:
- "zsh -c 'source {{ user_home }}/.zshrc'" # Загружает конфигурацию Zsh
- "nvim -e -c 'PlugInstall' -c 'qall!'" # Устанавливает плагины Neovim
- "git clone https://github.com/tmux-plugins/tpm {{ user_home }}/.config/tmux/plugins/tpm" # Загружает менеджер плагинов tmux
- "{{ user_home }}/.config/tmux/plugins/tpm/bin/install_plugins" # Устанавливает плагины tmux
ignore_errors: true # Игнорирует ошибки
changed_when: true # Помечает задачу как изменённую
failed_when: false # Не считает ошибку критической
no_log: true # Скрывает вывод (например, для паролей)
tags:
- dots
tests/test.yml — файл тестовых задач
---
### Тестовые задачи
- name: Test playbook # Тестовый playbook
vars:
ansible_become_password: "password" # Пароль для sudo
user_pkgs: # Список пакетов для установки
- "zsh"
- "tmux"
- "neovim"
hosts: localhost # Запуск на локальном хосте
# remote_user: root # (Закомментировано) Пользователь для удалённого подключения
gather_facts: true # Сбор фактов о системе
become: true # Выполнение с правами суперпользователя (sudo)
force_handlers: true # Принудительное выполнение обработчиков
# roles:
# - role: ../server-base-config # (Закомментировано) Подключение роли
connection: local # Использование локального соединения (без SSH)
tasks:
- name: Start debug # Отладочный вывод переменных
debug:
msg:
- "{{ ansible_distribution }}" # Выводит дистрибутив системы
- "{{ user_pkgs }}" # Выводит список пакетов
tags:
- debug # Метка для запуска отладки отдельно
tests/inventory.yml — файл инвентаризации для тестов
---
### Тестовый инвентаризация
all: # Глобальная группа хостов
hosts:
localhost: # Определяет локальный хост
ansible_host: localhost # Использует локальный адрес
# ansible_port: 22 # (Закомментировано) Порт SSH, по умолчанию 22
# ansible_user: user # (Закомментировано) Имя пользователя для подключения
# ansible_ssh_private_key_file: ~/.ssh/id_ed25519 # (Закомментировано) Путь к приватному SSH-ключу
vars/main.yml — файл с переменными
Файл с переменными, которые переопределяют оные в файле default/main.yml. Про него поговорим далее.
README.md — файл ридми
Файл с кратким руководством в формате markdown (в процессе).
---
### Playbook для инициализации роли
- name: Basic server configuration # Основная конфигурация сервера
hosts: all # Применение на всех хостах из инвентаря
# remote_user: root # (Закомментировано) Пользователь для удалённого подключения
gather_facts: true # Сбор фактов о системе
become: true # Выполнение с правами суперпользователя (sudo)
force_handlers: true # Принудительное выполнение обработчиков
roles:
- role: ../server-base-config # Запуск роли
Указание своих значений переменных
Перед запуском роли Ansible необходимо указать свои значения для обязательных переменных✍️.
Сделать это можно в двух местах: в ./default/main.yml и ./vars/main.yml. Первый, понятно по названию, содержит переменные по умолчанию, а второй переопределяет значения переменных из первого. Я рекомендую вам оставить ./default/main.yml в качестве шаблона, а свои значения задать в ./vars/main.yml.
Тут следует учитывать иерархию переопределения переменных. Смотрите комментарий под постом.
Открываем его на редактирование:
nvim ./roles/linux-base-config/vars/main.yml
Вы можете раскоментировать и изменить любые значения, я укажи лишь обязательные.
Флаги (true, false):
server_config — если true, выполняет пул задач для конфигурации сервера;
server_reboot — если true, перезапускает сервер после завершения всех задач;
user_config — если true, выполняет пул задач по настройке окружения пользователя.
Должен быть установлен хотя бы один флаг в true.
Переменные:
user_name — имя нового пользователя
user_password — пароль пользователя в виде хэш строки SHA-512 (как получить см. ниже)
user_ssh_pubkey — публичный SSH ключ (как получить см. ниже)
server_root_password — пароль пользователя root, также SHA-512
server_ssh_port — новый порт сервера SSH
server_ufw_ports — список tcp портов фаервола UFW, которые нужно открыть
В списке портов UFW обязательно укажите текущий SSH порт, чтобы не потерять доступ к серверу во время настройки.
Пароли пользователей вы можете указать явно (ansible все равно сделает из них строку SHA-512 на сервере), но так делать не рекомендуется☝️. Безопаснее всего указать их в виде хэш строки. К слову, аналогичным образом в файле /etc/shadow хранятся пароли локальных пользователей Linux.
Пароль в виде строки SHA-512
Чтобы получить hash пароля в SHA-512 воспользуйтесь утилитой mkpasswd (из пакета whois) или openssl (из пакета openssl):
mkpasswd --method=sha-512
# или
openssl passwd -6
Генерация публичного SSH ключа
Если у вас уже есть SSH ключи, просто скопируйте публичный и вставьте в соответствующую переменную: user_ssh_pubkey. Для генерации нового SSH ключа воспользуйтесь командой:
Подробнее про SSH ключи я рассказывал в прошлых статьях тут и тут.
Пример запуска playbook на двух хостах
В моей инвентаризацие Ansible есть два хоста с именами debian12 и ubuntu24. На их примере я и покажу, как запустить Playbook. Чтобы удостовериться в корректности написанных задач ansible, всегда рекомендуется прогонять плейбуки в режиме dry run🏃. Только учтите, что не все модули Ansible его поддерживают, например предусмотреть результат кастомных shell невозможно🤷♂️.
Запуск в режиме dry run
Вот команда запуска плейбука в режиме проверки (--check) для отдельных хостов из файла inventory (ключ -l или --limit + хосты через запятую):
ВНИМАНИЕ❗️ Данный playbook меняет номер порта демона sshd и отключает парольный доступ к серверу по SSH. Крайне рекомендуется запускать необкатанные плейбуки в тестовых средах. Все действия вы выполняете на свой страх и риск. Я вас предупредил)
Теперь запускаем плейбук, который внесет реальные изменения на хосты:
Готово👌. Если какие-то из задач завершились ошибкой😢, изучите вывод, при необходимости поправьте файлы роли и запустите плейбук заново (или обратитесь в наш чат за помощью). Помните, что ansible работает по принципу идемпотентности, т.е. приводит систему к состоянию. Чаще всего, если задача выполнилась успешно, то при следующем запуске она отработает без внесения изменений.
В конце своей работы (при наличии соответствующего флага) ansible отправит команду перезапуска системы (reboot) на удаленные хосты и удалит из списка открытых в фаерволе портов 22-й. В случае успеха плейбук должен положительно завершиться задачей “Wait for online”.
После отработки проверяем подключение к хостам уже под другими реквизитами:
Все отлично!
Если необходимо просто выполнить настройку окружения пользователя, например root, сделать это можно так:
Дополнительно: установка powerline шрифта для GUI сеанса
Если вы выполняли настройку окружения пользователя, то для корректной отрисовки иконок в вашем терминале во время графической сессии — необходимо использовать специальный мноноширный иконочный powerline шрифт🤯, например, из проекта Nerd fonts.
Мои читатели знают, что я предпочитаю шрифт Hack☝️. Вот простой пример, как его можно установить:
Обратите вниманием, что для выполнения команд потребуются права sudo. Либо установите шрифты только для текущего пользователя в директории ~/.local/share/fonts.
В команде curl используется механизм подстановки командной строки. Т.е. основной команде на скачивание: curl -fsSLO передается аргумент, который является результатом выполнения другой команды внутри конструкции $(command), выполняющейся предварительно. В итоге основная команда получит прямой URL на zip файл последнего релиза шрифта Hack из GitHub. Команда универсальна.
После установки шрифта, активируйте его в настройках вашего терминала🛠.
В Gnome-terminal это делается так:
Послесловие
Вот так автоматизация сокращает количество ручной работы в десятки раз.
Спасибо, что читаете 😊. Еще раз напомню, что актуальные версии файлов из статьи доступны в моем репозитории на GitHub.
Обязательно подписывайтесь на наш телеграм канал: @r4ven_me, уведомления о новых материалах на сайте приходят туда в день публикации. А если появились вопросы – приглашаю в наш дружелюбный Вороний чат 🚶♀️🐧🚶🐧🚶♂️🐧.
Когда вы первый раз заходите с помощью соцсетей, мы получаем публичную информацию из вашей учетной записи, предоставляемой провайдером услуги соцсети в рамках ваших настроек конфиденциальности. Мы также автоматически получаем ваш e-mail адрес для создания вашей учетной записи на нашем веб сайте. Когда она будет создана, вы будете авторизованы под этой учетной записью.
Не согласенСогласен
Я разрешаю создать мне учетную запись
Когда вы первый раз заходите с помощью соцсетей, мы получаем публичную информацию из вашей учетной записи, предоставляемой провайдером услуги соцсети в рамках ваших настроек конфиденциальности. Мы также автоматически получаем ваш e-mail адрес для создания вашей учетной записи на нашем веб сайте. Когда она будет создана, вы будете авторизованы под этой учетной записью.
В group_vars, host_vars можно описать все необходимые переменные для целых групп серверов или хоста, в том числе и секретные данные (пароли, логины и т.д.), при этом эти файлы можно спокойно зашифровать Ansible Vault’ом.
В целом, вы можете в ./default/main.yml определить сами переменные для использования в роли, без значений или с примерами необходимых значений и уже через внешние файлы подкидывать нужные значения, для всех ролей. Это ладно если парочка ролей, а если их с несколько десятков, которые могут содержать как общие, так и индивидуальные переменные, в том числе и секретные.
Последний раз редактировалось 13 дней назад Иван Чёрный ем
Эй, обратите внимание, что "Вороний блог" использует куки. Если Вы продолжите использовать данный сайт, это будет считаться что Вас это устраивает ;)Ok
Полезный комментарий из чата: