User Tools

Site Tools


ansible:ansible_for_aix

Ansible for AIX

https://galaxy.ansible.com/ui/repo/published/ibm/power_aix/

https://galaxy.ansible.com/ui/repo/published/ibm/power_vios/

https://galaxy.ansible.com/ui/repo/published/ibm/power_hmc/

https://galaxy.ansible.com/ui/repo/published/brocade/fos/

https://galaxy.ansible.com/ui/repo/published/ibm/storage_virtualize/

https://www.ansible.com/blog/aix-patch-management-with-ansible

https://github.com/aixoss/ansible-playbooks

https://github.com/IBM/ansible-power-aix-oracle

https://github.com/IBM/ansible-power-hmc

https://github.com/lg4U (PowerVC)

If server is installed on AIX, then install prerequisites AIX packages:

  • bos.loc.com.utf
  • bos.loc.utf.EN_US

And set LANG: export LANG=en_US.UTF-8

$ ansible-galaxy collection install ibm.power_aix
$ ansible-galaxy collection install community.general
$ ansible-galaxy collection install community.general.installp

When Ansible is installed, a default inventory file /etc/ansible/hosts is created. At this point, I’m going to include in the inventory the hosts used in this example:

  nim01 is our AIX 7.2 NIM Master which is functional and has an lpp_source defined.
  bruce is an AIX 7.2 NIM client registered to the nim01 NIM master.
  freddie is an AIX 7.2 NIM client registered to the nim01 NIM master.
$ cat /etc/ansible/hosts
nim01 ansible_host=10.0.0.5 ansible_user=root ansible_python_interpreter=/usr/bin/python
bruce ansible_host=10.0.0.6 ansible_user=root ansible_python_interpreter=/usr/bin/python
freddie ansible_host=10.0.0.7 ansible_user=root ansible_python_interpreter=/usr/bin/python

I’m now going to connect to all the systems over SSH as “root”. The usual practice is to have a service account with “sudo” access, however for this example I will use “root” in our lab environment. Using the ssh-copy-id command, I can distribute my SSH public key to the AIX servers.

$ ssh-copy-id root@nim01
$ ssh-copy-id root@bruce
$ ssh-copy-id root@freddie

The next step is to use the Ansible ping module to check that I can connect to the three hosts in our inventory.

$ ansible -m ping all

PLAY [Ansible Ad-Hoc] **************************************************************************

TASK [ping] ************************************************************************************
ok: [nim01]
ok: [freddie]
ok: [bruce]

PLAY RECAP ************************************************************************************
nim01                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
bruce                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
freddie                : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

Ansible needs “python” to be installed on the AIX systems, and ideally the “yum” package manager should also be configured on AIX. If your AIX systems do not have these packages installed, or is a vanilla installation of AIX, IBM provides an Ansible Role to “bootstrap” an AIX system and manage it.

The playbook below uses the IBM provided role to prepare an AIX system for Ansible automation.

$ cat aix_bootstrap.yml 
---

- name: Prep AIX for Ansible 
  hosts: all
  vars: 
    pkgtype: yum 
  collections:
    - ibm.power_aix
  roles:
    - power_aix_bootstrap

The following example demonstrates running the playbook; however, I can see that the hosts Ansible is running against already have “python” and “yum” installed, so there is no need for any changes to be made to these hosts.

$ ansible-playbook aix_bootstrap.yml

PLAY [Prep AIX for Ansible] ******************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [bruce]
ok: [freddie]
ok: [nim01]

TASK [ibm.power_aix.power_aix_bootstrap : Fail if pkgtype not specified] *********************************************************************************************************************************************************************
skipping: [nim01]
skipping: [bruce]
skipping: [freddie]

TASK [ibm.power_aix.power_aix_bootstrap : Fail if download_dir not specified] ****************************************************************************************************************************************************************
skipping: [nim01]
skipping: [bruce]
skipping: [freddie]

TASK [ibm.power_aix.power_aix_bootstrap : Fail if target_dir not specified] ******************************************************************************************************************************************************************
skipping: [nim01]
skipping: [bruce]
skipping: [freddie]

TASK [ibm.power_aix.power_aix_bootstrap : Fail if rpm_src not specified] *********************************************************************************************************************************************************************
skipping: [nim01]
skipping: [bruce]
skipping: [freddie]

