Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Dotfiles DevOps: Автоматизация локального окружения

Видео может быть заблокировано из-за расширений браузера. В статье вы найдете решение этой проблемы.

Подготовка рабочего окружения — это весьма распространённая задача. И Ansible с ней отлично справляется. Установить Git, настроить его, установить нужные приложения — всё это мы можем выполнить, если опишем нужные действия в плейбуке.

Пример файла playbook.yml

- name: Install tools packages
  hosts: localhost
  # Для всего блока будет запрошена эскалация привилегий
  become: yes
  tasks:
    - name: install packages
      ansible.builtin.apt:
        update_cache: yes
        state: present
        name:
          - git
          - curl
          - fzf

# В одном плейбуке может быть несколько блоков,
# из ролей и задач. В том числе могут быть и другие хосты
- name: install and setup docker
  hosts: localhost
  become: yes
  # Роли выполнятся до задач,
  # даже если в плейбуке они будут идти после задач
  roles:
    # Роли, которые взяты из Galaxy
    # вызываются по имени с неймспейсом (имя пользователя, имя роли)
    - name: geerlingguy.docker
      vars:
        docker_users:
          # Чтобы использовать значение переменной
          # используют кавычки и двойные фигурные скобки
        - "{{ user }}"

- name: Install and setup zsh
  hosts: localhost
  roles:
    - role: gantsign.oh-my-zsh
      vars:
        oh_my_zsh_install: yes
        users:
          - username: "{{ user }}"
            oh_my_zsh:
              theme: "{{ zsh_theme }}"
              plugins:
                - git
                - docker
                - docker-compose
                - zsh-syntax-highlighting

    - role: markosamuli.asdf
      vars:
        asdf_init_shell: true

  tasks:
    - name: Set zsh
      become: yes
      ansible.builtin.user:
        name: "{{ user }}"
        shell: /bin/zsh

    - name: Add $HOME/.local/bin to path
      ansible.builtin.lineinfile:
        state: present
        path: ~/.zshrc
        line: export PATH="$HOME/.local/bin:$PATH"

- name: Install asdf and plugins
  hosts: localhost
  roles:
    - role: markosamuli.asdf
      vars:
        asdf_plugins:
          - name: "ruby"
            versions: ["3.0.1"]
            global: "3.0.1"

          - name: "nodejs"
            versions: ["16.3.0"]
            global: "16.3.0"


- name: Setup git config
  hosts: localhost
  tasks:
    - name: Set global user.email
      # Модуль находится в коллекции Community.general,
      # для его вызова нужно обращаться по полному имени
      community.general.git_config:
        name: user.email
        scope: global
        value: "{{ git_user_email }}"

    - name: Set global user.name
      community.general.git_config:
        name: user.name
        scope: global
        value: "{{ git_user_name }}"

    - name: Setup aliases to ~/.gitconfig
      community.general.git_config:
        name: "alias.{{ item.name }}"
        scope: global
        # Задача вызывается несколько раз в цикле
        # Каждый элемент - это объект, указанный в with_items ниже
        value: "{{ item.value }}"
      with_items:
        - { name: co, value: checkout }
        - { name: ci, value: commit }
        - { name: st, value: status }
        - { name: br, value: branch }
        - { name: hist, value: "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short" }
        - { name: type, value: 'cat-file -t' }
        - { name: dump, value: 'cat-file -p' }
        - { name: commend, value: 'commit --amend' }

    - name: Set vim as editor
      community.general.git_config:
        name: core.editor
        scope: global
        value: vim

    - name: Copy git global ignore file
      ansible.builtin.copy:
        # Файлы, которые должны быть скопированы, находятся относительно плейбука рядом
        src: files/gitignore_global
        dest: "~/.gitignore_global"

    - name: Set global gitignore
      community.general.git_config:
        name: core.excludesFile
        scope: global
        value: ~/.gitignore_global

Пример файла requirements.yml

# Зависимости для ansible делятся на роли и коллекции (ролей)
# Роли и коллекции можно найти на https://galaxy.ansible.com/
roles:
  - name: geerlingguy.docker
    # Без указания версии ставится самая последняя версия
    version: '4.0.0'

  - name: gantsign.oh-my-zsh

  - name: markosamuli.asdf

collections:
  - community.general

Пример файла inventory.ini

; Файл может не имеет расширения .ini или называться по другому
; Инвентори файл может быть описан в yml формате
; https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

; алиас (имя хоста в рамках Ansible), адрес, тип подключения (для удаленных хостов используется ssh подключение)
localhost ansible_host=127.0.0.1 ansible_connection=local

Пример файла host_vars/localhost.yml

# Имя файла это имя хоста, которое указано в инвентори файле
# host_vars/<hostname>.yml - это соглашение по которому Ansible подгружает переменные
# https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#understanding-variable-precedence

# Синтаксис - обычный yml
# Эти переменные будут привязаны к хосту, к ним можно обратиться в плейбуке

param: abc
param2: "{{ param }}"

Команды, которые могут пригодиться

# Запуск adhoc команды
ansible localhost -m ping

# Запуск плейбука выполняется командой ansible-playbook
# Флаг -v, -vv, -vvv указывает на подробность вывода Ansible
# флаг -i указывает на файл инвентори в котором прописаны хосты для запуска
ansible-playbook -i inventory.ini playbook.yml -v

# флаг -K это сокращенная запись флага --ask-become-pass
# для указания пароля для sudo (когда указываем become: true для эскалации прав)
ansible-playbook -i inventory.ini playbook.yml -v -K

# Установка ролей и коллекций выполняется разными командами
ansible-galaxy collection install -r requirements.yml
ansible-galaxy role install -r requirements.yml

Самостоятельная работа

  1. Изучите содержимое файла mokevnin/dotfiles/Makefile
  2. Создайте на гитхабе репозиторий dotfiles
  3. Добавьте в него Makefile с задачей make install-language, которая устанавливает интерпретатор или компилятор языка, с которым вы работаете

Дополнительные материалы

  1. Что такое Makefile и как начать его использовать
  2. Пример Dotfiles

Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Изображение Тото

Задавайте вопросы, если хотите обсудить теорию или упражнения. Команда поддержки Хекслета и опытные участники сообщества помогут найти ответы и решить задачу