2018-03-11 Ansible Playbook for ASMLIB Setup

Overview

Now that I have the ORACLE ASMLIB software installed, I need to configure it.

References

Procedure

Outline

There are two (2) parts:

    1. Configure the ASMLib driver as described in F.4.1.2.1 Installing and Configuring the Oracle ASM Library Driver Software.
    2. Initialise the ASM disks as described in F.4.1.2.2 Configuring Disk Devices to Use Oracle ASM Library Driver on x86 Systems.

I ended up with my most complex Ansible playbook so far. The playbook consisted of two (2) files:

    1. oracleasm.yml
    2. oracleasm_init_disk.yml

Main Playbook

The main playbook is oracleasm.yml. It has three (3) main steps:

    1. Ensure that the Oracle ASMLib driver is configured and enabled
    2. Ensure that the Oracle ASMLib Driver is initialized and loaded
    3. Initialize all required disk devices with the Oracle ASMLib driver

The contents of the main playbook, oracleasm.yml, are:

--- - name: Configure ORACLE ASMLib Driver hosts: redfern1.yaocm.id.au become: yes tasks: # ============================================================================ # Ensure that the Oracle ASMLib driver is configured and enabled # User should be 'oracle' # Group should be 'asmadmin' # ============================================================================ - name: Get Oracle ASMLib Driver Configuration command: /usr/sbin/oracleasm configure register: oasm_config changed_when: false - debug: var: oasm_config verbosity: 1 - name: Set Owner for Oracle ASMLib Driver command: /usr/sbin/oracleasm configure -u oracle when: oasm_config.stdout_lines[1] != "ORACLEASM_UID=oracle" - name: Set Group for Oracle ASMLib Driver command: /usr/sbin/oracleasm configure -g asmadmin when: oasm_config.stdout_lines[2] != "ORACLEASM_GID=asmadmin" - name: Enable Oracle ASMLib Driver command: /usr/sbin/oracleasm configure -e when: oasm_config.stdout_lines[0] == "ORACLEASM_ENABLED=false" # ============================================================================ # Ensure that the Oracle ASMLib Driver is initialized and loaded # ============================================================================ - name: Check Oracle ASMLib Driver Status command: /usr/sbin/oracleasm status register: oasm_status changed_when: false failed_when: false no_log: true - debug: var: oasm_status verbosity: 1 - name: Load and initialize Oracle ASMLib Driver command: /usr/sbin/oracleasm init when: oasm_status.stdout_lines[0] | match("Checking if ASM is loaded. no") - name: Verify Oracle ASMLib Driver is loaded and initialized command: /usr/sbin/oracleasm status register: oasm_status changed_when: false # ============================================================================ # Initialize all required disk devices with the Oracle ASMLib driver # ============================================================================ - include_tasks: oracleasm_init_disk.yml with_items: - { dev: /dev/xvdd, disk: DATA } - { dev: /dev/xvde, disk: FRA } - { dev: /dev/xvdf, disk: REDO1 } - { dev: /dev/xvdg, disk: REDO2 } - { dev: /dev/xvdh, disk: VOTE } loop_control: loop_var: oasm_disk ...

Note:

For command tasks that just get information, the following parameters are recommended:

register: <variable> # Put command output into this variable changed_when: false # Always set the task status to ok, otherwise the status will be changed because the command executed successfully failed_when: false # Ignore non-zero return codes, and set the task status to ok, otherwise the status will be failed no_log: true # Do not dump any messages even if command fails because of non-zero return codes (even though failed_when is false)

The last two (2) parameters can be omitted if the command does not fail when getting the information. For example, the oracleasm status fails if the driver is not loaded. But the oracleasm configure just returns the configuration settings and a zero (0) return code.

Note:

To dump the contents of variables only when the ansible-playbook is run with the -v parameter, use the debug module as follows:

- debug: var: <variable> # command output gotten via the register parameter to the command module verbosity: 1 # minimum number of -v parameters needed to activate module (2 = -vv, 3 = -vvv, etc)

Although the -v parameter also displays the return values by the task, the debug module produces a more readable output. Also, the no_log=true suppresses any output from the task, leaving the debug module as the only way to see the output.

Note:

To loop over a block of several tasks, do not use Blocks. Use import_tasks within a loop.

Note:

See Tests for a description of the | match construct.

Tasks to Initialise ASM Disks

The playbook, oracleasm_init_disk.yml, has the following contents:

# ============================================================================== # Initialise a disk device only if it is not already an ASM disk # ============================================================================== - name: Query status of disk "{{ oasm_disk.dev }}1" command: /usr/sbin/oracleasm querydisk "{{ oasm_disk.dev }}1" changed_when: false failed_when: false no_log: true register: oasm_disk_status - debug: var: oasm_disk_status verbosity: 1 - name: Ensure that there is one partition that occupies whole disk "{{ oasm_disk.dev }}" parted: device: "{{ oasm_disk.dev }}" number: 1 state: present label: msdos part_type: primary part_start: 0% part_end: 100% - name: Initialize "{{ oasm_disk.dev }}1" as "{{ oasm_disk.disk }}" command: /usr/sbin/oracleasm createdisk "{{ oasm_disk.disk }}" "{{ oasm_disk.dev }}1" when: oasm_disk_status.stdout_lines[0] | match("Device .* is not marked as an ASM disk")

Note:

This is not a complete YAML file because the header and footer are missing.

Note:

See Tests for a description of the | match construct.

Sample Run

Using the following command, a complete run of setting up of ORACLE ASMLib driver can be done:

ansible-playbook --ask-become-pass oracleasm.yml