TASK [ibm.power_aix.power_aix_bootstrap : Fail if yum_src not specified] *********************************************************************************************************************************************************************
skipping: [nim01]
skipping: [bruce]
skipping: [freddie]

TASK [ibm.power_aix.power_aix_bootstrap : Bootstrap yum] *************************************************************************************************************************************************************************************
included: /home/tholloway/.ansible/collections/ansible_collections/ibm/power_aix/roles/power_aix_bootstrap/tasks/yum_install.yml for nim01, bruce, freddie

TASK [ibm.power_aix.power_aix_bootstrap : Check for existence of yum] ************************************************************************************************************************************************************************
changed: [bruce]
changed: [nim01]
changed: [freddie]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
nim01                  : ok=3    changed=1    unreachable=0    failed=0    skipped=5    rescued=0    ignored=0   
bruce                  : ok=3    changed=1    unreachable=0    failed=0    skipped=5    rescued=0    ignored=0   
freddie                : ok=3    changed=1    unreachable=0    failed=0    skipped=5    rescued=0    ignored=0 

Running an AIX Update using NIM and Ansible

First off, I’ll use a simple playbook to see what “oslevel” our NIM master and NIM clients are on, before I start.

$ cat check_os_version.yml
---
- name: talk to all hosts just so we can learn about them
  hosts: all
  tasks:
    - name: Classify hosts depending on their OS distribution
      group_by:
        key: os_{{ ansible_facts['distribution'] }}

- hosts: os_CentOS
  gather_facts: False
  tasks:
     - name: Check version of Linux system
       shell: "cat /etc/centos-release | tail -1 | sed 's/(AltArch)//' | rev | awk '{print $1}' | rev"
       register: output_oslevel
     - name: Print the oslevel
       debug:
         msg: "{{ ansible_hostname }} has the {{ ansible_distribution }} oslevel of {{ output_oslevel.stdout }}"

- hosts: os_AIX
  gather_facts: False
  tasks:
     - name: Check oslevel of AIX system
       shell: "oslevel -s"
       register: output_oslevel
     - name: Print the oslevel
       debug:
         msg: "{{ ansible_hostname }} has the {{ ansible_distribution }} oslevel of {{ output_oslevel.stdout }}"

Running that playbook delivers the below result. I can see that bruce and freddie are a service pack behind.

$ ansible-playbook aix_oslevel_check.yml 

PLAY [AIX oslevel checking playbook ] *****************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [bruce]
ok: [freddie]
ok: [nim01]

TASK [Gather LPP Facts] **********************************************************************************************************************************************************************************************************************
changed: [freddie]
changed: [bruce]
changed: [nim01]

TASK [Print the oslevel] *********************************************************************************************************************************************************************************************************************
ok: [nim01] => 
  msg: nim01 has the AIX oslevel of 7200-05-02-2114
ok: [bruce] => 
  msg: bruce has the AIX oslevel of 7200-05-01-2038
ok: [freddie] => 
  msg: freddie has the AIX oslevel of 7200-05-01-2038

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
nim01                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
bruce                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
freddie                : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

To ensure all systems are operating on the same OS level, I need to download the latest service pack. It should define an “lpp_source” on our NIM master. Make sure that the name of the “lpp_source” matches the example below, or the Ansible module will not detect the “oslevel”.

$ cat aix_download.yml 
---

- name: AIX Patching Playbook 
  hosts: nim01
  vars: 
    oslevel: 7200-05-02
    nim_lpp_source: 7200-05-02-2114-lpp_source
  collections:
    - ibm.power_aix
  tasks:

  - name: Download AIX Updates
    nim_suma:
      action: download
      download_dir: "/export/nim/lpp_source"
      lpp_source_name: "{{ nim_lpp_source }}"
      oslevel: "{{ oslevel }}"
      targets: 'bruce, freddie' 

Next step is to run the download playbook. It will download the required updates from IBM Fix Central and define an “lpp_source” on the NIM master:

$ ansible-playbook aix_download.yml 

PLAY [AIX Patching Playbook] *****************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [nim01]

TASK [Download AIX Updates] ******************************************************************************************************************************************************************************************************************
changed: [nim01]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
nim01                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Now I can run a patching playbook, which will make use of the “alt_disk” and “nim” Ansible modules. The playbook is going to perform the following tasks:

  Remove any existing “altinst_rootvg” “alt_disk_copy” that is left on the AIX system.
  Create a new “alt_disk_copy” clone of the root volume group to a spare disk as a backup.
  Run an application stop script.
  Run the AIX update via task delegation to the NIM master.
  Reboot.
  Run an application start script.
