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

Gdy po reinstalacji za pomocą mechanizmy Zero Touch Provisioning maszyna wirtualna się uruchomi odtwarzamy z kopii zapasowej konfigurację Cisco ISE. Jest to o tyle proste, że w konfiguracji ZTP wskazaliśmy, że API Cisco ISE ma być domyślnie aktywne. Zapraszam na ostatnią część cyklu, w którym odtworzymy konfigurację Cisco ISE z kopii zapasowej.

Odtwarzamy konfigurację repozytorium

Abyśmy mogli odtworzyć konfigurację z kopii zapasowej Cisco ISE musimy najpierw skonfigurować informacje o repozytorium, na którym się kopia znajduje. W moim przypadku jest to serwer FTP. Co prawda możemy wskazać repozytorium bezpośrednio w pliku konfiguracyjnym mechanizmu Zero Touch Provisionig. Jest jednak jedno ograniczenie. Możemy w nim wskazać jedynie takie repozytorium, które nie wymaga uwierzytelnienia, na przykład dostępne po TFTP. Takie repozytorium nie nadaje się zbytnio do przechowywania plików z kopią zapasową. Na szczęście za pomocą ZTP zdefiniowaliśmy użytkownika, którego użyjemy do połączenia z API.

Playbook składa się z jednego zadania, w którym konfiguruję parametry repozytorium. Muszę wskazać protokół używany do komunikacji z repozytorium, nazwę repozytorium, informacje o loginie i haśle oraz ścieżce do katalogu repozytorium. 

---
- name: Configure repository restoring from backup
  hosts: all
  gather_facts: no

  tasks:
    - name: Create repository
      cisco.ise.repository:
        ise_hostname: "{{ vm_name }}"
        ise_username: "{{ ise_username_firstboot }}"
        ise_password: "{{ ise_password_firstboot }}"
        ise_verify: false
        state: present
        enablePki: false
        name: "NAS_FTP"
        password: "SuperTajneHaslo"
        path: "/home/ise-lab"
        protocol: "FTP"
        serverName: "192.168.1.250"
        userName: "userftp"

Odtwarzamy kopię zapasową

Do odtworzenia konfiguracji Cisco ISE z kopii zapasowej potrzebujemy dwóch elementów – skonfigurowanego repozytorium oraz nazwy pliku z kopią zapasową, którą chcemy odtworzyć. Repozytorium dodaliśmy w poprzednim kroku.

Nazwę pliku z najnowszą kopią zapasową wydobywamy podobnie jak w pierwszych krokach scenariusza datę ostatniej wykonanej kopii zapasowej. Playbook rozpoczyna od wylistowania plików na zdalnym serwerze, wykorzystując do tego polecenie curl przekazane przez moduł shell. Uwierzytelnianie do serwera FTP odbywa się przy użyciu nazwy użytkownika i hasła zmiennych. Wynik tego zadania jest rejestrowany w zmiennej output. Następnie playbook filtruje wynik wylistowanych plików, aby wyciągnąć te linie, które zaczynają się od “ise-lab-CFG10”. Wykorzystuje do tego mechanizm faktów Ansible (set_fact), przechowując wyniki w zmiennej file_lines. W kolejnym kroku playbook dokonuje ekstrakcji nazw plików wraz z datami z odfiltrowanych linii, stosując wyrażenie regularne. Zadanie to również korzysta z set_fact do zapisania wyników do zmiennej files_with_date. Playbook identyfikuje najnowszy plik z backupem poprzez wybranie ostatniego elementu listy files_with_date i zapisuje nazwę tego pliku do zmiennej most_recent_filename za pomocą kolejnego zadania set_fact.

Następnie następuje przywrócenie najnowszego backupu przy użyciu modułu cisco.ise.backup_restore. Dane do uwierzytelnienia i konieczne parametry, takie jak nazwa repozytorium czy plik do przywrócenia, są przekazywane modułowi. Wynik tego zadania jest ponownie rejestrowany, tym razem w zmiennej result. Playbook rejestruje takze identyfikator zadania przywracania z odpowiedzi Cisco ISE, a następnie w kolejnym kroku sprawdza status tego zadania przy użyciu modułu cisco.ise.tasks_info. W ten sposób sprawdzamy, czy proces odtwarzania się prawidłowo rozpoczął. Na zakończenie procesu odtworzenia czekamy 70 minut. Czas ten powinniśmy dostosować do prędkości serwera, na którym odtwarzamy Cisco ISE.

