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.au
included: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.au
included: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.au
included: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.au
included: /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.au
included: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.au
included: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.au
included: /etc/ansible/oracleasm_init_disk.yml for redfern1.yaocm.id.au
included: /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