Skip to content
2 changes: 1 addition & 1 deletion roles/sap_hana_install/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ Installs SAP HANA on `host1` and `host2`, while running on host `host0` where ex
```yaml
---
- name: Ansible Play for SAP HANA installation - Add hosts
hosts: host0, host1
hosts: host0, host1, host2
become: true
tasks:
- name: Execute Ansible Role sap_hana_install
Expand Down
11 changes: 7 additions & 4 deletions roles/sap_hana_install/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,9 @@ sap_hana_install_keep_copied_sarfiles: false
# For installing SAP HANA with fapolicyd support, set the following variable to `true`:
sap_hana_install_configure_fapolicyd: false

# (RedHat specific) desired fapolicyd service status (only if sap_hana_install_configure_fapolicyd is 'true')
# For not enabling and not starting the fapolicyd service after the installation has finished, set the following
# variable to `false`:
sap_hana_install_enable_fapolicyd: true
# (RedHat specific) desired fapolicyd service status (only if 'sap_hana_install_configure_fapolicyd' is set to 'true').
# For enabling and starting the fapolicyd service after the installation has finished, set the following variable to 'true'.
sap_hana_install_enable_fapolicyd: false

# (RedHat specific) fapolicyd integrity level
# When using fapolicyd, you can set the following variable to one of `none`, `size`, `sha256`, or `ima`. Note that before setting
Expand Down Expand Up @@ -274,3 +273,7 @@ sap_hana_install_create_initial_tenant: 'y'

# Display SAP HANA hdblcm unattended mode output (hdblcm stdout)
sap_hana_install_display_unattended_output: false

# (Optional) Set to `true` to skip the filesystem check during SAP HANA installation.
# This is not recommended, but can be used in case of a non-Production environment.
sap_hana_install_skip_filesystem_check: false
2 changes: 1 addition & 1 deletion roles/sap_hana_install/tasks/hana_addhosts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
cmd: "{{ __sap_hana_install_hdblcm_command }}"
register: __sap_hana_install_register_hdblcm_add_hosts
args:
chdir: "{{ sap_hana_install_shared_path }}/{{ sap_hana_install_sid }}/hdblcm"
chdir: "{{ __sap_hana_install_shared_path }}/hdblcm"
changed_when: "'SAP HANA Lifecycle Management' in __sap_hana_install_register_hdblcm_add_hosts.stdout"
when: not ansible_check_mode

Expand Down
84 changes: 52 additions & 32 deletions roles/sap_hana_install/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,34 @@
tags: always
tags: always


# Process all hosts in play and define flag facts based on their intended role during installation.
# - Detect Scale-Out and Addhosts operations.
# - Set host identification flags
# - Validate addhosts list against hosts in the play.
- name: SAP HANA - Main - Identify hosts in play
ansible.builtin.include_tasks:
file: pre_tasks/identify_hosts.yml


# SAP HANA presence has to be validated for both new system and adding new hosts.
# - Detection is executed even in force mode, but fails are skipped to allow execution of the role.
# - Host identification flags are used to ignore /hana/shared file detection check for Scale-Out addhosts hosts.
- name: SAP HANA - Main - Validate presence of existing SAP HANA database
ansible.builtin.include_tasks:
file: pre_tasks/hana_exists.yml
file: pre_tasks/detect_hana.yml
apply:
tags:
- sap_hana_install_check_hana_exists
when:
- (sap_hana_install_new_system and not sap_hana_install_force)
or not sap_hana_install_new_system
tags:
- sap_hana_install_check_hana_exists


- name: SAP HANA - Main - Identify hosts in play based on addhosts
# Validate detected SAP installations against allowed Scale-Out scenarios.
- name: SAP HANA - Main - Validate hosts in play
ansible.builtin.include_tasks:
file: pre_tasks/identify_hosts.yml
file: pre_tasks/validate_hosts.yml
when: __sap_hana_install_fact_is_scaleout


- name: SAP HANA - Main - Ensure SAP HANA is running for existing systems or addhosts operations
Expand All @@ -77,10 +88,18 @@
# - Configuration - Run always to ensure idempotent outcome.

- name: Block for Installation tasks
when: sap_hana_install_new_system or
('sap_hana_install_create_configfile' in ansible_run_tags | d([])) or
('sap_hana_install_hdblcm_commandline' in ansible_run_tags | d([]))
# Stop execution of remaining tasks in the role, if any task in the block failed on any host.
# This ensures that the role does not proceed skipping failed host, but fails the entire role execution.
# 'any_errors_fatal' is not documented to work on task level, therefore we use simple block.
# http://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_error_handling.html#aborting-on-the-first-error-any-errors-fatal
# Runs on all hosts in Scale-Out scenario, but allows independent failures for single host installations.
any_errors_fatal: "{{ true if __sap_hana_install_fact_is_scaleout else false }}"
when:
- sap_hana_install_new_system
or (ansible_run_tags | d([])
| intersect(['sap_hana_install_create_configfile', 'sap_hana_install_hdblcm_commandline'])) | length > 0
block:
# Task file contains pseudo-idempotency checks and cannot be skipped for installed system.
- name: SAP HANA - Install - Pre-Tasks
ansible.builtin.include_tasks:
file: pre_install.yml
Expand All @@ -91,9 +110,9 @@
- name: SAP HANA - Install
ansible.builtin.include_tasks:
file: hana_install.yml
when: >
(not __sap_hana_install_fact_is_installed and __sap_hana_install_fact_is_main_host) or
('sap_hana_install_hdblcm_commandline' in ansible_run_tags | d([]))
when:
- (not __sap_hana_install_fact_is_installed and __sap_hana_install_fact_is_main_host)
or (ansible_run_tags | d([]) | intersect(['sap_hana_install_hdblcm_commandline'])) | length > 0
tags: sap_hana_install_hdblcm_commandline

- name: SAP HANA - Install - Post-tasks
Expand All @@ -102,20 +121,26 @@


- name: Block for Addhosts tasks
when: >
not sap_hana_install_new_system and
((__sap_hana_install_fact_is_scaleout and __sap_hana_install_fact_is_installed) or
('sap_hana_install_hdblcm_commandline' in ansible_run_tags | d([])) or
('sap_hana_install_create_configfile' in ansible_run_tags | d([])))
# Stop execution of remaining tasks in the role, if any task in the block failed on any host.
# This ensures that the role does not proceed skipping failed host, but fails the entire role execution.
# 'any_errors_fatal' is not documented to work on task level, therefore we use simple block.
# http://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_error_handling.html#aborting-on-the-first-error-any-errors-fatal
# Runs on all hosts in addhosts scenario.
any_errors_fatal: true
when:
- not sap_hana_install_new_system
and (__sap_hana_install_fact_is_scaleout
or (ansible_run_tags | d([])
| intersect(['sap_hana_install_create_configfile', 'sap_hana_install_hdblcm_commandline'])) | length > 0)
block:
# Execute only if new hosts are to be added.
- name: SAP HANA - Addhosts - Pre-Tasks
ansible.builtin.include_tasks:
file: pre_addhosts.yml
when: >
(__sap_hana_install_fact_addhosts_hosts_new | d([]) | length > 0) or
('sap_hana_install_hdblcm_commandline' in ansible_run_tags | d([])) or
('sap_hana_install_create_configfile' in ansible_run_tags | d([]))
when:
- __sap_hana_install_fact_addhosts_hosts_new | d([]) | length > 0
or (ansible_run_tags | d([])
| intersect(['sap_hana_install_create_configfile', 'sap_hana_install_hdblcm_commandline'])) | length > 0
tags:
- sap_hana_install_hdblcm_commandline
- sap_hana_install_create_configfile
Expand All @@ -124,9 +149,9 @@
ansible.builtin.include_tasks:
file: hana_addhosts.yml
when:
(__sap_hana_install_fact_addhosts_hosts_new | d([]) | length > 0 and __sap_hana_install_fact_is_main_host) or
('sap_hana_install_hdblcm_commandline' in ansible_run_tags | d([])) or
('sap_hana_install_create_configfile' in ansible_run_tags | d([]))
- (__sap_hana_install_fact_addhosts_hosts_new | d([]) | length > 0 and __sap_hana_install_fact_is_main_host)
or (ansible_run_tags | d([])
| intersect(['sap_hana_install_create_configfile', 'sap_hana_install_hdblcm_commandline'])) | length > 0
tags:
- sap_hana_install_hdblcm_commandline
- sap_hana_install_create_configfile
Expand All @@ -148,7 +173,7 @@
gsub ("^\\s*hosts?: ", ""); gsub (", ", ","); print; a=0}
}'
args:
chdir: "{{ sap_hana_install_shared_path }}/{{ sap_hana_install_sid }}/hdblcm"
chdir: "{{ __sap_hana_install_shared_path }}/hdblcm"
register: __sap_hana_install_register_completion_result
changed_when: false
when:
Expand All @@ -164,11 +189,6 @@
SID - {{ sap_hana_install_sid }}
NR - {{ sap_hana_install_number }}

{% if sap_hana_install_new_system and __sap_hana_install_fact_is_installed and __sap_hana_install_fact_addhosts_hosts_new | length > 0 %}
The new hosts defined in the variable 'sap_hana_install_addhosts' were not added: {{ __sap_hana_install_fact_addhosts_hosts_new | join(', ') }}.
Execute this role with the variable 'sap_hana_install_new_system' set to false to add new hosts.
{% endif %}

{% if sap_hana_install_configure_firewall %}
Firewall is enabled and SAP HANA ports are open.
{% endif %}
Expand All @@ -179,8 +199,8 @@
Fapolicyd is configured for SAP folders ({{ sap_hana_install_directories | map('quote') | join(', ') }}).
{% endif %}
vars:
__sap_hana_install_fact_hana_version: "{{ __sap_hana_install_register_completion_result.stdout.split(';')[0] }}"
__sap_hana_install_fact_hana_hosts: "{{ __sap_hana_install_register_completion_result.stdout.split(';')[1] }}"
__sap_hana_install_fact_hana_version: "{{ __sap_hana_install_register_completion_result.stdout.split(';')[0] | d('N/A') }}"
__sap_hana_install_fact_hana_hosts: "{{ __sap_hana_install_register_completion_result.stdout.split(';')[1] | d('N/A') }}"
when:
- not ansible_check_mode
- __sap_hana_install_fact_is_main_host
3 changes: 3 additions & 0 deletions roles/sap_hana_install/tasks/post_addhosts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,6 @@
# Ensure fapolicyd is checked only on supported systems.
- ansible_facts['os_family'] == "RedHat"
- __sap_hana_install_configure_fapolicyd
# Added to ensure that fapolicyd is configured only on new installations
# to avoid trusting potentially compromised files in existing installation.
- __sap_hana_install_fact_is_new_addhost_host
4 changes: 4 additions & 0 deletions roles/sap_hana_install/tasks/post_install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- name: Block with tasks for new HANA Systems
when:
- not __sap_hana_install_fact_is_installed
# Execute only on main host and skip execution on addhosts.
- __sap_hana_install_fact_is_main_host
block:

Expand Down Expand Up @@ -75,3 +76,6 @@
# Ensure fapolicyd is checked only on supported systems.
- ansible_facts['os_family'] == "RedHat"
- __sap_hana_install_configure_fapolicyd
# Added to ensure that fapolicyd is configured only on new installations
# to avoid trusting potentially compromised files in existing installation.
- not __sap_hana_install_fact_is_installed
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
- name: SAP HANA - Post-Tasks - Construct an hdbcheck command line
ansible.builtin.set_fact:
__sap_hana_install_fact_installation_check_command: "set -o pipefail && ./hdbcheck -b --read_password_from_stdin=xml
--property_file={{ sap_hana_install_shared_path }}/{{ sap_hana_install_sid }}/global/hdb/install/support/hdbcheck.xml
--property_file={{ __sap_hana_install_shared_path }}/global/hdb/install/support/hdbcheck.xml
--remote_execution=ssh
--scope=system
-b < {{ __sap_hana_install_register_tmpdir.path }}/configfile.cfg.xml"
Expand All @@ -61,7 +61,7 @@
- name: SAP HANA - Post-Tasks - hdbcheck - Perform the check # noqa command-instead-of-shell
ansible.builtin.shell: "{{ __sap_hana_install_fact_installation_check_command }}"
args:
chdir: "{{ sap_hana_install_shared_path }}/{{ sap_hana_install_sid }}/global/hdb/install/bin"
chdir: "{{ __sap_hana_install_shared_path }}/global/hdb/install/bin"
register: __sap_hana_install_register_installation_check
changed_when: false
when: sap_hana_install_use_hdbcheck | d(true)
Expand All @@ -77,7 +77,7 @@
- name: SAP HANA - Post-Tasks - hdblcm - Perform the check # noqa command-instead-of-shell
ansible.builtin.shell: "{{ __sap_hana_install_fact_installation_check_command }}"
args:
chdir: "{{ sap_hana_install_shared_path }}/{{ sap_hana_install_sid }}/hdblcm"
chdir: "{{ __sap_hana_install_shared_path }}/hdblcm"
register: __sap_hana_install_register_installation_check
changed_when: false
when: not sap_hana_install_use_hdbcheck | d(true)
Expand Down
10 changes: 10 additions & 0 deletions roles/sap_hana_install/tasks/post_tasks/user_expiration.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# SPDX-License-Identifier: Apache-2.0
---

# NOTE: This can be replaced completely by 'ansible.builtin.user' module when we increase minimum ansible version to 2.18!
# Argument '-I' is set by module parameter 'password_expire_account_disable' added in 2.18.
# ansible.builtin.user:
# name: "{{ user_item }}"
# password_expire_min: 0 # chage -m 0
# password_expire_max: 99999 # chage -M 99999
# password_expire_account_disable: -1 # chage -I -1
# expires: -1 # chage -E -1

# Current use of 'chage' will always be marked as change in Ansible logs, regardless of outcome.
- name: SAP HANA - Post-Tasks - Set '{{ sap_hana_install_sid | lower }}adm' to not expire
ansible.builtin.shell: |
chage -m 0 -M 99999 -I -1 -E -1 {{ sap_hana_install_sid | lower }}adm
Expand Down
22 changes: 11 additions & 11 deletions roles/sap_hana_install/tasks/pre_addhosts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,16 @@
key: sapadm
failed_when: false

# hana_exists already found existing database, this is additional check.
# getent_group['sapsys'][1] and getent_passwd['sapadm'][2] are Group ID.
- name: SAP HANA - Addhosts - Pre-Tasks - Assert that user 'sapadm' is present with group 'sapsys'
ansible.builtin.assert:
that:
- "'sapsys' in getent_group"
- "'sapadm' in getent_passwd"
# Ensure sapadm user is assigned to sapsys group
- getent_group['sapsys'][1] == getent_passwd['sapadm'][2]
fail_msg: >-
FAIL: User 'sapadm' with group 'sapsys' does not exist!
# detect_hana already found existing database, this is additional check.
# ansible_facts["getent_group"]['sapsys'][1] and ansible_facts["getent_passwd"]['sapadm'][2] are Group ID.
- name: SAP HANA - Addhosts - Pre-Tasks - Fail if user 'sapadm' is not present with group 'sapsys'
ansible.builtin.fail:
msg: |
FAIL: User 'sapadm' with group 'sapsys' does not exist or it has incorrect group ID!
when:
- ansible_facts["getent_group"]['sapsys'] is not defined
or ansible_facts["getent_passwd"]['sapadm'] is not defined
or ansible_facts["getent_group"]['sapsys'][1] != ansible_facts["getent_passwd"]['sapadm'][2]

# TODO: Issue#1123 Remove default to master
- name: SAP HANA - Addhosts - Pre-Tasks - Generate password hash for 'sap_hana_install_sapadm_password'
Expand Down Expand Up @@ -82,6 +81,7 @@
- name: SAP HANA - Addhosts - Pre-Tasks - Check shared filesystems
ansible.builtin.include_tasks:
file: pre_tasks/check_filesystems.yml
when: not sap_hana_install_skip_filesystem_check | d(false)


# Update HANA directory permissions
Expand Down
4 changes: 3 additions & 1 deletion roles/sap_hana_install/tasks/pre_install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@
- name: SAP HANA - Install - Pre-Tasks - Check shared filesystems
ansible.builtin.include_tasks:
file: pre_tasks/check_filesystems.yml
when: __sap_hana_install_fact_is_scaleout
when:
- __sap_hana_install_fact_is_scaleout
- not sap_hana_install_skip_filesystem_check | d(false)


# We need to change permissions only after filesystem check has passed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
- name: SAP HANA - Addhosts - Pre-Tasks - Create 'sapsys' group on new host
ansible.builtin.group:
name: sapsys
gid: "{{ hostvars[__sap_hana_install_fact_main_host]['getent_group']['sapsys'][1] }}"
gid: "{{ hostvars[__sap_hana_install_fact_main_host]['ansible_facts']['getent_group']['sapsys'][1] }}"
state: present
become: true

# User 'sidadm' is not required for addhosts, only sapadm user.
- name: SAP HANA - Addhosts - Pre-Tasks - Create 'sapadm' user on new host
ansible.builtin.user:
name: sapadm
uid: "{{ hostvars[__sap_hana_install_fact_main_host]['getent_passwd']['sapadm'][1] }}"
home: "{{ hostvars[__sap_hana_install_fact_main_host]['getent_passwd']['sapadm'][4] }}"
shell: "{{ hostvars[__sap_hana_install_fact_main_host]['getent_passwd']['sapadm'][5] }}"
uid: "{{ hostvars[__sap_hana_install_fact_main_host]['ansible_facts']['getent_passwd']['sapadm'][1] }}"
home: "{{ hostvars[__sap_hana_install_fact_main_host]['ansible_facts']['getent_passwd']['sapadm'][4] }}"
shell: "{{ hostvars[__sap_hana_install_fact_main_host]['ansible_facts']['getent_passwd']['sapadm'][5] }}"
groups: sapsys
append: true
state: present
Expand Down
Loading