diff --git a/modules/powervs-vpc-landing-zone/submodules/ansible/ansible_node_packages.sh b/modules/powervs-vpc-landing-zone/submodules/ansible/ansible_node_packages.sh index b6d5afa9..c54df03d 100644 --- a/modules/powervs-vpc-landing-zone/submodules/ansible/ansible_node_packages.sh +++ b/modules/powervs-vpc-landing-zone/submodules/ansible/ansible_node_packages.sh @@ -8,7 +8,7 @@ ############################################################ GLOBAL_RHEL_PACKAGES="rhel-system-roles rhel-system-roles-sap expect" -GLOBAL_GALAXY_COLLECTIONS="ibm.power_linux_sap:>=3.0.0,<4.0.0" +GLOBAL_GALAXY_COLLECTIONS="ibm.power_linux_sap:>=3.0.0,<4.0.0 ibm.power_aix:>=2.0.0,<3.0.0" ############################################################ # Start functions diff --git a/modules/powervs-vpc-landing-zone/submodules/ansible/templates-ansible/configure-aix-services/ansible_exec.sh.tftpl b/modules/powervs-vpc-landing-zone/submodules/ansible/templates-ansible/configure-aix-services/ansible_exec.sh.tftpl new file mode 100644 index 00000000..6792e4f6 --- /dev/null +++ b/modules/powervs-vpc-landing-zone/submodules/ansible/templates-ansible/configure-aix-services/ansible_exec.sh.tftpl @@ -0,0 +1,22 @@ +#!/bin/bash + +### Using input variables from terraform +ansible_playbook=${ansible_playbook_file} +ansible_log_path=${ansible_log_path} +ansible_inventory=${ansible_inventory} +ansible_private_key_file=${ansible_private_key_file} + +# Create ansible.cfg file +ansible_playbook_name=$(basename $${ansible_playbook}) +echo -e "[defaults]\nhost_key_checking=False" >ansible.cfg +export ANSIBLE_LOG_PATH=$${ansible_log_path}/$${ansible_playbook_name}.$(date "+%Y.%m.%d-%H.%M.%S").log +export ANSIBLE_PRIVATE_KEY_FILE=$${ansible_private_key_file} + +#Execute ansible playbook +unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} +if [ $? -ne 0 ]; then + rm -rf $${ansible_private_key_file} + exit 1 +fi +echo \"Playbook command successful\" +rm -rf $${ansible_private_key_file} diff --git a/modules/powervs-vpc-landing-zone/submodules/ansible/templates-ansible/configure-aix-services/playbook-configure-aix-services.yml.tftpl b/modules/powervs-vpc-landing-zone/submodules/ansible/templates-ansible/configure-aix-services/playbook-configure-aix-services.yml.tftpl new file mode 100644 index 00000000..32afd52d --- /dev/null +++ b/modules/powervs-vpc-landing-zone/submodules/ansible/templates-ansible/configure-aix-services/playbook-configure-aix-services.yml.tftpl @@ -0,0 +1,285 @@ +--- +- name: AIX Configuration (proxy, rootvg, curl, data fs, nfs, ntp) + hosts: all + gather_facts: no + + vars: + EXTEND_ROOT_VOLUME_WWN: "${EXTEND_ROOT_VOLUME_WWN}" + DATA_VOLUME_WWN: "${DATA_VOLUME_WWN}" + DATA_VOLUME_MOUNT_PATH: "${DATA_VOLUME_MOUNT_PATH}" + DATAVG: "${DATAVG}" + DATALV: "${DATALV}" + PROXY_IP_PORT: "${PROXY_IP_PORT}" + NO_PROXY: "${NO_PROXY}" + NFS_ENABLE: "${NFS_ENABLE}" + NFS_MOUNT_POINT: "${NFS_MOUNT_POINT}" + NFS_HOST_OR_PATH: "${NFS_HOST_OR_PATH}" + NTP_ENABLE: "${NTP_ENABLE}" + NTP_SERVER: "${NTP_SERVER}" + DNS_ENABLE: "${DNS_ENABLE}" + DNS_SERVER_1: "${DNS_SERVER_1}" + # Hardcoded values (Terraform can override) + NFS_DOMAIN: "${NFS_DOMAIN}" + NFS_HOSTNAME: "${NFS_HOSTNAME}" + ansible_shell_executable: /usr/bin/ksh + ansible_shell_type: sh + + tasks: + + ############################################################## + # Configure Proxy + ############################################################## + - name: Configure Proxy + block: + - name: Set proxy environment variables in /etc/profile + ansible.builtin.blockinfile: + path: /etc/profile + marker: "# {mark} PROXY SETTINGS" + block: | + export http_proxy=http://{{ PROXY_IP_PORT }} + export https_proxy=http://{{ PROXY_IP_PORT }} + export HTTP_PROXY=http://{{ PROXY_IP_PORT }} + export HTTPS_PROXY=http://{{ PROXY_IP_PORT }} + export no_proxy={{ NO_PROXY }} + + - name: Export proxy variables for current session + ansible.builtin.shell: | + export http_proxy=http://{{ PROXY_IP_PORT }} + export https_proxy=http://{{ PROXY_IP_PORT }} + export HTTP_PROXY=http://{{ PROXY_IP_PORT }} + export HTTPS_PROXY=http://{{ PROXY_IP_PORT }} + export no_proxy={{ NO_PROXY }} + changed_when: false + tags: proxy + + ############################################################## + # Extend rootvg + ############################################################## + - name: Extend rootvg + block: + - name: Discover hdisk by WWN for rootvg extension (run cfgmgr first) + ansible.builtin.shell: | + cfgmgr >/dev/null 2>&1 + lspv -u | tr '[:upper:]' '[:lower:]' | + awk -v w="{{ EXTEND_ROOT_VOLUME_WWN | lower }}" 'index($0,w){print $1; exit}' + register: hdisk_name + changed_when: false + + - name: Get current MAX PPs per PV for rootvg + ansible.builtin.shell: "lsvg rootvg | grep 'MAX PPs per PV' | awk '{print $5}'" + register: chvg_limit + changed_when: false + + - name: Update rootvg partition limit if less than 1024 + ansible.builtin.shell: "chvg -t 16 rootvg" + when: chvg_limit.stdout | int < 1024 + changed_when: false + + - name: Mark hdisk as physical volume + ansible.builtin.command: "chdev -l {{ hdisk_name.stdout }} -a pv=yes" + when: hdisk_name.stdout != "" + changed_when: false + + - name: Extend rootvg with new disk + community.general.aix_lvg: + vg: rootvg + pvs: ["{{ hdisk_name.stdout }}"] + force: true + state: present + when: hdisk_name.stdout != "" + + - name: Resize filesystems + community.general.aix_filesystem: + filesystem: "{{ item.filesystem }}" + size: "{{ item.size }}" + state: present + loop: + - { filesystem: "/", size: "8G" } + - { filesystem: "/usr", size: "8G" } + - { filesystem: "/opt", size: "6G" } + - { filesystem: "/var", size: "6G" } + - { filesystem: "/tmp", size: "4G" } + tags: rootvg + + ############################################################## + # Install curl package + ############################################################## + - name: Install curl package + block: + - name: Install curl package using dnf + ansible.builtin.shell: | + . /etc/profile && echo 'y' | /opt/freeware/bin/dnf install curl-7.53* + register: curl_install + changed_when: "'Complete!' in curl_install.stdout or 'Nothing to do.' in curl_install.stdout" + + - name: Verify curl installation + ansible.builtin.shell: | + . /etc/profile && /opt/freeware/bin/dnf list installed curl | grep curl + register: curl_check + changed_when: false + failed_when: curl_check.rc != 0 + tags: curl + + ############################################################## + # Create filesystem for data volume + ############################################################## + - name: Create filesystem for data volume + block: + - name: Get hdisk for data volume + ansible.builtin.shell: | + lspv -u | tr '[:upper:]' '[:lower:]' | + awk -v w="{{ DATA_VOLUME_WWN | lower }}" 'index($0,w){print $1; exit}' + register: data_hdisk + changed_when: false + + - name: Fail if data hdisk not found + ansible.builtin.fail: + msg: "Error: Disk {{ DATA_VOLUME_WWN }} not found." + when: data_hdisk.stdout == "" + + - name: Create Volume Group ({{ DATAVG }}) on data hdisk + ibm.power_aix.lvg: + vg_name: "{{ DATAVG }}" + pvs: ["{{ data_hdisk.stdout }}"] + state: present + + - name: Gather LVM facts + ibm.power_aix.lvm_facts: + register: lvm_info + + - name: Calculate LV size = Free PPs × PP Size + ansible.builtin.set_fact: + datalv_size: "{{ (lvm_info.ansible_facts.LVM.VGs[DATAVG]['FREE PPs'] | regex_search('^\\d+') | int) * + (lvm_info.ansible_facts.LVM.VGs[DATAVG]['PP SIZE'] | regex_search('^\\d+') | int) }}M" + + - name: Create Logical Volume ({{ DATALV }}) in {{ DATAVG }} + ibm.power_aix.lvol: + vg: "{{ DATAVG }}" + lv: "{{ DATALV }}" + size: "{{ datalv_size }}" + state: present + when: + - "DATALV not in (lvm_info.ansible_facts.LVM.VGs[DATAVG].LVs | default({}))" + - (lvm_info.ansible_facts.LVM.VGs[DATAVG]['FREE PPs'] | regex_search('^\\d+') | int) > 0 + + - name: Ensure mount path exists + ansible.builtin.file: + path: "{{ DATA_VOLUME_MOUNT_PATH }}" + state: directory + mode: '0755' + + - name: Ensure filesystem exists on LV and is mounted + ibm.power_aix.filesystem: + device: "/dev/{{ DATALV }}" + filesystem: "{{ DATA_VOLUME_MOUNT_PATH }}" + fs_type: jfs2 + auto_mount: yes + permissions: rw + state: present + + - name: Ensure mount is active + ibm.power_aix.mount: + mount_dir: "{{ DATA_VOLUME_MOUNT_PATH }}" + state: mount + + - name: Verify filesystem mounted with df -g + ansible.builtin.shell: df -g | grep "{{ DATA_VOLUME_MOUNT_PATH }}" + register: df_output + changed_when: false + tags: data + + ############################################################## + # Configure NFS + ############################################################## + - name: Configure NFS + when: NFS_ENABLE | bool + block: + - name: Set NFS domain + ansible.builtin.command: chnfsdom "{{ NFS_DOMAIN }}" + changed_when: false + + - name: Ensure NFS services running + ansible.builtin.command: startsrc -g nfs + changed_when: false + + - name: Ensure NFS server entry in /etc/hosts + ansible.builtin.lineinfile: + path: /etc/hosts + line: "{{ NFS_HOST_OR_PATH.split(':')[0] }} {{ NFS_HOSTNAME }}" + state: present + + - name: Create mount directory + ansible.builtin.file: + path: "{{ NFS_MOUNT_POINT }}" + state: directory + + - name: Ensure NFS filesystem stanza exists (persistent) + ibm.power_aix.filesystem: + device: "{{ NFS_HOST_OR_PATH.split(':')[1] }}" + filesystem: "{{ NFS_MOUNT_POINT }}" + fs_type: nfs4 + auto_mount: yes + permissions: rw + state: present + nfs_server: "{{ NFS_HOSTNAME }}" + + - name: Ensure NFS is actually mounted now + ibm.power_aix.mount: + mount_dir: "{{ NFS_MOUNT_POINT }}" + state: mount + + - name: Show NFS mount status + ansible.builtin.command: df -g {{ NFS_MOUNT_POINT }} + register: nfs_mount_status + changed_when: false + tags: nfs + + ############################################################## + # Configure NTP (persistent) + ############################################################## + - name: Configure NTP (persistent) + when: NTP_ENABLE | bool + block: + - name: Ensure NTP server entry is in /etc/ntp.conf + ansible.builtin.lineinfile: + path: /etc/ntp.conf + line: "server {{ NTP_SERVER }}" + state: present + + - name: Ensure NTP daemon entry exists in /etc/inittab (persistent) + ibm.power_aix.inittab: + name: xntpd + runlevel: '2' + action: 'respawn' + command: '/usr/bin/startsrc -s xntpd > /dev/console 2>&1' + state: present + + - name: Restart NTP service + ansible.builtin.service: + name: xntpd + state: restarted + + - name: Verify NTP service with ntpq -p + ansible.builtin.command: ntpq -p + register: ntpq_output + changed_when: false + tags: ntp + + ############################################################## + # Configure DNS + ############################################################## + - name: Configure DNS + when: DNS_ENABLE | bool + block: + - name: Ensure DNS server entry is first in /etc/resolv.conf + ansible.builtin.lineinfile: + path: /etc/resolv.conf + line: "nameserver {{ DNS_SERVER_1 }}" + insertbefore: BOF + state: present + + - name: Verify DNS configuration + ansible.builtin.command: cat /etc/resolv.conf + register: dns_output + changed_when: false + tags: dns diff --git a/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.md b/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.md index 27fffac2..7dd4c2f7 100644 --- a/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.md +++ b/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.md @@ -1,7 +1,7 @@ --- copyright: years: 2024, 2025 -lastupdated: "2025-08-07" +lastupdated: "2025-09-08" keywords: subcollection: deployable-reference-architectures authors: @@ -15,7 +15,7 @@ image_source: https://github.com/terraform-ibm-modules/terraform-ibm-powervs-inf use-case: ITServiceManagement industry: Technology content-type: reference-architecture -version: v9.0.0 +version: v9.0.1 compliance: SAPCertified --- @@ -28,7 +28,7 @@ compliance: SAPCertified {: toc-industry="Technology"} {: toc-use-case="ITServiceManagement"} {: toc-compliance="SAPCertified"} -{: toc-version="v9.0.0"} +{: toc-version="v9.0.1"} The Power Virtual Server with VPC landing zone as variation 'Extend Power Virtual Server with VPC landing zone' creates an additional Power Virtual Server workspace and connects it with the already created Power Virtual Server with VPC landing zone. It builds on the existing Power Virtual Server with VPC landing zone deployed as a variation 'Create a new architecture'. diff --git a/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md b/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md index 09200744..d785356c 100644 --- a/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md +++ b/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md @@ -1,7 +1,7 @@ --- copyright: years: 2024, 2025 -lastupdated: "2025-08-07" +lastupdated: "2025-09-08" keywords: subcollection: deployable-reference-architectures authors: @@ -16,7 +16,7 @@ image_source: https://github.com/terraform-ibm-modules/terraform-ibm-powervs-inf use-case: ITServiceManagement industry: Technology content-type: reference-architecture -version: v9.0.0 +version: v9.0.1 compliance: --- @@ -28,7 +28,7 @@ compliance: {: toc-content-type="reference-architecture"} {: toc-industry="Technology"} {: toc-use-case="ITServiceManagement"} -{: toc-version="v9.0.0"} +{: toc-version="v9.0.1"} Quickstart deployment of the Power Virtual Server with VPC landing zone creates VPC services, a Power Virtual Server workspace, and interconnects them. It also deploys a Power Virtual Server of chosen T-shirt size or custom configuration. Supported Os are Aix, IBM i, and Linux images. diff --git a/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.md b/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.md index 24f79f60..fa95a5fc 100644 --- a/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.md +++ b/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.md @@ -1,7 +1,7 @@ --- copyright: years: 2024, 2025 -lastupdated: "2025-08-07" +lastupdated: "2025-09-08" keywords: subcollection: deployable-reference-architectures authors: @@ -15,7 +15,7 @@ image_source: https://github.com/terraform-ibm-modules/terraform-ibm-powervs-inf use-case: ITServiceManagement industry: Technology content-type: reference-architecture -version: v9.0.0 +version: v9.0.1 compliance: SAPCertified --- @@ -28,7 +28,7 @@ compliance: SAPCertified {: toc-industry="Technology"} {: toc-use-case="ITServiceManagement"} {: toc-compliance="SAPCertified"} -{: toc-version="v9.0.0"} +{: toc-version="v9.0.1"} The Standard deployment of the Power Virtual Server with VPC landing zone creates VPC services and a Power Virtual Server workspace and interconnects them. diff --git a/solutions/standard-plus-vsi/README.md b/solutions/standard-plus-vsi/README.md index 8260a11d..a4d2a336 100644 --- a/solutions/standard-plus-vsi/README.md +++ b/solutions/standard-plus-vsi/README.md @@ -55,6 +55,7 @@ This example sets up the following infrastructure: | Name | Source | Version | |------|--------|---------| +| [pi\_aix\_configure\_services](#module\_pi\_aix\_configure\_services) | ../../modules/powervs-vpc-landing-zone/submodules/ansible | n/a | | [pi\_scc\_wp\_agent](#module\_pi\_scc\_wp\_agent) | ../../modules/powervs-vpc-landing-zone/submodules/ansible | n/a | | [powervs\_instance](#module\_powervs\_instance) | terraform-ibm-modules/powervs-instance/ibm | 2.7.0 | | [standard](#module\_standard) | ../../modules/powervs-vpc-landing-zone | n/a | @@ -63,7 +64,6 @@ This example sets up the following infrastructure: | Name | Type | |------|------| -| [terraform_data.aix_init](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | | [ibm_iam_auth_token.auth_token](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.82.0/docs/data-sources/iam_auth_token) | data source | ### Inputs diff --git a/solutions/standard-plus-vsi/aix-init/aix_init.sh.tftpl b/solutions/standard-plus-vsi/aix-init/aix_init.sh.tftpl deleted file mode 100644 index ad2e7e31..00000000 --- a/solutions/standard-plus-vsi/aix-init/aix_init.sh.tftpl +++ /dev/null @@ -1,266 +0,0 @@ -#!/bin/ksh - -# Variables -EXTEND_ROOT_VOLUME_WWN=${pi_storage_configuration.0.wwns} -DATA_VOLUME_WWN=${pi_storage_configuration.1.wwns} -DATA_VOLUME_MOUNT_PATH=${pi_storage_configuration.1.mount} -DATAVG='${pi_storage_configuration.1.name}vg' -DATALV='${pi_storage_configuration.1.name}lv' -PROXY_IP_PORT=${network_services_config.squid.squid_server_ip_port} -NO_PROXY=${network_services_config.squid.no_proxy_hosts} -NFS_ENABLE=${network_services_config.nfs.enable} -NFS_MOUNT_POINT=${network_services_config.nfs.nfs_client_path} -NFS_HOST_OR_PATH=${network_services_config.nfs.nfs_server_path} -NFS_DOMAIN="test.com" -NFS_HOSTNAME="nfs_server" -NTP_ENABLE=${network_services_config.ntp.enable} -NTP_SERVER=${network_services_config.ntp.ntp_server_ip} -NTP_CONF="/etc/ntp.conf" -ETC_HOSTS="/etc/hosts" - -############################################################## -# Extend boot volume -############################################################## - -# Change rootvg physical partition limit if not already set -CHVG_LIMIT=$(lsvg rootvg | grep "MAX PPs per PV" | awk '{print $5}') -if [[ "$CHVG_LIMIT" -lt 1024 ]]; then - echo "Updating rootvg partition limit..." - chvg -t 16 rootvg -fi - -# Get hdisk for rootvg extension -while true; do - sleep 5 - cfgmgr - hdisk_name=$(lspv -u | grep -i $EXTEND_ROOT_VOLUME_WWN | awk '{ print $1 }') - if [[ -n $hdisk_name ]]; then - break - fi -done - -# Check if hdisk is already in rootvg -VGNAME=$(lspv $hdisk_name | awk '/VOLUME GROUP:/ {print $NF}') -if [[ "$VGNAME" != "rootvg" ]]; then - echo "Adding $hdisk_name to rootvg..." - chdev -l $hdisk_name -a pv=yes - cfgmgr - /usr/sbin/extendvg '-f' 'rootvg' $hdisk_name - for fs in / /usr /opt /var /tmp; do - echo "Ensuring $fs is extended by 4GB" - chfs -a size=+4G $fs - done -else - echo "$hdisk_name already part of rootvg." -fi - - -################################################################### -# Create Filesystem for data volume -################################################################### - -# Get hdisk for data volume -hdisk_name=$(lspv -u | grep -i $DATA_VOLUME_WWN | awk '{ print $1 }') -if [ -z "$hdisk_name" ]; then - echo "Error: Disk $DATA_VOLUME_WWN not found." - exit 1 -fi - -# Initialize disk only if not already a PV -PVTEST=$(lspv | grep $hdisk_name) -if [[ -z "$PVTEST" ]]; then - echo "Initializing $hdisk_name as a physical volume..." - chdev -l $hdisk_name -a pv=yes -fi - -# Check if VG exists -if ! lsvg $DATAVG >/dev/null 2>&1; then - echo "Creating volume group $DATAVG..." - mkvg -y $DATAVG $hdisk_name -else - echo "Volume group $DATAVG already exists." -fi - -# Check if LV exists -if ! ls -l /dev/$DATALV >/dev/null 2>&1; then - FREE_LPS=$(lsvg $DATAVG | grep "FREE PPs" | awk '{print $6}') - if [[ -z "$FREE_LPS" || "$FREE_LPS" -le 0 ]]; then - echo "No free space available in volume group $DATAVG." - exit 3 - fi - echo "Creating logical volume $DATALV using $FREE_LPS LPs..." - mklv -t jfs2 -y $DATALV $DATAVG $FREE_LPS -else - echo "Logical volume $DATALV already exists." -fi - -# Create mount point if it doesn't exist -if [[ ! -d "$DATA_VOLUME_MOUNT_PATH" ]]; then - echo "Creating mount point $DATA_VOLUME_MOUNT_PATH..." - mkdir -p $DATA_VOLUME_MOUNT_PATH -fi - -# Check if filesystem already exists and is in /etc/filesystems -if ! grep -q "$DATA_VOLUME_MOUNT_PATH" /etc/filesystems; then - echo "Creating filesystem on $DATALV mounted at $DATA_VOLUME_MOUNT_PATH..." - crfs -v jfs2 -d $DATALV -m $DATA_VOLUME_MOUNT_PATH -A yes -else - echo "Filesystem for $DATA_VOLUME_MOUNT_PATH already exists in /etc/filesystems." -fi - -# Ensure mount -mount | grep -q "$DATA_VOLUME_MOUNT_PATH" -if [ $? -ne 0 ]; then - echo "Mounting $DATA_VOLUME_MOUNT_PATH..." - mount $DATA_VOLUME_MOUNT_PATH -else - echo "$DATA_VOLUME_MOUNT_PATH is already mounted." -fi - -# Final check -echo "Filesystem status:" -df -g $DATA_VOLUME_MOUNT_PATH - - -################################################################### -# Configure proxy -################################################################### - -# Proxy settings -http_proxy="http://$PROXY_IP_PORT" -https_proxy="http://$PROXY_IP_PORT" -HTTP_PROXY="http://$PROXY_IP_PORT" -HTTPS_PROXY="http://$PROXY_IP_PORT" -no_proxy="$NO_PROXY" - -# System-wide configuration in /etc/profile -profile_file="/etc/profile" - -# Function to add proxy setting if it doesn't already exist -add_proxy_setting() { - local var_name="$1" - local var_value="$2" - # Check if the export line already exists in the profile file - if ! grep -q "export $var_name=$var_value" "$profile_file"; then - echo "export $var_name=$var_value" | tee -a "$profile_file" > /dev/null - fi -} - -# Add proxy settings to /etc/profile (system-wide, for all users) -add_proxy_setting "http_proxy" "$http_proxy" -add_proxy_setting "https_proxy" "$https_proxy" -add_proxy_setting "HTTP_PROXY" "$HTTP_PROXY" -add_proxy_setting "HTTPS_PROXY" "$HTTPS_PROXY" -add_proxy_setting "no_proxy" "$no_proxy" - -# Apply them immediately in current shell -export http_proxy="$http_proxy" -export https_proxy="$https_proxy" -export HTTP_PROXY="$HTTP_PROXY" -export HTTPS_PROXY="$HTTPS_PROXY" -export no_proxy="$no_proxy" - -################################################################### -# Install curl package -################################################################### -echo 'y' | /opt/freeware/bin/dnf install curl-7.53* - - -################################################################### -# Mount File storage share -################################################################### - -# Check if NFS_ENABLE is set to true -if [[ "$NFS_ENABLE" != "true" ]]; then - echo "NFS configuration is disabled (NFS_ENABLE=$NFS_ENABLE). Skipping setup." -else - - if [[ -z "$NFS_HOST_OR_PATH" ]]; then - echo "Usage: $0 " - exit 1 - fi - - # Parse NFS Host and 4th Octet, and set domain - NFS_IP=$(echo "$NFS_HOST_OR_PATH" | sed 's/:.*//') - FOURTH_OCTET=$(echo "$NFS_IP" | awk -F. '{print $4}') - - if [[ -z "$FOURTH_OCTET" || "$NFS_IP" != 10.30.40.* ]]; then - echo "Error: Invalid or unexpected NFS IP format: $NFS_IP" - exit 2 - fi - - HOST_ENTRY="10.30.40.$FOURTH_OCTET $NFS_HOSTNAME" - - chnfsdom "$NFS_DOMAIN" - - # Start NFS Services If Not Already Running - echo "Starting NFS services..." - startsrc -g nfs - echo "NFS services are already running." - - # Add NFS Server to /etc/hosts - if ! grep -q "$HOST_ENTRY" "$ETC_HOSTS"; then - echo "Adding host entry: $HOST_ENTRY" - echo "$HOST_ENTRY" >> "$ETC_HOSTS" - else - echo "Host entry already present: $HOST_ENTRY" - fi - - # Create Mount Point If It Doesn't Exist - if [[ ! -d "$NFS_MOUNT_POINT" ]]; then - echo "Creating mount point: $NFS_MOUNT_POINT" - mkdir -p "$NFS_MOUNT_POINT" - else - echo "Mount point already exists: $NFS_MOUNT_POINT" - fi - - # Mount NFS Share If Not Already Mounted - if ! mount | grep -wq "$NFS_MOUNT_POINT"; then - echo "Mounting NFS share using NFSv4..." - mount -o vers=4 "$NFS_HOST_OR_PATH" "$NFS_MOUNT_POINT" - if [[ $? -eq 0 ]]; then - echo "NFS share mounted successfully at $NFS_MOUNT_POINT" - else - echo "Error: Failed to mount NFS share" - exit 3 - fi - else - echo "NFS share is already mounted at $NFS_MOUNT_POINT" - fi -fi - -################################################################### -# Configure NTP -################################################################### - -# Check if the NTP server is already configured -if [ "$NTP_ENABLE" = true ]; then - if ! grep -q "server $NTP_SERVER" "$NTP_CONF"; then - echo "Setting NTP server to $NTP_SERVER..." - echo "server $NTP_SERVER" >> "$NTP_CONF" - else - echo "NTP server $NTP_SERVER is already configured." - fi - - # Check if the NTP service is running - NTP_STATUS=$(lssrc -s xntpd | awk 'NR>1 {print $4}') - if [ "$NTP_STATUS" != "active" ]; then - echo "Stopping and restarting NTP service..." - stopsrc -s xntpd - startsrc -s xntpd - else - echo "NTP service is already running." - fi - - echo "Setting NTP service to start automatically on reboot..." - chssys -s xntpd -a autorestart - - - # Verify NTP status - echo "Verifying NTP synchronization..." - ntpq -p - - echo "NTP configuration is complete." -else - echo "NTP configuration is disabled (NTP_ENABLE=$NTP_ENABLE). Skipping setup." -fi diff --git a/solutions/standard-plus-vsi/main.tf b/solutions/standard-plus-vsi/main.tf index 3a63b8e0..3cf7e29e 100644 --- a/solutions/standard-plus-vsi/main.tf +++ b/solutions/standard-plus-vsi/main.tf @@ -72,59 +72,61 @@ module "powervs_instance" { pi_network_services_config = local.pi_instance_os_type == "linux" ? local.network_services_config : null } -###################################################### -# AIX init if image name is 7xxx-xx-xx -###################################################### -resource "terraform_data" "aix_init" { - +module "pi_aix_configure_services" { + source = "../../modules/powervs-vpc-landing-zone/submodules/ansible" count = local.pi_instance_os_type == "aix" ? 1 : 0 depends_on = [module.standard, module.powervs_instance] - triggers_replace = { - "network_services_config" = local.network_services_config, - "pi_storage_configuration" = module.powervs_instance.pi_storage_configuration - } - connection { - type = "ssh" - user = "root" - bastion_host = module.standard.access_host_or_ip - host = module.powervs_instance.pi_instance_primary_ip - private_key = var.ssh_private_key - agent = false - timeout = "10m" - } + bastion_host_ip = module.standard.access_host_or_ip + ansible_host_or_ip = module.standard.ansible_host_or_ip + ssh_private_key = var.ssh_private_key + configure_ansible_host = false - # Create terraform scripts directory - provisioner "remote-exec" { - inline = ["mkdir -p /root/terraform_files", "chmod 777 /root/terraform_files", ] - } + src_script_template_name = "configure-aix-services/ansible_exec.sh.tftpl" + dst_script_file_name = "${var.prefix}-configure_aix_services_pi.sh" + + src_playbook_template_name = "configure-aix-services/playbook-configure-aix-services.yml.tftpl" + dst_playbook_file_name = "${var.prefix}-playbook-configure-aix-services-pi.yml" + + playbook_template_vars = { + EXTEND_ROOT_VOLUME_WWN = module.powervs_instance.pi_storage_configuration[0].wwns + DATA_VOLUME_WWN = module.powervs_instance.pi_storage_configuration[1].wwns + DATA_VOLUME_MOUNT_PATH = module.powervs_instance.pi_storage_configuration[1].mount + DATAVG = "${module.powervs_instance.pi_storage_configuration[1].name}vg" + DATALV = "${module.powervs_instance.pi_storage_configuration[1].name}lv" + + PROXY_IP_PORT = local.network_services_config.squid.squid_server_ip_port + NO_PROXY = local.network_services_config.squid.no_proxy_hosts + + NFS_ENABLE = local.network_services_config.nfs.enable + NFS_MOUNT_POINT = local.network_services_config.nfs.nfs_client_path + NFS_HOST_OR_PATH = local.network_services_config.nfs.nfs_server_path + + NTP_ENABLE = local.network_services_config.ntp.enable + NTP_SERVER = local.network_services_config.ntp.ntp_server_ip + + # hardcoded values for NFS configuration (dummy values) + NFS_DOMAIN = "test.com" + NFS_HOSTNAME = "nfs_server" + + DNS_ENABLE = local.network_services_config.dns.enable + DNS_SERVER_1 = local.network_services_config.dns.dns_server_ip - # Copy aix_init.sh shell file to ansible host - provisioner "file" { - content = templatefile("./aix-init/aix_init.sh.tftpl", - merge( - { "network_services_config" = local.network_services_config }, - { "pi_storage_configuration" = module.powervs_instance.pi_storage_configuration } - ) - ) - destination = "/root/terraform_files/aix_init.sh" - } - # Execute aix_ini.sh shell script to configure management services and create filesystem - provisioner "remote-exec" { - inline = [ - "chmod +x /root/terraform_files/aix_init.sh", - "/root/terraform_files/aix_init.sh", - ] } + src_inventory_template_name = "inventory.tftpl" + dst_inventory_file_name = "${var.prefix}-configure-aix-services-pi-inventory" + inventory_template_vars = { + host_or_ip = module.powervs_instance.pi_instance_primary_ip + } } module "pi_scc_wp_agent" { source = "../../modules/powervs-vpc-landing-zone/submodules/ansible" - depends_on = [module.standard, module.powervs_instance, terraform_data.aix_init] + depends_on = [module.standard, module.powervs_instance, module.pi_aix_configure_services] count = var.enable_scc_wp && contains(["aix", "linux"], local.pi_instance_os_type) ? 1 : 0 bastion_host_ip = module.standard.access_host_or_ip