PowerVC で RHEL のイメージ・キャプチャーを行う前の処理をAnsible で実行

#### はじめに

PowerVC で RHEL サーバーのイメージ・キャプチャーを行う際にマルチパス構成を解除してデプロイするにはキャプチャー前に設定が必要です。
その設定をAnsibleでの実行を試してみました。

設定内容は、["IBM Power Virtualization Center(PowerVC) 2.0 導入・運用ガイド"](https://ibm.ent.box.com/s/tb34vtxrgg14ty6xxrg4hza5o4p6f23y)　p60-64 に基づいています。

---
#### 環境


・キャプチャー・対象サーバー：  ホスト名 test0825 (RHEL 8.4 on S824) 


---
#### 実行スクリプト

```before_capture_rhel.yml
---
- hosts: test0825    　                  #＜＝ホスト名指定　要修正
  gather_facts: no
  become: yes

vars:
   services: 
     - cloud-init
     - cloud-init-local
     - cloud-config
     - cloud-final
     
  tasks:
   - name: 1. Start and enable cloud-init service
     service:
        name: "{{ service_name }}"
        state: started
        enabled: yes
     loop: "{{ services }}"
     loop_control:
      loop_var: service_name

   - name: 2. Check cloud-* Status
     shell: |
         systemctl -t service | grep cloud
         echo "#---------cloud-init.service--------#"; systemctl is-enabled cloud-init
         echo "#---------cloud-init-local.service--------#"; systemctl is-enabled cloud-init-local
         echo "#---------cloud-config.service--------#"; systemctl is-enabled cloud-config
         echo "#---------cloud-final.service--------#"; systemctl is-enabled cloud-final
     changed_when: false
     register: cloudinit_status

   - debug:   
       var: cloudinit_status.stdout_lines

   - name: 3. Check target files
     shell: |
         ls -l /etc/systemd/system/cloud-init.target.wants/
     changed_when: false
     register: cloudinit_targetcheck

   - debug:   
       var: cloudinit_targetcheck.stdout_lines

   - name: 4. multipath backup
     shell: |
         cp -p /etc/multipath/bindings /etc/multipath/bindings.bak
         cp -p /etc/multipath/wwids /etc/multipath/wwids.bak
         ls -l /etc/multipath/
     changed_when: false
     register: copied_file

   - debug:   
        var: copied_file.stdout_lines

   - name: 5. multipath reset
     shell: |
         cat /dev/null >  /etc/multipath/bindings
         cat /dev/null > /etc/multipath/wwids
         ls -l /etc/multipath/
     changed_when: false
     register: nulled_file

   - debug:   
        var: nulled_file.stdout_lines

   - name: 6. Delete HWADDR line
     shell: |
         ls -l /etc/sysconfig/network-scripts/ifcfg* | awk '{print $9}' > /tmp/test.txt
         for i in `cat /tmp/test.txt`; do sed -i '/HWADDR/d' $i; cat $i ; done
     changed_when: false
     register: networkscripts_check

   - debug:   
        var: networkscripts_check.stdout_lines

   - name: 7. Delete tmpfile
     file: 
        path: /tmp/test.txt
        state: absent
     register: tmpfile_check

   - debug: 
        var: tmpfile_check

   - name: 8. Add the cloudinit ds-identity.cfg 
     shell: |
          echo "policy: search,found=all,maybe=all,notfound=disabled" >  /etc/cloud/ds-identify.cfg
          cat  /etc/cloud/ds-identify.cfg
     changed_when: false
     register: dsidentity_check

   - debug:   
        var: dsidentity_check.stdout_lines

   - name: 9. Interface file check
     shell: |
          FILE70="/etc/udev/rules.d/70-persistent-net.rules"
          if [ -e $FILE70 ]; then
             cp -p $FILE70 $FILE70.bak
             cat /dev/null > $FILE70
          fi 
          FILE75="/lib/udev/rules.d/75-persistent-net-generator.rules"
          if [ -e  $FILE75 ]; then
             cp -p $FILE75 $FILE75.bak
             cat /dev/null > $FILE75
          fi
          echo "#---------70-persistent-net.rules--------#"; ls -l $FILE70 
          echo "#---------75-persistent-net-generator.rules--------#"; ls -l $FILE75
     changed_when: false   
     ignore_errors: yes
     register: interface_filecheck

   - debug:   
       var: interface_filecheck.stdout_lines

   - name: 10. boot image backup
     shell: |
         FILE=`ls /boot/initramfs*.ppc64le.img`
         DATE=`date +%m-%d-%H%M%S`
         cp -p ${FILE} ${FILE}_${DATE}.bak
         ls -l /boot/initram*.ppc64le.img*
     changed_when: false
     register: bootimage_filebackup

   - debug:   
       var: bootimage_filebackup.stdout_lines

   - name: 11. re-generate boot image
     shell: |
          dracut --force -H --add multipath
          ls -ltr /boot/initram*.ppc64le.img*
     changed_when: false
     register: bootimage_regenerate

   - debug:   
        var: bootimage_regenerate.stdout_lines

   - name: 12. check cloud.cfg file
     shell: |
          cat /etc/cloud/cloud.cfg
     changed_when: false
     register: cloudcfg_check

   - debug:   
        var: cloudcfg_check.stdout_lines

```

shell モジュール多めです..。


---
#### 実行


```
$ time ansible-playbook before_capture_rhel.yml

PLAY [test0825] ************************************************************************************

TASK [1. Start and enable cloud-init service] ******************************************************
changed: [test0825] => (item=cloud-init)
ok: [test0825] => (item=cloud-init-local)
changed: [test0825] => (item=cloud-config)
changed: [test0825] => (item=cloud-final)

TASK [2. Check cloud-* Status] *********************************************************************
ok: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "cloudinit_status.stdout_lines": [
        "cloud-config.service               loaded active exited  Apply the settings specified in cloud-config                                 ",
        "cloud-final.service                loaded active exited  Execute cloud user/final scripts                                             ",
        "cloud-init-local.service           loaded active exited  Initial cloud-init job (pre-networking)                                      ",
        "cloud-init.service                 loaded active exited  Initial cloud-init job (metadata service crawler)                            ",
        "#---------cloud-init.service--------#",
        "enabled",
        "#---------cloud-init-local.service--------#",
        "enabled",
        "#---------cloud-config.service--------#",
        "enabled",
        "#---------cloud-final.service--------#",
        "enabled"
    ]
}

TASK [3. Check target files] ***********************************************************************
ok: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "cloudinit_targetcheck.stdout_lines": [
        "total 0",
        "lrwxrwxrwx. 1 root root 44 Aug 25 02:51 cloud-config.service -> /usr/lib/systemd/system/cloud-config.service",
        "lrwxrwxrwx. 1 root root 43 Aug 25 02:52 cloud-final.service -> /usr/lib/systemd/system/cloud-final.service",
        "lrwxrwxrwx. 1 root root 48 Aug 25 02:50 cloud-init-local.service -> /usr/lib/systemd/system/cloud-init-local.service",
        "lrwxrwxrwx. 1 root root 42 Aug 25 02:49 cloud-init.service -> /usr/lib/systemd/system/cloud-init.service"
    ]
}

TASK [4. multipath backup] *************************************************************************
ok: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "copied_file.stdout_lines": [
        "total 24",
        "-rw-------. 1 root root 282 Aug 25 01:29 bindings",
        "-rw-------. 1 root root 282 Aug 25 01:29 bindings.bak",
        "-rw-------. 1 root root 282 Aug 25 01:29 bindings_org",
        "-rw-------. 1 root root 262 Aug 25 01:29 wwids",
        "-rw-------. 1 root root 262 Aug 25 01:29 wwids.bak",
        "-rw-------. 1 root root 262 Aug 25 01:29 wwids_org"
    ]
}

TASK [5. multipath reset] **************************************************************************
ok: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "nulled_file.stdout_lines": [
        "total 16",
        "-rw-------. 1 root root   0 Aug 31 01:20 bindings",
        "-rw-------. 1 root root 282 Aug 25 01:29 bindings.bak",
        "-rw-------. 1 root root 282 Aug 25 01:29 bindings_org",
        "-rw-------. 1 root root   0 Aug 31 01:20 wwids",
        "-rw-------. 1 root root 262 Aug 25 01:29 wwids.bak",
        "-rw-------. 1 root root 262 Aug 25 01:29 wwids_org"
    ]
}

TASK [6. Delete HWADDR line] ***********************************************************************
ok: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "networkscripts_check.stdout_lines": [
        "# Created by cloud-init on instance boot automatically, do not edit.",
        "#",
        "BOOTPROTO=dhcp",
        "DEVICE=env32",
        "ONBOOT=yes",
        "TYPE=Ethernet",
        "USERCTL=no",
        "# Created by cloud-init on instance boot automatically, do not edit.",
        "#",
        "BOOTPROTO=none",
        "DEFROUTE=yes",
        "DEVICE=env33",
        "GATEWAY=x.xxx.xxx.x",
        "IPADDR=x.xxx.xxx.xxx",
        "MTU=1500",
        "NETMASK=255.255.0.0",
        "ONBOOT=yes",
        "TYPE=Ethernet",
        "USERCTL=no"
    ]
}

TASK [7. Delete tmpfile] ***************************************************************************
changed: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "tmpfile_check": {
        "changed": true,
        "diff": {
            "after": {
                "path": "/tmp/test.txt",
                "state": "absent"
            },
            "before": {
                "path": "/tmp/test.txt",
                "state": "file"
            }
        },
        "failed": false,
        "path": "/tmp/test.txt",
        "state": "absent"
    }
}

TASK [8. Add the cloudinit ds-identity.cfg] ********************************************************
ok: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "dsidentity_check.stdout_lines": [
        "policy: search,found=all,maybe=all,notfound=disabled"
    ]
}

TASK [9. Interface file check] *********************************************************************
ok: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "interface_filecheck.stdout_lines": [
        "#---------70-persistent-net.rules--------#",
        "-rw-r--r--. 1 root root 0 Aug 31 01:30 /etc/udev/rules.d/70-persistent-net.rules",
        "#---------75-persistent-net-generator.rules--------#"
    ]
}

TASK [10. boot image backup] ***********************************************************************
ok: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "bootimage_filebackup.stdout_lines": [
        "-rw-------. 1 root root 58256515 Nov  8  2021 /boot/initramfs-4.18.0-305.el8.ppc64le.img",
        "-rw-------. 1 root root 58256515 Nov  8  2021 /boot/initramfs-4.18.0-305.el8.ppc64le.img_08-31-012018.bak"
    ]
}

TASK [11. re-generate boot image] ******************************************************************
ok: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "bootimage_regenerate.stdout_lines": [
        "-rw-------. 1 root root 58256515 Nov  8  2021 /boot/initramfs-4.18.0-305.el8.ppc64le.img_08-31-012018.bak",
        "-rw-------. 1 root root 56473713 Aug 31 01:20 /boot/initramfs-4.18.0-305.el8.ppc64le.img"
    ]
}

TASK [12. check cloud.cfg file] ********************************************************************
ok: [test0825]

TASK [debug] ***************************************************************************************
ok: [test0825] => {
    "cloudcfg_check.stdout_lines": [
        "users:",
        " - default",
        "",
        "disable_root: 0",
        "ssh_pwauth:   1",
        "",
        "mount_default_fields: [~, ~, 'auto', 'defaults,nofail,x-systemd.requires=cloud-init.service', '0', '2']",
        "resize_rootfs_tmp: /dev",
        "ssh_deletekeys:   1",
        "ssh_genkeytypes:  ['rsa', 'ecdsa', 'ed25519']",
        "syslog_fix_perms: ~",
        "disable_vmware_customization: false",
        "",
        "# add for PowerVC",
        "manage_resolv_conf: false",
        "datasource_list: [ ConfigDrive, NoCloud, None ]",
        "datasource:",
        "  ConfigDrive:",
        "    dsmode: local",
        "",
        "cloud_init_modules:",
        " - disk_setup",
        " - migrator",
        " - bootcmd",
        " - write-files",
        " - growpart",
        " - resizefs",
        " - set_hostname",
        "# - update_hostname",
        "# - update_etc_hosts",
        "  - rsyslog",
        " - users-groups",
        " - ssh",
        "",
        "cloud_config_modules:",
        " - mounts",
        "# - locale",
        " - set-passwords",
        " - rh_subscription",
        " - yum-add-repo",
        " - package-update-upgrade-install",
        " - timezone",
        " - puppet",
        " - chef",
        " - salt-minion",
        " - mcollective",
        " - disable-ec2-metadata",
        " - runcmd",
        "",
        "cloud_final_modules:",
        " - rightscale_userdata",
        " - scripts-per-once",
        " - scripts-per-boot",
        " - scripts-per-instance",
        " - scripts-user",
        " - ssh-authkey-fingerprints",
        " - keys-to-console",
        " - phone-home",
        " - reset_rmc",
        " - final-message",
        " - power-state-change:",
        "",
        "system_info:",
        "  default_user:",
        "    name: cloud-user",
        "    lock_passwd: true",
        "    gecos: Cloud User",
        "    groups: [adm, systemd-journal]",
        "    sudo: [\"ALL=(ALL) NOPASSWD:ALL\"]",
        "    shell: /bin/bash",
        "  distro: rhel",
        "  paths:",
        "    cloud_dir: /var/lib/cloud",
        "    templates_dir: /etc/cloud/templates",
        "  ssh_svcname: sshd",
        "",
        "# vim:syntax=yaml",
        "",
        "runcmd:",
        " - rm -f /etc/multipath/wwids",
        " - ofpathname -l $(lsprop /proc/device-tree/chosen | grep bootpath | awk -F \"\\\"\" '{print $2}') > /tmp/bootdisk",
        " - multipath -a /dev/$(cat /tmp/bootdisk)",
        " - dracut -f -a multipath"
    ]
}

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

ansible-playbook before_capture_rhel.yml  29.93s user 8.78s system 5% cpu 11:02.19 total
$x.xxx.xxx.xxx

```

実行所要時間は11分程度です。
サービス停止とenable化の最初の箇所で時間がかかっていました。

この後はVMシャットダウンが必要ですが、Ansible での実行は疎通が途絶えるため手動でLPAR停止を実行します。

---
#### おわりに


ひとまずキャプチャー前処理をAnsibleで実行することができました。
(今後スクリプトを修正する可能性はあります。)


以上です。