Automatyzacja odtwarzania Cisco ISE z backupu - część V

W poprzednich dwóch krokach sprawdziłem warunki, czy w ogóle mogę odtworzyć Cisco ISE z kopii zapasowej. Sprawdziłem czy mam “świeżą” kopię zapasową oraz czas licencji trial jest bliski wyczerpania. Jeżeli oba warunki są spełnione to mogę przechodzę do odtworzenia maszyny z kopii zapasowej. Na początek jednak muszę wyłączyć działającą maszynę wirtualną z Cisco ISE i na wszelki wypadek zrobić jej kopię zapasową na poziomie samego hypervisora.

Automation as seen by AI

Spis treści

 

Wyłączenie maszyny wirtualnej z Cisco ISE

Wyłączenie jakiejkolwiek maszyny wirtualnej czy fizycznego serwera przez odcięcie wirtualnego lub rzeczywistego zasilania nigdy nie jest dobrym pomysłem. Może to powodować utratę danych i błędy w logicznej strukturze dysków, które mogą uniemożliwić późniejsze ponowne uruchomienie serwera lub usług. Na wszelki wypadek, gdyby coś poszło nie tak, chcę mieć kopię całej maszyny wirtualnej bezpośrednio na serwerze, na której jest ona uruchamiana. Zatem muszę poprawnie zamknąć system aby uniknąć potencjalnych błędów.

Aby wyłączyć Cisco ISE muszę mieć dostęp do konsoli serwera za pomocą protokołu SSH. Warto w tym miejscu przypomnieć że konta do interfejsu GUI i konta do konsoli to dwie odmienne rzeczy. Fakt że mam dostęp do panelu administracyjnego GUI nie oznacza że mam jednocześnie dostęp do konsoli. Dobrą praktyką jest także aby konta interfejsu web i konta lokalne były od siebie oddzielone. Nawet jeżeli mają tę samą nazwę użytkownika, to powinniśmy im nadać inne hasła. 

Gdy już posiadam dostęp do konsoli Cisco ISE pozostaje zaprogramowanie logiki samego procesu wyłączenia serwera. Ja preferuję robienie tego w dwóch krokach:

  1. W pierwszym kroku wyłączam samą usługę Cisco ISE. Ten proces nie jest szybki, może trwać nawet 30 minut lub dłużej. Jeżeli zatrzymam najpierw usługę to mam pewność, że dane zgromadzone w Cisco ISE są poprawnie zapisane, a sama usługa zatrzymana.
  2. W drugim kroku wyłączam sam serwer. Mam gwarancję, że system plików pozostanie nieuszkodzony.

Zatrzymanie usługi Cisco ISE

Praca z konsolą Cisco ISE w skryptach Ansible nie jest trudna. W niczym nie odbiega ona od pracy z konsolą serwera Linux, używam nawet tych samych modułów Ansible. Jest jednak jeden haczyk. Praca z konsolą Cisco ISE przypomina pracę z konsolą bash czy sh Linuksa. Wydajemy nawet, obok poleceń typowych dla ISE, polecenia takie jak w typowym shell-u. Jeżeli jednak nie skonfigurujemy parametru ansible_network_os tak jakby było to router Cisco IOS, to komunikacja nie będzie działać poprawnie. W szczególności polecenia mogą się wtedy poprawnie nie wydawać, gdyż brakuje wciśnięcia wirtualnego “Enter” na końcu. Zatem playbook musimy zacząć od definicji parametrów połączenia z konsolą.

- name: Shutdown Cisco ISE
  hosts: ise
  gather_facts: no
  vars:
    ansible_become: no # ISE does not have a superuser/enable mode
    ansible_connection: ansible.netcommon.network_cli
    ansible_network_os: cisco.ios.ios
    ansible_command_timeout: 2200

Drugim niezbędnym parametrem jest ansible_command_timeout, który musimy ustawić na wartość większą niż czas wykonania komend, które będziemy wydawać. Jak już wspomniałem zatrzymanie procesu Cisco ISE może trwać kilkadziesiąt minut.