---

- name: AIX Patching Playbook 
  hosts: bruce,freddie
  vars: 
    nim_lpp_source: 7200-05-02-2114-lpp_source
    nim_master: nim01
  collections:
    - ibm.power_aix
  tasks:

  - name: Cleanup any existing alt_disk_copy 
    alt_disk:
      action: clean

  - name: Create an alt_disk_copy for backup
    alt_disk:
      targets: hdisk1

  - name: Stop Application
    shell: /usr/local/bin/stop.sh

  - name: Run AIX Update
    nim:
      action: update
      lpp_source: "{{ nim_lpp_source }}"
      targets: "{{ ansible_hostname }}"
    delegate_to: "{{ nim_master }}"    

  - name: Reboot
    reboot:
      post_reboot_delay: 180

  - name: Start Application
    shell: /usr/local/bin/start.sh

Now I will run the playbook and patch the NIM client systems “bruce” and “freddie”:

$ ansible-playbook aix_patching.yml 

 PLAY [AIX Patching Playbook] *****************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [bruce]
ok: [freddie]

TASK [Cleanup any existing alt_disk_copy] ****************************************************************************************************************************************************************************************************
changed: [bruce]
changed: [freddie]

TASK [Create an alt_disk_copy for backup] ****************************************************************************************************************************************************************************************************
changed: [bruce]
changed: [freddie]

TASK [Stop Application] **********************************************************************************************************************************************************************************************************************
changed: [bruce]
changed: [freddie]

TASK [Run AIX Update] *************************************************************************************************************************************************************************************************************************
changed: [bruce -> 10.0.0.5]
changed: [freddie -> 10.0.0.5]

TASK [Reboot] ********************************************************************************************************************************************************************************************************************************
changed: [freddie]
changed: [bruce]

TASK [Start Application] *********************************************************************************************************************************************************************************************************************
changed: [bruce]
changed: [freddie]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
bruce                 : ok=7    changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
freddie               : ok=7    changed=6    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Next, I will run the aix_oslevel_check.yml playbook again and see that the systems are all on AIX 7.2 TL5 SP2.

$ ansible-playbook aix_oslevel_check.yml 

PLAY [AIX oslevel checking playbook ] *****************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [bruce]
ok: [freddie]
ok: [nim01]

TASK [Gather LPP Facts] **********************************************************************************************************************************************************************************************************************
changed: [freddie]
changed: [bruce]
changed: [nim01]

TASK [Print the oslevel] *********************************************************************************************************************************************************************************************************************
ok: [nim01] => 
  msg: nim01 has the AIX oslevel of 7200-05-02-2114
ok: [bruce] => 
  msg: bruce has the AIX oslevel of 7200-05-02-2114
ok: [freddie] => 
  msg: freddie has the AIX oslevel of 7200-05-02-2114

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
nim01                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
bruce                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
freddie                : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

Another playbook

- name: Install package foo
  community.general.installp:
    name: foo
    repository_path: /repository/AIX71/installp/base
    accept_license: yes
    state: present

- name: Install bos.sysmgt that includes bos.sysmgt.nim.master, bos.sysmgt.nim.spot
  community.general.installp:
    name: bos.sysmgt
    repository_path: /repository/AIX71/installp/base
    accept_license: yes
    state: present

- name: Install bos.sysmgt.nim.master only
  community.general.installp:
    name: bos.sysmgt.nim.master
    repository_path: /repository/AIX71/installp/base
    accept_license: yes
    state: present

- name: Install bos.sysmgt.nim.master and bos.sysmgt.nim.spot
  community.general.installp:
    name: bos.sysmgt.nim.master, bos.sysmgt.nim.spot
    repository_path: /repository/AIX71/installp/base
    accept_license: yes
    state: present

- name: Remove packages bos.sysmgt.nim.master
  community.general.installp:
    name: bos.sysmgt.nim.master
    state: absent
    
    
- name: List all software products and installable options contained on an installation cartridge tape
  ibm.power_aix.installp:
    action: list
    device: /dev/rmt0.1

- name: List all customer-reported problems fixed by all software products on an installation tape
  ibm.power_aix.installp:
    action: list_fixes
    device: /dev/rmt0.1
    install_list: all