The output would look like the following:

SUDO password: PLAY [Configure ORACLE ASMLib Driver] ****************************************** TASK [Gathering Facts] ********************************************************* ok: [redfern1.yaocm.id.au] TASK [Get Oracle ASMLib Driver Configuration] ********************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Set Owner for Oracle ASMLib Driver] ************************************** changed: [redfern1.yaocm.id.au] TASK [Set Group for Oracle ASMLib Driver] ************************************** changed: [redfern1.yaocm.id.au] TASK [Enable Oracle ASMLib Driver] ********************************************* changed: [redfern1.yaocm.id.au] TASK [Check Oracle ASMLib Driver Status] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Load and initialize Oracle ASMLib Driver] ******************************** changed: [redfern1.yaocm.id.au] TASK [Verify Oracle ASMLib Driver is loaded and initialized] ******************* ok: [redfern1.yaocm.id.au] TASK [include_tasks] *********************************************************** included: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.auincluded: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.auincluded: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.auincluded: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.auincluded: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.au TASK [Query status of disk "/dev/xvdd1"] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Ensure that there is one partition that occupies whole disk "/dev/xvdd"] *** changed: [redfern1.yaocm.id.au] TASK [Initialize "/dev/xvdd1" as "DATA"] *************************************** changed: [redfern1.yaocm.id.au] TASK [Query status of disk "/dev/xvde1"] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Ensure that there is one partition that occupies whole disk "/dev/xvde"] *** changed: [redfern1.yaocm.id.au] TASK [Initialize "/dev/xvde1" as "FRA"] **************************************** changed: [redfern1.yaocm.id.au] TASK [Query status of disk "/dev/xvdf1"] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Ensure that there is one partition that occupies whole disk "/dev/xvdf"] *** changed: [redfern1.yaocm.id.au] TASK [Initialize "/dev/xvdf1" as "REDO1"] ************************************** changed: [redfern1.yaocm.id.au] TASK [Query status of disk "/dev/xvdg1"] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Ensure that there is one partition that occupies whole disk "/dev/xvdg"] *** changed: [redfern1.yaocm.id.au] TASK [Initialize "/dev/xvdg1" as "REDO2"] ************************************** changed: [redfern1.yaocm.id.au] TASK [Query status of disk "/dev/xvdh1"] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Ensure that there is one partition that occupies whole disk "/dev/xvdh"] *** changed: [redfern1.yaocm.id.au] TASK [Initialize "/dev/xvdh1" as "VOTE"] *************************************** changed: [redfern1.yaocm.id.au] PLAY RECAP ********************************************************************* redfern1.yaocm.id.au : ok=9 changed=14 unreachable=0 failed=0

Verify Idempotency of Playbook

The playbook is idempotent as demonstrated by the following output:

ansible-playbook --ask-become-pass oracleasm.yml SUDO password: PLAY [Configure ORACLE ASMLib Driver] ****************************************** TASK [Gathering Facts] ********************************************************* ok: [redfern1.yaocm.id.au] TASK [Get Oracle ASMLib Driver Configuration] ********************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Set Owner for Oracle ASMLib Driver] ************************************** skipping: [redfern1.yaocm.id.au] TASK [Set Group for Oracle ASMLib Driver] ************************************** skipping: [redfern1.yaocm.id.au] TASK [Enable Oracle ASMLib Driver] ********************************************* skipping: [redfern1.yaocm.id.au] TASK [Check Oracle ASMLib Driver Status] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Load and initialize Oracle ASMLib Driver] ******************************** skipping: [redfern1.yaocm.id.au] TASK [Verify Oracle ASMLib Driver is loaded and initialized] ******************* ok: [redfern1.yaocm.id.au] TASK [include_tasks] *********************************************************** included: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.auincluded: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.auincluded: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.auincluded: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.auincluded: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.au TASK [Query status of disk "/dev/xvdd1"] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Ensure that there is one partition that occupies whole disk "/dev/xvdd"] *** ok: [redfern1.yaocm.id.au] TASK [Initialize "/dev/xvdd1" as "DATA"] *************************************** skipping: [redfern1.yaocm.id.au] TASK [Query status of disk "/dev/xvde1"] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Ensure that there is one partition that occupies whole disk "/dev/xvde"] *** ok: [redfern1.yaocm.id.au] TASK [Initialize "/dev/xvde1" as "FRA"] **************************************** skipping: [redfern1.yaocm.id.au] TASK [Query status of disk "/dev/xvdf1"] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Ensure that there is one partition that occupies whole disk "/dev/xvdf"] *** ok: [redfern1.yaocm.id.au] TASK [Initialize "/dev/xvdf1" as "REDO1"] ************************************** skipping: [redfern1.yaocm.id.au] TASK [Query status of disk "/dev/xvdg1"] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Ensure that there is one partition that occupies whole disk "/dev/xvdg"] *** ok: [redfern1.yaocm.id.au] TASK [Initialize "/dev/xvdg1" as "REDO2"] ************************************** skipping: [redfern1.yaocm.id.au] TASK [Query status of disk "/dev/xvdh1"] *************************************** ok: [redfern1.yaocm.id.au] TASK [debug] ******************************************************************* skipping: [redfern1.yaocm.id.au] TASK [Ensure that there is one partition that occupies whole disk "/dev/xvdh"] *** ok: [redfern1.yaocm.id.au] TASK [Initialize "/dev/xvdh1" as "VOTE"] *************************************** skipping: [redfern1.yaocm.id.au] PLAY RECAP ********************************************************************* redfern1.yaocm.id.au : ok=19 changed=0 unreachable=0 failed=0