Rozpocznę od wykonania zadania o nazwie „Stop ISE service”, gdzie użyję komendy application stop ise do zatrzymania usługi ISE. Dopuszczę niepowodzenia tego zadania (ignore_errors: true), aby wyłapać potencjalne błędy. Następnie, w zadaniu „Check ISE Application Server Status” sprawdzę status serwera aplikacji ISE, używając komendy show application status ise. Sprawdzanie statusu będzie kontynuowane, dopóki nie uzyskam potwierdzenia w wyjściu, że serwer aplikacji nie działa. Zadanie to wykona się maksymalnie 60 razy co 60 sekund. Dopuszczam również niepowodzenia tego zadania.
  tasks:
    - name: Stop ISE service
        ansible_command_timeout: 2200
      ansible.netcommon.cli_command:
        command: application stop ise
      ignore_errors: true

    - name: Check ISE Application Server Status
      ansible.netcommon.cli_command:
        command: "show application status ise"
      register: result
      until: "'Application Server                     not running' in result.stdout"
      retries: 60
      delay: 60
      ignore_errors: true

W przypadku obu zadań parametry powinniśmy dostosować się do własnych potrzeb. Także kwestie ignorowania potencjalnych błędów w danym zadaniu muszą odzwierciedlać w pełni realizowane przez Ciebie zadanie. Pamiętaj, że prezentuję tutaj tylko przykłady, które są odpowiednie dla mnie. Każdy fragment kodu powinien być dostosowany do Twoich potrzeb.

Previous slide
Next slide

Wyłączenie serwera Cisco ISE

W następnym kroku przystępuję do zadania „Halt current ISE instance”, gdzie wydam komendę halt w celu zatrzymania działającej instancji ISE. Zrób nasz która potencjalnie pojawia się na tym etapie to konieczność odpowiedzenia na pytanie które będzie zadane na naszej konsoli . Na szczęście moduł ansible.netcommon.cli_command umożliwia interakcję na konsoli. Działa ona w ten sposób, że programujemy frazy, które będą wyszukiwane w wyświetlanym tekście i definiujemy dane, które mają wtedy zostać na konsoli wprowadzone. W odpowiedzi na monit, potwierdzę kontynuację zamknięcia wpisując „y”. Ponieważ ISE w wersji 3.2 może się nie zamknąć poprawnie, jeśli limit czasu wynosi mniej niż około 7 minut, ustawiam limit czasu na 600 sekund. Zmieniam w tym zadaniu lokalnie wartość timeout względem globalnego parametru ustawionego na początku playbooka. Rejestruję też wynik wykonania zadania by go potem wyświetlić w logach

    - name: Halt current ISE instance
      vars:
        #  ⚠SE 3.2: A command timeout of < ~7 minutes will cause a failure!
        ansible_command_timeout: 600
      ansible.netcommon.cli_command:
        command: halt
        check_all: yes # run all of the commands
        prompt:
          - Continue with shutdown
        answer:
          - "y"
      register: output
          - ansible.builtin.debug:
        msg: "{{ output }}"

Wyłączenie maszyny wirtualnej Cisco ISE nastąpi samoczynnie. Nie musimy dodatkowo wyłączać jej z poziomu hypervisora.

Kopia zapasowa na ESXi

Kolekcja community.vmware to zestaw modułów, wtyczek i ról utrzymywanych przez społeczność, które umożliwiają zarządzanie różnymi aspektami infrastruktury VMware. Dostępne są moduły do zarządzania maszynami wirtualnymi, sieciami, składami danych, folderami, zasadami tagowania i wieloma innymi elementami w środowisku VMware vSphere. Działają one zarówno z zaistalowanym vCenter jak i bezpośrednio na hypervisorach ESXi. Do korzystania z modułów z tej kolekcji wymagane jest posiadanie odpowiednich bibliotek Pythona, takich jak PyVmomi.

Mój playbook ma zdefiniowane trzy zadania. Rozpocznę od wykonania „Get current date”, gdzie uruchomię komendę date "+%Y%m%d" na lokalnym hoście (delegate_to: localhost). Komenda ta zwróci bieżącą datę w formacie YYYYMMDD, którą zarejestruję pod nazwą current_date. Umożliwi mi to wykorzystanie tej daty w nowej nazwie VM.

    - name: Get current date
      command: date "+%Y%m%d"
      delegate_to: localhost
      register: current_date