- name: Install all filesets within the bos.net software package and expand file systems if necessary
  ibm.power_aix.installp:
    extend_fs: yes
    device: /usr/sys/inst.images
    install_list: bos.net

- name: Reinstall and commit the NFS software product option that is already installed on the system at the same level
  ibm.power_aix.installp:
    commit: yes
    force: yes
    device: /dev/rmt0.1
    install_list: bos.net.nfs.client:4.1.0.0

- name: Remove a fileset named bos.net.tcp.server
  ibm.power_aix.installp:
    action: deinstall
    install_list: bos.net.tcp.server

NFS mount

First solution

Using shell, mount and umount

[root@aix200]/root> cat mksysb_nfs.yml
---
- name: "Run Mksysb"
  hosts: aix200
  become: yes
  become_user: root
  vars:
    NIM_Server: "nimsrv01"
    backup_repo: "/export/mksysb"
    NFS_mount: "/mksysb"
  tasks:
    - name: Monut filesystem
      shell: "mount -o vers=4,soft {{ NIM_Server }}:{{ backup_repo }} {{ NFS_mount }}"
    - name: "Run mksysb backup"
      mksysb:
       name: "{{ansible_hostname}}_mksysb_{{ansible_date_time.date}}"
       storage_path: "{{ NFS_mount }}"
       exclude_files: yes
    - name: "unmount NFS"
      mount:
       path: "{{ NFS_mount }}"
       state: unmounted

Second solution

On AIX, to be sure that filesystem will be mounted add it into /etc/filesystems, else it 'll failed

[root@aix200]/root> cat /etc/filesystems
...

/mksysb:
        dev             = "/export/mksysb"
        vfs             = nfs
        nodename        = nimsrv01
        mount           = false
        options         = bg,soft,intr,vers=4,sec=sys
        account         = false
[root@lnx100 playbooks]# cat mount_nfs.yml
---
- name: "Mount NFS"
  hosts: aix200
  become: yes
  become_user: root
  vars:
    NIM_Server: "nimsrv01"
    backup_repo: "/export/mksysb"
    NFS_mount: "/mksysb"
  tasks:
    - name: Mount NFS filesystem from nimsrv01.
      community.general.aix_filesystem:
        filesystem: "{{ NFS_mount }}"
        fs_type: nfs
        device: "{{ backup_repo }}"
        nfs_server: "{{ NIM_Server }}"
        auto_mount: no
        state: mounted

Mksysb on NIM (NFS)

[root@lnxa100 playbooks]# cat mount_nfs.yml
---
- name: "Run Mksysb"
  hosts: aixb200
  become: yes
  become_user: root
  vars:
    NIM_Server: "aixnb001"
    backup_repo: "/export/mksysb"
    NFS_mount: "/mksysb"
  tasks:
    - name: Monut filesystem
      shell: "mount -o vers=4,soft {{ NIM_Server }}:{{ backup_repo }} {{ NFS_mount }}"
    - name: "Run mksysb backup"
      mksysb:
       name: "{{ansible_hostname}}_mksysb_{{ansible_date_time.date}}"
       storage_path: "{{ NFS_mount }}"
       exclude_files: yes
    - name: "unmount NFS"
      shell: "umount  {{ NFS_mount }}"
      fstab: /etc/filesystems

Log and debug

The IBM Power Systems AIX collection uses the standard Ansible log system that is using the syslog subsystem on the managed nodes.

To activate AIX syslog you can update the configuration file /etc/syslog.conf with a selector user.info (or user.debug for more details) such as:

$ vi /etc/syslog.conf
user.info /var/log/syslog/user.info rotate size 1m files 4 compress

and restarting syslogd subsystem and look for Ansible logs:

$ > /var/log/syslog/user.info
$ refresh -s syslogd
$ grep ansible /var/log/syslog/user.info
May  6 03:28:27 nimmaster user:info ansible-nim: Invoked with resource=None force=False description=None script=damien_script lpp_source=None action=script asynchronous=True location=None device=None group=None operation=None targets=['nimclient01']
May  6 03:28:27 nimmaster user:info ansible-nim: *** START ***
...

To see the full debug log messages you should set the selector field to user.debug and run the playbook with the environment variable ANSIBLE_DEBUG=1

