3sky's notes

Minimalistyczny blog o TI.

Ansible with jump host

2021-03-23 4 min czytania 3sky

Witaj

Początkowego żartu nie udało mi się przetłumaczyć, ale ogólnie brakuję mi morza i dawno go nie widziałem. Prawie to samo mogę powiedzieć o Ansible. Ostatni raz, kiedy użyłem tego narzędzia do rozwiązywania rzeczywistych problemów, mniej więcej 2 lata temu. Szczerze mówiąc, w tym okresie Ansible stał się (przynajmniej moim zdaniem) kolejnym nudnym i staromodnym narzędziem. Kto korzysta z Ansible, jeśli mamy kontenery, Kubernetes Engines i Serverless? Tylko nudni ludzie. A wiesz, kto nie korzysta z Ansible? Osoby bez życia osobistego lub interesujących problemu do rozwiązania. Jestem nudny…

Problem

Jak możesz założyć, nie jestem mistrzem Ansible. Znam większość podstaw, ale mimo to czasami zatrzymam się na jakiejś małej, ukrytej opcji lub dziwnego przypadku użycia trochę za długo. To będzie jeden z tych przypadków użycia. Uruchamianie Ansible przez serwer przesiadkowy.

Scenariusz

Mam maszynę wirtualną. Zupełnie nowa i świeża maszyna z niesamowitym sprzętem - powiedzmy potwór GPU do procesów uczenia maszynowego. Siedzi zamknięta w jakimś biurze. Brak statycznego adresu IP. Mogę połączyć się z tym komputerem przez odwrotne tunelowanie SSH za pośrednictwem innego serwera. Jak ułatwić sobie połączenie?

SSH config

Jeśli zastanawiasz się, dlaczego użytkownicy Linuksa nie używają narzędzi takich jak MobaXterm, odpowiedzią jest ~/.ssh/config. Podstawowa konfiguracja będzie wyglądać następująco:

Host test-3sky-dev
    # test, Suse
    HostName 3.22.11.33
    User kuba
    Port 31
    IdentityFile ~/.ssh/id_rsa_xy

Dzięki temu mogę tylko wpisać ssh test-3sky-dev i buum jestem na mojej testowej maszynie wirtualnej. Słodko.

Dodaj jumphost

W naszym przypadku załóżmy, że mam dostęp do monster-3sky-dev tylko z poziomu test-3sky-dev. Jak to zrobić? Kolejny prosty przykład.

Host test-3sky-dev
    # test, Suse
    HostName 3.22.11.33
    User kuba
    Port 31
    IdentityFile ~/.ssh/id_rsa_xy

Host monster-3sky-dev
    # prod, ubuntu
   HostName 12.22.11.33
   User kuba
   Port 45
   ProxyJump test-3sky-dev

Uwierzytelnianie

Lubię unikać uwierzytelniania za pomocą hasła, więc zalecam ssh-copy-id

# on test-3sky-dev machine
ssh-keygen -t rsa -b 4096 -C "test-3sky-dev"
ssh-copy-id -i ~/.ssh/id_rsa_yx.pub [email protected] -p 45

Następnie konfiguracja ~ / .ssh / config \ na mojej stacji przesiadkowej

Host monster-3sky-dev
   HostName 12.22.11.33
   User kuba
   Port 45
   IdentityFile ~/.ssh/id_rsa_yx

Wreszcie

Po prostu uciekaj z mojej stacji roboczej - słodko.

ssh monster-3sky-dev

Implementacja

Jak widać, mogę połączyć się z VM przez tunelowanie SSH, było to proste i dość szybkie. Teraz integracja z Ansible. Napiszmy kilka super prostych playbooków, takich jak:

---
- name: ADD NEW USER
  gather_facts: false
  user: kuba
  hosts: monster-3sky-dev
  become: yes
  vars:
    user: "adam"

  tasks:
    - name: Ensure group "{{ user }}" exists
      ansible.builtin.group:
        name: "{{ user }}"
        state: present

    - name: Add the user "{{ user }}"
      ansible.builtin.user:
        name: "{{ user }}"
        shell: /bin/bash
        groups:
          - "{{ user }}"
          - docker
        append: yes
        home: /home/{{ user }}
        password: "{{ 'password' | password_hash('sha512') }}"
        update_password: on_create

    - name: Creat home dirs
      ansible.builtin.file:
        path: "{{ item }}"
        state: directory
        mode: '0755'
        owner: "{{ user }}"
        group: "{{ user }}"
      loop:
        - /home/{{ user }}
        - /home/{{ user }}/bin
        - /home/{{ user }}/tools

Teraz muszę podać tylko różnice między zwykłym hostem a hostem znajdującym się za firewallem.

Spójrzmy na mój plik typu inventory:

[gpu]
monster-3sky-dev ansible_python_interpreter=/usr/bin/python3

Brak adresu IP. I o to chodzi. Podczas wykonywania polecenia ansible-playbook muszę określić jedną zmienną środowiskową - ANSIBLE_SSH_ARGS. A tak to wygląda:

ANSIBLE_SSH_ARGS="-F /home/kuba/.ssh/config" ansible monster-3sky-dev -m ping -i host.ini
monster-3sky-dev | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Jedna ważna rzecz. Nazwa hosta z pliku zasobów musi być zgodna z nazwą hosta z pliku .ssh/config.

Jak uruchomić Playbook? Niemal w ten sam sposób.

ANSIBLE_SSH_ARGS="-F /home/kuba/.ssh/config" ansible-playbook add_users/add_user.yaml -i host.ini

Podsumowanie

OK, więc to by było na tyle. Nic nadzwyczajnego, ale znalezienie odpowiedniego rozwiązania zajeło mi trochę czasu. To także jedna z tych rzeczy, nad którymi warto pracować. Nie mam już potrzeby wyszukiwania w Google rozwiązania. Mam je tutaj. Ten artykuł został napisany w ORG-mode, a następnie przekonwertowany na plik Hugo MD. To była ciekawa przygoda, zwłaszcza gdy Emacs stał się moim głównym narzędziem, jak już wspominałem. Ach i OpenSuse. Ostatnio miałem problem z Fedorą związany z dns-resolver. Od początku marca jestem szczęśliwym użytkownikiem OpenSuse Tumbleweed i muszę powiedzieć, że to niesamowita dystrybucja. Coś pomiędzy Archlinux (system wydań kroczących), a Fedorą (łatwa w użyciu i stabilna). Może jakaś długa recenzja? Nie jestem pewien, ale do tej pory jestem bardzo zadowolony z SUSE.