deploy/ansible/roles-sap-os/2.6-sap-mounts/tasks/2.6.1-anf-mounts.yaml (809 lines of code) (raw):

# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # /*---------------------------------------------------------------------------8 # | | # | Perform the ANF system mounts | # | | # +------------------------------------4--------------------------------------*/ --- - name: "ANF Mount: Set the NFS Service name" ansible.builtin.set_fact: nfs_service: "{% if distribution_id in ['redhat8', 'redhat9'] %}nfs-server{% else %}{% if distribution_id == 'redhat7' %}nfs{% else %}{% if distribution_id == 'oraclelinux8' %}rpcbind{% else %}nfsserver{% endif %}{% endif %}{% endif %}" - name: "ANF Mount: Set the NFSmount options" ansible.builtin.set_fact: mnt_options: 'rw,nfsvers=4.1,hard,timeo=600,rsize=262144,wsize=262144,noatime,lock,_netdev,sec=sys' when: distribution_full_id not in ['redhat8.4', 'redhat8.6', 'redhat8.8', 'redhat9.0', 'redhat9.2', 'sles_sap15.2', 'sles_sap15.3', 'sles_sap15.4', 'sles_sap15.5', 'sles_sap15.6'] - name: "ANF Mount: Set the NFSmount options" ansible.builtin.set_fact: mnt_options: 'rw,nfsvers=4.1,hard,timeo=600,rsize=262144,wsize=262144,noatime,lock,_netdev,sec=sys,nconnect=8' when: distribution_full_id in ['redhat8.4', 'redhat8.6', 'redhat8.8', 'redhat9.0', 'redhat9.2', 'sles_sap15.2', 'sles_sap15.3', 'sles_sap15.4', 'sles_sap15.5', 'sles_sap15.6'] - name: "ANF Mount: Define this SID" ansible.builtin.set_fact: this_sid: { 'sid': '{{ sap_sid | upper }}', 'dbsid_uid': '{{ hdbadm_uid }}', 'sidadm_uid': '{{ sidadm_uid }}', 'ascs_inst_no': '{{ scs_instance_number }}', 'pas_inst_no': '{{ pas_instance_number }}', 'app_inst_no': '{{ app_instance_number }}' } - name: "ANF Mount: Create list of all_sap_mounts to support " ansible.builtin.set_fact: all_sap_mounts: "{% if MULTI_SIDS is defined %}{{ MULTI_SIDS }}{% else %}{{ all_sap_mounts | default([]) + [this_sid] }}{% endif %}" db_hosts: "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_DB') }}" - name: "ANF Mount: Ensure the NFS service is stopped" ansible.builtin.systemd: name: "{{ nfs_service }}" state: stopped when: - "'scs' in supported_tiers" - sap_mnt is not defined - sap_trans is not defined # /*---------------------------------------------------------------------------8 # | | # | Mount the ANF Volumes | # | Make sure to set the NFS domain in /etc/idmapd.conf on the VM to match the | # | default domain configuration on Azure NetApp Files: defaultv4iddomain.com. | # | and the mapping is set to nobody | # | We use tier in tasks as well, to treat any special scenarios that may arise| # +------------------------------------4--------------------------------------*/ # For additional information refer to the below URLs # https://docs.microsoft.com/en-us/azure/virtual-machines/workloads/sap/sap-hana-high-availability-netapp-files-suse#mount-the-azure-netapp-files-volume # https://docs.microsoft.com/en-us/azure/virtual-machines/workloads/sap/sap-hana-high-availability-netapp-files-red-hat#mount-the-azure-netapp-files-volume - name: "ANF Mount: NFS Domain Setting (ANF)" block: - name: "ANF Mount: Domain is configured as the default Azure NetApp Files domain" ansible.builtin.lineinfile: path: /etc/idmapd.conf regexp: '^[ #]*Domain = ' line: 'Domain = defaultv4iddomain.com' insertafter: '[General]' when: - tier == 'sapos' register: id_mapping_changed - name: "ANF Mount: Make sure that user mapping is set to 'nobody'" ansible.builtin.lineinfile: path: /etc/idmapd.conf regexp: '^[ #]*Nobody-User = ' line: 'Nobody-User = nobody' insertafter: '^[ #]*Nobody-User = ' when: - tier == 'sapos' register: id_mapping_changed - name: "ANF Mount: Make sure that group mapping is set to 'nobody'" ansible.builtin.lineinfile: path: /etc/idmapd.conf regexp: '^[ #]*Nobody-Group = ' line: 'Nobody-Group = nobody' insertafter: '^[ #]*Nobody-Group = ' when: - tier == 'sapos' register: id_mapping_changed when: - tier == 'sapos' - name: "ANF Mount: Set nfs4_disable_idmapping to Y" ansible.builtin.lineinfile: path: /etc/modprobe.d/nfs.conf line: 'options nfs nfs4_disable_idmapping=Y' create: true mode: 0644 when: - tier == 'sapos' - name: "ANF Mount: Ensure the services are restarted" block: - name: "AF Mount: Ensure the rpcbind service is restarted" ansible.builtin.systemd: name: rpcbind state: restarted - name: "ANF Mount: Ensure the NFS ID Map service is restarted" ansible.builtin.systemd: name: "nfs-idmapd" daemon-reload: true state: restarted - name: "ANF Mount: Pause for 5 seconds" ansible.builtin.pause: seconds: 5 - name: "ANF Mount: Ensure the NFS service is restarted" ansible.builtin.systemd: name: "{{ nfs_service }}" state: restarted when: - id_mapping_changed is changed # /*---------------------------------------------------------------------------8 # | | # | Prepare for the /usr/sap mounts | # | Create temporary directory structure | # | Mount the share, create the directory structure on share | # | Unmount and clean up temporary directory structure | # | | # +------------------------------------4--------------------------------------*/ - name: "ANF Mount: install:Get the Server name list" ansible.builtin.set_fact: first_app_server_temp: "{{ first_app_server_temp | default([]) + [item] }}" with_items: - "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_PAS') }}" - "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_DB') }}" # 'target_nodes': ['app','pas'], - will be set to only pas as we do not # have the ability to set the different app instance numbers for multiple nodes # todo: fix this so that we validate that the app_instance_number is not the # same as the pas_instance_number. If it is the same, then we should only # mount the pas instance. - name: "ANF Mount: usr/sap" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'usrsap', 'temppath': 'tmpusersap', 'mount': '{{ usr_sap_mountpoint }}', 'opts': 'rw,hard,rsize=65536,wsize=65536,sec=sys,vers=4.1,tcp', 'path': '/usr/sap', 'set_chattr_on_dir': false, 'target_nodes': ['pas'], 'create_temp_folders': false } vars: primary_host: "{{ first_app_server_temp | first }}" when: - tier == 'sapos' - usr_sap_mountpoint is defined # /*---------------------------------------------------------------------------8 # | | # | Prepare for the sap_mnt mounts | # | Create temporary directory structure | # | Mount the share, create the directory structure on share | # | Unmount and clean up temporary directory structure | # | | # +------------------------------------4--------------------------------------*/ - name: "ANF Mount: (sapmnt)" block: - name: "ANF Mount: Create /saptmp" ansible.builtin.file: path: "/saptmp" state: directory mode: 0755 group: sapsys - name: "ANF Mount: (sapmnt)" block: - name: "ANF Mount: Filesystems on ANF (sapmnt)" ansible.posix.mount: src: "{{ sap_mnt }}" path: "/saptmp" fstype: "nfs4" opts: "rw,hard,rsize=65536,wsize=65536,sec=sys,vers=4.1,tcp" state: mounted rescue: - name: "ANF Mount: Clear the cache of the nfsidmap daemon (ANF)" ansible.builtin.shell: | nfsidmap -c - name: "ANF Mount: Ensure the rpcbind service is restarted" ansible.builtin.systemd: name: rpcbind daemon-reload: true state: restarted - name: "ANF Mount: Create SAP Directories (spmnt & usrsap)" ansible.builtin.file: path: "{{ item.path }}" state: directory mode: 0755 loop: - { path: '/saptmp/sapmnt{{ sap_sid | upper }}' } - { path: '/saptmp/usrsap{{ sap_sid | upper }}' } - { path: '/saptmp/usrsap{{ sap_sid | upper }}{{ instance_type | lower }}{{ scs_instance_number }}' } - { path: '/saptmp/usrsap{{ sap_sid | upper }}ers{{ ers_instance_number }}' } - { path: '/saptmp/usrsap{{ sap_sid | upper }}sys' } - name: "ANF Mount: Create SAP Directories (ANF)" ansible.builtin.file: path: "/saptmp/sapmnt{{ item.sid | upper }}" state: directory mode: 0755 loop: "{{ MULTI_SIDS }}" when: MULTI_SIDS is defined - name: "ANF Mount: Unmount file systems (sap_mnt)" ansible.posix.mount: src: "{{ sap_mnt }}" path: "/saptmp" state: unmounted - name: "ANF Mount: Delete locally created SAP Directories" ansible.builtin.file: path: "{{ item.path }}" state: absent loop: - { path: '/saptmp/sapmnt{{ sap_sid | upper }}' } - { path: '/saptmp/usrsap{{ sap_sid | upper }}' } - { path: '/saptmp/usrsap{{ sap_sid | upper }}{{ instance_type | lower }}{{ scs_instance_number }}' } - { path: '/saptmp/usrsap{{ sap_sid | upper }}ers{{ ers_instance_number }}' } - { path: '/saptmp/usrsap{{ sap_sid | upper }}sys' } - name: "ANF Mount: Remove SAP Directories (ANF)" ansible.builtin.file: path: "/saptmp/sapmnt{{ item.sid | upper }}" state: absent loop: "{{ MULTI_SIDS }}" when: MULTI_SIDS is defined - name: "ANF Mount: Cleanup fstab and directory (sap_mnt)" ansible.posix.mount: src: "{{ sap_mnt }}" path: "/saptmp" fstype: "nfs4" opts: "rw,hard,rsize=65536,wsize=65536,sec=sys,vers=4.1,tcp" state: absent when: - tier == 'sapos' - "'scs' in supported_tiers" - sap_mnt is defined # /*---------------------------------------------------------------------------8 # | | # | Perform the sap_mnt mounts | # | Create directories and make them immutable | # | | # +------------------------------------4--------------------------------------*/ - name: "ANF Mount: Create SAP Directories (sapmnt)" ansible.builtin.file: owner: "{{ item.sidadm_uid }}" group: sapsys mode: 0755 path: "/sapmnt/{{ item.sid }}" state: directory register: is_created_now loop: "{{ all_sap_mounts }}" when: - tier == 'sapos' - node_tier in ['app','scs','ers', 'pas'] or 'scs' in supported_tiers - sap_mnt is defined - name: "ANF Mount: Change attribute only when we create SAP Directories (sap_mnt)" ansible.builtin.file: path: "{{ item.item.path }}" state: directory mode: 0755 attr: i+ loop: "{{ is_created_now.results }}" when: - tier == 'sapos' - item.item is changed register: set_immutable_attribute - name: "ANF Mount: Create SAP Directories (scs & ers)" ansible.builtin.file: path: "{{ item.path }}" state: directory owner: '{{ sidadm_uid }}' group: sapsys mode: 0755 loop: - { path: '/usr/sap/{{ sap_sid | upper }}' } - { path: '/usr/sap/{{ sap_sid | upper }}/SYS' } - { path: '/usr/sap/{{ sap_sid | upper }}/{{ instance_type | upper }}{{ scs_instance_number }}' } - { path: '/usr/sap/{{ sap_sid | upper }}/ERS{{ ers_instance_number }}' } when: - tier == 'sapos' - node_tier in ['scs','ers'] or 'scs' in supported_tiers - sap_mnt is defined - MULTI_SIDS is undefined register: is_created_now3 - name: "ANF Mount: Change attribute only when we create SAP Directories (scs & ers)" ansible.builtin.file: path: "{{ item.item.path }}" state: directory mode: 0755 attr: i+ loop: "{{ is_created_now3.results }}" when: - tier == 'sapos' - item.item is changed register: set_immutable_attribute - name: "ANF Mount: Debug" ansible.builtin.debug: msg: 'isHA:{{ scs_high_availability }} | node_tier:{{ node_tier }} | tier:{{ tier }} | sapmnt:{{ sap_mnt }}' - name: "ANF Mount: sapmnt/{{ sap_sid | upper }} - Distributed Non-HA" ansible.posix.mount: src: "{{ item.src }}" path: "{{ item.path }}" fstype: "{{ item.type }}" opts: 'rw,hard,rsize=65536,wsize=65536,sec=sys,vers=4.1,tcp' state: mounted loop: - { type: 'nfs4', src: '{{ sap_mnt }}/sapmnt{{ sap_sid | upper }}', path: '/sapmnt/{{ sap_sid | upper }}' } when: - tier == 'sapos' - sap_mnt is defined - not scs_high_availability - ansible_play_hosts_all | length > 1 - node_tier != 'hana' - name: "ANF Mount: sapmnt/{{ sap_sid | upper }} - Single instance" ansible.posix.mount: src: "{{ item.src }}" path: "{{ item.path }}" fstype: "{{ item.type }}" opts: 'rw,hard,rsize=65536,wsize=65536,sec=sys,vers=4.1,tcp' state: mounted loop: - { type: 'nfs4', src: '{{ sap_mnt }}/sapmnt{{ sap_sid | upper }}', path: '/sapmnt/{{ sap_sid | upper }}' } when: - tier == 'sapos' - sap_mnt is defined - not scs_high_availability - ansible_play_hosts_all | length == 1 - name: "ANF Mount: sapmnt/{{ sap_sid | upper }} - Standalone MULTI_SIDS" become: true become_user: root ansible.posix.mount: src: "{{ sap_mnt }}/sapmnt{{ item.sid }}" path: "/sapmnt/{{ item.sid }}" fstype: 'nfs4' opts: 'rw,hard,rsize=65536,wsize=65536,sec=sys,vers=4.1,tcp' state: mounted loop: "{{ MULTI_SIDS }}" when: - not scs_high_availability - sap_mnt is defined - MULTI_SIDS is defined - name: "ANF Mount: sapmnt/{{ sap_sid | upper }} - High Availability" ansible.posix.mount: src: "{{ item.src }}" path: "{{ item.path }}" fstype: "{{ item.type }}" opts: 'rw,hard,rsize=65536,wsize=65536,sec=sys,vers=4.1,tcp' state: mounted loop: - { type: 'nfs4', src: '{{ sap_mnt }}/sapmnt{{ sap_sid | upper }}', path: '/sapmnt/{{ sap_sid | upper }}' } when: - scs_high_availability - tier in ['sapos'] - node_tier != 'hana' - sap_mnt is defined - name: "ANF Mount: Set Permissons on /sapmnt directory" ansible.builtin.file: owner: '{{ sidadm_uid }}' group: sapsys path: "/sapmnt/{{ sap_sid | upper }}" state: directory recurse: true - name: "ANF Mount: usr/sap/{{ sap_sid | upper }}/SYS" ansible.posix.mount: src: "{{ item.src }}" path: "{{ item.path }}" fstype: "{{ item.type }}" opts: 'rw,hard,rsize=65536,wsize=65536,sec=sys,vers=4.1,tcp' state: mounted loop: - { type: 'nfs4', src: '{{ sap_mnt }}/usrsap{{ sap_sid | upper }}sys', path: '/usr/sap/{{ sap_sid | upper }}/SYS' } when: - scs_high_availability - tier in ['sapos'] - node_tier in ['scs','ers'] - sap_mnt is defined # /*---------------------------------------------------------------------------8 # | | # | Prepare for the sap_trans, install mounts | # | Create temporary directory structure | # | Mount the share, create the directory structure on share | # | Unmount and clean up temporary directory structure | # | | # +------------------------------------4--------------------------------------*/ - name: "ANF Mount: install:Get the Server name list" ansible.builtin.set_fact: first_server_temp: "{{ first_server_temp | default([]) + [item] }}" with_items: - "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_SCS') }}" - "{{ query('inventory_hostnames', '{{ sap_sid | upper }}_DB') }}" - name: "ANF Mount: sap_trans" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'trans', 'temppath': 'saptrans', 'mount': '{{ sap_trans }}', 'opts': 'rw,hard,rsize=65536,wsize=65536,sec=sys,vers=4.1,tcp', 'path': '/usr/sap/trans', 'permissions': '0775', 'set_chattr_on_dir': false, 'target_nodes': ['app','pas', 'ers', 'scs'], 'create_temp_folders': false } vars: primary_host: "{{ first_server_temp | first }}" when: - tier == 'sapos' - sap_trans is defined - name: "ANF Mount: install" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'install', 'temppath': 'sapinstall', 'folder': '{{ bom_base_name }}', 'mount': '{{ usr_sap_install_mountpoint }}', 'opts': 'rw,hard,rsize=65536,wsize=65536,sec=sys,vers=4.1,tcp', 'path': '/usr/sap/install', 'permissions': '0775', 'set_chattr_on_dir': false, 'target_nodes': ['all'], 'create_temp_folders': true } vars: primary_host: "{{ first_server_temp | first }}" when: - tier == 'sapos' - usr_sap_install_mountpoint is defined # /*---------------------------------------------------------------------------8 # | | # | Prepare the OS for running SAP HANA on | # | Azure NetApp Files with NFS | # | | # +------------------------------------4--------------------------------------*/ - name: "ANF Mount: Prepare the OS for running SAP HANA on Azure NetApp with NFS" block: - name: "ANF Mount: Create configuration file for the NetApp configuration settings" ansible.builtin.blockinfile: path: /etc/sysctl.d/91-NetApp-HANA.conf backup: true create: true mode: 0644 marker: "# {mark} HANA NetApp configuration high availability" block: | net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.rmem_default = 16777216 net.core.wmem_default = 16777216 net.core.optmem_max = 16777216 net.ipv4.tcp_rmem = 4096 131072 16777216 net.ipv4.tcp_wmem = 4096 16384 16777216 net.core.netdev_max_backlog = 300000 net.ipv4.tcp_slow_start_after_idle=0 net.ipv4.tcp_no_metrics_save = 1 net.ipv4.tcp_moderate_rcvbuf = 1 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_sack = 1 when: - node_tier == 'hana' - name: "Backward Compatibility - Check required Database HA variables" ansible.builtin.set_fact: database_high_availability: "{{ db_high_availability | default(false) }}" when: - db_high_availability is defined - database_high_availability is not defined - name: "ANF Mount: Create configuration file for the NetApp configuration settings" ansible.builtin.blockinfile: path: /etc/sysctl.d/91-NetApp-HANA.conf backup: true create: true mode: 0644 marker: "# {mark} HANA NetApp configuration standalone" block: | net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.rmem_default = 16777216 net.core.wmem_default = 16777216 net.core.optmem_max = 16777216 net.ipv4.tcp_rmem = 4096 131072 16777216 net.ipv4.tcp_wmem = 4096 16384 16777216 net.core.netdev_max_backlog = 300000 net.ipv4.tcp_slow_start_after_idle=0 net.ipv4.tcp_no_metrics_save = 1 net.ipv4.tcp_moderate_rcvbuf = 1 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_timestamps = 1 net.ipv4.tcp_sack = 1 when: - node_tier == 'hana' - not database_high_availability - name: "ANF Mount: Create configuration file with additional optimization settings" ansible.builtin.blockinfile: path: /etc/sysctl.d/ms-az.conf backup: true create: true mode: 0644 marker: "# {mark} HANA NetApp optimizations" block: | net.ipv6.conf.all.disable_ipv6 = 1 net.ipv4.tcp_max_syn_backlog = 16348 net.ipv4.conf.all.rp_filter = 0 sunrpc.tcp_slot_table_entries = 128 vm.swappiness=10 when: - node_tier == 'hana' # /*-----------------------------------------------------------------------8 # | Configure the maximum number of (TCP) RPC requests that can be in | # | flight at a time (to the NFS server) to be 128 | # |--------------------------------4--------------------------------------*/ - name: "ANF Mount: configure the maximum number of RPC requests for the NFS session" ansible.builtin.blockinfile: path: /etc/modprobe.d/sunrpc.conf backup: true create: true mode: 0644 marker: "# {mark} NFS RPC Connections" block: "options sunrpc tcp_max_slot_table_entries=128" when: - node_tier == 'hana' when: - tier == 'sapos' - node_tier == 'hana' # /*---------------------------------------------------------------------------8 # | | # | ANF Mount: Run tasks for non-scale out setups | # | | # +------------------------------------4--------------------------------------*/ # Standard block tasks for non scale out setups - name: "ANF Mount: Run tasks for non-scale out HANA setups" when: - not database_scale_out - tier == 'sapos' - node_tier == 'hana' block: - name: "ANF Mount: Create /hana folder" ansible.builtin.file: path: /hana mode: 0755 state: directory group: sapsys - name: "ANF Mount: HANA data" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'data', 'temppath': 'hanadata', 'folder': 'hanadata', 'mount': '{{ hana_data_mountpoint[0] }}', 'opts': '{{ mnt_options }}', 'path': '/hana/data', 'permissions': '0755', 'set_chattr_on_dir': false, 'target_nodes' : ['hana'], 'create_temp_folders': true } vars: primary_host: "{{ db_hosts[0] }}" when: - hana_data_mountpoint is defined - hana_data_mountpoint | length > 0 - ansible_hostname == db_hosts[0] - name: "ANF Mount: HANA log" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'log', 'temppath': 'hanalog', 'folder': 'hanalog', 'mount' : '{{ hana_log_mountpoint[0] }}', 'opts': '{{ mnt_options }}', 'path' : '/hana/log', 'permissions': '0755', 'set_chattr_on_dir': false, 'target_nodes': ['hana'], 'create_temp_folders': true } vars: primary_host: "{{ db_hosts[0] }}" when: - hana_log_mountpoint is defined - hana_log_mountpoint | length > 0 - ansible_hostname == db_hosts[0] - name: "ANF Mount: HANA shared" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'shared', 'temppath': 'hanashared', 'folder': 'hanashared', 'mount': '{{ hana_shared_mountpoint[0] }}', 'opts': '{{ mnt_options }}', 'path': '/hana/shared', 'permissions': '0775', 'set_chattr_on_dir': false, 'target_nodes' : ['hana'], 'create_temp_folders': true } vars: primary_host: "{{ db_hosts[0] }}" when: - hana_shared_mountpoint is defined - hana_shared_mountpoint | length > 0 - not database_scale_out - name: "ANF Mount: HANA data (secondary)" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'data', 'temppath': 'hanadata', 'folder': 'hanadata', 'mount': '{{ hana_data_mountpoint[1] }}', 'opts': '{{ mnt_options }}', 'path': '/hana/data', 'permissions': '0755', 'set_chattr_on_dir': false, 'target_nodes' : ['hana'], 'create_temp_folders': true } vars: primary_host: "{{ db_hosts[1] }}" when: - hana_data_mountpoint is defined - hana_data_mountpoint | length > 1 - db_hosts | length == 2 - ansible_hostname == db_hosts[1] - name: "ANF Mount: HANA log (secondary)" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'log', 'temppath': 'hanalog', 'folder': 'hanalog', 'mount' : '{{ hana_log_mountpoint[1] }}', 'opts': '{{ mnt_options }}', 'path' : '/hana/log', 'permissions': '0755', 'set_chattr_on_dir': false, 'target_nodes': ['hana'], 'create_temp_folders': true } vars: primary_host: "{{ db_hosts[1] }}" when: - hana_log_mountpoint is defined - hana_log_mountpoint | length > 1 - db_hosts | length ==2 - ansible_hostname == db_hosts[1] - name: "ANF Mount: HANA shared (secondary)" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'shared', 'temppath': 'hanashared', 'folder': 'hanashared', 'mount': '{{ hana_shared_mountpoint[1] }}', 'opts': '{{ mnt_options }}', 'path': '/hana/shared', 'permissions': '0775', 'set_chattr_on_dir': false, 'target_nodes' : ['hana'], 'create_temp_folders': true } vars: primary_host: "{{ db_hosts[1] }}" when: - hana_shared_mountpoint is defined - hana_shared_mountpoint | length > 1 - not database_scale_out - name: "ANF Mount: Set Permissons on HANA Directories ({{ item.path }})" ansible.builtin.file: owner: '{{ hdbadm_uid }}' group: sapsys path: "{{ item.path }}" state: directory recurse: true loop: - { 'path': '/hana/data' } - { 'path': '/hana/log' } - { 'path': '/hana/shared' } # /*---------------------------------------------------------------------------8 # | | # | ANF Mount: Run tasks for scale out setups | # | | # +------------------------------------4--------------------------------------*/ # Run this block set when database_scale_out is true # when database_high_availability is true, we need two values for hana_shared_mountpoint which will be mounted on alternative nodes denoting two sites. # When database_high_availability is false/undefined, only one value of hana_shared_mountpoint is used and mounted on all HANA hosts. - name: "ANF Mount: Run tasks for scale out HANA setups" when: - database_scale_out - tier == 'sapos' - node_tier == 'hana' block: - name: "ANF Mount: Scale Out - Create SAP Directories" ansible.builtin.file: owner: '{{ hdbadm_uid }}' group: sapsys mode: 0755 path: "{{ item.path }}" state: directory with_items: # Variables are defined in /deploy/ansible/var/ansible-input-api.yaml file - { path: '{{ hana_log_basepath }}' } - { path: '{{ hana_shared_basepath }}' } - { path: '{{ hana_usrsap_basepath }}' } - { path: '{{ hana_data_basepath }}'} # This only runs for HANA Scale out with standby node configuration # Only first HANA shared volume is used. - name: "ANF Mount: HANA shared - Scale out - Shared storage with stand-by" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'shared', 'temppath': 'shared', # change folder to match the mount folder within the share 'folder': 'shared', 'mount': '{{ hana_shared_mountpoint[0] }}', 'opts': '{{ mnt_options }}', 'path': '{{ hana_shared_basepath }}', 'permissions': '0775', 'set_chattr_on_dir': false, 'target_nodes' : ['hana'], 'create_temp_folders': true } vars: primary_host: "{{ ansible_hostname }}" when: - hana_shared_mountpoint is defined - hana_shared_mountpoint | length > 0 - not database_high_availability # This runs for HANA scale out with HSR & Pacemaker. # We need two HANA shared volumes, one for each site - name: "ANF Mount: HANA shared - Scale out - HSR & Pacemaker" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'shared', 'temppath': 'shared', # change folder to match the mount folder within the share 'folder': 'shared', # Logic : hana_shared_mountpoint[0] goes on odd numbered HANA hosts and hana_shared_mountpoint[1] goes on even numbered HANA hosts. # 'mount': "{% if ansible_hostname in query('inventory_hostnames', '{{ sap_sid | upper }}_DB')[0::2] %}{{ hana_shared_mountpoint[0] }}{% else %}{{ hana_shared_mountpoint[1] }}{% endif %}", 'mount': "{% if site | default('SITE1') == 'SITE1' %}{{ hana_shared_mountpoint[0] }}{% else %}{{ hana_shared_mountpoint[1] }}{% endif %}", 'opts': '{{ mnt_options }}', 'path': '{{ hana_shared_basepath }}', 'permissions': '0775', 'set_chattr_on_dir': false, 'target_nodes' : ['hana'], 'create_temp_folders': true } vars: primary_host: "{{ ansible_hostname }}" when: - hana_shared_mountpoint is defined - hana_shared_mountpoint | length > 1 - database_high_availability # This runs for unique folder path within corresponding /hana/shared per node for Scale out with Standby. # Scale out with Shared storage and stand-by will always use /usr/sap/<SID> derived from /hana/shared directory. /usr/sap base can be on root file system or a small disk to store supporting SAP binaries. # Note: For Scale out - HSR & Pacemaker, we recommend Premium SSD/V2 at the moment. Support for ANF shares will be added in the near future - name: "ANF Mount: usrsap - Scale out - Shared storage with stand-by" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml loop: - { 'type': 'usrsap', 'temppath': 'usrsap', 'folder': "usr-sap-hanadb{{ lookup('ansible.utils.index_of', db_hosts, 'eq', ansible_hostname) }}", 'mount': '{{ hana_shared_mountpoint[0] }}', 'opts': '{{ mnt_options }}', 'path': '{{ hana_usrsap_basepath }}', 'permissions': '0775', 'set_chattr_on_dir': false, 'target_nodes' : ['hana'], 'create_temp_folders': true } vars: primary_host: "{{ ansible_hostname }}" when: - hana_shared_mountpoint is defined - hana_shared_mountpoint | length == 1 # For Scale out without HSR/pacemaker. Relies on ANF + hot spare to provide HA. - not database_high_availability # This runs for HANA Scale out - Shared storage with Stand by. Since the /hana/data & /hana/log is shared across HANA nodes # This builds a list of unique hana data mountpoints for each of the HANA hosts - name: "ANF Mount: HANA Data - Scale out - Shared storage with stand-by - Create mount list" block: - name: "Initialize HANA Data mountpoints" ansible.builtin.set_fact: hana_data_scaleout_mountpoint: [] - name: "Build HANA Data mountpoints" ansible.builtin.set_fact: # hana_data_mountpoint: "{{ hana_data_mountpoint | default([]) + [item] }}" hana_data_scaleout_mountpoint: "{{ hana_data_scaleout_mountpoint + dataupdate }}" loop: "{{ hana_data_mountpoint }}" loop_control: index_var: my_index # Note the object structure and specific key:pair value. Do not modify those hard coded. vars: dataupdate: - { type: 'data', temppath: 'hanadata', folder: 'hanadata', mount: "{{ item }}", opts: "{{ mnt_options }}", path: "{{ hana_data_basepath + '/mnt0000' + ( my_index + 1 )| string }}", permissions: '0775', set_chattr_on_dir: false, target_nodes: ['hana'], create_temp_folders: 'true' } when: - hana_data_mountpoint is defined - not database_high_availability - name: "DEBUG:ANF Mount: HANA Data - Scale out - Shared storage with stand-by - Create mount list" ansible.builtin.debug: var: hana_data_scaleout_mountpoint verbosity: 2 when: - hana_data_scaleout_mountpoint is defined - name: "ANF Mount: HANA Data - Scale out - Shared storage with stand-by" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml # Do not change this to loop:. It Breaks. i don't know why but this modification only seems to work with with_items: despite multiple formatting attempts. with_items: - "{{ hana_data_scaleout_mountpoint | list }}" vars: primary_host: "{{ ansible_hostname }}" when: - hana_data_mountpoint is defined - not database_high_availability # This runs for HANA Scale out - Shared storage with Stand by. Since the /hana/data & /hana/log is shared across HANA nodes # This builds a list of unique hana data mountpoints for each of the HANA hosts - name: "ANF Mount: HANA Log - Scale out - Shared storage with stand-by - Create mount list" block: - name: "Initialize HANA Log mountpoints" ansible.builtin.set_fact: hana_log_scaleout_mountpoint: [] - name: "Build HANA log mountpoints" ansible.builtin.set_fact: hana_log_scaleout_mountpoint: "{{ hana_log_scaleout_mountpoint + logupdate }}" loop: "{{ hana_log_mountpoint }}" loop_control: index_var: my_index # Note the object structure and specific key:pair value. Do not modify those hard coded. vars: logupdate: - { type: 'log', temppath: 'hanalog', folder: 'hanalog', mount: "{{ item }}", opts: "{{ mnt_options }}", path: "{{ '/hana/log/' + (db_sid | upper ) + '/mnt0000' + ( my_index + 1 )| string }}", permissions: '0775', set_chattr_on_dir: false, target_nodes: ['hana'], create_temp_folders: 'true' } when: - hana_log_mountpoint is defined - name: "DEBUG:ANF Mount: HANA Log - Scale out - Shared storage with stand-by - Create mount list" ansible.builtin.debug: var: hana_log_scaleout_mountpoint verbosity: 2 - name: "ANF Mount: HANA Log - Scale out - Shared storage with stand-by" ansible.builtin.include_tasks: 2.6.1.1-anf-mount.yaml # Do not change this to loop:. It Breaks. i don't know why but this modification only seems to work with with_items: despite multiple formatting attempts. with_items: - "{{ hana_log_scaleout_mountpoint | list }}" vars: primary_host: "{{ ansible_hostname }}" when: - hana_log_mountpoint is defined - name: "ANF Mount: Set Permissons on HANA Directories ({{ item.path }})" ansible.builtin.file: owner: '{{ hdbadm_uid }}' group: sapsys path: "{{ item.path }}" state: directory recurse: true with_items: - { 'path': '{{ hana_shared_basepath }}' } - { 'path': '{{ hana_usrsap_basepath }}' } - name: "ANF Mount: Set Permissons on HANA Directories ({{ item.path }})" ansible.builtin.file: owner: '{{ hdbadm_uid }}' group: sapsys path: "{{ item.path }}" state: directory recurse: true with_items: - "{{ hana_log_scaleout_mountpoint }}" when: - hana_log_scaleout_mountpoint is defined - name: "ANF Mount: Set Permissons on HANA Directories ({{ item.path }})" ansible.builtin.file: owner: '{{ hdbadm_uid }}' group: sapsys path: "{{ item.path }}" state: directory recurse: true with_items: - "{{ hana_data_scaleout_mountpoint }}" when: - hana_data_scaleout_mountpoint is defined ...