---
- name: Configure repository restoring from backup
  hosts: all
  connection: local
  gather_facts: no

  tasks:
    - name: List files on remote server
      shell:
        cmd: "curl --silent --user {{ ftp_username }}:{{ ftp_password }} {{ ftp_url }}"
      register: output

    - name: Extract lines starting with ise-lab-CFG10
      set_fact:
          file_lines: "{{ output.stdout.split('\n') | select('match', '^.* ise-lab-CFG10.*$') | list }}"

    - name: Extract filenames and dates
      set_fact:
        files_with_date: "{{ file_lines | map('regex_replace', '.* ([A-Za-z]{3} +\\d+ \\d+:\\d+) (ise-lab-CFG10-.*)', '\\1 \\2') | list }}"

    - name: Get the most recent file
      set_fact:
        most_recent_file_orig: "{{ files_with_date | last }}"

    - name: Extract filename
      set_fact:
        most_recent_filename: "{{ most_recent_file_orig.split()[-1] }}"

    - name: Restore latest backup
      cisco.ise.backup_restore:
        ise_hostname: "{{ vm_name }}"
        ise_username: "{{ ise_username_firstboot }}"
        ise_password: "{{ ise_password_firstboot }}"
        ise_verify: false
        backupEncryptionKey: "{{ ise_backup_password }}"
        repositoryName: "NAS_FTP"
        restoreFile: "{{ most_recent_filename }}"
        restoreIncludeAdeos: true
      register: result

    - name: Record TaskID for restore task
      set_fact:
        restore_task_id: "{{ result.ise_response.response.id }}"

    - name: Get Tasks status
      cisco.ise.tasks_info:
        ise_hostname: "{{ vm_name }}"
        ise_username: "{{ ise_username_firstboot }}"
        ise_password: "{{ ise_password_firstboot }}"
        ise_verify: false
        taskId: "{{ restore_task_id }}"
      register: result
      ignore_errors: true

    - name: Sleeping for 70 minutes
      pause:
        minutes: 70

Previous slide
Next slide

Pipeline Jenkins

Jeżeli zadania z powyższych kroków zakończyły się poprawnie otrzymujemy działającą instalację Cisco ISE. Odtworzyliśmy konfigurację z kopii zapasowej w sposób zautomatyzowany. Musimy wtedy wykonać tylko jedną subtelną operację. Z kopii zapasowej odtworzyliśmy w konfiguracji informację o repozytorium, na które wykonywany jest cyklicznie backup. Musimy jednak na nowo wprowadzić hasło, w przeciwnym razie zadania cykliczne skończą się niepowodzeniem. W tym celu uruchamiamy jeszcze raz ten sam playbook, który wcześniej wykorzystaliśmy do utworzenia repozytorium.

W pipeline Jenkinsfile w moim przypadku operują innymi parametrami logowania zapisanymi w konfiguracji ZTP, i innymi w konfiguracji produkcyjnej. Dlatego muszę pilnować jakie wartości przekazuję do playbooków w każdym z kroków.

stage('Restore FTP repository definition') {
            environment {
                ise_username_firstboot = credentials('ise_username_firstboot')
                ise_password_firstboot = credentials('ise_password_firstboot')
            }
            steps {
                ansiblePlaybook(
                    playbook: 'ise-create-repository.yaml',
                    inventory: 'inventory-localhost',
                    extraVars: [
                     vm_name: params.vm_name,
                     ise_username_firstboot: env.ise_username_firstboot,
                     ise_password_firstboot: env.ise_password_firstboot
                    ]
                )
            }
        }
        stage('Restore latest backup') {
            environment {
                ise_username_firstboot = credentials('ise_username_firstboot')
                ise_password_firstboot = credentials('ise_password_firstboot')
                ise_username = credentials('ise_username')
                ise_password = credentials('ise_password')
                ftp_username = credentials('ftp_username')
                ftp_password = credentials('ftp_password')
                ise_backup_password = credentials('ise_backup_password')
            }
            steps {
                ansiblePlaybook(
                    playbook: 'ise-restore-latest-backup.yaml',
                    inventory: 'inventory-localhost',
                    extraVars: [
                     vm_name: params.vm_name,
                     ise_username_firstboot: env.ise_username_firstboot,
                     ise_password_firstboot: env.ise_password_firstboot,
                     ise_username: env.ise_username,
                     ise_password: env.ise_password,
                     ftp_url: params.ftp_url,
                     ftp_username: env.ftp_username,
                     ftp_password: env.ftp_password,
                     ise_backup_password: env.ise_backup_password,
                    ]
                )
            }
        }
        stage('Update password in FTP repository definition') {
            environment {
                ise_username_firstboot = credentials('ise_username')
                ise_password_firstboot = credentials('ise_password')
            }
            steps {
                ansiblePlaybook(
                    playbook: 'ise-create-repository.yaml',
                    inventory: 'inventory-localhost',
                    extras: '-vvvv',
                    extraVars: [
                     vm_name: params.vm_name,
                     ise_username_firstboot: env.ise_username_firstboot,
                     ise_password_firstboot: env.ise_password_firstboot
                    ]
                )
            }
        }


Pamiętajmy, aby po świeżej instalacji Cisco ISE nie logować się do panelu GUI. ISE wymusza przy pierwszym logowaniu zmianę hasła, my zaś chcemy użyć zdefiniowanego przez w ZTP konta, które w późniejszym etapie zmienimy na konto zapisane w kopii zapasowej.

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)