$ vi /etc/syslog.conf
user.debug /var/log/syslog.user.debug rotate size 1m files 4 compress
$ >/var/log/syslog.user.debug
$ refresh -s syslogd
$ ANSIBLE_DEBUG=1 ansible-playbook -M plugins/modules ./demo_nim.yml -vvv

Examples

Upgrade AIX NIM

[root@lnx01 production]# cat upgrade_aix_nim.yml
---
- name: "Run Mksysb"
  hosts: aix07
  become: yes
  become_user: root
  vars:
    NIM_Server: "nimsrv"
    nim_lpp_source: "/export/aix7200-05/aix7200-05-03_lpp"
    NFS_mount: "/mnt"

  tasks:

    - name: Mount AIX Filesets
      shell: "mount -o vers=4 {{ NIM_Server }}:{{ nim_lpp_source }} {{ NFS_mount }}"
      register: nfsmount

    - name: upgrade OS
      shell: install_all_updates -d "{{ NFS_mount }}" -rc -Y
      when: ansible_distribution == 'AIX'
      register: output
    - debug: var=output

    - name: "unmount NFS"
      mount:
        path: "{{ NFS_mount }}"
        state: unmounted

mksysb AIX NIM

[root@lnx01 production]# cat mksysb.yml
---
- name: "Run Mksysb"
  hosts: aix07
  become: yes
  become_user: root
  vars:
    NIM_Server: "nimsrv"
    backup_repo: "/export/mksysb"
    NFS_mount: "/mksysb"
    nfsmounts:
      - {  path: "/mksysb", src: "nimsrv:/export/mksysb" }
  tasks:

    - name: Mount AIX Filesets
      shell: "mount -o vers=4 {{ NIM_Server }}:{{ backup_repo }} {{ NFS_mount }}"
      register: nfsmount
    - name: "Run mksysb backup"
      mksysb:
        name: "{{ansible_hostname}}_mksysb_{{ansible_date_time.date}}"
        storage_path: "{{ NFS_mount }}"
        exclude_files: yes
        create_map_files: yes
    - name: "unmount NFS"
      mount:
        path: "{{ NFS_mount }}"
        state: unmounted

AIX NIMadm alternate disk migration

Below is an example of how to invoke the options. I'd added the “default('N/A')” to avoid errors if the variable was not defined, as the role is coded for “N/A”, but should also work with “default(omit)”

- name: Include nim_alt_disk_migration role
  include_role:
    name: nim_alt_disk_migration
    apply:
      delegate_to: "{{ NIM_Master }}"
      connection:  "{{ NIM_Conn }}"
  vars:
    nim_client:      "{{ NIM_Client }}"
    target_disk:
      disk_name:     "{{ Target_DISK.disk_name }}"
      force:         "{{ NIMADM_Force }}"
    lpp_source:      "{{ Target_LPPS }}"
    spot:            "{{ Target_SPOT }}"
    nim_mast_lpp:    "{{ NIM_Mast_LPP }}"
    nimadm_cache_vg: "{{ NIMADM_VG | default('N/A') }}"
    nimadm_bundle:   "{{ Target_eFix | default('N/A') }}"
    nimadm_bidata:   "{{ BOS_Inst_Data | default('N/A') }}"
    control_phases:
      validate_nim_resources: "{{ NIM_Res_Check }}"
      perform_migration:      "{{ NIM_Migration }}
    debug_skip_nimadm:        "{{ Skip_nimadm }}"
# ansible-galaxy collection list ibm.power_aix
# /.ansible/collections/ansible_collections
Collection    Version
------------- -------
ibm.power_aix 1.8.1

This Ansible role, nim_alt_disk_migration, can be used for “migrating an alternate disk to a higher AIX level”.

Here’s the playbook I used, called nimadm.yml:

---
- name: NIMADM playbook
  hosts: aixmig
  gather_facts: no
  collections:
    ibm.power_aix
  tasks:
    - include_role:
        name: nim_alt_disk_migration
        apply:
          delegate_to: lpar1
      vars:
        nimadm_cache_vg: nimadmvg
        nim_client: aixmig
        target_disk:
          disk_name: hdisk0
        lpp_source: AIX73TL1SP1
        spot: spotAIX73TL1SP1
      register: nimadm_results
    - name: "Debug: nimadm_results"
      ansible.builtin.debug: var=nimadm_results
ansible/ansible_for_aix.txt · Last modified: 2024/10/10 14:28 by manu