W następnym zadaniu wykorzystam moduł community.vmware.vmware_guest_info do zebrania informacji o maszynie wirtualnej. Podam szczegóły, takie jak nazwa hosta, nazwa użytkownika, hasło oraz lokalizację datacenter i folderu, w którym znajduje się VM. Informacje te pobiorę dla maszyny o nazwie określonej w zmiennej vm_name. Zawiera ona nazwę DNS mojej instancji ISE. Przekazuję ją jako parametr wywołania w Jenkins. Zebrane dane zapiszę w zmiennej vm_info i pozwolę na ignorowanie ewentualnych błędów w tym zadaniu. Zadanie to także zostanie wykonane na moim lokalnym hoście.

    - name: Gather VM info
      community.vmware.vmware_guest_info:
        hostname: '{{ inventory_hostname }}'
        username: '{{ esxi_username }}'
        password: '{{ esxi_password }}'
        validate_certs: no
        datacenter: ha-datacenter
        folder: "/vm"
        name: '{{ vm_name }}'
      register: vm_info
      ignore_errors: true
      delegate_to: localhost

W ostatnim kroku użyję modułu community.vmware.vmware_guest do zmiany nazwy maszyny wirtualnej. Nowa nazwa będzie zawierała prefiks “ise-lab-“, datę zwróconą przez wcześniejsze zadanie, oraz sufiks “-backup.virl.lan”. Operację tę wykonam tylko wtedy, gdy UUID instancji VM jest zdefiniowany (co jest sprawdzane warunkiem when: vm_info.instance.instance_uuid is defined). Podobnie jak wcześniej, wykonam to zadanie na moim lokalnym hoście.

    - name: Rename VM if it exists
      community.vmware.vmware_guest:
        hostname: '{{ inventory_hostname }}'
        username: '{{ esxi_username }}'
        password: '{{ esxi_password }}'
        validate_certs: no
        uuid: "{{ vm_info.instance.hw_product_uuid }}"
        name: "ise-lab-{{ current_date.stdout }}-backup.virl.lan"
      when: vm_info.instance.instance_uuid is defined
      delegate_to: localhost

Poprawne wykonanie tego playbooka spowouje zmianę nazwy obecnej maszyny wirtualnej.

Jenkins pipeline

Na koniec zostawiam fragment kodu Jenkinsfile służący do uruchomienia tych dwóch playbooków. Pamiętajmy że niepowodzenie wykonania któregokolwiek z nich zakończy błędem działanie całego potoku.

 stage('Halt current ISE server') {
	 environment {
		 ise_ssh_username = credentials('ise_ssh_username')
		 ise_ssh_password = credentials('ise_ssh_password')
	 }
	 steps {
		 ansiblePlaybook(
			 playbook: 'ise-shutdown.yaml',
			 inventory: 'inventory-ise',
			 extraVars: [
			  ansible_ssh_user: env.ise_ssh_username,
			  ansible_ssh_password: env.ise_ssh_password,
			 ]
		 )
	 }
 }
 stage('Rename current VM and save it as a backup') {
	 environment {
		 esxi_username = credentials('esxi_username')
		 esxi_password = credentials('esxi_password')
	 }
	 steps {
		 ansiblePlaybook(
			 playbook: 'ise-vm-rename.yaml',
			 inventory: 'inventory-esxi',
			 extraVars: [
			  esxi_username: env.esxi_username,
			  esxi_password: env.esxi_password,
			  vm_name: params.vm_name,
			 ]
		 )
	 }
}

E-BOOK

Zaczynasz swój pierwszy projekt związany z automatyzacją?

Ten e-book jest dla Ciebie! Zawiera sprawdzone podejście, które realizowałem w wielu projektach. Sprawdź co możesz zrobić, by odnieść sukces!


Subscribe
Powiadom o
guest

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

0 komentarzy
Inline Feedbacks
View all comments

ZdradziĆ Ci sekretY udanego projektu automatyzacji?

(link otwiera się w nowym oknie)