diff --git a/roles/sap_ha_pacemaker_cluster/README.md b/roles/sap_ha_pacemaker_cluster/README.md
index 6cf0c731a..eb5a60660 100644
--- a/roles/sap_ha_pacemaker_cluster/README.md
+++ b/roles/sap_ha_pacemaker_cluster/README.md
@@ -427,9 +427,9 @@ sap_ha_pacemaker_cluster_resource_defaults:
### sap_ha_pacemaker_cluster_vip_client_interface
- _Type:_ `str`
-- _Default:_ `eth0`
OS device name of the network interface to use for the Virtual IP configuration.
+When there is only one interface on the system, its name will be used by default.
### sap_ha_pacemaker_cluster_vip_hana_primary_ip_address
diff --git a/roles/sap_ha_pacemaker_cluster/defaults/main.yml b/roles/sap_ha_pacemaker_cluster/defaults/main.yml
index 9b208d45a..a95e171b8 100644
--- a/roles/sap_ha_pacemaker_cluster/defaults/main.yml
+++ b/roles/sap_ha_pacemaker_cluster/defaults/main.yml
@@ -98,7 +98,7 @@ sap_ha_pacemaker_cluster_fence_options:
### VIP resource default patterns
sap_ha_pacemaker_cluster_vip_resource_agent: "ocf:heartbeat:IPaddr2"
-sap_ha_pacemaker_cluster_vip_client_interface: eth0
+sap_ha_pacemaker_cluster_vip_client_interface: ''
# Multiple VIP parameters can be defined and will be combined.
# See tasks/include_construct_vip_resources.yml
diff --git a/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml b/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml
index a2035e47a..5a394c0ae 100644
--- a/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml
+++ b/roles/sap_ha_pacemaker_cluster/meta/argument_specs.yml
@@ -325,9 +325,9 @@ argument_specs:
# type: str
sap_ha_pacemaker_cluster_vip_client_interface:
- default: eth0
description:
- OS device name of the network interface to use for the Virtual IP configuration.
+ - When there is only one interface on the system, its name will be used by default.
required: false
type: str
diff --git a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml
index 5217de9e8..98a49b57c 100644
--- a/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml
+++ b/roles/sap_ha_pacemaker_cluster/tasks/construct_vars_vip_resources_default.yml
@@ -13,5 +13,7 @@
- attrs:
- name: ip
value: "{{ vip_list_item.value | quote }}"
+ - name: nic
+ value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}"
when:
- __sap_ha_pacemaker_cluster_vip_resource_id not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id'))
diff --git a/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml b/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml
index ab3e1bb74..f132a6738 100644
--- a/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml
+++ b/roles/sap_ha_pacemaker_cluster/tasks/include_vars_common.yml
@@ -7,6 +7,24 @@
ansible.builtin.setup:
gather_subset: hardware,interfaces
+# Multi-NIC:
+# Find out if there is more than one interface present, this will
+# be used for determining the target NIC for VIP configurations.
+# Assumption: The local loopback "lo" is always in the list.
+- name: "SAP HA Prepare Pacemaker - Set multi-NIC when more than one interface is found"
+ ansible.builtin.set_fact:
+ __sap_ha_pacemaker_cluster_nic_multi_bool: true
+ when:
+ - ansible_interfaces | length > 2
+
+- name: "SAP HA Prepare Pacemaker - Set interface name when only one interface is present"
+ ansible.builtin.set_fact:
+ sap_ha_pacemaker_cluster_vip_client_interface: "{{ ansible_default_ipv4.interface }}"
+ when:
+ - not __sap_ha_pacemaker_cluster_nic_multi_bool
+ - sap_ha_pacemaker_cluster_vip_client_interface == ''
+
+
# Include vars files based on the environment.
# Respect order for potential variable precedence.
- name: "SAP HA Prepare Pacemaker - Include environment specific variables"
diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml
index 7cec51de1..c34cfac8f 100644
--- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml
+++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_aws_ec2_vs.yml
@@ -12,6 +12,8 @@
- attrs:
- name: ip
value: "{{ vip_list_item.value }}"
+ - name: nic
+ value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}"
when:
- vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id'))
- (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or
diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml
index da995eae2..97b662d67 100644
--- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml
+++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_ibmcloud_powervs.yml
@@ -12,6 +12,8 @@
- attrs:
- name: ip
value: "{{ vip_list_item.value }}"
+ - name: nic
+ value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}"
when:
- vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id'))
- (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or
diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml
index 34982f29b..244532aeb 100644
--- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml
+++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_cloud_msazure_vm.yml
@@ -12,6 +12,8 @@
- attrs:
- name: ip
value: "{{ vip_list_item.value }}"
+ - name: nic
+ value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}"
when:
- vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id'))
- (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or
diff --git a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml
index da995eae2..97b662d67 100644
--- a/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml
+++ b/roles/sap_ha_pacemaker_cluster/tasks/platform/construct_vars_vip_resources_hyp_ibmpower_vm.yml
@@ -12,6 +12,8 @@
- attrs:
- name: ip
value: "{{ vip_list_item.value }}"
+ - name: nic
+ value: "{{ sap_ha_pacemaker_cluster_vip_client_interface }}"
when:
- vip_list_item.key not in (__sap_ha_pacemaker_cluster_resource_primitives | map(attribute='id'))
- (sap_ha_pacemaker_cluster_vip_method == 'ipaddr') or
diff --git a/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml b/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml
index 2ae0ed659..6d77a1c67 100644
--- a/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml
+++ b/roles/sap_ha_pacemaker_cluster/tasks/validate_input_parameters.yml
@@ -1,30 +1,92 @@
---
# The SAP ID must follow a strict format and not use reserved special values
-# TODO: This check may be better placed in a SAP role earlier in the chain...
-- name: "SAP HA Prepare Pacemaker - Validate SAP System ID (SAP HANA)"
+- name: "SAP HA Prepare Pacemaker - (SAP HANA) Validate SAP System ID"
ansible.builtin.assert:
that:
- sap_ha_pacemaker_cluster_hana_sid | length == 3
- sap_ha_pacemaker_cluster_hana_sid not in __sap_sid_prohibited
+ fail_msg: |
+ Host type = {{ sap_ha_pacemaker_cluster_host_type }}
+ Requires 'sap_ha_pacemaker_cluster_hana_sid' to be defined!
when:
- - "'hana' in sap_ha_pacemaker_cluster_host_type"
- - sap_ha_pacemaker_cluster_hana_sid is defined
- - sap_ha_pacemaker_cluster_hana_sid | length > 0
+ - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0
-- name: "SAP HA Prepare Pacemaker - Validate SAP System ID (SAP Netweaver)"
+- name: "SAP HA Prepare Pacemaker - (SAP NetWeaver) Validate SAP System ID"
ansible.builtin.assert:
that:
- sap_ha_pacemaker_cluster_netweaver_sid | length == 3
- sap_ha_pacemaker_cluster_netweaver_sid not in __sap_sid_prohibited
+ fail_msg: |
+ Host type = {{ sap_ha_pacemaker_cluster_host_type }}
+ Requires 'sap_ha_pacemaker_cluster_netweaver_sid' to be defined!
when:
- - "'nwas' in sap_ha_pacemaker_cluster_host_type"
- - sap_ha_pacemaker_cluster_netweaver_sid is defined
- - sap_ha_pacemaker_cluster_netweaver_sid | length > 0
+ - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas') | length > 0
-- name: "SAP HA Prepare Pacemaker - Verify that a SID is defined"
+# NIC definition validation
+- name: "SAP HA Prepare Pacemaker - Verify that a custom NIC name is defined when multiple NICs exist"
ansible.builtin.assert:
that:
- - sap_ha_pacemaker_cluster_hana_sid is defined
- or sap_ha_pacemaker_cluster_netweaver_sid is defined
- - sap_ha_pacemaker_cluster_hana_sid | length > 0
- or sap_ha_pacemaker_cluster_netweaver_sid | length > 0
+ - sap_ha_pacemaker_cluster_vip_client_interface is defined
+ - sap_ha_pacemaker_cluster_vip_client_interface | length > 0
+ fail_msg:
+ Multiple interfaces are found on the system.
+
+ {{ ansible_interfaces | to_nice_yaml }}
+
+ In this case 'sap_ha_pacemaker_cluster_vip_client_interface' must be defined.
+ when:
+ - ansible_interfaces | length > 2
+
+- name: "SAP HA Prepare Pacemaker - Verify that the custom NIC name exists"
+ ansible.builtin.assert:
+ that:
+ - sap_ha_pacemaker_cluster_vip_client_interface in ansible_interfaces
+ fail_msg: "The interface '{{ sap_ha_pacemaker_cluster_vip_client_interface }}' does not exist on this system!"
+ when:
+ - sap_ha_pacemaker_cluster_vip_client_interface | length > 0
+
+# VIP definition validation
+- name: "SAP HA Prepare Pacemaker - (HANA primary) Verify that the VIP is defined"
+ ansible.builtin.assert:
+ that:
+ - sap_ha_pacemaker_cluster_vip_hana_primary_ip_address is defined
+ - sap_ha_pacemaker_cluster_vip_hana_primary_ip_address | length > 0
+ fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_hana_primary_ip_address' is not defined."
+ when:
+ - sap_ha_pacemaker_cluster_host_type | select('search', 'hana') | length > 0
+
+- name: "SAP HA Prepare Pacemaker - (NetWeaver ASCS) Verify that the VIP is defined"
+ ansible.builtin.assert:
+ that:
+ - sap_ha_pacemaker_cluster_vip_netweaver_ascs_ip_address is defined
+ - sap_ha_pacemaker_cluster_vip_netweaver_ascs_ip_address | length > 0
+ fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_netweaver_ascs_ip_address' is not defined."
+ when:
+ - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_ascs') | length > 0
+
+- name: "SAP HA Prepare Pacemaker - (NetWeaver ERS) Verify that the VIP is defined"
+ ansible.builtin.assert:
+ that:
+ - sap_ha_pacemaker_cluster_vip_netweaver_ers_ip_address is defined
+ - sap_ha_pacemaker_cluster_vip_netweaver_ers_ip_address | length > 0
+ fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_netweaver_ers_ip_address' is not defined."
+ when:
+ - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_ascs_ers') | length > 0
+
+- name: "SAP HA Prepare Pacemaker - (NetWeaver PAS) Verify that the VIP is defined"
+ ansible.builtin.assert:
+ that:
+ - sap_ha_pacemaker_cluster_vip_netweaver_pas_ip_address is defined
+ - sap_ha_pacemaker_cluster_vip_netweaver_pas_ip_address | length > 0
+ fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_netweaver_pas_ip_address' is not defined."
+ when:
+ - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_pas') | length > 0
+
+- name: "SAP HA Prepare Pacemaker - (NetWeaver AAS) Verify that the ERS VIP is defined"
+ ansible.builtin.assert:
+ that:
+ - sap_ha_pacemaker_cluster_vip_netweaver_aas_ip_address is defined
+ - sap_ha_pacemaker_cluster_vip_netweaver_aas_ip_address | length > 0
+ fail_msg: "Host type = '{{ sap_ha_pacemaker_cluster_host_type }}', but 'sap_ha_pacemaker_cluster_vip_netweaver_aas_ip_address' is not defined."
+ when:
+ - sap_ha_pacemaker_cluster_host_type | select('search', 'nwas_abap_pas_aas') | length > 0
diff --git a/roles/sap_ha_pacemaker_cluster/vars/main.yml b/roles/sap_ha_pacemaker_cluster/vars/main.yml
index c96a08fbf..27b93aee8 100644
--- a/roles/sap_ha_pacemaker_cluster/vars/main.yml
+++ b/roles/sap_ha_pacemaker_cluster/vars/main.yml
@@ -27,37 +27,14 @@ __sap_ha_pacemaker_cluster_required_facts:
# - virtualization_role # subset: virtual
# - virtualization_type # subset: virtual
+# By default assume non-multi-NIC configuration.
+# This is automatically adjusted during preparation tasks.
+__sap_ha_pacemaker_cluster_nic_multi_bool: false
+
# Define empty parameters to avoid undefined input variables.
# The arguments_spec check complains.
# The actual values must be empty, they are set by various tasks!
-__sap_ha_pacemaker_cluster_hana_primary_synonyms:
- - primary
- - hana_primary
- - promoted
- - rw
-
-__sap_ha_pacemaker_cluster_hana_secondary_synonyms:
- - secondary
- - hana_secondary
- - unpromoted
- - ro
-
-__sap_ha_pacemaker_cluster_nwas_ascs_synonyms:
- - ascs
- - nwas_ascs
- - nwas_abap_ascs
-
-__sap_ha_pacemaker_cluster_nwas_ers_synonyms:
- - ers
- - nwas_ers
- - nwas_abap_ers
-
-__sap_ha_pacemaker_cluster_nwas_pas_synonyms:
- - pas
- - nwas_pas
- - nwas_abap_pas
-
# (cloud) platform helper variable - leave empty for default = not cloud
__sap_ha_pacemaker_cluster_platform: ''
__sap_ha_pacemaker_cluster_supported_platforms: