Spersonalizowane dotfiles dla DevOps-a

Spersonalizowane dotfiles dla DevOps-a

W dzisiejszym artykule chciałbym omówić istotny aspekt, który znacząco ułatwia pracę każdego DevOps a mianowicie pliki dotfiles. Dowiesz się, czym są te pliki i dlaczego są one ważne dla specjalistów DevOps, ale również dla każdego programisty i innych użytkowników. Pokażę, jak dobrze skonfigurowane dotfiles mogą znacząco usprawnić codzienną pracę oraz jak w łatwy i automatyczny sposób je spersonalizować i wdrożyć. Zapraszam do zapoznania się z treścią artykułu!

Co to jest dotfile?

Dotfiles to pliki, których nazwa poprzedzona jest kropką: na przykład .gitconfig, .bash_profile, .vimrc itd. W systemach Linux pliki te są ukryte i domyślnie nie są widoczne przy użyciu polecenia ls, ale można je zobaczyć dodając flagę -a (all). Zazwyczaj znajdują się one w katalogach domowych użytkowników. Służą one do przechowywania konfiguracji narzędzi, których używamy. Często konfigurujemy je raz, a potem przez dłuższy czas do nich nie wracamy, dlatego też ukrywamy je za pomocą kropki, aby nie przeszkadzały nam w codziennych obowiązkach.

Jestem zdania, że każdy sprawny specjalista DevOps, programista, inżynier danych czy guru baz danych powinien zadbać o odpowiednio skonfigurowany zestaw dotfiles, który pozwoli na szybkie i sprytne wykonywanie codziennych obowiązków. W tym artykule chciałbym pokazać Wam wybrane narzędzia, z których na co dzień korzystam abyście mogli na tej podstawie stworzyć swoje własne.

Konfiguracja dotfiles z pomocą Ansibla

Na tej stronie znajdziecie przykład repozytorium zawierającego mój szablon dotfiles, który wykorzystam do skonfigurowania czystej maszyny Ubuntu na platformie AWS. Zanim jednak uruchomimy skrypt warto spojrzeć na kod i zrozumieć co on robi.

UWAGA NA ZMIANY W REPOZYTORIACH !!!

Proszę zwrócić uwagę na daty commitów, które znajdziecie we wszystkich repozytoriach dostępnych na https://github.com/red-devops. Często korzystam z wcześniejszego kodu w kolejnych wpisach, dostosowując go do bieżących zadań. W związku z tym może się zdarzyć, że kod prezentowany w tym wpisie będzie różnił się od tego, który znajdziecie w najnowszym commicie repozytorium. Niemniej jednak wszystkie główne commity zostawiam, dlatego proszę porównywać daty publikacji wpisu z datami commitów.

Szablon ten jest stworzony tak, aby ułatwić proces konfiguracji środowiska pracy na nowej maszynie. Zawiera zestaw moich preferencji i narzędzi, które pomagają mi wydajniej pracować na codzień.

#!/bin/bash

## setup Ansible
sudo apt-get update 2>&1
sudo apt install -y python3-pip 2>&1
sudo pip3 install --upgrade pip
sudo pip3 install ansible virtualenv yamllint boto3 pre-commit

## run Ansible playbook
cd ansible
ansible-playbook -i inventories/local/inventory personalize.yaml 2>&1 | tee ./ansible.log

Do konfiguracji maszyny użyjemy playbooka Ansibla w taki sposób, że zostanie wykonany na lokalnej maszynie. Jednak przed uruchomieniem skryptu warto sprawdzić kilka rzeczy, aby upewnić się, że wszystko przebiegnie pomyślnie.

Uwaga !!!

Jeśli nie jesteś zaznajomiony z narzędziem Ansible i wcześniej nie miałeś okazji go używać w swojej pracy wówczas gorąco Ci polecam zapoznanie się z moim wcześniejszym wpisem, w którym dokładnie opisuję to narzędzie.
link: https://red-devops.pl/ansible-skuteczne-i-proste-konfigurowanie-infrastruktury/

Wracając do instalacji. Po pierwsze, należy sprawdzić czy użytkownik, który wykonuje skrypt ma uprawnienia do używania sudo oraz czy jego nazwa jest zgodna ze zmienną zdefiniowaną w plikach ansible/group_vars/all.yaml oraz ansible.cfg. To pozwoli na upewnienie się, że skrypt działa pod oczekiwanym użytkownikiem i na podstawie odpowiednich konfiguracji.

apt_packages:
  - zsh
  - jq
  - unzip
  - awscli
user_name: jarek
home_dir: "/home/{{ user_name }}"

Przyjrzyjmy się teraz samemu playbookowi. Poniżej znajduje się playbook, który zostanie uruchomiony na lokalnej maszynie za pomocą Ansible.

---

- name: Setup dotfile
  hosts: all
  become: yes
  tasks:

  - name: Install Packages
    apt:
      name: "{{ apt_packages }}"
      state: present
    tags:
      - apt

  - name: Create Dirs in Home
    file:
      state: directory
      path: "{{ home_dir }}/{{ item }}"
      owner: "{{ user_name }}"
      group: "{{ user_name }}"
    with_items:
      - bin

  - name: HashiCorp Tools
    unarchive:
      src: "{{ item }}"
      dest: "{{ home_dir }}/bin"
      remote_src: yes
      owner: "{{ user_name }}"
      group: "{{ user_name }}"
    with_items:
      - "https://releases.hashicorp.com/packer/1.9.2/packer_1.9.2_linux_amd64.zip"
      - "https://releases.hashicorp.com/terraform/1.5.4/terraform_1.5.4_linux_amd64.zip"
      - "https://releases.hashicorp.com/vault/1.14.1/vault_1.14.1_linux_amd64.zip"
      - "https://releases.hashicorp.com/consul/1.16.0/consul_1.16.0_linux_amd64.zip"
      - "https://releases.hashicorp.com/nomad/1.6.0/nomad_1.6.0_linux_amd64.zip"
    tags:
      - hashi
  
  - name: Other Tools
    unarchive:
      src: "{{ item }}"
      dest: "{{ home_dir }}/bin"
      remote_src: yes
      owner: "{{ user_name }}"
      group: "{{ user_name }}"
    with_items:
      - "https://github.com/junegunn/fzf/releases/download/0.40.0/fzf-0.40.0-linux_amd64.tar.gz"
    tags:
      - other

  - name: GitHub checkout oh-my-zsh
    become: no
    git:
      repo: "https://github.com/robbyrussell/oh-my-zsh.git"
      dest: "{{ home_dir }}/.oh-my-zsh"
    tags:
    - zsh

  - name: GitHub checkout fzf
    become: no
    git:
      repo: "https://github.com/junegunn/fzf.git"
      dest: "{{ home_dir }}/.fzf-base"
    tags:
    - zsh
  
  - name: Link fzf in fzf-base
    become: no
    file:
      dest: "{{ home_dir }}/.fzf-base/shell/fzf"
      src: "{{ home_dir }}/bin/fzf"
      state: link
      owner: "{{ user_name }}"
      group: "{{ user_name }}"
    tags:
    - zsh
  
  - name: Copy zshrc
    template:
      src: files/zshrc
      dest: "{{ home_dir }}/.zshrc"
      owner: "{{ user_name }}"
      group: "{{ user_name }}"
    tags:
    - zsh
  
  - name: Copy gitconfig
    copy:
      src: gitconfig
      dest: "{{ home_dir }}/.gitconfig"
      owner: "{{ user_name }}"
      group: "{{ user_name }}"
  
  - name: Change Shell to zsh
    user:
      name: "{{ user_name }}"
      shell: /bin/zsh
      

Playbook jest prosty i czytelny. Jego zadaniem jest instalacja pakietów, pobranie wymaganych repozytoriów i narzędzi HashiCorp. Dodatkowo playbook przenosi nasze pliki konfiguracyjne do odpowiednich lokalizacji. W efekcie, po wykonaniu skryptu nasze środowisko pracy jest gotowe do działania, a my możemy zacząć pracę w wygodny i spersonalizowany sposób.

Warto podkreślić, że ten konkretny przykład jest dostosowany do dystrybucji Ubuntu. Jednakże playbook można łatwo dostosować do innych dystrybucji Linuxa takich jak Fedora.

Idempotentność jaką oferuje Ansible idealnie nadaje się do zadań instalacyjnych, a playbook pozwala zaoszczędzić czas i uniknąć ręcznej konfiguracji środowiska na każdej nowej maszynie. Dzięki temu możemy szybko rozpocząć pracę na nowym środowisku, które idealnie odpowiada naszym potrzebom.

Przed i po – Różnice w terminalu po wdrożeniu

Oto wygląd naszej konsoli przed personalizacją i instalacją wszystkich narzędzi. Na ekranie widoczny jest adres IP tymczasowej wirtualnej maszyny, na której planujemy przeprowadzić konfigurację.

W tej chwili nasze środowisko nie zostało jeszcze dostosowane do naszych potrzeb, ale to się zmieni wraz z wykonaniem playbooka. Po uruchomieniu skryptu wszystkie wymagane narzędzia zostaną zainstalowane, a nasze pliki konfiguracyjne zostaną umieszczone na właściwych miejscach.

Po wykonaniu skryptu w momencie przejścia do użytkownika jarek automatycznie zostanie dla niego ustawiona powłoka zsh wraz z wszystkimi jej dobrodziejstwami. W pliku konfiguracyjnym ansible/files/zshrc dodałem pluginy dla git, AWS, Nomad i fzf, co znacznie usprawnia pracę z tymi narzędziami.

Przykładowo fzf to bardzo przydatne narzędzie do wyszukiwania w historii wcześniej wykonanych komend za pomocą kombinacji klawiszy ’Ctrl+R’. Dodatkowo plugin dla AWS pomaga zorientować się, z jakiego profilu obecnie korzystamy, a plugin dla git jest niezbędny przy pracy z repozytoriami. Natomiast wtyczka dla Nomad poprawia podpowiedzi w interfejsie CLI.

Powyższy przykład dotfile jest jedynie szablonem, a w mojej codziennej pracy korzystam z bardziej spersonalizowanej wersji, która zawiera również elementy prywatne. Niemniej jednak dla potrzeb tego wpisu dzielę się z Wami wersją okrojoną. Warto podkreślić, że w pliku konfiguracyjnym zsh możemy umieszczać nasze własne funkcje, które dodatkowo przyspieszą naszą pracę. Ta elastyczność daje nam duże możliwości ułatwiania sobie powtarzalnych zadań i dostosowywania środowiska pracy do naszych unikalnych potrzeb.

Zachęcam Was serdecznie do stworzenia własnego skryptu z dotfiles i czerpania korzyści z zaoszczędzonego dzięki niemu czasu.

Comments are closed.