--- # Playbook: ora_stand_datapatch.yml # Usage example: # ansible-playbook playbooks/ora_stand_datapatch.yml \ # -e server=togoria \ # -e oracle_sid=NABOOPRD - name: Gather facts for a specific inventory host hosts: "{{ server }}" gather_facts: yes become: true become_user: oracle become_method: su pre_tasks: - name: Ensure 'server' variable is provided assert: that: server is defined fail_msg: "Please provide the server via -e 'server='" - name: Ensure 'oracle_sid' variable is provided assert: that: oracle_sid is defined fail_msg: "Please provide the oracle_sid via -e 'oracle_sid='" tasks: - name: Show selected system facts debug: msg: hostname: "{{ (ansible_facts.nodename | default(ansible_facts.hostname)) | default('unknown') }}" os_family: "{{ ansible_facts.os_family | default(ansible_facts.distribution | default('unknown')) }}" operating_system: "{{ ansible_facts.distribution | default('unknown') }} {{ ansible_facts.distribution_version | default('') }}" ip_address: "{{ ansible_default_ipv4.address | default('unknown') }}" hardware_model: "{{ ansible_facts['machine'] | default('unknown') }}" cpu_count: "{{ ansible_facts['processor_vcpus'] | default(ansible_facts['processor_count'] | default('unknown')) }}" ram_gb: "{{ (ansible_facts['memtotal_mb'] / 1024) | int | default('unknown') }}" - name: Source oraenv and display OPatch informations shell: | . oraenv <<< {{ oracle_sid }} && $ORACLE_HOME/OPatch/opatch version && echo && echo && $ORACLE_HOME/OPatch/opatch lspatches register: opatch_output when: oracle_sid is defined - name: Display OPatch output debug: var: opatch_output.stdout_lines when: oracle_sid is defined - name: Check Oracle instance status via sqlplus as SYSDBA shell: | . oraenv <<< {{ oracle_sid }} >/dev/null 2>&1 $ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL' set heading off feedback off verify off pagesize 0 select status from v$instance; exit SQL register: instance_status changed_when: false when: oracle_sid is defined - name: Show Oracle instance status debug: msg: "Oracle instance {{ oracle_sid }} status: {{ instance_status.stdout | trim | default('unknown') }}" when: oracle_sid is defined - name: Fail if Oracle instance is not OPEN fail: msg: "Oracle instance {{ oracle_sid }} is not OPEN (status: {{ instance_status.stdout | default('unknown') }})" when: oracle_sid is defined and ("OPEN" not in (instance_status.stdout | default(''))) - name: List PDBs (if multitenant) shell: | . oraenv <<< {{ oracle_sid }} >/dev/null 2>&1 $ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL' set heading off feedback off verify off pagesize 0 select name||':'||open_mode from v$pdbs where name!='PDB$SEED'; exit SQL register: pdb_list failed_when: false changed_when: false when: oracle_sid is defined - name: Determine if database is multitenant set_fact: is_multitenant: "{{ (pdb_list.stdout is defined) and ('ORA-' not in pdb_list.stdout) and (pdb_list.stdout | trim != '') }}" when: oracle_sid is defined - name: Show PDB list (if multitenant) debug: var: pdb_list.stdout_lines when: oracle_sid is defined and is_multitenant - name: Check for non-OPEN PDBs shell: | . oraenv <<< {{ oracle_sid }} >/dev/null 2>&1 $ORACLE_HOME/bin/sqlplus -s / as sysdba <<'SQL' set heading off feedback off verify off pagesize 0 select name||':'||open_mode from v$pdbs where name!='PDB$SEED' and upper(open_mode) not like '%READ WRITE%'; exit SQL register: pdb_not_open failed_when: false changed_when: false when: oracle_sid is defined and is_multitenant - name: Filter non-empty PDB results set_fact: pdb_not_open_filtered: "{{ pdb_not_open.stdout_lines | select('match', '^.+:.+$') | list }}" when: oracle_sid is defined and is_multitenant - name: Fail if any PDB is not OPEN fail: msg: "PDB(s) not OPEN: {{ pdb_not_open_filtered }}" when: oracle_sid is defined and is_multitenant and (pdb_not_open_filtered | length) > 0