in devops ~ read.
Hack your workspace

Hack your workspace

Что есть на работе у каждого разработчика, тестировщика или другого айтишника? Независимо от компании, специализации и прочего? Бьюсь об заклад, что это рабочее окружение. Ваше рабочее окружение. Набор файлов на вашем компьютере. Набор команд в консоли на кончиках ваших пальцев. Набор ритуалов, которые вы делаете каждый день.

Часто ли вы задумываетесь, как много действий нужно совершить новичку, чтобы начать эффективно работать? Что делать, если завтра ваш жесткий диск прикажет долго жить? И сколько раз в день вы делаете очевидные для вас, но возможно неэффективные действия?

Положа руку на сердце, мало кто из нас бакапит свой жесткий диск. Ещё меньше тех, кто помнит какие именно, когда и куда вносил настройки, без некоторых из которых в самый нужный момент отвалится банальная сборка ПО. А уж про передачу разных xxx.properties через мессенджер я просто промолчу.

Кажется, что все эти проблемы имеют отражение в классическом системном администрировании. Только там они имеют как правильно несколько большее влияние на жизнь и здоровье компании и её отдельных представителей. Чтобы их сгладить или искоренить (например, ручную настройку серверов), прогрессивное человечество придумало такую штуку как "инфраструктура как код", которая в своём экстремальном проявлении приводит к тому, что вся инфраструктура становится иммутабельной, и тот же сервер порой проще пересоздать с чистого листа, чем обновлять.

Основным принципом инфраструктуры как код является машиночитаемое представление конфигурации в виде набора файлов, которые по правилам хорошего тона находятся в системе хранения исходных кодов. Проще говоря, вся конфигурация должна быть в коде, а код в гите.

Попробуем руководствоваться тем же принципом при настройке своего рабочего окружения.

Вот не самый полный список задач, которые нужно было сделать мне при выходе на новое место работы, чтобы начать эффективно работать:

  • установить утилитный софт на рабочую машину
  • выкачать из репозитория набор проектов
  • сконфигурировать настройки локального окружения, которые хранятся в .properties-файлах
  • сделать себе мета-обёртку из gradle
  • сгенерировать и положить в нужные места сертификаты и т.д.

Все эти пункты без сомнения можно сделать вручную, а некоторые к слову можно и не делать вовсе. Для новичков есть специальный гайд, в котором подробно описаны все шаги, но проходить его второй раз когда-нибудь в светлом будущем мне не хотелось. Это во-первых, а во-вторых часть действий нужно выполнять периодически.

Поэтому было решено заавтоматизировать самого себя с помощью простой и понятной команды:

ansible-playbook -i local-inv setup.yml  

В local-inv нет ничего интересного кроме объявления того, что мы будем выполнять playbook на локальной машине:

[local]
localhost ansible_connection=local  

Верхнеуровнего наш алгоритм настройки можно представить так:

#checkout repositories from git
- include: checkout.yml
  tags: checkout

#configure your local environment
- include: configure.yml
  tags: configure

#add useful mappings to your hosts file
- include: hosts.yml
  tags: hosts_mapping

#add gradle support
- include: gradle.yml
  tags: gradle

#clean and build all repositories
- include: build.yml
  tags: build

#deploy apps
- include: deploy.yml
  tags: deploy

#certificates installation
- include: certificates.yml
  tags: certificates

Под каждым таким include-ом скрывается последовательность шагов, которую нам нужно выполнить для достижения цели. Помимо этого с помощью механизма тэгов мы можем выполнить только часть работ. Например, перезатемплейтить конфиги. А, скажем, выкачать все нужные репозитории мы можем следующим образом:

- name: checkout services
  git:
    repo: "{{ git.root }}/{{ item.name }}.git"
    dest: "{{ work_dir }}/{{ item.name }}"
    update: yes
  with_items:
    - "{{ services }}"
  tags:
    - services

где services это список сервисов, определяемые через структуру данных в переменных, которые мы можем менять под себя:

services:  
  - { name: messages-service }
  - { name: discussions-service }
  - { name: attachments-service, local: true }

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

- name: create local properties for services
  template:
    src: service.properties.j2
    dest: "{{ work_dir }}/{{ item.name }}/service.properties"
    mode: 0644
  with_items:
    - "{{ services }}"

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

- stat: path={{ username }}.key
  register: certkey

- name: generate private key
  shell: openssl genrsa -out {{ username }}.key -aes256 4096
  when: not certkey.stat.exists

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

Бонусом к такому подходу мы получаем возможность не заставлять читать новичков гайды, а просто запускать один скрипт. Пользоваться им и вносить в него улучшения.

И если меня сейчас кто-нибудь спросит: "А с чего начать какой-нибудь DevOps в компании Х?", то, пожалуй, лучшим ответом будет: "С самого себя".

comments powered by Disqus