In this session we can see below topics and demo is done on oracle 18C version. Testing is on going with multiple oracle versions and will push all the codes w.r.t versions along with screenshots .
1.Introduction
2.Patching automation with Ansible
3.Demo
4.Conclusion
1.Introduction
Oracle Database patching
Oracle Critical Patch Update progra
- Collection of security fixes for Oracle products
- Released every quarter around 17th: January, April, July, October
Database patching is evolving
CPU/SPU or PSU in Oracle Database 11g
PSU / Proactive Bundle Patch for Oracle Database 12c R1
RU / RUR starting in Oracle Database 12c R2
Patching automation with Ansible
Introduction to Ansible
Ansible language
Ansible tasks, playbook and roles
Patching automation with Ansible
Introduction to Ansible
Ansible is a simple automation language
Open source automation tool
Designed for multi-tier deployment
Agentless – Ansible relies on SSH and Python
Push based
Tasks oriented – easy to read
The module supports 11g, 12c ,18c and 19c database versions. It should work properly on 10g as well, but I haven’t tested it. Expected actions performed by the module:
- The module will identify which database instances, listeners and ASM instances are running.
- The module will shut down all listeners and database instances only if the home from which services are running is being patched.
- The module will start up all previously stopped services after it completes with patching*
- The module will skip databases which are not in READ WRITE state**
- The module will identify if a given database is in STANDBY or PRIMARY role***
- The module always patches GI homes with opatchauto
- The module always patches DB homes with opatch
- The module will make multiple restarts of the databases and listeners during the process
How to run
There are 3 steps you need to do prior to run the playbook
- Define patch binaries location. The patch binaries location is defined with “swlib_path” variable in “vars/global.yml”
- Define patch metadata. You need to define each patch metadata in “vars/patch_dictionary/patch_dict.yml”. The format is as follows:
--
25XXXX: -> patch_id (it's in the name of the file you download from Oracle)
patch_proactive_bp_id -> patch proactive bundle patch id (if it's bundle patch)
patch_gi_id: -> GI patch ID. If it's GI only, the "patch_gi_id" has the same value as "patch_id"
patch_db_id -> DB patch ID
patch_ocw_id -> OCW patch ID (applicable if the patch is COMBO patch)
patch_ojvm_id -> OJVM patch ID
patch_acfs_id: -> ACFS patch ID
patch_dbwlm_id: -> DBWLM path ID
patch_dir: -> patch directory (directory where patch file is extracted)
file: -> patch file name (not used currently)
only_oh: -> whether the patch is for OH binaries only
desc: -> patch description (usually should contain the patch name)
--
3.Define Oracle homes and databases to be patched in vars/main.yml file. For example
--
#
# List of oracle homes and databases to patch.
#
ora_home_list:
- oracle_owner: -> OS owner of the oracle binaries
oracle_home_path: -> OH OS path
oratab_file: -> Absolute path for oratab file. This can be ignored if the global value is set.
run_only_checks: -> Indicator whether to run onl prereq checks against OH
patch_id: -> Patch ID of the patch which is to be applied. This module needs to find a match in "vars/patch_dictionary/patch_dict.yml"
patch_only_oh: -> Indicator whether to patch only OH without the databases (True/False)
patch_ojvm: -> Indicator whether to apply OJVM patch (applicable if the patch is COMBO) (True/False)
patch_db_all: -> Indicator whether to apply the patch on all databases after patching the OH ("patch_only_oh" has precedence over "patch_db_all") (True/False)
patch_db_list: "" -> Comma separated list (in quotes!) of specific databases to patch ("patch_db_all" has precedence over "patch_db_list")
host: -> It allows the user to specify a mapping to specific host for which this list entry is valid. It's applicable only if the playbook is executed against group of hosts
backup_oh: -> Indicator whether to backup oracle home binaries (True/False)
skip: -> Main indicator whether to skip this item list or not
debug: -> Enables debug mode (True/False)
--
Once you have defined the necessary variables, you start the playbook with:
ansible-playbook path_to_playbook -k
The -k option is not mandatory if you use SSH keys for authentication.
Required packages
For this module to work “pexpect” package needs to be installed on the target machine. This is required because in some (most) cases OPatch will (prompt) ask questions. The module uses “pexpect” to populate OPatch answers.
If required package is missing the module will fail with a message: module fail: Required “pexpect” (RPM) library not found.
Example run
As final note, here is an example where I have patched 18c binaries with patch: 28822489 – Database Release Update 18.5.0.
patch_dict.yml (patch metadata definition)
28822489:
patch_proactive_bp_id:
patch_gi_id:
patch_db_id: 28822489
patch_ocw_id:
patch_ojvm_id:
patch_acfs_id:
patch_dbwlm_id:
patch_dir: 28822489
file: p28822489_180000_Linux-x86-64.zip
only_oh: False
desc: "Database Release Update 18.5.0"
ora_home_list variable definition in main.yml
ora_home_list:
- oracle_owner: oracle
oracle_home_path: /u01/app/oracle/18.3.0.0/db1-base
oratab_file:
run_only_checks:
debug: False
patch_id: 28822489
patch_only_oh: False
patch_ojvm: True
patch_db_all: True
patch_db_list: "" # Comma separated list of db_unique_names
host:
backup_oh: False # Indicator whether to backup oracle home
skip: False
Playbook run:
[ansible@ansible-control ansible-orapatch]$ ansible-playbook orapatch.yml -k
SSH password:
-->[Applicable if you patch Grid Infrastructure]<--
Enter root password (press enter to skip):
Enter root password again (press enter to skip):
PLAY [Patch oracle software] **********************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ****************************************************************************************************************************************************************************************************************
ok: [ora18c]
TASK [assert] *************************************************************************************************************************************************************************************************************************
ok: [ora18c] => {
"changed": false,
"msg": "All assertions passed"
}
TASK [orapatch : [SYSTEM] Include vars] ***********************************************************************************************************************************************************************************************
ok: [ora18c]
TASK [orapatch : [SYSTEM] Push sql scripts] *******************************************************************************************************************************************************************************************
ok: [ora18c]
TASK [orapatch : [SYSTEM] Ensure 'orapatch' log file exists] **************************************************************************************************************************************************************************
ok: [ora18c]
TASK [orapatch : [SYSTEM] Start logger session] ***************************************************************************************************************************************************************************************
ok: [ora18c]
TASK [orapatch : Backup oracle home] **************************************************************************************************************************************************************************************************
skipping: [ora18c] => (item=[0, {u'patch_db_list': u'', u'skip': False, u'run_only_checks': None, u'patch_id': 28822489, u'oracle_home_path': u'/u01/app/oracle/18.3.0.0/db1-base', u'patch_db_all': True, u'debug': False, u'oracle_owner': u'oracle', u'patch_ojvm': True, u'patch_only_oh': False, u'host': None, u'oratab_file': None, u'backup_oh': False}])
TASK [orapatch : Check OPatch minimum version] ****************************************************************************************************************************************************************************************
ok: [ora18c] => (item={u'patch_db_list': u'', u'skip': False, u'run_only_checks': None, u'patch_id': 28822489, u'oracle_home_path': u'/u01/app/oracle/18.3.0.0/db1-base', u'patch_db_all': True, u'debug': False, u'oracle_owner': u'oracle', u'patch_ojvm': True, u'patch_only_oh': False, u'host': None, u'oratab_file': None, u'backup_oh': False})
[WARNING]: Module did not set no_log for root_password
TASK [orapatch : Check conflicts against OH] ******************************************************************************************************************************************************************************************
ok: [ora18c] => (item={u'patch_db_list': u'', u'skip': False, u'run_only_checks': None, u'patch_id': 28822489, u'oracle_home_path': u'/u01/app/oracle/18.3.0.0/db1-base', u'patch_db_all': True, u'debug': False, u'oracle_owner': u'oracle', u'patch_ojvm': True, u'patch_only_oh': False, u'host': None, u'oratab_file': None, u'backup_oh': False})
TASK [orapatch : Patch OH] ************************************************************************************************************************************************************************************************************
ok: [ora18c] => (item={u'patch_db_list': u'', u'skip': False, u'run_only_checks': None, u'patch_id': 28822489, u'oracle_home_path': u'/u01/app/oracle/18.3.0.0/db1-base', u'patch_db_all': True, u'debug': False, u'oracle_owner': u'oracle', u'patch_ojvm': True, u'patch_only_oh': False, u'host': None, u'oratab_file': None, u'backup_oh': False})
TASK [orapatch : Patch DB] ************************************************************************************************************************************************************************************************************
ok: [ora18c] => (item={u'patch_db_list': u'', u'skip': False, u'run_only_checks': None, u'patch_id': 28822489, u'oracle_home_path': u'/u01/app/oracle/18.3.0.0/db1-base', u'patch_db_all': True, u'debug': False, u'oracle_owner': u'oracle', u'patch_ojvm': True, u'patch_only_oh': False, u'host': None, u'oratab_file': None, u'backup_oh': False})
TASK [orapatch : Patch OH OJVM] *******************************************************************************************************************************************************************************************************
ok: [ora18c] => (item={u'patch_db_list': u'', u'skip': False, u'run_only_checks': None, u'patch_id': 28822489, u'oracle_home_path': u'/u01/app/oracle/18.3.0.0/db1-base', u'patch_db_all': True, u'debug': False, u'oracle_owner': u'oracle', u'patch_ojvm': True, u'patch_only_oh': False, u'host': None, u'oratab_file': None, u'backup_oh': False})
TASK [orapatch : Patch DB OJVM] *******************************************************************************************************************************************************************************************************
ok: [ora18c] => (item={u'patch_db_list': u'', u'skip': False, u'run_only_checks': None, u'patch_id': 28822489, u'oracle_home_path': u'/u01/app/oracle/18.3.0.0/db1-base', u'patch_db_all': True, u'debug': False, u'oracle_owner': u'oracle', u'patch_ojvm': True, u'patch_only_oh': False, u'host': None, u'oratab_file': None, u'backup_oh': False})
TASK [orapatch : [SYSTEM] End logger session] *****************************************************************************************************************************************************************************************
ok: [ora18c]
TASK [orapatch : [SYSTEM] Fetch orapatch logfile] *************************************************************************************************************************************************************************************
changed: [ora18c]
PLAY RECAP ****************************************************************************************************************************************************************************************************************************
ora18c : ok=14 changed=1 unreachable=0 failed=0