Benutzer-Werkzeuge

Webseiten-Werkzeuge


linux:oracle_linux_8_ansible

Ein Oracle Linux 8 Basis System für Ansible verwenden - eine Oracle Umgebung mit Ansible warten

Aufgabe:

Das Verteilen von Oracle Patchen soll über Ansible automatisiert werden, dazu ist es aber im ersten Schritt notwendig sich mit Anible vertraut zu machen.

Ansible (https://www.ansible.com/) ist ein Open-Source Werkzeug zur Konfiguration und Administration, insbesondere im Umfeld von RedHat basierenden Server Systemen.

Für die Verwaltung von Ansible steht als OpenSource Projekt Ansible AWX ( https://github.com/ansible/awx ) zur Verfügung , die gleiche Applikation mit Support von Red Hat als Ansible Tower (https://www.ansible.com/).


Setup der Entwicklungs-Umgebung

In der produktiven Umgebung wird Ansible mit Ansible Tower als lizensierte Umgebung auf RedHat eingesetzt.

Aber um die Oracle Skripte im Vorfeld zu entwickeln und sich in die Materie einzuarbeiten, wird eine reine Ansible Open Source Umgebung unter Oracle Linux 8 aufgesetzt.

Im ersten Schritt wird ein Oracle Linux 8 als Standardsystem wie für eine DB Umgebung aufgesetzt ⇒ siehe dazu Ein Oracle Linux 8 Basis System .


Ansible über EPL unter Oracle Linux 8 installieren

EPL Repositorie einrichten

Wir benötigen noch das Oracle EPL Repostiory:

#Was ist bereits aktiviert?
dnf repolist
 
 
# EPL nachinstallieren
dnf info oracle-epel-release-el8.x86_64
dnf install oracle-epel-release-el8.x86_64
 
 
# oder falls nur dekativiert
# yum-config-manager --enable ol8_developer_EPEL
 
dnf repolist
 
repo id               repo name
ol8_UEKR6             Latest Unbreakable Enterprise Kernel Release 6 for Oracle Linux 8 (x86_64)
ol8_appstream         Oracle Linux 8 Application Stream (x86_64)
ol8_baseos_latest     Oracle Linux 8 BaseOS Latest (x86_64)
ol8_developer_EPEL    Oracle Linux 8 EPEL Packages for Development (x86_64)

Ansible installieren

dnf search ansible
 
dnf install ansible ansible-doc vim-ansible

Version und Pfade prüfen:

ansible --version
ansible 2.9.21
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, May 19 2021, 10:00:09) [GCC 8.4.1 20200928 (Red Hat 8.4.1-1.0.1)]

Master User anlegen

Gruppen und User anlegen:

useradd  ansible
passwd ansible
 
su - ansible
 
 
#generate ssh key
ssh-keygen -t rsa
 
 
# Zugriff auf sich selbst konfigurieren!
 
ssh  ansible01.pipperr.local  cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
 
#Auf die richtigen Rechte achten!
chmod 600 ~/.ssh/authorized_keys

Den Ansible User in der Umgebung anlegen und die Schlüssel in der Umgebung verteilen

Ansible arbeitet per SSH Key, d.h. auf den jeweiligen Maschinen muss zuvor der SSH Key verteilt und ein User wie „ansible“ sollte auf den Maschinen existieren, das Arbeiten nur mit „root“ ist nicht zu empfehlen.

Der User Ansible muss auf der Maschine ohne Password sudo ausführen können, d.h. er muss in der Sudo Liste stehen!

Manuell anlegen

User manuell anlegen, diese Schritte wohlen wir aber im Anschluss automatisieren.

Auf dem ersten Zielsystem:

useradd  ansible
passwd ansible
 
usermod -G wheel ansible
 
visudo
 
%wheel  ALL=(ALL)       NOPASSWD: ALL
 
su - ansible
 
ssh-keygen -t rsa

Key Austausch mit den Key vom Ansible Server:

# Vom Ansible Server aus!
# Auf jedem Ziel System anmelden: 
 
ssh apex01.pipperr.local 
   ssh ansible01.pipperr.local cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
   chmod 600 ~/.ssh/authorized_keys
   exit

Ansible Grundlagen und die ersten Playbooks erstellen

Begrifflichkeiten:

  • Playbook Kompletter Ablauf - enthält die Plays
  • Plays last die eigentlichen Tasks zusammen und verbindet diese mit einer Gruppe von Hosts
  • Tasks die eigentlichen konkreten Aufgaben die auf einem Host durchgeführt werden sollen

Die eigentlichen Play Books werden unter dem User „ansible“ erstellt.

Um ein zentrale Stelle für die Entwicklung der Playbooks zu verwenden, folgende Struktur unter /srv/ansible angelegt:

  • /srv/ansible für alle ansible relevanten Daten
  • /srv/ansible/inventory - Die Server Liste
  • /srv/ansible/«PLAY_BOOK» - Projektverzeichnis für das Playbook
  • Link /srv/ansible/«PLAY_BOOK»/inventory auf /srv/ansible/inventory um in allen Playbooks die gesamte Serverliste zu verwenden
#root
mkdir /srv/ansible
 
chown -R ansible:ansible /srv/ansible

Im Playbook empfiehlt die Dokumentation von Ansible hier die folgende Struktur ⇒ https://docs.ansible.com/ansible/latest/user_guide/sample_setup.html .

  • README.md - Doku
  • groups_vars - Gruppen Definitionen
  • hosts_vars - Hosts Definitionen
  • inventory - Inventar Listen
  • side.yml - was wollen wir tun
  • templates - Templates auf die in den Tasks zugegriffen wird

Aufbau einer Beispiel Umgebung, im ersten Schritt eine Template Struktur anlegen um diese immer wieder zu verwenden:

su - ansible
 
touch /srv/ansible/inventory
 
mkdir /srv/ansible/play_book_template
 
cd /srv/ansible/play_book_template
 
# Grund Struktur anlegen
 
touch README.md
mkdir group_vars
mkdir hosts_vars
ln -s /srv/ansible/inventory  inventory
touch site.yml
mkdir templates

Zentrales Inventory hinterlegen

Um nicht in jedem Playbook alle Ziel pflegen zu müssen, wird diese Datei zentral angelegt und verlinkt:

Datei /srv/ansible/inventory

vi /srv/ansible/inventory
 
[ORA_SERVER]
apex01.pipperr.local
 
 
[MANAGMENT]
ansible01.pipperr.local

Inventory aus KeePass erzeugen

Mit Hilfe des Pyhton Moduls PyKeePass https://pypi.org/project/pykeepass/https://github.com/libkeepass/pykeepass“ lässt sich aus einer vorhanden Key Passdatei ein Inventroy erzeugen.

Siehe dazu ⇒ Keepass Datei mit Python auslesen um Ansible Konfiguration zu erzeugen


Ohne Playbook arbeiten - auf allen Server ein Kommando ausführen

Liegt ein Inventory vor und ist der Zugriff konfiguriert kann ein Befehl auch auf allen Knoten mit der „-a“ Option ausgeführt werden.

#Hier noch mit Passwort:
 
ansible ORA_SERVER -a "/bin/uname -a" -k
 
SSH password:
 
apex01.pipperr.local | CHANGED | rc=0 >>
Linux apex01.pipperr.local 5.4.17-2036.103.3.1.el8uek.x86_64 #2 SMP Sun Feb 14 12:54:18 PST 2021 x86_64 x86_64 x86_64 GNU/Linux

Oder ein einfaches PlayBook erstellen, und den Output ausgeben und in eine Datei schreiben lassen.

---
- name: Execute Command
  hosts: all
  tasks:
     - name: Execute Command
       command: "/bin/uname -a"
       register: serverInfo

     - debug: var=serverInfo.stdout_lines
     
     - name: Write variable to file
       local_action: copy content="{{serverInfo}}" dest=./server_info
[ansible@ansible01 deploy_ansible_user]$ ansible-playbook execute.yml  -k --verbose
Using /srv/ansible/deploy_ansible_user/ansible.cfg as config file
SSH password:
 
PLAY [Execute Command] *********************************************************************************************************************
 
TASK [Gathering Facts] *********************************************************************************************************************
ok: [apex01.pipperr.local]
ok: [ansible01.pipperr.local]
 
TASK [Execute Command] *********************************************************************************************************************
changed: [ansible01.pipperr.local] => {"changed": true, "cmd": ["/bin/uname", "-a"], "delta": "0:00:00.003301", "end": "2021-06-12 17:47:09.810925", "rc": 0, "start": "2021-06-12 17:47:09.807624", "stderr": "", "stderr_lines": [], "stdout": "Linux ansible01.pipperr.local 5.4.17-2102.201.3.el8uek.x86_64 #2 SMP Fri Apr 23 09:05:57 PDT 2021 x86_64 x86_64 x86_64 GNU/Linux", "stdout_lines": ["Linux ansible01.pipperr.local 5.4.17-2102.201.3.el8uek.x86_64 #2 SMP Fri Apr 23 09:05:57 PDT 2021 x86_64 x86_64 x86_64 GNU/Linux"]}
changed: [apex01.pipperr.local] => {"changed": true, "cmd": ["/bin/uname", "-a"], "delta": "0:00:00.004017", "end": "2021-06-12 17:47:09.864344", "rc": 0, "start": "2021-06-12 17:47:09.860327", "stderr": "", "stderr_lines": [], "stdout": "Linux apex01.pipperr.local 5.4.17-2036.103.3.1.el8uek.x86_64 #2 SMP Sun Feb 14 12:54:18 PST 2021 x86_64 x86_64 x86_64 GNU/Linux", "stdout_lines": ["Linux apex01.pipperr.local 5.4.17-2036.103.3.1.el8uek.x86_64 #2 SMP Sun Feb 14 12:54:18 PST 2021 x86_64 x86_64 x86_64 GNU/Linux"]}
 
TASK [debug] *******************************************************************************************************************************
ok: [apex01.pipperr.local] => {
    "serverInfo.stdout_lines": [
        "Linux apex01.pipperr.local 5.4.17-2036.103.3.1.el8uek.x86_64 #2 SMP Sun Feb 14 12:54:18 PST 2021 x86_64 x86_64 x86_64 GNU/Linux"
    ]
}
ok: [ansible01.pipperr.local] => {
    "serverInfo.stdout_lines": [
        "Linux ansible01.pipperr.local 5.4.17-2102.201.3.el8uek.x86_64 #2 SMP Fri Apr 23 09:05:57 PDT 2021 x86_64 x86_64 x86_64 GNU/Linux"
    ]
}
 
 
PLAY RECAP *********************************************************************************************************************************
ansible01.pipperr.local    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
apex01.pipperr.local       : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Playbook Beispiel - Ansible User auf den zu überwachenden Knoten über Root anlegen

Über den User Root soll im ersten Schritt der Ansible User mit dem jeweiligen Root Passwort angelegt werden.

Wenn das Root Passwort aber nicht überall gleich ist muss das Password auf Host Ebene hinterlegt werden, falls gleich kann das auf der „all“ Ebene erfolgen.

Da das natürlich sehr unsicher ist, muss dann verschlüsselt abgelegt werden! Bzw. besser in diesem Schritt gar nicht hinterlegen und mit der Option -k interaktiv angeben (all wenigstens in einer Gruppe gleich!)!

Unser Template kopieren:

cp -r /srv/ansible/play_book_template /srv/ansible/deploy_ansible_user
Ansible konfigurieren

Um die -i Option zu sparen eine ansible.cfg anlegen

vi ansible.cfg
 
[defaults]
inventory = ./inventory
remote_user = root
 
#Vault Password 
vault_password_file = ./vault-pass.txt
 
# avoid warning message python path
interpreter_python = auto_silent
 
#noch check host keys to avoid errors
host_key_checking = false
 
[privilege_escalation]
become = false
Parameter für die Ziel Gruppe hinterlegen

Datei group_vars/«GROUP_NAME»

vi group_vars/ORACLE_SERVER

---
admin_group: wheel
Parameter für alle Gruppen hinterlegen

Datei group_vars/all

vi group_vars/all

---
#Access to all servers default
ansible_connection: ssh
ansible_ssh_user: root
ansible_ssh_pass: <<my_mostly_used_root_pwd>>

# 
management_user_pwd: Secret1!

Im nächsten Schritt wird das verschlüsselt dazu kann iAnsible Vault verwendet werden.

Vrschlüsseln mit:

ansible-vault encrypt ./group_vars/all
 
New Vault password:
Confirm New Vault password:
Encryption successful
 
#Bei Bedarf anpassen
ansible-vault edit ./group_vars/all

Möglichkeiten nun das Vault Passwort beim Aufruf eines Playbooks zu hinterlegen:

  • Interaktiv das Passwort eingeben werden, Option „–ask-vault-pass“
  • Passwort in einer Datei wie vault-pass.txt hinterlegen, diese vor GIT und dem Zugriff schützen, beim Aufruf des Playbooks mit angeben - Option „– vault-password-file vault-pass.txt“
  • Die Datei mit dem Passwort in der ansible.cfg hinterlege mit „vault_password_file = ./vault-pass.txt“
Zugriff testen

Test des Zugriffes über:

ansible all --list-hosts
 
# mit der K Option für die Password Übergabe
ansible all -m setup -u root -k
 
#nur eine Gruppe aufrufen
ansible ORA_SERVER -m ping -k
Die notwendigenTasks anlegen
  1. Erzeugeden Ansible User
  2. Sudo Konfiguration ausrollen
  3. SSH Public Key der Management Umgebung verteilen

Erzeugeden Ansible User vi create_user.yml:

create_user.yml
---
- name: Create Ansible User
  hosts: ORA_SERVER
  tasks:
  - name: Create Ansible User
    ansible.builtin.user:
     name: ansible
     groups: "{{ admin_group }}"
     append: true
     create_home: true
     comment: "Ansible Management Account"
     expires: -1
     password: "{{  management_user_pwd | password_hash('sha512','A512') }}"
  - name: Deploy Local User SSH Key
    authorized_key:
     user: ansible
     state: present
     manage_dir: true
     key: "{{ lookup('file', '/home/ansible/.ssh/id_rsa.pub') }}"
  - name: Setup Sudo Access for Devops User
    ansible.builtin.copy:
     dest: /etc/sudoers.d/ansible
     content: 'devops ALL=(ALL) NOPASSWD: ALL'
     validate: /usr/sbin/visudo -cf %s

Check:

ansible-playbook create_user.yml --syntax-check

Starten:

ansible-playbook create_user.yml -k
 
 
SSH password:
 
PLAY [Create Ansible User] *************************************************************************************************************
 
TASK [Gathering Facts] *****************************************************************************************************************
ok: [apex01.pipperr.local]
 
TASK [Create Ansible User] *************************************************************************************************************
ok: [apex01.pipperr.local]
 
TASK [Deploy Local User SSH Key] *******************************************************************************************************
ok: [apex01.pipperr.local]
 
TASK [Setup Sudo Access for Devops User] ***********************************************************************************************
changed: [apex01.pipperr.local]
 
PLAY RECAP *****************************************************************************************************************************
apex01.pipperr.local       : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Löschen des Ansible User

vi remove_user.yml

remove_user.yml
---
- name:  drop Ansible User
  hosts: ORA_SERVER
  tasks:
  - name: drop Ansible User
    user:
     name: ansible
     state: absent
     remove: true
 

Check:

ansible-playbook remove_user.yml --syntax-check

Ausführen:

ansible-playbook remove_user.yml -k
 
SSH password:
 
PLAY [drop Ansible User] ***************************************************************************************************************
 
TASK [Gathering Facts] *****************************************************************************************************************
ok: [apex01.pipperr.local]
 
TASK [drop Ansible User] ***************************************************************************************************************
changed: [apex01.pipperr.local]
 
TASK [Remove Sudo Entry] ***************************************************************************************************************
changed: [apex01.pipperr.local]
 
PLAY RECAP *****************************************************************************************************************************
apex01.pipperr.local       : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


Playbook Beispiel - SQL*Plus aufrufen und Script ausführen

Unser Template kopieren:

cp -r /srv/ansible/play_book_template /srv/ansible/oracle_maintenance
Ansible konfigurieren

Ansible CFG auf das Projekt anpassen

vi ansible.cfg
 
[defaults]
inventory = ./inventory
remote_user = ansible
 
# avoid warning message python path
interpreter_python = auto_silent
Parameter für die Ziel Hosts hinterlegen

Datei host_vars/«host_name»

vi host_vars/apex01.pipperr.local

---
hostname: apex01.pipperr.local
IP: 10.10.10.90
roles:
  - common
  - dbserver

virtual: true

oracle_envs:
 - oracle_home: /opt/oracle/product/19c/dbhome_1
   oracle_sid:
    - GPIDB1
    - PRDDB
 - oracle_home: /opt/oracle/product/18c/dbhome_1
   oracle_sid:
    - GPIDB

Pro Server so eine Datei anlegen, die Oracle Umgebungen werden als Listen angelegt da ja meherer Oracle Homes und Oracle Datenbaken auf dem Server liegen können.

Im Ansible Script wird dann mit „with_items“ bzw. „with_subelements“ über diese Liste itteriert.

Parameter für alle Gruppen hinterlegen

Datei group_vars/all

vi group_vars/all

---
#empty in this case
Zugriff testen

Test des Zugriffes über:

ansible all --list-hosts
 
# mit der K Option für die Password Übergabe
ansible all -m setup -u root -k
 
#nur eine Gruppe aufrufen
ansible ORA_SERVER -m ping -k
Die notwendigenTasks anlegen
  1. Verzeichnis für die Skripte anlegen
  2. Script auf dem Server kopieren
  3. Script in SQL*Plus ausführen

vi execute_set_pack_access.yml:

execute_set_pack_access.yml
---
- name: Call SQL*Plus Script to disable all mangement packs
  hosts: ORA_SERVER
  tasks:
  - name: Create the Script Directory
    become: yes
    become_user: oracle
    ansible.builtin.file:
      owner: oracle
      group: oinstall
      path: "/home/oracle/ansible_scripts/"
      state: directory
  - name: Copy the sql*plus script
    become: yes
    become_user: oracle
    ansible.builtin.copy:
      src: ./scripts/set_pack_access.sql
      dest: /home/oracle/ansible_scripts
  - name: Call the script as oracle user
    become: yes
    become_user: oracle
    command: "$ORACLE_HOME/bin/sqlplus -s / as sysdba @/home/oracle/ansible_scripts/set_pack_access.sql"
    environment:
      ORACLE_HOME: "{{ item.0.oracle_home }}"
      ORACLE_SID:  "{{ item.1 }}"
    with_subelements:
     - "{{ oracle_envs }}"
     - oracle_sid

Check:

ansible-playbook execute_set_pack_access.yml --syntax-check
SQL*Plus Script anlegen

vi ./scripts/set_pack_access.sql

SELECT USER FROM dual;
exit

Starten:

ansible-playbook execute_set_pack_access.yml --verbose
 
 
Using /srv/ansible/oracle_maintenance/ansible.cfg as config file
 
PLAY [Call SQL*Plus Script to disable all mangement packs] *********************************************************************************
 
TASK [Gathering Facts] *********************************************************************************************************************
ok: [apex01.pipperr.local]
 
TASK [Create the Script Directory] *********************************************************************************************************
ok: [apex01.pipperr.local] => {"changed": false, "gid": 54321, "group": "oinstall", "mode": "0755", "owner": "oracle", "path": "/home/oracle/ansible_scripts/", "size": 33, "state": "directory", "uid": 54321}
 
TASK [Copy the sql*plus script] ************************************************************************************************************
ok: [apex01.pipperr.local] => {"changed": false, "checksum": "8353662eb6e8d7ee1b6979d949ba695779046674", "dest": "/home/oracle/ansible_scripts/set_pack_access.sql", "gid": 54321, "group": "oinstall", "mode": "0644", "owner": "oracle", "path": "/home/oracle/ansible_scripts/set_pack_access.sql", "size": 29, "state": "file", "uid": 54321}
 
TASK [Call the script as oracle user] ******************************************************************************************************
changed: [apex01.pipperr.local] => {"changed": true, "cmd": ["$ORACLE_HOME/bin/sqlplus", "-s", "/", "as", "sysdba", "@/home/oracle/ansible_scripts/set_pack_access.sql"], "delta": "0:00:00.051674", "end": "2021-06-13 00:45:36.059234", "rc": 0, "start": "2021-06-13 00:45:36.007560", "stderr": "", "stderr_lines": [], "stdout": "\nUSER\n--------------------------------------------------------------------------------\nSYS", "stdout_lines": ["", "USER", "--------------------------------------------------------------------------------", "SYS"]}
 
PLAY RECAP *********************************************************************************************************************************
apex01.pipperr.local       : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Mit diesem ersten Elemente lassen sich nun einfach Scripte auf den Datenbank Server verteilen und ausführen.



Quellen

Cookies helfen bei der Bereitstellung von Inhalten. Diese Website verwendet Cookies. Mit der Nutzung der Website erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Computer gespeichert werden. Außerdem bestätigen Sie, dass Sie unsere Datenschutzerklärung gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website. Weitere Information
"Autor: Gunther Pipperr"
linux/oracle_linux_8_ansible.txt · Zuletzt geändert: 2021/06/14 22:00 von gpipperr