diff --git a/README.md b/README.md index f50634e..d15b0bc 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,20 @@ -# Three Tier SAP S/4HANA Stack Deployment using Terraform and Ansible integration +# Three Tier SAP S/4HANA Stack Deployment using Terraform and Ansible Automation ## Description This automation solution is designed for the deployment of **Three Tier SAP S/4HANA Stack** using IBM Cloud Schematics or CLI. The SAP solution will be deployed on top of one of the following Operating Systems: **Red Hat Enterprise Linux 8.6 for SAP, Red Hat Enterprise Linux 8.4 for SAP, SUSE Linux Enterprise Server 15 SP 4 for SAP, SUSE Linux Enterprise Server 15 SP 3 for SAP** in an existing IBM Cloud Gen2 VPC, using an existing [bastion host with secure remote SSH access](https://github.com/IBM-Cloud/sap-bastion-setup). -The solution is based on Terraform remote-exec and Ansible playbooks executed by Schematics and it is implementing a 'reasonable' set of best practices for SAP VSI host configuration. +The solution is based on Terraform scripts and Ansible playbooks and it is implementing a 'reasonable' set of best practices for SAP hosts configuration. **It contains:** -- Terraform scripts for the deployment of two VSIs, in an EXISTING VPC, with Subnet and Security Group. The VSIs are intended to be used: one for the data base instance and the other for the application instance. The automation has support for the following versions: Terraform >= 1.5.7 and IBM Cloud provider for Terraform >= 1.57.0. Note: The deployment was tested with Terraform 1.5.7 -- Bash scripts used for the checking of the prerequisites required by SAP VSIs deployment and for the integration into a single step in IBM Schematics GUI of the VSI provisioning and the **SAP S/4HANA Stack** installation. -- Ansible scripts to configure Three Tier SAP S/4HANA primary application server and a HANA 2.0 node. +- Terraform scripts for the deployment of two servers, in an EXISTING VPC, with Subnet and Security Group. The servers are intended to be used: one for the data base instance and the other for the application instance. The automation has support for the following versions: Terraform >= 1.5.7 and IBM Cloud provider for Terraform >= 1.57.0. Note: The deployment was tested with Terraform 1.6.6 +- Bash scripts used for the checking of the prerequisites required by SAP servers deployment and for the integration into a single step in IBM Schematics GUI of the server provisioning and the **SAP S/4HANA Stack** installation. +- Ansible scripts to configure the LVM and filesystems, the OS parameters, a Three Tier SAP S/4HANA primary application server and a HANA 2.0 node. Please note that Ansible is started by Terraform and must be available on the same host. - -In order to track the events specific to the resources deployed by this solution, the [IBM Cloud Activity Tracker](https://cloud.ibm.com/docs/activity-tracker?topic=activity-tracker-getting-started#gs_ov) to be used should be specified. -IBM Cloud Activity Tracker service collects and stores audit records for API calls made to resources that run in the IBM Cloud. It can be used to monitor the activity of your IBM Cloud account, investigate abnormal activity and critical actions, and comply with regulatory audit requirements. In addition, you can be alerted on actions as they happen. - - ## Contents - [1.1 Installation media](#11-installation-media) -- [1.2 VSI Configuration](#12-vsi-configuration) +- [1.2 Server Configuration](#12-server-configuration) - [1.3 VPC Configuration](#13-vpc-configuration) - [1.4 Files description and structure](#14-files-description-and-structure) - [1.5 General input variabiles](#15-general-input-variables) @@ -32,15 +27,18 @@ SAP HANA installation media used for this deployment is the default one for **SA SAP S/4HANA installation media used for this deployment is the default one for **SAP S/4HANA 2.0** available at SAP Support Portal under *INSTALLATION AND UPGRADE* area and it has to be provided manually in the input parameter file. -## 1.2 VSI Configuration -The VSIs are deployed with one of the following Operating Systems for DB server: **Red Hat Enterprise Linux 8.6 for SAP HANA (amd64)**, **Red Hat Enterprise Linux 8.4 for SAP HANA (amd64)**, **Suse Linux Enterprise Server 15 SP 4 for SAP HANA (amd64)**, **Suse Linux Enterprise Server 15 SP 3 for SAP HANA (amd6)** and with one of the following Operating Systems for APP server: **Red Hat Enterprise Linux 8.6 for SAP Applications (amd64)**, **Red Hat Enterprise Linux 8.4 for SAP Applications (amd64)**, **Suse Enterprise Linux 15 SP4 for SAP Applications (amd64)**, **Suse Enterprise Linux 15 SP3 for SAP Applications (amd64)**. The SSH keys are configured to allow root user access. The following storage volumes are creating during the provisioning: +## 1.2 Server Configuration +The Servers are deployed with one of the following Operating Systems for DB server: **Red Hat Enterprise Linux 8.6 for SAP HANA (amd64)**, **Red Hat Enterprise Linux 8.4 for SAP HANA (amd64)**, **Suse Linux Enterprise Server 15 SP 4 for SAP HANA (amd64)**, **Suse Linux Enterprise Server 15 SP 3 for SAP HANA (amd6)** and with one of the following Operating Systems for APP server: **Red Hat Enterprise Linux 8.6 for SAP Applications (amd64)**, **Red Hat Enterprise Linux 8.4 for SAP Applications (amd64)**, **Suse Enterprise Linux 15 SP4 for SAP Applications (amd64)**, **Suse Enterprise Linux 15 SP3 for SAP Applications (amd64)**. The SSH keys are configured to allow root user access. The following storage volumes are creating during the provisioning: HANA DB VSI Disks: -- the disk sizes depend on the selected profile, according to [Intel Virtual Server certified profiles on VPC infrastructure for SAP HANA](https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc) - Updated on 2023-03-08 +- the disk sizes depend on the selected profile, according to [Intel Virtual Server certified profiles on VPC infrSAP HANA DB Server Disks: +- the disk sizes depend on the selected profile, according to [Intel Virtual Server certified profiles on VPC infrastructure for SAP HANA](https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc) - Last updated 2023-12-28 and to [Bare metal servers certified profiles on VPC infrastructure for SAP HANA](https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-bm-vpc) - Last updated 2024-05-13 -Note: LVM will be used for **`/hana/data`**, **`hana/log`**, **`/hana/shared`** and **`/usr/sap`**, for all storage profiles, excepting **`vx2d-44x616`** and **`vx2d-88x1232`** profiles, where **`/hana/data`** and **`/hana/shared`** won't be manged by LVM, according to [Intel Virtual Server certified profiles on VPC infrastructure for SAP HANA](https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc#vx2d-16x224) - Updated on 2023-03-08 and to [Storage design considerations](https://cloud.ibm.com/docs/sap?topic=sap-storage-design-considerations#hana-iaas-mx2-16x128-32x256-configure) - Updated on 2022-05-19 +Note: For SAP HANA on a VSI, according to [Intel Virtual Server certified profiles on VPC infrastructure for SAP HANA](https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc#vx2d-16x224) - Last updated 2022-01-28 and to [Storage design considerations](https://cloud.ibm.com/docs/sap?topic=sap-storage-design-considerations) - Last updated 2024-01-25, LVM will be used for **`/hana/data`**, **`hana/log`**, **`/hana/shared`** and **`/usr/sap`**, for all storage profiles, with the following exceptions: +- **`/hana/data`** and **`/hana/shared`** for the following profiles: **`vx2d-44x616`** and **`vx2d-88x1232`** +- **`/hana/shared`** for the following profiles: **`vx2d-144x2016`**, **`vx2d-176x2464`**, **`ux2d-36x1008`**, **`ux2d-48x1344`**, **`ux2d-72x2016`**, **`ux2d-100x2800`**, **`ux2d-200x5600`**. -For example, in case of deploying a HANA VM, using the default value for VSI profile `mx2-16x128`, the automation will execute the following storage setup: +For example, in case of deploying a SAP HANA on a VSI, using the value `mx2-16x128` for the VSI profile , the automation will execute the following storage setup: - 3 volumes x 500 GB each for `_hana_vg` volume group - the volume group will contain the following logical volumes (created with three stripes): - `_hana_data_lv` - size 988 GB @@ -49,8 +47,19 @@ For example, in case of deploying a HANA VM, using the default value for VSI pro - 1 volume x 50 GB for `/usr/sap` (volume group: `_usr_sap_vg`, logical volume: `_usr_sap_lv`) - 1 volume x 10 GB for a 2 GB SWAP logical volume (volume group: `_swap_vg`, logical volume: `_swap_lv`) +In case of deploying a SAP HANA on a Bare Metal Server, using the value `bx2d-metal-96x384` for the Bare Metal Server profile, the automation will execute the following storage setup: +- 4 disks x 2.9 TB each for `_vg0` volume group + - the volume group will contain the following logical volumes (created with raid10, mirror and two stripes): + - `_hana_log_lv` - size 384 GB + - `_hana_shared` - size 384 GB +- 4 disks x 2.9 TB each for `_vg1` volume group + - the volume group will contain the following logical volumes (created with raid10, mirror and two stripes): + - `_hana_data_lv` - size 100%FREE +- 1 directory `/usr/sap` +- 1 SWAP file of 2 GB `/_swapfile` + SAP APPs VSI Disks: -- 1x 40 GB disk with 10 IOPS / GB - SWAP +- 1 disk with 10 IOPS / GB - SWAP (the size depends on the OS profile used, for `bx2-4x16` the size will be 48 GB) - 1 x 128 GB disk with 10 IOPS / GB - DATA In order to perform the deployment you can use either the CLI component or the GUI component (Schematics) of the automation solution. @@ -64,56 +73,53 @@ The Security Rules inherited from BASTION deployment are the following: ## 1.4 Files description and structure -The solution is based on Terraform remote-exec and Ansible playbooks executed by Schematics and it is implementing a 'reasonable' set of best practices for SAP VSI host configuration. +The solution is based on Terraform remote-exec and Ansible playbooks executed by Schematics and it is implementing a 'reasonable' set of best practices for SAP server configuration. - `modules` - directory containing the terraform modules. - `ansible` - directory containing the SAP ansible playbooks. - - `main.tf` - contains the configuration of the VSI for the deployment of the current SAP solution. - - `output.tf` - contains the code for the information to be displayed after the VSI is created (VPC, Hostname, Private IP). + - `main.tf` - contains the configuration of the server for the deployment of the current SAP solution. + - `output.tf` - contains the code for the information to be displayed after the server is created (VPC, Hostname, Private IP). - `integration*.tf & generate*.tf` files - contain the integration code that makes the SAP variabiles from Terraform available to Ansible. - `provider.tf` - contains the IBM Cloud Provider data in order to run `terraform init` command. - - `variables.tf` - contains variables for the VPC and VSI. + - `variables.tf` - contains variables for the VPC and server. - `versions.tf` - contains the minimum required versions for terraform and IBM Cloud provider. - `sch.auto.tfvars` - contains programatic variables. ## 1.5 General Input variables -The following parameters can be set in the Schematics workspace: VPC, Subnet, Security group, Resource group, Hostname, Profile, Image, SSH Keys and your SAP system configuration variables, as below: +The following parameters can be set: -**VSI input parameters** +**General input parameters:** Parameter | Description ----------|------------ -IBMCLOUD_API_KEY | IBM Cloud API key (Sensitive* value). -PRIVATE_SSH_KEY | id_rsa private key content in OpenSSH format (Sensitive* value). This private key should be used only during the terraform provisioning and it is recommended to be changed after the SAP deployment. -SSH_KEYS | List of SSH Keys UUIDs that are allowed to SSH as root to the VSI. Can contain one or more IDs. The list of SSH Keys is available [here](https://cloud.ibm.com/vpc-ext/compute/sshKeys).
Sample input (use your own SSH UUIDs from IBM Cloud):
[ "r010-57bfc315-f9e5-46bf-bf61-d87a24a9ce7a" , "r010-3fcd9fe7-d4a7-41ce-8bb3-d96e936b2c7e" ] +IBMCLOUD_API_KEY | IBM Cloud API key (Sensitive* value). The IBM Cloud API Key can be created [here](https://cloud.ibm.com/iam/apikeys) +SSH_KEYS | List of SSH Keys UUIDs that are allowed to SSH as root to the server. Can contain one or more IDs. The list of SSH Keys is available [here](https://cloud.ibm.com/vpc-ext/compute/sshKeys).
Sample input (use your own SSH UUIDs from IBM Cloud):
[ "r010-57bfc315-f9e5-46bf-bf61-d87a24a9ce7a" , "r010-3fcd9fe7-d4a7-41ce-8bb3-d96e936b2c7e" ] BASTION_FLOATING_IP | BASTION FLOATING IP. It can be copied from the Bastion Server Deployment "OUTPUTS" at the end of "Apply plan successful" message. -RESOURCE_GROUP | The name of an EXISTING Resource Group for VSIs and Volumes resources.
Default value: "Default". The list of Resource Groups is available [here](https://cloud.ibm.com/account/resource-groups). +RESOURCE_GROUP | The name of an EXISTING Resource Group for servers and Volumes resources.
Default value: "Default". The list of Resource Groups is available [here](https://cloud.ibm.com/account/resource-groups). REGION | The cloud region where to deploy the solution.
The regions and zones for VPC are listed [here](https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones-vpc).
Review supported locations in IBM Cloud Schematics [here](https://cloud.ibm.com/docs/schematics?topic=schematics-locations).
Sample value: eu-de. ZONE | The cloud zone where to deploy the solution.
Sample value: eu-de-2. VPC | The name of an EXISTING VPC. The list of VPCs is available [here](https://cloud.ibm.com/vpc-ext/network/vpcs) SUBNET | The name of an EXISTING Subnet. The list of Subnets is available [here](https://cloud.ibm.com/vpc-ext/network/subnets). SECURITY_GROUP | The name of an EXISTING Security group. The list of Security Groups is available [here](https://cloud.ibm.com/vpc-ext/network/securityGroups). -DB_HOSTNAME | The Hostname for the HANA VSI. The hostname should be up to 13 characters as required by SAP. For more information on rules regarding hostnames for SAP systems, check [SAP Note 611361: Hostnames of SAP ABAP Platform servers](https://launchpad.support.sap.com/#/notes/%20611361) -DB_PROFILE | The instance profile used for the HANA VSI. The list of certified profiles for HANA VSIs is available [here](https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc).
Details about all x86 instance profiles are available [here](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles).
For more information about supported DB/OS and IBM Gen 2 Virtual Server Instances (VSI), check [SAP Note 2927211: SAP Applications on IBM Virtual Private Cloud](https://launchpad.support.sap.com/#/notes/2927211)
Default value: "mx2-16x128" -DB_IMAGE | The OS image used for HANA VSI (See Obs*). A list of images is available [here](https://cloud.ibm.com/docs/vpc?topic=vpc-about-images).
Default value: ibm-redhat-8-6-amd64-sap-hana-5 + +**Server input parameters** +HANA_SERVER_TYPE | The type of SAP HANA Server. Allowed vales: "virtual" or "bare metal" +DB_HOSTNAME | The Hostname for the HANA Server. The hostname should be up to 13 characters as required by SAP. For more information on rules regarding hostnames for SAP systems, check [SAP Note 611361: Hostnames of SAP ABAP Platform servers](https://launchpad.support.sap.com/#/notes/%20611361) +DB_PROFILE | The instance profile used for the SAP HANA Server. The list of the certified profiles for SAP HANA on a VSI is available [here](https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc). The list of the certified profiles for SAP HANA on a Bare Metal Server is available [here](https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-bm-vpc).
Details about all x86 instance profiles are available [here](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles).
For more information about supported DB/OS and IBM Gen 2 Servers, check [SAP Note 2927211: SAP Applications on IBM Virtual Private Cloud](https://launchpad.support.sap.com/#/notes/2927211)
+DB_IMAGE | The OS image used for HANA Server (See Obs*). A list of images is available [here](https://cloud.ibm.com/docs/vpc?topic=vpc-about-images).
Default value: ibm-redhat-8-6-amd64-sap-hana-6 APP_HOSTNAME | The Hostname for the SAP Application VSI. The hostname should be up to 13 characters as required by SAP. For more information on rules regarding hostnames for SAP systems, check [SAP Note 611361: Hostnames of SAP ABAP Platform servers](https://launchpad.support.sap.com/#/notes/%20611361) APP_PROFILE | The instance profile used for SAP Application VSI. A list of profiles is available [here](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles)
For more information about supported DB/OS and IBM Gen 2 Virtual Server Instances (VSI), check [SAP Note 2927211: SAP Applications on IBM Virtual Private Cloud](https://launchpad.support.sap.com/#/notes/2927211)
Default value: "bx2-4x16" -APP_IMAGE | The OS image used for SAP Application VSI (See Obs*). A list of images is available [here](https://cloud.ibm.com/docs/vpc?topic=vpc-about-images).
Default value: ibm-redhat-8-6-amd64-sap-applications-5 - +APP_IMAGE | The OS image used for SAP Application VSI (See Obs*). A list of images is available [here](https://cloud.ibm.com/docs/vpc?topic=vpc-about-images).
Default value: ibm-redhat-8-6-amd64-sap-applications-6 -**Activity Tracker input parameters** - -Parameter | Description -----------|------------ -ATR_NAME | ATR_NAME The name of an existent Activity Tracker instance, in the same region chosen for SAP system deployment. The list of available Activity Tracker is available here Example: ATR_NAME="Activity-Tracker-SAP-eu-de". **SAP input parameters** Parameter | Description | Requirements ----------|-------------|------------- S4HANA_VERSION | The version of S/4HANA | The version can take one of the following values: 2020, 2021, 2022, 2023. -HANA_SID | The SAP system ID identifies the SAP HANA system
_(See Obs.*)_ |
  • Consists of exactly three alphanumeric characters
  • Has a letter for the first character
  • Does not include any of the reserved IDs listed in SAP Note 1979280
| +HANA_SID | The SAP system ID identifies the SAP HANA system. Default value: HDB
_(See Obs.*)_ |
  • Consists of exactly three alphanumeric characters
  • Has a letter for the first character
  • Does not include any of the reserved IDs listed in SAP Note 1979280
| +HANA_TENANT | SAP HANA tenant name. Default value: HDB | HANA_SYSNO | Specifies the instance number of the SAP HANA system|
  • Two-digit number from 00 to 97
  • Must be unique on a host
HANA_SYSTEM_USAGE | System Usage | Default: custom
Valid values: production, test, development, custom HANA_COMPONENTS | SAP HANA Components | Default: server
Valid values: all, client, es, ets, lcapps, server, smartda, streaming, rdsync, xs, studio, afl, sca, sop, eml, rme, rtl, trp @@ -132,9 +138,6 @@ KIT_SAPHOSTAGENT_FILE | Path to SAP Host Agent archive (SAR) | As downloaded fro KIT_HDBCLIENT_FILE | Path to HANA DB client archive (SAR) | As downloaded from SAP Support Portal KIT_S4HANA_EXPORT | Path to S/4HANA Installation Export dir | The archives downloaded from SAP Support Portal should be present in this path -**SAP Passwords** -The passwords for the SAP system will be hidden during the schematics apply step and will not be available after the deployment. - Parameter | Description | Requirements ----------|-------------|------------- SAP_MAIN_PASSWORD | Common password for all users that are created during the installation |
  • It must be 8 to 14 characters long
  • It must contain at least one digit (0-9)
  • It must not contain \ (backslash) and " (double quote)
@@ -145,17 +148,6 @@ HANA_MAIN_PASSWORD | HANA system master password |
  • It must be 8 to 14 ch - **Sensitive** - The variable value is not displayed in your Schematics logs and it is hidden in the input field.
    - The following parameters should have the same values as the ones set for the BASTION server: REGION, ZONE, VPC, SUBNET, SECURITYGROUP. - For any manual change in the terraform code, you have to make sure that you use a certified image based on the SAP NOTE: 2927211. -- OS **image** for **DB VSI.** Supported OS images for DB VSIs: ibm-sles-15-4-amd64-sap-hana-5, ibm-sles-15-3-amd64-sap-hana-8, ibm-redhat-8-6-amd64-sap-hana-5, ibm-redhat-8-4-amd64-sap-hana-7. - - The list of available VPC Operating Systems supported by SAP: SAP note '2927211 - SAP Applications on IBM Virtual Private Cloud (VPC) Infrastructure environment' https://launchpad.support.sap.com/#/notes/2927211; The list of all available OS images: https://cloud.ibm.com/docs/vpc?topic=vpc-about-images - - Default variable: DB_IMAGE = "ibm-redhat-8-6-amd64-sap-hana-5" -- OS **image** for **SAP APP VSI**. Supported OS images for APP VSIs: ibm-sles-15-4-amd64-sap-applications-6, ibm-sles-15-3-amd64-sap-applications-9, ibm-redhat-8-6-amd64-sap-applications-5, ibm-redhat-8-4-amd64-sap-applications-4 -. - - The list of available VPC Operating Systems supported by SAP: SAP note '2927211 - SAP Applications on IBM Virtual Private Cloud (VPC) Infrastructure environment' https://launchpad.support.sap.com/#/notes/2927211; The list of all available OS images: https://cloud.ibm.com/docs/vpc?topic=vpc-about-images - - Default variable: APP_IMAGE = "ibm-redhat-8-6-amd64-sap-applications-5" -- SAP **HANA Installation path kit** - - Supported SAP HANA versions on RHEL8.6, RHEL8.4, SLES15.4 and SLES15.3: HANA 2.0 SP 5 Rev 57, kit file: 51055299.ZIP - - Example for RHEL8 or SLES15: KIT_SAPHANA_FILE = "/storage/HANADB/51055299.ZIP" - - Default variable: KIT_SAPHANA_FILE = "/storage/HANADB/51055299.ZIP" **Installation media validated for this solution:** @@ -178,14 +170,14 @@ HANA DB | 2.0 SPS07 rev73 | 51057281.ZIP OS version | Image | Role -----------|-----------|----------- -Red Hat Enterprise Linux 8.6 for SAP HANA (amd64) | ibm-redhat-8-6-amd64-sap-hana-5 | DB -Red Hat Enterprise Linux 8.6 for SAP Applications (amd64) | ibm-redhat-8-6-amd64-sap-applications-5 | APP -SUSE Linux Enterprise Server 15 SP4 for SAP HANA | ibm-sles-15-4-amd64-sap-hana-6 | DB -SUSE Linux Enterprise Server 15 SP4 for SAP Applications | ibm-sles-15-4-amd64-sap-applications-7 | APP -Red Hat Enterprise Linux 8.4 for SAP HANA (amd64) | ibm-redhat-8-4-amd64-sap-hana-9 | DB -Red Hat Enterprise Linux 8.4 for SAP Applications (amd64) | ibm-redhat-8-4-amd64-sap-applications-9 | APP -SUSE Linux Enterprise Server 15 SP3 for SAP HANA | ibm-sles-15-3-amd64-sap-hana-9 | DB -SUSE Linux Enterprise Server 15 SP3 for SAP Applications | ibm-sles-15-3-amd64-sap-applications-10 | APP +Red Hat Enterprise Linux 8.6 for SAP HANA (amd64) | ibm-redhat-8-6-amd64-sap-hana-6 | DB +Red Hat Enterprise Linux 8.6 for SAP Applications (amd64) | ibm-redhat-8-6-amd64-sap-applications-6 | APP +SUSE Linux Enterprise Server 15 SP4 for SAP HANA | ibm-sles-15-4-amd64-sap-hana-7 | DB +SUSE Linux Enterprise Server 15 SP4 for SAP Applications | ibm-sles-15-4-amd64-sap-applications-8 | APP +Red Hat Enterprise Linux 8.4 for SAP HANA (amd64) | ibm-redhat-8-4-amd64-sap-hana-10 | DB +Red Hat Enterprise Linux 8.4 for SAP Applications (amd64) | ibm-redhat-8-4-amd64-sap-applications-10 | APP +SUSE Linux Enterprise Server 15 SP3 for SAP HANA | ibm-sles-15-3-amd64-sap-hana-10 | DB +SUSE Linux Enterprise Server 15 SP3 for SAP Applications | ibm-sles-15-3-amd64-sap-applications-11 | APP --- S/4HANA 2022 @@ -206,14 +198,14 @@ HANA DB | 2.0 SPS07 rev73 | 51057281.ZIP OS version | Image | Role -----------|-----------|----------- -Red Hat Enterprise Linux 8.6 for SAP HANA (amd64) | ibm-redhat-8-6-amd64-sap-hana-5 | DB -Red Hat Enterprise Linux 8.6 for SAP Applications (amd64) | ibm-redhat-8-6-amd64-sap-applications-5 | APP -SUSE Linux Enterprise Server 15 SP4 for SAP HANA | ibm-sles-15-4-amd64-sap-hana-6 | DB -SUSE Linux Enterprise Server 15 SP4 for SAP Applications | ibm-sles-15-4-amd64-sap-applications-7 | APP -Red Hat Enterprise Linux 8.4 for SAP HANA (amd64) | ibm-redhat-8-4-amd64-sap-hana-9 | DB -Red Hat Enterprise Linux 8.4 for SAP Applications (amd64) | ibm-redhat-8-4-amd64-sap-applications-9 | APP -SUSE Linux Enterprise Server 15 SP3 for SAP HANA | ibm-sles-15-3-amd64-sap-hana-9 | DB -SUSE Linux Enterprise Server 15 SP3 for SAP Applications | ibm-sles-15-3-amd64-sap-applications-10 | APP +Red Hat Enterprise Linux 8.6 for SAP HANA (amd64) | ibm-redhat-8-6-amd64-sap-hana-6 | DB +Red Hat Enterprise Linux 8.6 for SAP Applications (amd64) | ibm-redhat-8-6-amd64-sap-applications-6 | APP +SUSE Linux Enterprise Server 15 SP4 for SAP HANA | ibm-sles-15-4-amd64-sap-hana-7 | DB +SUSE Linux Enterprise Server 15 SP4 for SAP Applications | ibm-sles-15-4-amd64-sap-applications-8 | APP +Red Hat Enterprise Linux 8.4 for SAP HANA (amd64) | ibm-redhat-8-4-amd64-sap-hana-10 | DB +Red Hat Enterprise Linux 8.4 for SAP Applications (amd64) | ibm-redhat-8-4-amd64-sap-applications-10 | APP +SUSE Linux Enterprise Server 15 SP3 for SAP HANA | ibm-sles-15-3-amd64-sap-hana-10 | DB +SUSE Linux Enterprise Server 15 SP3 for SAP Applications | ibm-sles-15-3-amd64-sap-applications-11 | APP --- S/4HANA 2021 @@ -234,14 +226,14 @@ HANA DB | 2.0 SPS07 rev73 | 51057281.ZIP OS version | Image | Role -----------|-----------|----------- -Red Hat Enterprise Linux 8.6 for SAP HANA (amd64) | ibm-redhat-8-6-amd64-sap-hana-5 | DB -Red Hat Enterprise Linux 8.6 for SAP Applications (amd64) | ibm-redhat-8-6-amd64-sap-applications-5 | APP -SUSE Linux Enterprise Server 15 SP4 for SAP HANA | ibm-sles-15-4-amd64-sap-hana-6 | DB -SUSE Linux Enterprise Server 15 SP4 for SAP Applications | ibm-sles-15-4-amd64-sap-applications-7 | APP -Red Hat Enterprise Linux 8.4 for SAP HANA (amd64) | ibm-redhat-8-4-amd64-sap-hana-9 | DB -Red Hat Enterprise Linux 8.4 for SAP Applications (amd64) | ibm-redhat-8-4-amd64-sap-applications-9 | APP -SUSE Linux Enterprise Server 15 SP3 for SAP HANA | ibm-sles-15-3-amd64-sap-hana-9 | DB -SUSE Linux Enterprise Server 15 SP3 for SAP Applications | ibm-sles-15-3-amd64-sap-applications-10 | APP +Red Hat Enterprise Linux 8.6 for SAP HANA (amd64) | ibm-redhat-8-6-amd64-sap-hana-6 | DB +Red Hat Enterprise Linux 8.6 for SAP Applications (amd64) | ibm-redhat-8-6-amd64-sap-applications-6 | APP +SUSE Linux Enterprise Server 15 SP4 for SAP HANA | ibm-sles-15-4-amd64-sap-hana-7 | DB +SUSE Linux Enterprise Server 15 SP4 for SAP Applications | ibm-sles-15-4-amd64-sap-applications-8 | APP +Red Hat Enterprise Linux 8.4 for SAP HANA (amd64) | ibm-redhat-8-4-amd64-sap-hana-10 | DB +Red Hat Enterprise Linux 8.4 for SAP Applications (amd64) | ibm-redhat-8-4-amd64-sap-applications-10 | APP +SUSE Linux Enterprise Server 15 SP3 for SAP HANA | ibm-sles-15-3-amd64-sap-hana-10 | DB +SUSE Linux Enterprise Server 15 SP3 for SAP Applications | ibm-sles-15-3-amd64-sap-applications-11 | APP --- S/4HANA 2020 @@ -268,28 +260,29 @@ HANA DB | 2.0 SPS07 rev73 | 51057281.ZIP OS version | Image | Role -----------|-----------|----------- -Red Hat Enterprise Linux 8.6 for SAP HANA (amd64) | ibm-redhat-8-6-amd64-sap-hana-5 | DB -Red Hat Enterprise Linux 8.6 for SAP Applications (amd64) | ibm-redhat-8-6-amd64-sap-applications-5 | APP -SUSE Linux Enterprise Server 15 SP4 for SAP HANA | ibm-sles-15-4-amd64-sap-hana-5 | DB -SUSE Linux Enterprise Server 15 SP4 for SAP Applications | ibm-sles-15-4-amd64-sap-applications-6 | APP +Red Hat Enterprise Linux 8.6 for SAP HANA (amd64) | ibm-redhat-8-6-amd64-sap-hana-6 | DB +Red Hat Enterprise Linux 8.6 for SAP Applications (amd64) | ibm-redhat-8-6-amd64-sap-applications-6 | APP +SUSE Linux Enterprise Server 15 SP4 for SAP HANA | ibm-sles-15-4-amd64-sap-hana-7 | DB +SUSE Linux Enterprise Server 15 SP4 for SAP Applications | ibm-sles-15-4-amd64-sap-applications-8 | APP ## 2.1 Executing the deployment of **Three Tiers SAP S/4HANA Stack** in GUI (Schematics) -### IBM Cloud API Key -The IBM Cloud API Key should be provided as input value of type sensitive for "IBMCLOUD_API_KEY" variable, in `IBM Schematics -> Workspaces -> -> Settings` menu. -The IBM Cloud API Key can be created [here](https://cloud.ibm.com/iam/apikeys). - +The solution is based on Terraform remote-exec and Ansible playbooks executed by Schematics ### Input parameters -The following parameters can be set in the Schematics workspace: VPC, Subnet, Security group, Resource group, Hostname, Profile, Image, SSH Keys and your SAP system configuration variables. These are described in [General input variables Section](#15-general-input-variables) section. +The following parameters that can be set in the Schematics workspace are described in [General input variables Section](#15-general-input-variables) section. Beside [General input variables Section](#15-general-input-variables), the below ones, in IBM Schematics have specific description and GUI input options: -**VSI input parameters:** +**Server input parameters:** Parameter | Description ----------|------------ -PRIVATE_SSH_KEY | Input your id_rsa private key pair content in OpenSSH format (Sensitive* value). This private key should be used only during the terraform provisioning and it is recommended to be changed after the SAP deployment. +PRIVATE_SSH_KEY | id_rsa private SSH key content in OpenSSH format (Sensitive* value). This private SSH key should be used only during the terraform provisioning and it is recommended to be changed after the SAP deployment. +ID_RSA_FILE_PATH | The file path for the private ssh key. It will be automatically generated. If it is changed, it must contain the relative path from git repo folders. Example: ansible/id_rsa_s4hana_dst + +**SAP and HANA Passwords** +The passwords for the SAP and HANA systems will be hidden during the schematics apply step and will not be available after the deployment. ### Steps to follow @@ -326,19 +319,17 @@ PRIVATE_SSH_KEY | Input your id_rsa private key pair content in OpenSSH format ( 7. Review the logs to ensure that no errors occurred during the provisioning, modification, or deletion process. - In the output of the Schematics `Apply Plan` the private IP address of the VSI hosts, the hostname of the VSIs, the VPC and the Activity Tracker instance name will be displayed. + In the output of the Schematics `Apply Plan` the private IP address of the Servers, the hostname of the servers, the VPC and the Activity Tracker instance name will be displayed. ## 2.2 Executing the deployment of **Three Tiers SAP S4HANA Stack** in CLI ### IBM Cloud API Key For the script configuration add your IBM Cloud API Key in terraform planning phase command 'terraform plan --out plan1'. -You can create an API Key [here](https://cloud.ibm.com/iam/apikeys). ### Input parameter file -The solution is configured by editing your variables in the file `input.auto.tfvars` -Edit your VPC, Subnet, Security group, Hostnames, Profile, Image, SSH Keys and starting with minimal recommended disk sizes like so: +The solution is configured by editing the variable values in the file `input.auto.tfvars`. See the example below: -**VSI input parameters** +**Server input parameters** ```shell ########################################################## @@ -346,15 +337,15 @@ Edit your VPC, Subnet, Security group, Hostnames, Profile, Image, SSH Keys and s ###################################################### REGION = "eu-de" -# Region for the VSI. Supported regions: https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones-vpc +# Region for the server. Supported regions: https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones-vpc # Example: REGION = "eu-de" ZONE = "eu-de-1" -# Availability zone for VSI. Supported zones: https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones-vpc +# Availability zone for the server. Supported zones: https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones-vpc # Example: ZONE = "eu-de-1" VPC = "ic4sap" -# EXISTING VPC, previously created by the user in the same region as the VSI. The list of available VPCs: https://cloud.ibm.com/vpc-ext/network/vpcs +# EXISTING VPC, previously created by the user in the same region as the server. The list of available VPCs: https://cloud.ibm.com/vpc-ext/network/vpcs # Example: VPC = "ic4sap" SECURITY_GROUP = "ic4sap-securitygroup" @@ -366,45 +357,48 @@ RESOURCE_GROUP = "wes-automation" # Example: RESOURCE_GROUP = "wes-automation" SUBNET = "ic4sap-subnet" -# EXISTING Subnet in the same region and zone as the VSI, previously created by the user. The list of available Subnets: https://cloud.ibm.com/vpc-ext/network/subnets +# EXISTING Subnet in the same region and zone as the server, previously created by the user. The list of available Subnets: https://cloud.ibm.com/vpc-ext/network/subnets # Example: SUBNET = "ic4sap-subnet" SSH_KEYS = ["r010-8f72b994-c17f-4500-af8f-d05680374t3c", "r011-8f72v884-c17f-4500-af8f-d05900374t3c"] -# List of SSH Keys UUIDs that are allowed to SSH as root to the VSI. The SSH Keys should be created for the same region as the VSI. The list of available SSH Keys UUIDs: https://cloud.ibm.com/vpc-ext/compute/sshKeys +# List of SSH Keys UUIDs that are allowed to SSH as root to the server. The SSH Keys should be created for the same region as the server. The list of available SSH Keys UUIDs: https://cloud.ibm.com/vpc-ext/compute/sshKeys # Example: SSH_KEYS = ["r010-8f72b994-c17f-4500-af8f-d05680374t3c", "r011-8f72v884-c17f-4500-af8f-d05900374t3c"] ID_RSA_FILE_PATH = "ansible/id_rsa" -# Input your existing id_rsa private key file path in OpenSSH format with 0600 permissions. -# This private key it is used only during the terraform provisioning and it is recommended to be changed after the SAP deployment. +# The id_rsa private key file path in OpenSSH format with 0600 permissions. +# This private key is used only during the terraform provisioning and it is recommended to be changed after the SAP deployment. # It must contain the relative or absoute path from your Bastion. -# Examples: "ansible/id_rsa_s4hana" , "~/.ssh/id_rsa_s4hana" , "/root/.ssh/id_rsa". +# Examples: "ansible/id_rsa_s4hana_dst" , "~/.ssh/id_rsa_s4hana_dst" , "/root/.ssh/id_rsa". ########################################################## -# Activity Tracker variables: +# SAP HANA Server variables ########################################################## -ATR_NAME = "Activity-Tracker-SAP-eu-de" -# The name of the Activity Tracker instance, in the same region chosen for SAP system deployment. -# Example: ATR_NAME="Activity-Tracker-SAP-eu-de" +HANA_SERVER_TYPE = "virtual" +# The type of SAP HANA Server. Allowed vales: "virtual" or "bare metal" +# Example: HANA_SERVER_TYPE = "bare metal" ########################################################## -# DB VSI variables: +# DB server variables: ########################################################## DB_HOSTNAME = "ic4sapdb" -# The Hostname for the DB VSI. The hostname should be up to 13 characters, as required by SAP +# The Hostname for the DB server. The hostname should be up to 13 characters, as required by SAP # Example: DB_HOSTNAME = "ic4sapdb" DB_PROFILE = "mx2-16x128" -# The instance profile used for the HANA VSI. The list of certified profiles for HANA VSIs: https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc -# Details about all x86 instance profiles: https://cloud.ibm.com/docs/vpc?topic=vpc-profiles). -# For more information about supported DB/OS and IBM Gen 2 Virtual Server Instances (VSI), check [SAP Note 2927211: SAP Applications on IBM Virtual Private Cloud](https://launchpad.support.sap.com/#/notes/2927211) -# Default value: "mx2-16x128" - -DB_IMAGE = "ibm-redhat-8-6-amd64-sap-hana-5" -# OS image for DB VSI. Validated OS images for DB VSIs: ibm-redhat-8-6-amd64-sap-hana-5, ibm-redhat-8-4-amd64-sap-hana-9, ibm-sles-15-4-amd64-sap-hana-6, ibm-sles-15-3-amd64-sap-hana-9. +# The profile used for SAP HANA Server. +# The list of certified profiles for SAP HANA Virtual Servers is available here: https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc +# The list of certified profiles for SAP HANA Bare Metal Servers is available here: https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-bm-vpc. +# Details about all x86 instance profiles are available here: https://cloud.ibm.com/docs/vpc?topic=vpc-profiles. +# Example of Virtual Server Instance profile for SAP HANA: DB_PROFILE ="mx2-16x128". +# Example of Bare Metal profile for SAP HANA: DB_PROFILE = "bx2d-metal-96x384". +# For more information about supported DB/OS and IBM VPC, check SAP Note 2927211: "SAP Applications on IBM Virtual Private Cloud". + +DB_IMAGE = "ibm-redhat-8-6-amd64-sap-hana-6" +# OS image for DB server. Validated OS images for DB serverss: ibm-redhat-8-6-amd64-sap-hana-6, ibm-redhat-8-4-amd64-sap-hana-10, ibm-sles-15-4-amd64-sap-hana-7, ibm-sles-15-3-amd64-sap-hana-10. # The list of available VPC Operating Systems supported by SAP: SAP note '2927211 - SAP Applications on IBM Virtual Private Cloud (VPC) Infrastructure environment' https://launchpad.support.sap.com/#/notes/2927211; The list of all available OS images: https://cloud.ibm.com/docs/vpc?topic=vpc-about-images -# Example: DB_IMAGE = "ibm-sles-15-4-amd64-sap-hana-6" +# Example: DB_IMAGE = "ibm-sles-15-4-amd64-sap-hana-7" ########################################################## # SAP APP VSI variables: @@ -417,10 +411,10 @@ APP_HOSTNAME = "ic4sapapp" APP_PROFILE = "bx2-4x16" # The APP VSI profile. Supported profiles: bx2-4x16. The list of available profiles: https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui -APP_IMAGE = "ibm-redhat-8-6-amd64-sap-applications-5" -# OS image for SAP APP VSI. Validated OS images for APP VSIs: ibm-redhat-8-6-amd64-sap-applications-5, ibm-redhat-8-4-amd64-sap-applications-9, ibm-sles-15-4-amd64-sap-applications-7, ibm-sles-15-3-amd64-sap-applications-10. +APP_IMAGE = "ibm-redhat-8-6-amd64-sap-applications-6" +# OS image for SAP APP VSI. Validated OS images for APP VSIs: ibm-redhat-8-6-amd64-sap-applications-6, ibm-redhat-8-4-amd64-sap-applications-10, ibm-sles-15-4-amd64-sap-applications-8, ibm-sles-15-3-amd64-sap-applications-11. # The list of available VPC Operating Systems supported by SAP: SAP note '2927211 - SAP Applications on IBM Virtual Private Cloud (VPC) Infrastructure environment' https://launchpad.support.sap.com/#/notes/2927211; The list of all available OS images: https://cloud.ibm.com/docs/vpc?topic=vpc-about-images -# Example: APP-IMAGE = "ibm-sles-15-4-amd64-sap-applications-7" +# Example: APP-IMAGE = "ibm-sles-15-4-amd64-sap-applications-8" ``` Edit your SAP system configuration variables that will be passed to the ansible automated deployment: @@ -446,6 +440,10 @@ HANA_SYSNO = "00" # SAP HANA instance number. Should follow the SAP rules for instance number naming. # Example: HANA_SYSNO = "01" +HANA_TENANT = "HDB" +# SAP HANA tenant name +# Example:HANA_TENANT = "HDB_TEN1" + HANA_SYSTEM_USAGE = "custom" # System usage. Default: custom. Suported values: production, test, development, custom # Example: HANA_SYSTEM_USAGE = "custom" @@ -454,9 +452,9 @@ HANA_COMPONENTS = "server" # SAP HANA Components. Default: server. Supported values: all, client, es, ets, lcapps, server, smartda, streaming, rdsync, xs, studio, afl, sca, sop, eml, rme, rtl, trp # Example: HANA_COMPONENTS = "server" -KIT_SAPHANA_FILE = "/storage/HANADB/51057281.ZIP" +KIT_SAPHANA_FILE = "/storage/HANADB/SP07/Rev73/51057281.ZIP" # SAP HANA Installation kit path -# Example for Red Hat 8 or Suse 15: KIT_SAPHANA_FILE = "/storage/HANADB/51057281.ZIP" +# Example for Red Hat 8 or Suse 15: KIT_SAPHANA_FILE = "/storage/HANADB/SP07/Rev73/51057281.ZIP" ########################################################## # SAP system configuration diff --git a/ansible/roles/s4appfs/defaults/main.yml b/ansible/roles/s4appfs/defaults/main.yml index d016f15..c81cf5b 100644 --- a/ansible/roles/s4appfs/defaults/main.yml +++ b/ansible/roles/s4appfs/defaults/main.yml @@ -1,41 +1,3 @@ --- -#Disk size config -sap_disk_size: "128.00 GB" -swap_disk_size: "40.00 GB" -#Logical volume size config -# swap_lv_size: "30g" -usrsap_lv_size: "5g" -sap_lv_size: "20g" -sapmnt_lv_size: "20g" -saptrans_lv_size: "50g" - -swap_lv: - - size: 38 - ram_min: 32 - ram_max: 63 - - size: 38 - ram_min: 64 - ram_max: 127 - - size: 38 - ram_min: 128 - ram_max: 255 - - size: 38 - ram_min: 256 - ram_max: 511 - - size: 38 - ram_min: 512 - ram_max: 1023 - - size: 224 - ram_min: 1024 - ram_max: 2047 - - size: 38 - ram_min: 2048 - ram_max: 4095 - - size: 288 - ram_min: 4096 - ram_max: 8191 - - size: 38 - ram_min: 8192 - ram_max: 20000 ... diff --git a/ansible/roles/s4appfs/filter_plugins/filesystemdata.py b/ansible/roles/s4appfs/filter_plugins/filesystemdata.py new file mode 100644 index 0000000..bc18d11 --- /dev/null +++ b/ansible/roles/s4appfs/filter_plugins/filesystemdata.py @@ -0,0 +1,56 @@ +#!/usr/bin/python + +class FilterModule(object): + '''Data related to filesystems for HANA VM''' + + def filters(self): + return { + 'filesystemdata': self.filesystemdata + } + + def filesystemdata(self, data_list): + final_list = [] + data_map = data_list[0] + sid = data_list[1] + for k, v in data_map.items(): + key_to_check = 'lvm' + if key_to_check in v: + for m in v['lvm']['lv']: + temp_list = [] + fs_device = "/dev/" + sid + "_" + v['lvm']['vg']['vg_name'] + "/" + sid + "_" + m['lv_name'] + mp = None + fs_options = "" + mount_opt = "defaults" + mount_source = fs_device + if "label" in m.keys(): + fs_options = "-L " + m['label'] + mount_source = "LABEL=" + m['label'] + if "fs_create_options" in m.keys(): + fs_options = fs_options + " " + m['fs_create_options'] + if "mount_point" in m.keys(): + mp = m['mount_point'] + if "mount_options" in m.keys(): + mount_opt = m['mount_options'] + fs_info = { "fs_device": fs_device, "fs_type": m['fs_type'], "mp": mp, "fs_options": fs_options, "mount_source": mount_source, "mount_opt": mount_opt } + temp_list.append(fs_info) + final_list.append(temp_list) + else: + temp_list = [] + fs_device = v['device'][0] + "1" + fs_options = "" + mount_opt = "" + mount_source = fs_device + mp = None + if "label" in v.keys(): + fs_options = "-L " + v['label'] + mount_source = "LABEL=" + v['label'] + if "fs_create_options" in v.keys(): + fs_options = fs_options + " " + v['fs_create_options'] + if "mount_point" in v.keys(): + mp = v['mount_point'] + if "mount_options" in v.keys(): + mount_opt = v['mount_options'] + fs_info = { "fs_device": fs_device, "fs_type": v['fs_type'], "mp": mp, "fs_options": fs_options, "mount_source": mount_source, "mount_opt": mount_opt } + temp_list.append(fs_info) + final_list.append(temp_list) + return final_list diff --git a/ansible/roles/s4appfs/filter_plugins/lvmdata.py b/ansible/roles/s4appfs/filter_plugins/lvmdata.py new file mode 100644 index 0000000..b5575db --- /dev/null +++ b/ansible/roles/s4appfs/filter_plugins/lvmdata.py @@ -0,0 +1,39 @@ +#!/usr/bin/python + +class FilterModule(object): + '''Data related to LVM for HANA VM''' + + def filters(self): + return { + 'lvmdata': self.lvmdata + } + + def lvmdata(self, data_map): + final_list = [] + for k, v in data_map.items(): + if 'lvm' in v.keys(): + for m in v['lvm']['lv']: + temp_list = [] + lv_size = "" + if '%' not in m['lv_size']: + lv_size = m['lv_size'] + "G" + else: + lv_size = m['lv_size'] + lv_options = "" + if "raid_type" in m.keys(): + lv_options = "--type " + m['raid_type'] + if "mirrors" in m.keys(): + lv_options += " -m " + m['mirrors'] + if "lv_stripes" in m.keys(): + lv_options += " -i " + m['lv_stripes'] + if "lv_stripe_size" in m.keys(): + lv_options += " -I " + m['lv_stripe_size'] + lvm_info = { "vg_name": v['lvm']['vg']['vg_name'], "lv_name": m['lv_name'], "lv_size": lv_size, "lv_options": lv_options } + temp_list.append(lvm_info) + final_list.append(temp_list) + for i in range(len(final_list)): + # LVM data 'hana_data_lv' should be last in array (in case it will be created in 'hana_vg') as we want 100%FREE as size + if final_list[i][0]['lv_name'] == 'hana_data_lv': + final_list.append(final_list.pop(i)) + break + return final_list diff --git a/ansible/roles/s4appfs/filter_plugins/partitionlist.py b/ansible/roles/s4appfs/filter_plugins/partitionlist.py new file mode 100644 index 0000000..dd8f7e1 --- /dev/null +++ b/ansible/roles/s4appfs/filter_plugins/partitionlist.py @@ -0,0 +1,17 @@ +#!/usr/bin/python + +class FilterModule(object): + '''List of devices for partitions on HANA VM''' + + def filters(self): + return { + 'partitionlist': self.partitionlist + } + + def partitionlist(self, data_map): + final_list = [] + for k, v in data_map.items(): + key_to_check = 'lvm' + if key_to_check not in v: + final_list.append(v['device']) + return final_list diff --git a/ansible/roles/s4appfs/filter_plugins/storagedetails.py b/ansible/roles/s4appfs/filter_plugins/storagedetails.py new file mode 100644 index 0000000..0acaaf6 --- /dev/null +++ b/ansible/roles/s4appfs/filter_plugins/storagedetails.py @@ -0,0 +1,93 @@ +#!/usr/bin/python + +import decimal + +class FilterModule(object): + '''Storage details from profile containing also the devices for HANA VM''' + + def filters(self): + return { + 'storagedetails': self.storagedetails + } + + def storagedetails(self, data_list): + # data_list[0] - json file data + # data_list[1] - ansible_devices data + # data_list[2] - selected storage profile + json_file_data = data_list[0] + ansible_devices_data = data_list[1] + hana_profile = data_list[2] + + storage_profile_info = json_file_data['profiles'][hana_profile]['storage'] + + # Get a list with the provisioned disk sizes + size_provisioned_disks = [] + for m, n in ansible_devices_data.items(): + size_provisioned_disks.append(n['size']) + + # Sort the list with provisioned disk sizes + size_provisioned_disks_sorted = sorted(size_provisioned_disks) + + # Get a list of disk sizes corresponding to the selected profile + size_profile_disks = [] + for k, v in storage_profile_info.items(): + display_size = "" + if float(v['disk_size']) >= 1024: + rounded_val = round(decimal.Decimal(float(v['disk_size']) / 1024), 2) + no_decimal_places = abs(rounded_val.as_tuple().exponent) + if no_decimal_places == 0: + display_size = str(rounded_val) + ".00 TB" + elif no_decimal_places == 1: + display_size = str(rounded_val) + "0 TB" + elif no_decimal_places == 2: + display_size = str(rounded_val) + " TB" + else: + display_size = v['disk_size'] + ".00 GB" + for t in range(int(v['disk_count'])): + size_profile_disks.append(display_size) + + # Sort the list with disk sizes from profile + size_profile_disks_sorted = sorted(size_profile_disks) + + # Non-HANA provisioned disks (only different sizes) + non_hana_disks = [x for x in size_provisioned_disks_sorted if x not in size_profile_disks_sorted] + + # Remove non-hana disks (only different sizes) from the list of provisioned disks + for t in non_hana_disks: + for j in size_provisioned_disks_sorted: + if t == j: + size_provisioned_disks_sorted.remove(j) + break + + # Get the missing disks + if (len(size_profile_disks_sorted) - len(size_provisioned_disks_sorted) > 0) or (len(set(size_profile_disks_sorted)) != len(set(size_provisioned_disks_sorted))): + msg = "The disks required for profile '" + hana_profile + "' are missing. The following disks sizes are required: " + str(size_profile_disks_sorted)[1:-1] + ". The following disk sizes were deployed: " + str(size_provisioned_disks_sorted)[1:-1] + return msg + else: + temp_list = [] + for k, v in sorted(storage_profile_info.items()): + new_list1 = [] + new_list2 = [] + display_size = "" + if float(v['disk_size']) >= 1024: + rounded_val = round(decimal.Decimal(float(v['disk_size']) / 1024), 2) + no_decimal_places = abs(rounded_val.as_tuple().exponent) + if no_decimal_places == 0: + display_size = str(rounded_val) + ".00 TB" + elif no_decimal_places == 1: + display_size = str(rounded_val) + "0 TB" + elif no_decimal_places == 2: + display_size = str(rounded_val) + " TB" + else: + display_size = v['disk_size'] + ".00 GB" + for t in range(int(v['disk_count'])): + new_list1.append(v['disk_size']) + for m, n in sorted(ansible_devices_data.items()): + if (n['size'] == display_size) and ("dm-" not in m) and (m not in temp_list) and n['partitions'] == {} and n['links']['labels'] == [] and len(n['links']['ids']) > 0: + new_list2.append("/dev/" + m) + temp_list.append(m) + break + storage_profile_info[k]['disk_size'] = new_list1 + storage_profile_info[k]['device'] = new_list2 + final_storage = storage_profile_info + return final_storage diff --git a/ansible/roles/s4appfs/tasks/main.yml b/ansible/roles/s4appfs/tasks/main.yml index fbb0c67..d1e0c20 100644 --- a/ansible/roles/s4appfs/tasks/main.yml +++ b/ansible/roles/s4appfs/tasks/main.yml @@ -1,166 +1,122 @@ --- -- name: Get available storage devices for swap +- name: Set default JSON file set_fact: - swap_disk: "{{ swap_disk|default([]) + [device.key] }}" - when: - - not device.value.partitions - - not device.value.holders - - device.key is search('vd') - - device.value.size == swap_disk_size - loop: "{{ ansible_devices | dict2items }}" - loop_control: - loop_var: device - -- name: Check if the required storage device for swap is found - fail: - msg: "Could not find a free {{ swap_disk_size }} storage device for swap" - when: swap_disk is not defined - -- name: Create a volume group for swap - lvg: - vg: "{{ sap_sid|lower }}_swap_vg" - pvs: "/dev/{{ swap_disk[0] }}" - pesize: "32" + sapapp_vol_setup_json: "sapapp_vm_volume_layout.json" -- name: Get available storage devices for SAP instance - set_fact: - sap_disk: "{{ sap_disk|default([]) + [device.key] }}" - when: - - not device.value.partitions - - not device.value.holders - - device.key is search('vd') - - device.value.size == sap_disk_size - loop: "{{ ansible_devices | dict2items }}" - loop_control: - loop_var: device +- name: Check if the JSON file for SAP APP VSI storage configuration is available on Ansible controller + stat: + path: "{{ playbook_dir }}/{{ sapapp_vol_setup_json }}" + register: json_sapapp_storage_file_status + delegate_to: localhost -- name: Check if the required storage device for SAP instance is found +- name: Fail if the JSON file is missing fail: - msg: "Could not find a free {{ sap_disk_size }} storage device for SAP instance" - when: sap_disk is not defined + msg: "The file {{ playbook_dir }}/{{ sapapp_vol_setup_json }} is missing." + when: not json_sapapp_storage_file_status.stat.exists -- name: Create a volume group for SAP instance - lvg: - vg: "{{ sap_sid|lower }}_app_vg" - pvs: "/dev/{{ sap_disk[0] }}" - pesize: "32" +- name: Get the JSON file content + shell: "cat {{ playbook_dir }}/{{ sapapp_vol_setup_json }}" + register: sapapp_result + changed_when: false + when: json_sapapp_storage_file_status.stat.exists + delegate_to: localhost -- name: Get the RAM size +- name: Replace the holders in the output with the appropriate values set_fact: - app_ram: "{{ app_profile.split('-')[1].split('x')[1] }}" + sapapp_result: "{{ (sapapp_result | regex_replace(replace_item.old_val, replace_item.new_val)) }}" + loop: + - { old_val: '', new_val: "{{ sap_sid | lower }}" } + - { old_val: '', new_val: "{{ swap_disk_size }}" } + - { old_val: '', new_val: "{{ sap_sid | upper }}" } + loop_control: + loop_var: replace_item -- name: Get the swap logical volume size for RAM lower than 32 GB +- name: Save the JSON data to a variable as a fact set_fact: - swap_lv_size: "{{ app_ram | int * 2 }}g" - when: app_ram | int < 32 + sapapp_jsondata: "{{ sapapp_result.stdout | from_json }}" -- name: Get the swap logical volume size for RAM higher than 32 GB and lower than 8192 +- name: Set the SAP APP profile set_fact: - swap_lv_size: "{{ data_swap.size }}g" - loop: "{{ swap_lv }}" - loop_control: - loop_var: data_swap - when: (app_ram | int >= 32) and (app_ram | int < 8192) and (app_ram | int >= data_swap.ram_min) and (app_ram | int <= data_swap.ram_max) + sapapp_profile: "default" -- name: Get the swap logical volume size for RAM higher than 8192 +- name: Detect the appropriate disks to be configured set_fact: - swap_lv_size: "32g" - when: app_ram | int >= 8192 + sapapp_final_storage: "{{ [sapapp_jsondata, ansible_devices, sapapp_profile] | list | storagedetails }}" -- name: Create a logical volume for swap - lvol: - vg: "{{ sap_sid|lower }}_swap_vg" - lv: "{{ sap_sid|lower }}_swap_lv" - size: "{{ swap_lv_size }}" - -- name: Create a logical volume for /usr/sap - lvol: - vg: "{{ sap_sid|lower }}_app_vg" - lv: "{{ sap_sid|lower }}_usrsap_lv" - size: "{{ usrsap_lv_size }}" +- name: Get the missing disks + fail: + msg: "{{ sapapp_final_storage }}" + when: sapapp_final_storage is not mapping -- name: Create a logical volume for /usr/sap/{{ sap_sid|upper }} - lvol: - vg: "{{ sap_sid|lower }}_app_vg" - lv: "{{ sap_sid|lower }}_sap_lv" - size: "{{ sap_lv_size }}" +- name: Display final_storage + debug: + var: sapapp_final_storage -- name: Create a logical volume for /sapmnt/{{ sap_sid|upper }} - lvol: - vg: "{{ sap_sid|lower }}_app_vg" - lv: "{{ sap_sid|lower }}_sapmnt_lv" - size: "{{ sapmnt_lv_size }}" +- name: Create the volume groups + lvg: + vg: "{{ sap_sid | lower }}_{{ sapapp_stg_details.value.lvm.vg.vg_name }}" + pvs: "{{ sapapp_stg_details.value.device | join(',') }}" + loop: "{{ sapapp_final_storage | dict2items }}" + loop_control: + loop_var: sapapp_stg_details + when: '"lvm" in sapapp_stg_details.value.keys()' -- name: Create a logical volume for /usr/sap/trans +- name: Create the logical volumes lvol: - vg: "{{ sap_sid|lower }}_app_vg" - lv: "{{ sap_sid|lower }}_saptrans_lv" - size: "{{ saptrans_lv_size }}" - -- name: Create a swap filesystem - filesystem: - fstype: swap - dev: "/dev/{{ sap_sid|lower }}_swap_vg/{{ sap_sid|lower }}_swap_lv" - -- name: Create filesystem for /usr/sap - filesystem: - fstype: ext4 - dev: "/dev/{{ sap_sid|lower }}_app_vg/{{ sap_sid|lower }}_usrsap_lv" - -- name: Create filesystem for /usr/sap/{{ sap_sid|upper }} - filesystem: - fstype: ext4 - dev: "/dev/{{ sap_sid|lower }}_app_vg/{{ sap_sid|lower }}_sap_lv" - -- name: Create filesystem for /sapmnt/{{ sap_sid|upper }} - filesystem: - fstype: ext4 - dev: "/dev/{{ sap_sid|lower }}_app_vg/{{ sap_sid|lower }}_sapmnt_lv" + vg: "{{ sap_sid|lower }}_{{ sapapp_lvm_data[0]['vg_name'] }}" + lv: "{{ sap_sid|lower }}_{{ sapapp_lvm_data[0]['lv_name'] }}" + size: "{{ sapapp_lvm_data[0]['lv_size'] }}" + opts: "{{ sapapp_lvm_data[0]['lv_options'] }}" + shrink: false + loop: "{{ sapapp_final_storage | lvmdata }}" + loop_control: + loop_var: sapapp_lvm_data + +- name: Create the partitions + parted: + device: "{{ sapapp_part[0] }}" + number: 1 + label: gpt + state: present + loop: "{{ sapapp_final_storage | partitionlist }}" + loop_control: + loop_var: sapapp_part -- name: Create filesystem for /usr/sap/trans +- name: Create the filesystems filesystem: - fstype: ext4 - dev: "/dev/{{ sap_sid|lower }}_app_vg/{{ sap_sid|lower }}_saptrans_lv" - -- name: Add swap device to /etc/fstab - lineinfile: - path: /etc/fstab - regexp: "^/dev/{{ sap_sid|lower }}_swap_vg/{{ sap_sid|lower }}_swap_lv" - line: "/dev/{{ sap_sid|lower }}_swap_vg/{{ sap_sid|lower }}_swap_lv swap swap defaults 0 0" + fstype: "{{ sapapp_fs_data[0]['fs_type'] }}" + dev: "{{ sapapp_fs_data[0]['fs_device'] }}" + opts: "{{ sapapp_fs_data[0]['fs_options'] }}" + loop: "{{ [sapapp_final_storage, sap_sid | lower] | filesystemdata }}" + loop_control: + loop_var: sapapp_fs_data -- name: Check the current swap size +- name: Check if the filesystems should be mounted in a specific order set_fact: - sap_vm_swap: "{{ ansible_swaptotal_mb }}" - -- name: Mount swap volume - command: swapon -a - when: sap_vm_swap == 0 - -- name: Mount /usr/sap and add it to /etc/fstab - mount: - path: "/usr/sap" - src: "/dev/{{ sap_sid|lower }}_app_vg/{{ sap_sid|lower }}_usrsap_lv" - fstype: ext4 - state: mounted + mounpoints: mp_d[0]['mp'] + loop: "{{ [sapapp_final_storage, sap_sid | lower] | filesystemdata }}" + loop_control: + loop_var: sapapp_mp_d + when: sapapp_mp_d[0]['mp'] != None -- name: Mount /usr/sap/{{ sap_sid|upper }} and add it to /etc/fstab +- name: Mount the filesystems mount: - path: "/usr/sap/{{ sap_sid|upper }}" - src: "/dev/{{ sap_sid|lower }}_app_vg/{{ sap_sid|lower }}_sap_lv" - fstype: ext4 + path: "{{ sapapp_mp_data[0]['mp'] }}" + src: "{{ sapapp_mp_data[0]['mount_source'] }}" + fstype: "{{ sapapp_mp_data[0]['fs_type'] }}" + opts: "{{ sapapp_mp_data[0]['mount_opt'] }}" state: mounted + loop: "{{ [sapapp_final_storage, sap_sid | lower] | filesystemdata }}" + loop_control: + loop_var: sapapp_mp_data + when: sapapp_mp_data[0]['mp'] != None -- name: Mount /sapmnt/{{ sap_sid|upper }} and add it to /etc/fstab - mount: - path: "/sapmnt/{{ sap_sid|upper }}" - src: "/dev/{{ sap_sid|lower }}_app_vg/{{ sap_sid|lower }}_sapmnt_lv" - fstype: ext4 - state: mounted +- name: Create SWAP on VSI + ansible.builtin.include_tasks: + file: swap_vm.yml -- name: Mount /usr/sap/trans and add it to /etc/fstab - mount: - path: "/usr/sap/trans" - src: "/dev/{{ sap_sid|lower }}_app_vg/{{ sap_sid|lower }}_saptrans_lv" - fstype: ext4 - state: mounted +- name: Reboot target host + reboot: + connect_timeout: 5 + post_reboot_delay: 10 ... diff --git a/ansible/roles/s4appfs/tasks/swap_vm.yml b/ansible/roles/s4appfs/tasks/swap_vm.yml new file mode 100644 index 0000000..898ea31 --- /dev/null +++ b/ansible/roles/s4appfs/tasks/swap_vm.yml @@ -0,0 +1,22 @@ +--- +- name: Get SWAP LV name + set_fact: + sapapp_swap_lv: "{{ sapapp_swap_data[0]['fs_device'] }}" + loop: "{{ [sapapp_final_storage, sap_sid | lower] | filesystemdata }}" + loop_control: + loop_var: sapapp_swap_data + +- name: Check the current SWAP size + set_fact: + sapapp_swap: "{{ ansible_swaptotal_mb }}" + +- name: Mount SWAP volume + command: "swapon -av {{ sapapp_swap_lv }}" + when: sapapp_swap == 0 + +- name: Add SWAP device to /etc/fstab + lineinfile: + path: /etc/fstab + regexp: "^{{ sapapp_swap_lv }}" + line: "{{ sapapp_swap_lv }} swap swap defaults 0 0" +... diff --git a/ansible/roles/s4appinst/templates/sapinst_2020.cfg b/ansible/roles/s4appinst/templates/sapinst_2020.cfg index f546f9b..571052b 100644 --- a/ansible/roles/s4appinst/templates/sapinst_2020.cfg +++ b/ansible/roles/s4appinst/templates/sapinst_2020.cfg @@ -143,7 +143,8 @@ NW_HDB_DB.abapSchemaPassword = {{ sap_main_password }} NW_HDB_getDBInfo.dbhost = {{ hdb_host }} # Database system ID -NW_HDB_getDBInfo.dbsid = {{ hdb_sid|upper }} +# NW_HDB_getDBInfo.dbsid = {{ hdb_sid|upper }} +NW_HDB_getDBInfo.dbsid = {{ hana_tenant|upper }} # The instance number of the SAP HANA database server NW_HDB_getDBInfo.instanceNumber = {{ hdb_instance_number }} diff --git a/ansible/roles/s4appinst/templates/sapinst_2021.cfg b/ansible/roles/s4appinst/templates/sapinst_2021.cfg index f1f5f1f..f3ea056 100644 --- a/ansible/roles/s4appinst/templates/sapinst_2021.cfg +++ b/ansible/roles/s4appinst/templates/sapinst_2021.cfg @@ -190,7 +190,8 @@ NW_HDB_DB.installPAi = false NW_HDB_getDBInfo.dbhost = {{ hdb_host }} # Database system ID -NW_HDB_getDBInfo.dbsid = {{ hdb_sid|upper }} +# NW_HDB_getDBInfo.dbsid = {{ hdb_sid|upper }} +NW_HDB_getDBInfo.dbsid = {{ hana_tenant|upper }} # The instance number of the SAP HANA database server NW_HDB_getDBInfo.instanceNumber = {{ hdb_instance_number }} diff --git a/ansible/roles/s4appinst/templates/sapinst_2022.cfg b/ansible/roles/s4appinst/templates/sapinst_2022.cfg index 7e5a30b..9243e0c 100644 --- a/ansible/roles/s4appinst/templates/sapinst_2022.cfg +++ b/ansible/roles/s4appinst/templates/sapinst_2022.cfg @@ -184,7 +184,8 @@ NW_HDB_DB.installPAi = false NW_HDB_getDBInfo.dbhost = {{ hdb_host }} # Database system ID -NW_HDB_getDBInfo.dbsid = {{ hdb_sid|upper }} +# NW_HDB_getDBInfo.dbsid = {{ hdb_sid|upper }} +NW_HDB_getDBInfo.dbsid = {{ hana_tenant|upper }} # The instance number of the SAP HANA database server NW_HDB_getDBInfo.instanceNumber = {{ hdb_instance_number }} diff --git a/ansible/roles/s4appinst/templates/sapinst_2023.cfg b/ansible/roles/s4appinst/templates/sapinst_2023.cfg index 6463fca..d454b62 100644 --- a/ansible/roles/s4appinst/templates/sapinst_2023.cfg +++ b/ansible/roles/s4appinst/templates/sapinst_2023.cfg @@ -196,7 +196,8 @@ NW_HDB_DB.installPAi = false NW_HDB_getDBInfo.dbhost = {{ hdb_host }} # Database system ID -NW_HDB_getDBInfo.dbsid = {{ hdb_sid|upper }} +# NW_HDB_getDBInfo.dbsid = {{ hdb_sid|upper }} +NW_HDB_getDBInfo.dbsid = {{ hana_tenant|upper }} # The instance number of the SAP HANA database server NW_HDB_getDBInfo.instanceNumber = {{ hdb_instance_number }} diff --git a/ansible/roles/saphanainst/tasks/main.yml b/ansible/roles/saphanainst/tasks/main.yml index b85e6ed..ba8f6ca 100644 --- a/ansible/roles/saphanainst/tasks/main.yml +++ b/ansible/roles/saphanainst/tasks/main.yml @@ -16,6 +16,18 @@ shell: "{{ hana_kit }}/DATA_UNITS/HDB_SERVER_LINUX_X86_64/hdblcm --configfile={{ hana_kit }}/hanaconfig.cfg -b" when: not hdb_install_status.stat.exists +- name: Check if SAP HANA Tenant + shell: | + set -o pipefail + su - {{ hana_sid|lower }}adm -c "hdbnsutil -printsysteminformation | grep -v SYSTEMDB" + register: sysinfo_cmd + changed_when: false + +- name: Create SAP HANA Tenant if it doesn't exist + shell: su - {{ hana_sid|lower }}adm -c "hdbsql -d SYSTEMDB -u SYSTEM -p \"{{ hana_main_password }}\" -i {{ hana_sysno }} \"CREATE DATABASE {{ hana_tenant | upper }} SYSTEM USER PASSWORD \\\"{{ hana_main_password }}\\\"\"" + no_log: true + when: hana_tenant | upper not in sysinfo_cmd.stdout + - name: Cleanup file: path: "{{ hana_kit }}" diff --git a/ansible/roles/saphanainst/templates/hanaconfig.cfg b/ansible/roles/saphanainst/templates/hanaconfig.cfg index 291aea4..c6dc5ac 100644 --- a/ansible/roles/saphanainst/templates/hanaconfig.cfg +++ b/ansible/roles/saphanainst/templates/hanaconfig.cfg @@ -46,7 +46,8 @@ install_hostagent=y db_isolation=low # Create initial tenant database ( Default: y ) -create_initial_tenant=y +# create_initial_tenant=y +create_initial_tenant=n # Non-standard Shared File System checkmnt= @@ -79,7 +80,7 @@ listen_interface= internal_network= # SAP HANA System ID -sid={{ hana_sid }} +sid={{ hana_sid | upper }} # Instance Number number={{ hana_sysno }} diff --git a/ansible/roles/saphanareq/filter_plugins/filesystemdata.py b/ansible/roles/saphanareq/filter_plugins/filesystemdata.py index 8e1d443..bc18d11 100644 --- a/ansible/roles/saphanareq/filter_plugins/filesystemdata.py +++ b/ansible/roles/saphanareq/filter_plugins/filesystemdata.py @@ -20,45 +20,37 @@ def filesystemdata(self, data_list): fs_device = "/dev/" + sid + "_" + v['lvm']['vg']['vg_name'] + "/" + sid + "_" + m['lv_name'] mp = None fs_options = "" - label = "" + mount_opt = "defaults" mount_source = fs_device - if m['lv_name'] == 'hana_data_lv': - label = "HANA_DATA" - elif m['lv_name'] == 'hana_log_lv': - label = "HANA_LOG" - elif m['lv_name'] == 'hana_shared_lv': - label = "HANA_SHARED" - else: - label = "" - if label != "": - fs_options = "-L " + label - mount_source = "LABEL=" + label + if "label" in m.keys(): + fs_options = "-L " + m['label'] + mount_source = "LABEL=" + m['label'] + if "fs_create_options" in m.keys(): + fs_options = fs_options + " " + m['fs_create_options'] if "mount_point" in m.keys(): mp = m['mount_point'] - fs_info = { "fs_device": fs_device, "fs_type": m['fs_type'], "mp": mp, "fs_options": fs_options, "mount_source": mount_source } + if "mount_options" in m.keys(): + mount_opt = m['mount_options'] + fs_info = { "fs_device": fs_device, "fs_type": m['fs_type'], "mp": mp, "fs_options": fs_options, "mount_source": mount_source, "mount_opt": mount_opt } temp_list.append(fs_info) final_list.append(temp_list) else: temp_list = [] fs_device = v['device'][0] + "1" fs_options = "" - label = "" + mount_opt = "" mount_source = fs_device mp = None + if "label" in v.keys(): + fs_options = "-L " + v['label'] + mount_source = "LABEL=" + v['label'] + if "fs_create_options" in v.keys(): + fs_options = fs_options + " " + v['fs_create_options'] if "mount_point" in v.keys(): mp = v['mount_point'] - if mp == "/hana/data": - label = "HANA_DATA" - elif mp == "/hana/log": - label = "HANA_LOG" - elif mp == "/hana/shared": - label = "HANA_SHARED" - else: - label = "" - if label != "": - fs_options = "-L " + label - mount_source = "LABEL=" + label - fs_info = { "fs_device": fs_device, "fs_type": v['fs_type'], "mp": mp, "fs_options": fs_options, "mount_source": mount_source } + if "mount_options" in v.keys(): + mount_opt = v['mount_options'] + fs_info = { "fs_device": fs_device, "fs_type": v['fs_type'], "mp": mp, "fs_options": fs_options, "mount_source": mount_source, "mount_opt": mount_opt } temp_list.append(fs_info) final_list.append(temp_list) return final_list diff --git a/ansible/roles/saphanareq/filter_plugins/lvmdata.py b/ansible/roles/saphanareq/filter_plugins/lvmdata.py index bedf950..b5575db 100644 --- a/ansible/roles/saphanareq/filter_plugins/lvmdata.py +++ b/ansible/roles/saphanareq/filter_plugins/lvmdata.py @@ -11,35 +11,29 @@ def filters(self): def lvmdata(self, data_map): final_list = [] for k, v in data_map.items(): - key_to_check = 'lvm' - if key_to_check in v: - # In case the sum of the sizes of all LVs from the VG is lower than VG size - # and we don't want 'hana_data_lv' to be created as '100%FREE' - lv100free = True - total_lv_size = 0 - vgsize = 0 - for t in v['disk_size']: - vgsize += int(t) - lvminfo = v['lvm']['lv'] - for n in lvminfo: - total_lv_size += int(n['lv_size']) - if vgsize > total_lv_size: - lv100free = False + if 'lvm' in v.keys(): for m in v['lvm']['lv']: temp_list = [] lv_size = "" - # For HANA VMs, SWAP size is always 2 GB - # The volume group 'hana_vg' will always contain logical volume 'hana_data_lv' - if k == 'swap' or (k == 'hana_vg' and m['lv_name'] != 'hana_data_lv') or (lv100free == False and k == 'hana_vg' and m['lv_name'] == 'hana_data_lv'): + if '%' not in m['lv_size']: lv_size = m['lv_size'] + "G" else: - lv_size = '100%FREE' - lvm_info = { "vg_name": v['lvm']['vg']['vg_name'], "lv_name": m['lv_name'], "lv_size": lv_size, "lv_stripes": m['lv_stripes'], "lv_stripe_size": m['lv_stripe_size'] } + lv_size = m['lv_size'] + lv_options = "" + if "raid_type" in m.keys(): + lv_options = "--type " + m['raid_type'] + if "mirrors" in m.keys(): + lv_options += " -m " + m['mirrors'] + if "lv_stripes" in m.keys(): + lv_options += " -i " + m['lv_stripes'] + if "lv_stripe_size" in m.keys(): + lv_options += " -I " + m['lv_stripe_size'] + lvm_info = { "vg_name": v['lvm']['vg']['vg_name'], "lv_name": m['lv_name'], "lv_size": lv_size, "lv_options": lv_options } temp_list.append(lvm_info) final_list.append(temp_list) for i in range(len(final_list)): # LVM data 'hana_data_lv' should be last in array (in case it will be created in 'hana_vg') as we want 100%FREE as size - if final_list[i][0]['vg_name'] == 'hana_vg' and final_list[i][0]['lv_name'] == 'hana_data_lv': + if final_list[i][0]['lv_name'] == 'hana_data_lv': final_list.append(final_list.pop(i)) break return final_list diff --git a/ansible/roles/saphanareq/filter_plugins/storagedetails.py b/ansible/roles/saphanareq/filter_plugins/storagedetails.py index 4471592..0acaaf6 100644 --- a/ansible/roles/saphanareq/filter_plugins/storagedetails.py +++ b/ansible/roles/saphanareq/filter_plugins/storagedetails.py @@ -1,7 +1,6 @@ #!/usr/bin/python import decimal -import re class FilterModule(object): '''Storage details from profile containing also the devices for HANA VM''' @@ -21,26 +20,10 @@ def storagedetails(self, data_list): storage_profile_info = json_file_data['profiles'][hana_profile]['storage'] - # Create a sorted list with all disks device keys available on the VM - pattern = 'dm-' - all_disk_device_keys = sorted([item for item in ansible_devices_data if re.match(pattern, item) == None]) - - # Get the number of the disks to be configured - necessary_disks_number = "" - count_disks = 0 - for k, v in storage_profile_info.items(): - count_disks += int(v['disk_count']) - necessary_disks_number = str(count_disks) - - # Get a list with the device keys for disks to be configured - N = int(necessary_disks_number) - disk_device_keys = all_disk_device_keys[-N:] - - # Get a list with the provisioned disk sizes corresponding to the device keys for disks to be configured + # Get a list with the provisioned disk sizes size_provisioned_disks = [] for m, n in ansible_devices_data.items(): - if m in disk_device_keys and 'KB' not in n['size']: - size_provisioned_disks.append(n['size']) + size_provisioned_disks.append(n['size']) # Sort the list with provisioned disk sizes size_provisioned_disks_sorted = sorted(size_provisioned_disks) @@ -49,8 +32,8 @@ def storagedetails(self, data_list): size_profile_disks = [] for k, v in storage_profile_info.items(): display_size = "" - if int(v['disk_size']) >= 1024: - rounded_val = round(decimal.Decimal(int(v['disk_size']) / 1024), 2) + if float(v['disk_size']) >= 1024: + rounded_val = round(decimal.Decimal(float(v['disk_size']) / 1024), 2) no_decimal_places = abs(rounded_val.as_tuple().exponent) if no_decimal_places == 0: display_size = str(rounded_val) + ".00 TB" @@ -60,24 +43,34 @@ def storagedetails(self, data_list): display_size = str(rounded_val) + " TB" else: display_size = v['disk_size'] + ".00 GB" - for t in range(int(v['disk_count'])): + for t in range(int(v['disk_count'])): size_profile_disks.append(display_size) # Sort the list with disk sizes from profile size_profile_disks_sorted = sorted(size_profile_disks) + # Non-HANA provisioned disks (only different sizes) + non_hana_disks = [x for x in size_provisioned_disks_sorted if x not in size_profile_disks_sorted] + + # Remove non-hana disks (only different sizes) from the list of provisioned disks + for t in non_hana_disks: + for j in size_provisioned_disks_sorted: + if t == j: + size_provisioned_disks_sorted.remove(j) + break + # Get the missing disks - if (len(list(set(size_profile_disks_sorted) - set(size_provisioned_disks_sorted))) > 0) or (len(size_profile_disks_sorted) != len(size_provisioned_disks_sorted)): + if (len(size_profile_disks_sorted) - len(size_provisioned_disks_sorted) > 0) or (len(set(size_profile_disks_sorted)) != len(set(size_provisioned_disks_sorted))): msg = "The disks required for profile '" + hana_profile + "' are missing. The following disks sizes are required: " + str(size_profile_disks_sorted)[1:-1] + ". The following disk sizes were deployed: " + str(size_provisioned_disks_sorted)[1:-1] return msg else: temp_list = [] - for k, v in storage_profile_info.items(): + for k, v in sorted(storage_profile_info.items()): new_list1 = [] new_list2 = [] display_size = "" - if int(v['disk_size']) >= 1024: - rounded_val = round(decimal.Decimal(int(v['disk_size']) / 1024), 2) + if float(v['disk_size']) >= 1024: + rounded_val = round(decimal.Decimal(float(v['disk_size']) / 1024), 2) no_decimal_places = abs(rounded_val.as_tuple().exponent) if no_decimal_places == 0: display_size = str(rounded_val) + ".00 TB" @@ -89,8 +82,8 @@ def storagedetails(self, data_list): display_size = v['disk_size'] + ".00 GB" for t in range(int(v['disk_count'])): new_list1.append(v['disk_size']) - for m, n in ansible_devices_data.items(): - if (n['size'] == display_size) and (m in disk_device_keys) and (m not in temp_list): + for m, n in sorted(ansible_devices_data.items()): + if (n['size'] == display_size) and ("dm-" not in m) and (m not in temp_list) and n['partitions'] == {} and n['links']['labels'] == [] and len(n['links']['ids']) > 0: new_list2.append("/dev/" + m) temp_list.append(m) break diff --git a/ansible/roles/saphanareq/tasks/configurations/c_states.yml b/ansible/roles/saphanareq/tasks/configurations/c_states.yml new file mode 100644 index 0000000..29e5efb --- /dev/null +++ b/ansible/roles/saphanareq/tasks/configurations/c_states.yml @@ -0,0 +1,40 @@ +--- +# Set processor.max_cstate=1 intel_idle.max_cstate=1 in GRUB_CMDLINE_LINUX + +- name: Check if the server is using UEFI or BIOS + ansible.builtin.stat: + path: /sys/firmware/efi + register: uefi + +- name: Set GRUB command for non-UEFI + set_fact: + grub_cmd: "grub2-mkconfig -o /boot/grub2/grub.cfg" + when: not uefi.stat.exists + +- name: Set GRUB command for UEFI + set_fact: + grub_cmd: "grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg" + when: uefi.stat.exists and uefi.stat.isdir + +- name: Check if C-States parameters are configured in the boot command + lineinfile: + backup: true + path: /etc/default/grub + regexp: '^GRUB_CMDLINE_LINUX=".*max_cstate' + state: absent + check_mode: true + register: cstate_check + changed_when: false + +- name: Insert C-States parameters in GRUB_CMDLINE_LINUX if missing + lineinfile: + backrefs: true + path: /etc/default/grub + regexp: "^(GRUB_CMDLINE_LINUX=\".*)\"$" + line: '\1 processor.max_cstate=1 intel_idle.max_cstate=1"' + when: cstate_check.found == 0 + +- name: Enable grub changes + command: "{{ grub_cmd }}" + when: cstate_check.found == 0 +... diff --git a/ansible/roles/saphanareq/tasks/configurations/filesystems.yml b/ansible/roles/saphanareq/tasks/configurations/filesystems.yml index 4dccade..c6c474c 100644 --- a/ansible/roles/saphanareq/tasks/configurations/filesystems.yml +++ b/ansible/roles/saphanareq/tasks/configurations/filesystems.yml @@ -1,24 +1,37 @@ --- # Storage sizing -# https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc (Updated on 2023-03-08) -# https://cloud.ibm.com/docs/sap?topic=sap-storage-design-considerations#hana-iaas-mx2-16x128-32x256-configure (Updated on 2022-05-19) -# https://cloud.ibm.com/docs/sap?topic=sap-storage-design-considerations#hana-iaas-mx2-48x384-configure (Updated on 2022-05-19) +# https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc (Last updated 2023-12-28) +# https://cloud.ibm.com/docs/sap?topic=sap-storage-design-considerations#hana-iaas-mx2-16x128-32x256-configure (Last updated 2024-01-25) +# https://cloud.ibm.com/docs/sap?topic=sap-storage-design-considerations#hana-iaas-mx2-48x384-configure (Last updated 2024-01-25) +# https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-bm-vpc (Last updated 2024-05-13) +# # SAP Notes: +# - 2927211 - SAP Applications on IBM Cloud Virtual Private Cloud (VPC) Infrastructure environment (v46) # - 2779331 - HANA services use large SWAP memory (v5) +# LVM physical extent size - https://community.sap.com/t5/additional-blogs-by-sap/using-lvm-for-more-flexibility/ba-p/12871196 + +- name: Set default JSON file + set_fact: + hana_vol_setup_json: "hana_vm_volume_layout.json" + +- name: Get the appropriate JSON file + set_fact: + hana_vol_setup_json: "hana_bm_volume_layout.json" + when: "'-metal-' in hana_profile" - name: Check if the JSON file for SAP HANA storage configuration is available on Ansible controller stat: - path: "{{ playbook_dir }}/hana_volume_layout.json" + path: "{{ playbook_dir }}/{{ hana_vol_setup_json }}" register: json_storage_file_status delegate_to: localhost - name: Fail if the JSON file is missing fail: - msg: "The file {{ playbook_dir }}/hana_volume_layout.json is missing." + msg: "The file {{ playbook_dir }}/{{ hana_vol_setup_json }} is missing." when: not json_storage_file_status.stat.exists - name: Get the JSON file content - shell: "cat {{ playbook_dir }}/hana_volume_layout.json" + shell: "cat {{ playbook_dir }}/{{ hana_vol_setup_json }}" register: result changed_when: false when: json_storage_file_status.stat.exists @@ -42,11 +55,14 @@ msg: "{{ final_storage }}" when: final_storage is not mapping +- name: Display final_storage + debug: + var: final_storage + - name: Create the volume groups lvg: vg: "{{ hana_sid | lower }}_{{ stg_details.value.lvm.vg.vg_name }}" pvs: "{{ stg_details.value.device | join(',') }}" - pesize: "{{ stg_details.value.lvm.vg.pe_size_MB }}" loop: "{{ final_storage | dict2items }}" loop_control: loop_var: stg_details @@ -57,7 +73,7 @@ vg: "{{ hana_sid|lower }}_{{ lvm_data[0]['vg_name'] }}" lv: "{{ hana_sid|lower }}_{{ lvm_data[0]['lv_name'] }}" size: "{{ lvm_data[0]['lv_size'] }}" - opts: "-i{{ lvm_data[0]['lv_stripes'] }} -I{{ lvm_data[0]['lv_stripe_size'] }}" + opts: "{{ lvm_data[0]['lv_options'] }}" shrink: false loop: "{{ final_storage | lvmdata }}" loop_control: @@ -74,7 +90,7 @@ loop_var: part - name: Create the filesystems - filesystem: + filesystem: fstype: "{{ fs_data[0]['fs_type'] }}" dev: "{{ fs_data[0]['fs_device'] }}" opts: "{{ fs_data[0]['fs_options'] }}" @@ -87,30 +103,27 @@ path: "{{ mp_data[0]['mp'] }}" src: "{{ mp_data[0]['mount_source'] }}" fstype: "{{ mp_data[0]['fs_type'] }}" + opts: "{{ mp_data[0]['mount_opt'] }}" state: mounted loop: "{{ [final_storage, hana_sid | lower] | filesystemdata }}" loop_control: loop_var: mp_data when: mp_data[0]['mp'] != None -- name: Get SWAP LV name - set_fact: - swap_lv: "{{ swap_data[0]['fs_device'] }}" - loop: "{{ [final_storage, hana_sid | lower] | filesystemdata }}" - loop_control: - loop_var: swap_data - -- name: Check the current SWAP size - set_fact: - hana_vm_swap: "{{ ansible_swaptotal_mb }}" - -- name: Mount SWAP volume - command: "swapon -av {{ swap_lv }}" - when: hana_vm_swap == 0 - -- name: Add SWAP device to /etc/fstab - lineinfile: - path: /etc/fstab - regexp: "^{{ swap_lv }}" - line: "{{ swap_lv }} swap swap defaults 0 0" +- name: Create /usr/sap directory on Bare Metal + ansible.builtin.file: + path: /usr/sap + state: directory + mode: '0755' + when: "'-metal-' in hana_profile" + +- name: Create SWAP on Bare Metal + ansible.builtin.include_tasks: + file: swap_bm.yml + when: "'-metal-' in hana_profile" + +- name: Create SWAP on VSI + ansible.builtin.include_tasks: + file: swap_vm.yml + when: "'-metal-' not in hana_profile" ... diff --git a/ansible/roles/saphanareq/tasks/configurations/kernel_RedHat8.yml b/ansible/roles/saphanareq/tasks/configurations/kernel_RedHat8.yml index f853794..2af5667 100644 --- a/ansible/roles/saphanareq/tasks/configurations/kernel_RedHat8.yml +++ b/ansible/roles/saphanareq/tasks/configurations/kernel_RedHat8.yml @@ -9,7 +9,7 @@ reload: yes loop: - { name: vm.max_map_count, value: 2147483647 } - - { name: kernel.pid_max, value: 4194304 } + # - { name: kernel.pid_max, value: 4194304 } - { name: net.core.somaxconn, value: 4096 } - { name: net.ipv4.tcp_max_syn_backlog, value: 8192 } - { name: net.ipv4.tcp_slow_start_after_idle, value: 0 } diff --git a/ansible/roles/saphanareq/tasks/configurations/reboot.yml b/ansible/roles/saphanareq/tasks/configurations/reboot.yml index 7287953..568642e 100644 --- a/ansible/roles/saphanareq/tasks/configurations/reboot.yml +++ b/ansible/roles/saphanareq/tasks/configurations/reboot.yml @@ -1,6 +1,6 @@ --- - name: Reboot target host reboot: - connect_timeout: 5 - post_reboot_delay: 10 + connect_timeout: 60 + post_reboot_delay: 30 ... diff --git a/ansible/roles/saphanareq/tasks/configurations/saptune.yml b/ansible/roles/saphanareq/tasks/configurations/saptune.yml index 6209cc9..8900eef 100644 --- a/ansible/roles/saphanareq/tasks/configurations/saptune.yml +++ b/ansible/roles/saphanareq/tasks/configurations/saptune.yml @@ -7,11 +7,11 @@ - name: Check if HANA profile was already set command: "saptune status" - register: hana_profile + register: hana_saptuneprofile changed_when: False - failed_when: hana_profile.rc != 0 and hana_profile.rc != 3 + failed_when: hana_saptuneprofile.rc != 0 and hana_saptuneprofile.rc != 3 - name: Select HANA profile for saptune command: /usr/sbin/saptune solution apply HANA - when: "'HANA' not in hana_profile.stdout" + when: "'HANA' not in hana_saptuneprofile.stdout" ... diff --git a/ansible/roles/saphanareq/tasks/configurations/swap_bm.yml b/ansible/roles/saphanareq/tasks/configurations/swap_bm.yml new file mode 100644 index 0000000..77b8fbc --- /dev/null +++ b/ansible/roles/saphanareq/tasks/configurations/swap_bm.yml @@ -0,0 +1,33 @@ +--- +- name: Check for the SWAP space + stat: + path: "/{{ hana_sid|lower }}_swapfile" + register: swap_space + +- name: Create SWAP space + command: dd if=/dev/zero of=/{{ hana_sid|lower }}_swapfile bs=1048576 count=2048 + when: not swap_space.stat.exists + +- name: Set permission on SWAP file + ansible.builtin.file: + path: "/{{ hana_sid|lower }}_swapfile" + mode: 0600 + +- name: Create SWAP filesystem + command: mkswap /{{ hana_sid|lower }}_swapfile + when: not swap_space.stat.exists + +- name: Check the current SWAP size + set_fact: + hana_swap: "{{ ansible_swaptotal_mb }}" + +- name: Mount SWAP volume + command: "swapon -av /{{ hana_sid|lower }}_swapfile" + when: hana_swap == 0 + +- name: Add SWAP device to /etc/fstab + lineinfile: + path: /etc/fstab + regexp: "^\\/{{ hana_sid|lower }}_swapfile" + line: "/{{ hana_sid|lower }}_swapfile swap swap defaults 0 0" +... \ No newline at end of file diff --git a/ansible/roles/saphanareq/tasks/configurations/swap_vm.yml b/ansible/roles/saphanareq/tasks/configurations/swap_vm.yml new file mode 100644 index 0000000..11e901d --- /dev/null +++ b/ansible/roles/saphanareq/tasks/configurations/swap_vm.yml @@ -0,0 +1,22 @@ +--- +- name: Get SWAP LV name + set_fact: + swap_lv: "{{ swap_data[0]['fs_device'] }}" + loop: "{{ [final_storage, hana_sid | lower] | filesystemdata }}" + loop_control: + loop_var: swap_data + +- name: Check the current SWAP size + set_fact: + hana_swap: "{{ ansible_swaptotal_mb }}" + +- name: Mount SWAP volume + command: "swapon -av {{ swap_lv }}" + when: hana_swap == 0 + +- name: Add SWAP device to /etc/fstab + lineinfile: + path: /etc/fstab + regexp: "^{{ swap_lv }}" + line: "{{ swap_lv }} swap swap defaults 0 0" +... diff --git a/ansible/roles/saphanareq/tasks/configurations/tmpfs.yml b/ansible/roles/saphanareq/tasks/configurations/tmpfs.yml index ef306ad..b7f32c5 100644 --- a/ansible/roles/saphanareq/tasks/configurations/tmpfs.yml +++ b/ansible/roles/saphanareq/tasks/configurations/tmpfs.yml @@ -4,9 +4,15 @@ # - 2772999 - Red Hat Enterprise Linux 8.x: Installation and Configuration (v22) # - 941735 - SAP memory management system for 64-bit Linux systems (v11) -- name: Get the RAM size +- name: Get the RAM size for VSI set_fact: hana_ram_g: "{{ hana_profile.split('-')[1].split('x')[1] }}" + when: "'-metal-' not in hana_profile" + +- name: Get the RAM size for Bare Metal + set_fact: + hana_ram_g: "{{ hana_profile.split('-')[2].split('x')[1] }}" + when: "'-metal-' in hana_profile" - name: Set swap logical volume size for RAM higher than 8192 set_fact: @@ -46,4 +52,4 @@ path: /etc/fstab regexp: "^/dev/shm (.*)$" line: "tmpfs /dev/shm tmpfs size={{ tmpfs_size_g }}G,rw,nosuid,nodev 0 0" -... +... \ No newline at end of file diff --git a/ansible/roles/saphanareq/tasks/configurations/tsx.yml b/ansible/roles/saphanareq/tasks/configurations/tsx.yml new file mode 100644 index 0000000..c207efc --- /dev/null +++ b/ansible/roles/saphanareq/tasks/configurations/tsx.yml @@ -0,0 +1,15 @@ +--- +- name: Check if TSX parameter is configured in the boot command + lineinfile: + backup: true + path: /etc/default/grub + regexp: '^GRUB_CMDLINE_LINUX=".*tsx=on' + state: absent + check_mode: true + register: tsx_check + changed_when: false + +- name: Enable TSX + command: grubby --args="tsx=on" --update-kernel=ALL + when: tsx_check.found == 0 +... diff --git a/ansible/roles/saphanareq/vars/RedHat8.yml b/ansible/roles/saphanareq/vars/RedHat8.yml index 31b03db..add9039 100644 --- a/ansible/roles/saphanareq/vars/RedHat8.yml +++ b/ansible/roles/saphanareq/vars/RedHat8.yml @@ -30,6 +30,8 @@ saphana_required_packages: saphana_required_configurations: - "reqpkg" - "kernel_RedHat8" + - "c_states" + - "tsx" - "filesystems" - "tmpfs" - "tuned" diff --git a/ansible/roles/saphanareq/vars/SLES_SAP15.yml b/ansible/roles/saphanareq/vars/SLES_SAP15.yml index 1e84679..5fbd097 100644 --- a/ansible/roles/saphanareq/vars/SLES_SAP15.yml +++ b/ansible/roles/saphanareq/vars/SLES_SAP15.yml @@ -3,12 +3,15 @@ saphana_required_packages: - libgcc_s1 - libstdc++6 - libatomic1 + - lvm2 + - uuidd + - nfs-utils + saphana_required_configurations: - "reqpkg" - "kernel_SLES_SAP15" - "filesystems" - "tmpfs" - "saptune" - - "limits" - "reboot" -... +... diff --git a/files/hana_volume_layout.json b/files/hana_volume_layout.json deleted file mode 100644 index 49f5612..0000000 --- a/files/hana_volume_layout.json +++ /dev/null @@ -1,1477 +0,0 @@ -{ - "profiles": { - "mx2-16x128": { - "storage": { - "hana_vg": { - "disk_size": "500", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "988", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - }, - { - "lv_name": "hana_log_lv", - "lv_size": "256", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - }, - { - "lv_name": "hana_shared_lv", - "lv_size": "256", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], - "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] - } - }, - "mx2-32x256": { - "storage": { - "hana_vg": { - "disk_size": "500", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "988", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - }, - { - "lv_name": "hana_log_lv", - "lv_size": "256", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - }, - { - "lv_name": "hana_shared_lv", - "lv_size": "256", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], - "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] - } - }, - "mx2-48x384": { - "storage": { - "hana_vg": { - "disk_size": "500", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "616", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - }, - { - "lv_name": "hana_shared_lv", - "lv_size": "384", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "log": { - "disk_size": "100", - "disk_count": "4", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_log_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_log_lv", - "lv_size": "400", - "lv_stripes": "4", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], - "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] - } - }, - "vx2d-16x224": { - "storage": { - "hana_vg": { - "disk_size": "1120", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "672", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - }, - { - "lv_name": "hana_log_lv", - "lv_size": "224", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - }, - { - "lv_name": "hana_shared_lv", - "lv_size": "224", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "vx2d-44x616": { - "storage": { - "data": { - "disk_size": "1848", - "disk_count": "1", - "iops": "10iops-tier", - "fs_type": "xfs", - "mount_point": "/hana/data" - }, - "shared": { - "disk_size": "616", - "disk_count": "1", - "iops": "5iops-tier", - "fs_type": "xfs", - "mount_point": "/hana/shared" - }, - "log": { - "disk_size": "192", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_log_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_log_lv", - "lv_size": "576", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], - "olap": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "vx2d-88x1232": { - "storage": { - "data": { - "disk_size": "3696", - "disk_count": "1", - "iops": "10iops-tier", - "fs_type": "xfs", - "mount_point": "/hana/data" - }, - "shared": { - "disk_size": "1232", - "disk_count": "1", - "iops": "5iops-tier", - "fs_type": "xfs", - "mount_point": "/hana/shared" - }, - "log": { - "disk_size": "192", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_log_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_log_lv", - "lv_size": "576", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], - "olap": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "vx2d-144x2016": { - "storage": { - "data": { - "disk_size": "1024", - "disk_count": "4", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_data_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "4096", - "lv_stripes": "4", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - } - ] - } - }, - "log": { - "disk_size": "192", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_log_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_log_lv", - "lv_size": "576", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - } - ] - } - }, - "shared": { - "disk_size": "2016", - "disk_count": "1", - "iops": "5iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_shared_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_shared_lv", - "lv_size": "2016", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], - "olap": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "vx2d-176x2464": { - "storage": { - "data": { - "disk_size": "1280", - "disk_count": "4", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_data_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "5120", - "lv_stripes": "4", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - } - ] - } - }, - "log": { - "disk_size": "192", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_log_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_log_lv", - "lv_size": "576", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - } - ] - } - }, - "shared": { - "disk_size": "2464", - "disk_count": "1", - "iops": "5iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_shared_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_shared_lv", - "lv_size": "2464", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], - "olap": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "ux2d-8x224": { - "storage": { - "hana_vg": { - "disk_size": "1120", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "672", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - }, - { - "lv_name": "hana_log_lv", - "lv_size": "224", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - }, - { - "lv_name": "hana_shared_lv", - "lv_size": "224", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "ux2d-16x448": { - "storage": { - "hana_vg": { - "disk_size": "2240", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "1344", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - }, - { - "lv_name": "hana_log_lv", - "lv_size": "448", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - }, - { - "lv_name": "hana_shared_lv", - "lv_size": "448", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "ux2d-36x1008": { - "storage": { - "data": { - "disk_size": "1008", - "disk_count": "2", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_data_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "2016", - "lv_stripes": "2", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - } - ] - } - }, - "log": { - "disk_size": "192", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_log_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_log_lv", - "lv_size": "576", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - } - ] - } - }, - "shared": { - "disk_size": "1008", - "disk_count": "1", - "iops": "5iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_shared_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_shared_lv", - "lv_size": "1008", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "ux2d-48x1344": { - "storage": { - "data": { - "disk_size": "1350", - "disk_count": "2", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_data_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "2700", - "lv_stripes": "2", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - } - ] - } - }, - "log": { - "disk_size": "192", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_log_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_log_lv", - "lv_size": "576", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - } - ] - } - }, - "shared": { - "disk_size": "1344", - "disk_count": "1", - "iops": "5iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_shared_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_shared_lv", - "lv_size": "1344", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "ux2d-72x2016": { - "storage": { - "data": { - "disk_size": "1024", - "disk_count": "4", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_data_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "4096", - "lv_stripes": "4", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - } - ] - } - }, - "log": { - "disk_size": "192", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_log_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_log_lv", - "lv_size": "576", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - } - ] - } - }, - "shared": { - "disk_size": "2016", - "disk_count": "1", - "iops": "5iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_shared_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_shared_lv", - "lv_size": "2016", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "ux2d-100x2800": { - "storage": { - "data": { - "disk_size": "2100", - "disk_count": "4", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_data_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "8400", - "lv_stripes": "4", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - } - ] - } - }, - "log": { - "disk_size": "192", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_log_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_log_lv", - "lv_size": "576", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - } - ] - } - }, - "shared": { - "disk_size": "2800", - "disk_count": "1", - "iops": "5iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_shared_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_shared_lv", - "lv_size": "2800", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - }, - "ux2d-200x5600": { - "storage": { - "data": { - "disk_size": "4200", - "disk_count": "4", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_data_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_data_lv", - "lv_size": "16800", - "lv_stripes": "4", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/data" - } - ] - } - }, - "log": { - "disk_size": "192", - "disk_count": "3", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_log_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_log_lv", - "lv_size": "576", - "lv_stripes": "3", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/log" - } - ] - } - }, - "shared": { - "disk_size": "5600", - "disk_count": "1", - "iops": "5iops-tier", - "lvm": { - "vg": { - "vg_name": "hana_shared_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "hana_shared_lv", - "lv_size": "5600", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/hana/shared" - } - ] - } - }, - "usr_sap": { - "disk_size": "50", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "usr_sap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "usr_sap_lv", - "lv_size": "50", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "xfs", - "mount_point": "/usr/sap" - } - ] - } - }, - "swap": { - "disk_size": "10", - "disk_count": "1", - "iops": "10iops-tier", - "lvm": { - "vg": { - "vg_name": "swap_vg", - "pe_size_MB": "32" - }, - "lv": [ - { - "lv_name": "swap_lv", - "lv_size": "2", - "lv_stripes": "1", - "lv_stripe_size": "64", - "fs_type": "swap" - } - ] - } - } - }, - "processing_type": { - "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] - } - } - } - } \ No newline at end of file diff --git a/input.auto.tfvars b/input.auto.tfvars index 9ccb1d9..6fe2bbb 100644 --- a/input.auto.tfvars +++ b/input.auto.tfvars @@ -3,17 +3,17 @@ ###################################################### REGION = "" -# Region for the VSI. Supported regions: https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones-vpc +# Region for the server. Supported regions: https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones-vpc # Edit the variable value with your deployment Region. # Example: REGION = "eu-de" ZONE = "" -# Availability zone for VSI. Supported zones: https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones-vpc +# Availability zone for the server. Supported zones: https://cloud.ibm.com/docs/containers?topic=containers-regions-and-zones#zones-vpc # Edit the variable value with your deployment Zone. # Example: ZONE = "eu-de-1" VPC = "" -# EXISTING VPC, previously created by the user in the same region as the VSI. The list of available VPCs: https://cloud.ibm.com/vpc-ext/network/vpcs +# EXISTING VPC, previously created by the user in the same region as the server. The list of available VPCs: https://cloud.ibm.com/vpc-ext/network/vpcs # Example: VPC = "ic4sap" SECURITY_GROUP = "" @@ -25,45 +25,48 @@ RESOURCE_GROUP = "" # Example: RESOURCE_GROUP = "wes-automation" SUBNET = "" -# EXISTING Subnet in the same region and zone as the VSI, previously created by the user. The list of available Subnets: https://cloud.ibm.com/vpc-ext/network/subnets +# EXISTING Subnet in the same region and zone as the server, previously created by the user. The list of available Subnets: https://cloud.ibm.com/vpc-ext/network/subnets # Example: SUBNET = "ic4sap-subnet" SSH_KEYS = [""] -# List of SSH Keys UUIDs that are allowed to SSH as root to the VSI. The SSH Keys should be created for the same region as the VSI. The list of available SSH Keys UUIDs: https://cloud.ibm.com/vpc-ext/compute/sshKeys +# List of SSH Keys UUIDs that are allowed to SSH as root to the server. The SSH Keys should be created for the same region as the server. The list of available SSH Keys UUIDs: https://cloud.ibm.com/vpc-ext/compute/sshKeys # Example: SSH_KEYS = ["r010-8f72b994-c17f-4500-af8f-d05680374t3c", "r011-8f72v884-c17f-4500-af8f-d05900374t3c"] ID_RSA_FILE_PATH = "ansible/id_rsa" -# Input your existing id_rsa private key file path in OpenSSH format with 0600 permissions. -# This private key it is used only during the terraform provisioning and it is recommended to be changed after the SAP deployment. +# The id_rsa private key file path in OpenSSH format with 0600 permissions. +# This private key is used only during the terraform provisioning and it is recommended to be changed after the SAP deployment. # It must contain the relative or absoute path from your Bastion. -# Examples: "ansible/id_rsa_s4hana" , "~/.ssh/id_rsa_s4hana" , "/root/.ssh/id_rsa". +# Examples: "ansible/id_rsa_s4hana_dst" , "~/.ssh/id_rsa_s4hana_dst" , "/root/.ssh/id_rsa". ########################################################## -# Activity Tracker variables: +# SAP HANA Server variables ########################################################## -ATR_NAME = "" -# The name of an existent Activity Tracker instance, in the same region chosen for SAP system deployment. -# Example: ATR_NAME="Activity-Tracker-SAP-eu-de" +HANA_SERVER_TYPE = "" +# The type of SAP HANA Server. Allowed vales: "virtual" or "bare metal" +# Example: HANA_SERVER_TYPE = "bare metal" ########################################################## -# DB VSI variables: +# DB server variables: ########################################################## DB_HOSTNAME = "" -# The Hostname for the DB VSI. The hostname should be up to 13 characters, as required by SAP +# The Hostname for the DB server. The hostname should be up to 13 characters, as required by SAP # Example: DB_HOSTNAME = "icp4sapdb" -DB_PROFILE = "mx2-16x128" -# The instance profile used for the HANA VSI. The list of certified profiles for HANA VSIs: https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc -# Details about all x86 instance profiles: https://cloud.ibm.com/docs/vpc?topic=vpc-profiles). -# For more information about supported DB/OS and IBM Gen 2 Virtual Server Instances (VSI), check [SAP Note 2927211: SAP Applications on IBM Virtual Private Cloud](https://launchpad.support.sap.com/#/notes/2927211) -# Default value: "mx2-16x128" - -DB_IMAGE = "ibm-redhat-8-6-amd64-sap-hana-5" -# OS image for DB VSI. Validated OS images for DB VSIs: ibm-redhat-8-6-amd64-sap-hana-5, ibm-redhat-8-4-amd64-sap-hana-9, ibm-sles-15-4-amd64-sap-hana-6, ibm-sles-15-3-amd64-sap-hana-9. +DB_PROFILE = "" +# The profile used for SAP HANA Server. +# The list of certified profiles for SAP HANA Virtual Servers is available here: https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc +# The list of certified profiles for SAP HANA Bare Metal Servers is available here: https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-bm-vpc. +# Details about all x86 instance profiles are available here: https://cloud.ibm.com/docs/vpc?topic=vpc-profiles. +# Example of Virtual Server Instance profile for SAP HANA: DB_PROFILE ="mx2-16x128". +# Example of Bare Metal profile for SAP HANA: DB_PROFILE = "bx2d-metal-96x384". +# For more information about supported DB/OS and IBM VPC, check SAP Note 2927211: "SAP Applications on IBM Virtual Private Cloud". + +DB_IMAGE = "ibm-redhat-8-6-amd64-sap-hana-6" +# OS image for DB server. Validated OS images for DB serverss: ibm-redhat-8-6-amd64-sap-hana-6, ibm-redhat-8-4-amd64-sap-hana-10, ibm-sles-15-4-amd64-sap-hana-7, ibm-sles-15-3-amd64-sap-hana-10. # The list of available VPC Operating Systems supported by SAP: SAP note '2927211 - SAP Applications on IBM Virtual Private Cloud (VPC) Infrastructure environment' https://launchpad.support.sap.com/#/notes/2927211; The list of all available OS images: https://cloud.ibm.com/docs/vpc?topic=vpc-about-images -# Example: DB_IMAGE = "ibm-sles-15-4-amd64-sap-hana-6" +# Example: DB_IMAGE = "ibm-sles-15-4-amd64-sap-hana-7" ########################################################## # SAP APP VSI variables: @@ -76,10 +79,10 @@ APP_HOSTNAME = "" APP_PROFILE = "bx2-4x16" # The APP VSI profile. Supported profiles: bx2-4x16. The list of available profiles: https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui -APP_IMAGE = "ibm-redhat-8-6-amd64-sap-applications-5" -# OS image for SAP APP VSI. Validated OS images for APP VSIs: ibm-redhat-8-6-amd64-sap-applications-5, ibm-redhat-8-4-amd64-sap-applications-9, ibm-sles-15-4-amd64-sap-applications-7, ibm-sles-15-3-amd64-sap-applications-10. +APP_IMAGE = "ibm-redhat-8-6-amd64-sap-applications-6" +# OS image for SAP APP VSI. Validated OS images for APP VSIs: ibm-redhat-8-6-amd64-sap-applications-6, ibm-redhat-8-4-amd64-sap-applications-10, ibm-sles-15-4-amd64-sap-applications-8, ibm-sles-15-3-amd64-sap-applications-11. # The list of available VPC Operating Systems supported by SAP: SAP note '2927211 - SAP Applications on IBM Virtual Private Cloud (VPC) Infrastructure environment' https://launchpad.support.sap.com/#/notes/2927211; The list of all available OS images: https://cloud.ibm.com/docs/vpc?topic=vpc-about-images -# Example: APP-IMAGE = "ibm-sles-15-4-amd64-sap-applications-7" +# Example: APP-IMAGE = "ibm-sles-15-4-amd64-sap-applications-8" ########################################################## # S/4HANA version @@ -101,6 +104,10 @@ HANA_SYSNO = "00" # SAP HANA instance number. Should follow the SAP rules for instance number naming. # Example: HANA_SYSNO = "01" +HANA_TENANT = "HDB" +# SAP HANA tenant name +# Example:HANA_TENANT = "HDB_TEN1" + HANA_SYSTEM_USAGE = "custom" # System usage. Default: custom. Suported values: production, test, development, custom # Example: HANA_SYSTEM_USAGE = "custom" @@ -109,7 +116,7 @@ HANA_COMPONENTS = "server" # SAP HANA Components. Default: server. Supported values: all, client, es, ets, lcapps, server, smartda, streaming, rdsync, xs, studio, afl, sca, sop, eml, rme, rtl, trp # Example: HANA_COMPONENTS = "server" -KIT_SAPHANA_FILE = "/storage/HANADB/51057281.ZIP" +KIT_SAPHANA_FILE = "/storage/HANADB/SP07/Rev73/51057281.ZIP" # SAP HANA Installation kit path # Example for Red Hat 8 or Suse 15: KIT_SAPHANA_FILE = "/storage/HANADB/51057281.ZIP" @@ -117,7 +124,7 @@ KIT_SAPHANA_FILE = "/storage/HANADB/51057281.ZIP" # SAP system configuration ########################################################## -SAP_SID = "S4A" +SAP_SID = "NWD" # SAP System ID SAP_ASCS_INSTANCE_NUMBER = "01" diff --git a/integration.tf b/integration.tf index 39b4865..4f0eaab 100644 --- a/integration.tf +++ b/integration.tf @@ -5,11 +5,12 @@ resource "local_file" "ansible_inventory" { all: hosts: db_host: - ansible_host: "${data.ibm_is_instance.db-vsi.primary_network_interface[0].primary_ip[0].address}" + ansible_host: "${lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? data.ibm_is_instance.db-vsi[0].primary_network_interface[0].primary_ip[0].address : data.ibm_is_bare_metal_server.db-bms[0].primary_network_interface[0].primary_ip[0].address}" app_host: ansible_host: "${data.ibm_is_instance.app-vsi.primary_network_interface[0].primary_ip[0].address}" DOC filename = "ansible/inventory.yml" + count = (data.ibm_is_instance.db-vsi != [] || data.ibm_is_bare_metal_server.db-bms != []) ? 1 : 0 } @@ -22,17 +23,17 @@ resource "local_file" "app_ansible_saps4app-vars" { # Generated by "terraform plan&apply" command. # SAP system configuration +swap_disk_size: "${module.app-vsi.SWAP_DISK_SIZE}" sap_sid: "${var.SAP_SID}" app_profile: "${var.APP_PROFILE}" sap_ascs_instance_number: "${var.SAP_ASCS_INSTANCE_NUMBER}" sap_ci_instance_number: "${var.SAP_CI_INSTANCE_NUMBER}" sap_main_password: "${var.SAP_MAIN_PASSWORD}" -# db_host: "${module.db-vsi.PRIVATE-IP}" -# db_hostname: "${var.DB_HOSTNAME}" # HANA config -hdb_host: "${module.db-vsi.PRIVATE-IP}" +hdb_host: "${lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? data.ibm_is_instance.db-vsi[0].primary_network_interface[0].primary_ip[0].address : data.ibm_is_bare_metal_server.db-bms[0].primary_network_interface[0].primary_ip[0].address}" hdb_sid: "${var.HANA_SID}" +hana_tenant: "${var.HANA_TENANT}" hdb_instance_number: "${var.HANA_SYSNO}" hdb_main_password: "${var.HANA_MAIN_PASSWORD}" # Number of concurrent jobs used to load and/or extract archives to HANA Host @@ -67,6 +68,7 @@ hana_profile: "${var.DB_PROFILE}" # HANA DB configuration hana_sid: "${var.HANA_SID}" hana_sysno: "${var.HANA_SYSNO}" +hana_tenant: "${var.HANA_TENANT}" hana_main_password: "${var.HANA_MAIN_PASSWORD}" hana_system_usage: "${var.HANA_SYSTEM_USAGE}" hana_components: "${var.HANA_COMPONENTS}" @@ -76,11 +78,18 @@ kit_saphana_file: "${var.KIT_SAPHANA_FILE}" ... DOC filename = "ansible/saphana-vars.yml" + count = (data.ibm_is_instance.db-vsi != [] || data.ibm_is_bare_metal_server.db-bms != []) ? 1 : 0 } -# Export Terraform variable values to an Ansible var_file -resource "local_file" "tf_ansible_hana_storage_generated_file" { - depends_on = [ module.db-vsi ] - source = "files/hana_volume_layout.json" - filename = "ansible/hana_volume_layout.json" +# Export Terraform variable values to an Ansible var_file for HANA server +resource "local_file" "tf_ansible_vars_generated_file_db" { + source = "${lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? "${path.root}/modules/db-vsi/files/hana_vm_volume_layout.json" : "${path.root}/modules/db-bms/files/hana_bm_volume_layout.json"}" + filename = "${lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? "ansible/hana_vm_volume_layout.json": "ansible/hana_bm_volume_layout.json"}" + count = (data.ibm_is_instance.db-vsi != [] || data.ibm_is_bare_metal_server.db-bms != []) ? 1 : 0 +} + +# Export Terraform variable values to an Ansible var_file for APP Server +resource "local_file" "tf_ansible_vars_generated_file_app" { + source = "${path.root}/modules/app-vsi/files/sapapp_vm_volume_layout.json" + filename = "ansible/sapapp_vm_volume_layout.json" } diff --git a/main.tf b/main.tf index c3466f7..ccd9048 100644 --- a/main.tf +++ b/main.tf @@ -42,7 +42,6 @@ module "vpc-subnet" { module "db-vsi" { source = "./modules/db-vsi" - # depends_on = [ module.precheck-ssh-exec ] depends_on = [ module.vpc-subnet ] ZONE = var.ZONE VPC = var.VPC @@ -53,11 +52,27 @@ module "db-vsi" { IMAGE = var.DB_IMAGE RESOURCE_GROUP = var.RESOURCE_GROUP SSH_KEYS = var.SSH_KEYS + count = lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? 1 : 0 +} + +module "db-bms" { + source = "./modules/db-bms" + depends_on = [ module.vpc-subnet ] + ZONE = var.ZONE + VPC = var.VPC + SECURITY_GROUP = var.SECURITY_GROUP + SUBNET = var.SUBNET + HOSTNAME = var.DB_HOSTNAME + PROFILE = var.DB_PROFILE + IMAGE = var.DB_IMAGE + RESOURCE_GROUP = var.RESOURCE_GROUP + SSH_KEYS = var.SSH_KEYS + count = lower(trimspace(var.HANA_SERVER_TYPE)) != "virtual" ? 1 : 0 } module "app-vsi" { source = "./modules/app-vsi" - depends_on = [ module.db-vsi ] + depends_on = [ module.vpc-subnet ] ZONE = var.ZONE VPC = var.VPC SECURITY_GROUP = var.SECURITY_GROUP @@ -67,15 +82,13 @@ module "app-vsi" { IMAGE = var.APP_IMAGE RESOURCE_GROUP = var.RESOURCE_GROUP SSH_KEYS = var.SSH_KEYS - VOLUME_SIZES = [ "40" , "128" ] - VOL_PROFILE = "10iops-tier" } module "app-ansible-exec-schematics" { source = "./modules/ansible-exec" - depends_on = [ module.app-vsi, local_file.ansible_inventory, local_file.db_ansible_saphana-vars, local_file.app_ansible_saps4app-vars, local_file.tf_ansible_hana_storage_generated_file ] + depends_on = [ module.app-vsi, local_file.ansible_inventory, local_file.db_ansible_saphana-vars, local_file.app_ansible_saps4app-vars ] count = (var.PRIVATE_SSH_KEY == "n.a" && var.BASTION_FLOATING_IP == "localhost" ? 0 : 1) - IP = data.ibm_is_instance.db-vsi.primary_network_interface[0].primary_ip[0].address + IP = "${lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? data.ibm_is_instance.db-vsi[0].primary_network_interface[0].primary_ip[0].address : data.ibm_is_bare_metal_server.db-bms[0].primary_network_interface[0].primary_ip[0].address}" PLAYBOOK = "sap-s4hana.yml" BASTION_FLOATING_IP = var.BASTION_FLOATING_IP ID_RSA_FILE_PATH = var.ID_RSA_FILE_PATH @@ -85,11 +98,12 @@ module "app-ansible-exec-schematics" { module "ansible-exec-cli" { source = "./modules/ansible-exec/cli" - depends_on = [ module.app-vsi, local_file.ansible_inventory, local_file.db_ansible_saphana-vars, local_file.app_ansible_saps4app-vars, local_file.tf_ansible_hana_storage_generated_file ] + depends_on = [ module.app-vsi, local_file.ansible_inventory, local_file.db_ansible_saphana-vars, local_file.app_ansible_saps4app-vars ] count = (var.PRIVATE_SSH_KEY == "n.a" && var.BASTION_FLOATING_IP == "localhost" ? 1 : 0) - IP = data.ibm_is_instance.db-vsi.primary_network_interface[0].primary_ip[0].address + IP = "${lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? data.ibm_is_instance.db-vsi[0].primary_network_interface[0].primary_ip[0].address : data.ibm_is_bare_metal_server.db-bms[0].primary_network_interface[0].primary_ip[0].address}" ID_RSA_FILE_PATH = var.ID_RSA_FILE_PATH SAP_MAIN_PASSWORD = var.SAP_MAIN_PASSWORD + HANA_MAIN_PASSWORD = var.HANA_MAIN_PASSWORD PLAYBOOK = "sap-s4hana.yml" } diff --git a/modules/ansible-exec/cli/ansible-exec.tf b/modules/ansible-exec/cli/ansible-exec.tf index f2b2afc..9a4aad5 100644 --- a/modules/ansible-exec/cli/ansible-exec.tf +++ b/modules/ansible-exec/cli/ansible-exec.tf @@ -1,15 +1,29 @@ resource "null_resource" "ansible-exec" { + provisioner "remote-exec" { + connection { + type = "ssh" + user = "root" + host = var.IP + private_key = file(var.ID_RSA_FILE_PATH) + timeout = "10m" + } + inline = ["echo 'Connection established!'"] + } + provisioner "local-exec" { command = "ansible-playbook --private-key ${var.ID_RSA_FILE_PATH} -i ansible/inventory.yml ansible/${var.PLAYBOOK} " } provisioner "local-exec" { - command = "sed -i 's/${var.SAP_MAIN_PASSWORD}/xxxxxxxx/' terraform.tfstate" + command = "sed -i 's/${var.HANA_MAIN_PASSWORD}/xxxxxxxx/' terraform.tfstate" } + + provisioner "local-exec" { + command = "sed -i 's/${var.SAP_MAIN_PASSWORD}/xxxxxxxx/' terraform.tfstate" + } provisioner "local-exec" { command = "sleep 20; rm -rf ansible/*-vars.yml" } } - diff --git a/modules/ansible-exec/cli/variables.tf b/modules/ansible-exec/cli/variables.tf index 303c878..7031ac7 100644 --- a/modules/ansible-exec/cli/variables.tf +++ b/modules/ansible-exec/cli/variables.tf @@ -13,6 +13,11 @@ variable "SAP_MAIN_PASSWORD" { description = "SAP_MAIN_PASSWORD" } +variable "HANA_MAIN_PASSWORD" { + type = string + description = "HANA_MAIN_PASSWORD" +} + variable "ID_RSA_FILE_PATH" { nullable = false description = "Input your id_rsa private key file path in OpenSSH format." diff --git a/modules/ansible-exec/remote-exec.tf b/modules/ansible-exec/remote-exec.tf index b783879..69f014d 100644 --- a/modules/ansible-exec/remote-exec.tf +++ b/modules/ansible-exec/remote-exec.tf @@ -1,78 +1,92 @@ -resource "null_resource" "ansible-exec" { - - connection { - type = "ssh" - user = "root" - host = var.BASTION_FLOATING_IP - private_key = var.PRIVATE_SSH_KEY - timeout = "2m" - } - - - provisioner "file" { - source = "ansible" - destination = "/tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}" - } - - provisioner "file" { - source = "${var.ID_RSA_FILE_PATH}" - destination = "/tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/id_rsa" - } - - provisioner "remote-exec" { - inline = [ - "chmod 600 /tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/id_rsa", - ] - } - - provisioner "file" { - source = "modules/ansible-exec/check.ansible.sh" - destination = "/tmp/${var.IP}.check.ansible.sh" - } +resource "null_resource" "check-target-connection" { + connection { + bastion_host = var.BASTION_FLOATING_IP + host = var.IP + user = "root" + private_key = var.PRIVATE_SSH_KEY + timeout = "15m" + } + + provisioner "remote-exec" { + inline = ["echo 'Connection established with target!'"] + } +} - provisioner "remote-exec" { - inline = [ - "chmod +x /tmp/${var.IP}.check.ansible.sh", - ] - } +resource "null_resource" "ansible-exec" { - provisioner "file" { + depends_on = [null_resource.check-target-connection] + + connection { + type = "ssh" + user = "root" + host = var.BASTION_FLOATING_IP + private_key = var.PRIVATE_SSH_KEY + timeout = "10m" + } + + provisioner "file" { + source = "ansible" + destination = "/tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}" + } + + provisioner "file" { + source = "${var.ID_RSA_FILE_PATH}" + destination = "/tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/id_rsa" + } + + provisioner "remote-exec" { + inline = [ + "chmod 600 /tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/id_rsa", + ] + } + + provisioner "file" { + source = "modules/ansible-exec/check.ansible.sh" + destination = "/tmp/${var.IP}.check.ansible.sh" + } + + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/${var.IP}.check.ansible.sh", + ] + } + + provisioner "file" { source = "modules/ansible-exec/timeout.ansible.sh" destination = "/tmp/${var.IP}.timeout.ansible.sh" } - provisioner "remote-exec" { - inline = [ - "chmod +x /tmp/${var.IP}.timeout.ansible.sh", - ] - } - - provisioner "file" { - source = "modules/ansible-exec/while.sh" - destination = "/tmp/${var.IP}.while.sh" - } - - provisioner "remote-exec" { - inline = [ - "chmod +x /tmp/${var.IP}.while.sh", - ] - } - - provisioner "file" { - source = "modules/ansible-exec/error.sh" - destination = "/tmp/${var.IP}.error.sh" - } - - provisioner "remote-exec" { - inline = [ - "chmod +x /tmp/${var.IP}.error.sh", - ] - } - - provisioner "local-exec" { - command = "ssh -o 'StrictHostKeyChecking no' -i ${var.ID_RSA_FILE_PATH} root@${var.BASTION_FLOATING_IP} 'export ANSIBLE_CONFIG=/tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/ansible.cfg; nohup ansible-playbook --private-key /tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/id_rsa -i /tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/inventory.yml /tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/${var.PLAYBOOK} > /tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}.log 2>&1 &'" - } - + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/${var.IP}.timeout.ansible.sh", + ] + } + + provisioner "file" { + source = "modules/ansible-exec/while.sh" + destination = "/tmp/${var.IP}.while.sh" + } + + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/${var.IP}.while.sh", + ] + } + + provisioner "file" { + source = "modules/ansible-exec/error.sh" + destination = "/tmp/${var.IP}.error.sh" + } + + provisioner "remote-exec" { + inline = [ + "chmod +x /tmp/${var.IP}.error.sh", + ] + } + + provisioner "local-exec" { + command = "ssh -o 'StrictHostKeyChecking no' -i ${var.ID_RSA_FILE_PATH} root@${var.BASTION_FLOATING_IP} 'export ANSIBLE_CONFIG=/tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/ansible.cfg; nohup ansible-playbook --private-key /tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/id_rsa -i /tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/inventory.yml /tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}/${var.PLAYBOOK} > /tmp/ansible.${local.SAP_DEPLOYMENT}-${var.IP}.log 2>&1 &'" + } } resource "null_resource" "check-ansible" { diff --git a/modules/app-vsi/files/sapapp_vm_volume_layout.json b/modules/app-vsi/files/sapapp_vm_volume_layout.json new file mode 100644 index 0000000..725fb45 --- /dev/null +++ b/modules/app-vsi/files/sapapp_vm_volume_layout.json @@ -0,0 +1,65 @@ +{ + "profiles": { + "default": { + "storage": { + "app_vg": { + "disk_size": "128", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "_app_vg" + }, + "lv": [ + { + "lv_name": "_usrsap_lv", + "lv_size": "5", + "fs_type": "ext4", + "mount_point": "/usr/sap", + "mount_options": "defaults" + }, + { + "lv_name": "_sap_lv", + "lv_size": "20", + "fs_type": "ext4", + "mount_point": "/usr/sap/", + "mount_options": "defaults" + }, + { + "lv_name": "_sapmnt_lv", + "lv_size": "20", + "fs_type": "ext4", + "mount_point": "/sapmnt/", + "mount_options": "defaults" + }, + { + "lv_name": "_saptrans_lv", + "lv_size": "50", + "fs_type": "ext4", + "mount_point": "/usr/sap/trans", + "mount_options": "defaults" + } + ] + } + }, + "swap": { + "disk_size": "", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "100%FREE", + "fs_type": "swap" + } + ] + } + } + } + } + } +} diff --git a/modules/app-vsi/files/swap_size.json b/modules/app-vsi/files/swap_size.json new file mode 100644 index 0000000..ca32026 --- /dev/null +++ b/modules/app-vsi/files/swap_size.json @@ -0,0 +1,52 @@ +[ + { + "ram_min": 0, + "ram_max": 31, + "swap_size": 48 + }, + { + "ram_min": 32, + "ram_max": 63, + "swap_size": 64 + }, + { + "ram_min": 64, + "ram_max": 127, + "swap_size": 96 + }, + { + "ram_min": 128, + "ram_max": 255, + "swap_size": 128 + }, + { + "ram_min": 256, + "ram_max": 511, + "swap_size": 160 + }, + { + "ram_min": 512, + "ram_max": 1023, + "swap_size": 192 + }, + { + "ram_min": 1024, + "ram_max": 2047, + "swap_size": 224 + }, + { + "ram_min": 2048, + "ram_max": 4095, + "swap_size": 256 + }, + { + "ram_min": 4096, + "ram_max": 8191, + "swap_size": 288 + }, + { + "ram_min": 8192, + "ram_max": 20000, + "swap_size": 320 + } +] diff --git a/modules/app-vsi/output.tf b/modules/app-vsi/output.tf index e7c172e..3045511 100644 --- a/modules/app-vsi/output.tf +++ b/modules/app-vsi/output.tf @@ -5,3 +5,11 @@ output "HOSTNAME" { output "PRIVATE-IP" { value = ibm_is_instance.vsi.primary_network_interface.0.primary_ip.0.address } + +output "STORAGE-LAYOUT" { + value = local.display_crt_storage +} + +output "SWAP_DISK_SIZE" { + value = local.swap_size +} diff --git a/modules/app-vsi/variables.tf b/modules/app-vsi/variables.tf index 1110f86..33dc13b 100644 --- a/modules/app-vsi/variables.tf +++ b/modules/app-vsi/variables.tf @@ -13,7 +13,6 @@ variable "SUBNET" { description = "Subnet name" } - variable "RESOURCE_GROUP" { type = string description = "Resource Group" @@ -44,12 +43,26 @@ variable "SSH_KEYS" { description = "List of SSH Keys to access the VSI" } -variable "VOLUME_SIZES" { - type = list(string) - description = "List of volume sizes in GB to be created" -} - -variable "VOL_PROFILE" { - type = string - description = "Volume profile" +locals { + # SWAP + ram_size = tonumber(split("x", split("-", var.PROFILE)[1])[1]) + ram_ranges = jsondecode(file("${path.module}/files/swap_size.json")) + swap_list = [ + for range in local.ram_ranges : range.swap_size + if ( + (range.ram_min == null || local.ram_size >= range.ram_min) && + (range.ram_max == null || local.ram_size <= range.ram_max) + ) + ] + swap_size = local.swap_list[0] + # All volumes + storage = jsondecode(file("${path.module}/files/sapapp_vm_volume_layout.json")) + storage_default = "default" + crt_structure = local.storage != null ? local.storage.profiles["${local.storage_default}"]["storage"] : null + # Define VOLUMES_STRUCTURE tuple for preserving the order of the elements in hash (to make sure the order for the elements in VOLUME_SIZES and VOL_PROFILE is the same) + volume_structure = local.crt_structure != null ? flatten([ for k, v in local.crt_structure : v ]) : null + volume_sizes_raw = local.volume_structure != null ? flatten([ for k in range(length(local.volume_structure)) : [ [for _ in range(local.volume_structure[k]["disk_count"]) : local.volume_structure[k]["disk_size"]]]]) : [] + volume_sizes = local.volume_sizes_raw != [] ? flatten([ for k in local.volume_sizes_raw : replace(k, "", tostring(local.swap_size)) ]) : [] + vol_profile = local.volume_structure != null ? flatten([ for k in range(length(local.volume_structure)) : [ [for _ in range(local.volume_structure[k]["disk_count"]) : local.volume_structure[k]["iops"]]]]) : [] + display_crt_storage = local.volume_structure != null ? { for k, v in local.crt_structure : k => { for j, m in v : j => replace(m, "", tostring(local.swap_size)) if j != "lvm" && j != "fs_type" && j != "mount_point" }} : null } diff --git a/modules/app-vsi/volume.tf b/modules/app-vsi/volume.tf index 07cf897..e56748a 100644 --- a/modules/app-vsi/volume.tf +++ b/modules/app-vsi/volume.tf @@ -1,9 +1,9 @@ resource "ibm_is_volume" "vol" { -count = length( var.VOLUME_SIZES ) +count = length( local.volume_sizes ) > 0 && length( local.volume_sizes ) == length( local.vol_profile ) ? length( local.volume_sizes ) : 0 name = "${var.HOSTNAME}-vol${count.index}" zone = var.ZONE resource_group = data.ibm_resource_group.group.id - capacity = var.VOLUME_SIZES[count.index] - profile = var.VOL_PROFILE + capacity = local.volume_sizes[count.index] + profile = local.vol_profile[count.index] } diff --git a/modules/db-bms/bms.tf b/modules/db-bms/bms.tf new file mode 100644 index 0000000..79d6c49 --- /dev/null +++ b/modules/db-bms/bms.tf @@ -0,0 +1,46 @@ +data "ibm_is_vpc" "vpc" { + name = var.VPC +} + +data "ibm_is_security_group" "securitygroup" { + name = var.SECURITY_GROUP +} + +data "ibm_is_subnet" "subnet" { + name = var.SUBNET +} + +data "ibm_is_image" "image" { + name = var.IMAGE +} + +data "ibm_resource_group" "group" { + name = var.RESOURCE_GROUP +} + +resource "ibm_is_bare_metal_server" "bms" { + tags = [ "wes-sap-automation" ] + vpc = data.ibm_is_vpc.vpc.id + zone = var.ZONE + resource_group = data.ibm_resource_group.group.id + keys = var.SSH_KEYS + name = var.HOSTNAME + profile = var.PROFILE + image = data.ibm_is_image.image.id + timeouts { + create = "50m" + update = "50m" + delete = "50m" + } + primary_network_interface { + subnet = data.ibm_is_subnet.subnet.id + security_groups = [data.ibm_is_security_group.securitygroup.id] + } + lifecycle { + precondition { + condition = local.PROCESSING_TYPE_FOUND == true && local.OS_TYPE_FOUND == true + error_message = "The chosen storage PROFILE for HANA on Bare Metal \"${var.PROFILE}\" is not a certified storage profile for the selected OS IMAGE: \"${var.IMAGE}\". Please, chose the appropriate certified storage PROFILE for the HANA VSI from https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-bm-vpc . Make sure the selected PROFILE is certified for the selected OS type and for the proceesing type (SAP Business One, OLTP, OLAP)" + # error_message = "The chosen storage PROFILE for HANA on Bare Metal \"${var.PROFILE}\" is not a certified storage profile for processing type: \"${upper(local.HANA_PROCESSING_TYPE)}\" or for the selected OS IMAGE: \"${var.IMAGE}\". Please, chose the appropriate certified storage PROFILE for HANA Bare Metal server from https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-bm-vpc . Make sure the selected PROFILE is certified for the selected OS type and for the proceesing type (SAP Business One, OLTP, OLAP)" + } + } +} \ No newline at end of file diff --git a/modules/db-bms/files/hana_bm_volume_layout.json b/modules/db-bms/files/hana_bm_volume_layout.json new file mode 100644 index 0000000..9c38034 --- /dev/null +++ b/modules/db-bms/files/hana_bm_volume_layout.json @@ -0,0 +1,329 @@ +{ + "profiles": { + "cx2d-metal-96x192": { + "storage": { + "vg0": { + "disk_size": "2980", + "disk_count": "4", + "lvm": { + "vg": { + "vg_name": "vg0" + }, + "lv": [ + { + "lv_name": "hana_shared_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "192", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/shared", + "mount_options": "defaults", + "label": "HANA_SHARED" + }, + { + "lv_name": "hana_log_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "192", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "vg1": { + "disk_size": "2980", + "disk_count": "4", + "lvm": { + "vg": { + "vg_name": "vg1" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "100%FREE", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + } + }, + "processing_type": { + "sap_business_one": ["sles-15-3", "sles-15-4"] + } + }, + "bx2d-metal-96x384": { + "storage": { + "vg0": { + "disk_size": "2980", + "disk_count": "4", + "lvm": { + "vg": { + "vg_name": "vg0" + }, + "lv": [ + { + "lv_name": "hana_shared_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "384", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/shared", + "mount_options": "defaults", + "label": "HANA_SHARED" + }, + { + "lv_name": "hana_log_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "384", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "vg1": { + "disk_size": "2980", + "disk_count": "4", + "lvm": { + "vg": { + "vg_name": "vg1" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "100%FREE", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-15-3", "sles-15-4", "sles-15-5", "redhat-8-4", "redhat-8-6", "redhat-8-8", "redhat-9-0", "redhat-9-2"], + "olap": ["sles-15-3", "sles-15-4", "sles-15-5", "redhat-8-4", "redhat-8-6", "redhat-8-8", "redhat-9-0", "redhat-9-2"], + "sap_business_one": ["sles-15-3", "sles-15-4", "sles-15-5"] + } + }, + "mx2d-metal-96x768": { + "storage": { + "vg0": { + "disk_size": "2980", + "disk_count": "4", + "lvm": { + "vg": { + "vg_name": "vg0" + }, + "lv": [ + { + "lv_name": "hana_shared_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "768", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/shared", + "mount_options": "defaults", + "label": "HANA_SHARED" + }, + { + "lv_name": "hana_log_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "512", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "vg1": { + "disk_size": "2980", + "disk_count": "4", + "lvm": { + "vg": { + "vg_name": "vg1" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "100%FREE", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-15-3", "sles-15-4", "sles-15-5", "redhat-8-4", "redhat-8-6", "redhat-8-8", "redhat-9-0", "redhat-9-2"], + "olap": ["sles-15-3", "sles-15-4", "sles-15-5", "redhat-8-4", "redhat-8-6", "redhat-8-8", "redhat-9-0", "redhat-9-2"], + "sap_business_one": ["sles-15-3", "sles-15-4", "sles-15-5"] + } + }, + "ux2d-metal-112x3072": { + "storage": { + "vg0": { + "disk_size": "2980", + "disk_count": "4", + "lvm": { + "vg": { + "vg_name": "vg0" + }, + "lv": [ + { + "lv_name": "hana_shared_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "3072", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/shared", + "label": "HANA_SHARED" + }, + { + "lv_name": "hana_log_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "512", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "vg1": { + "disk_size": "2980", + "disk_count": "4", + "lvm": { + "vg": { + "vg_name": "vg1" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "raid_type": "raid10", + "mirrors": "1", + "lv_size": "100%FREE", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-15-3", "sles-15-4", "sles-15-5", "redhat-8-4", "redhat-8-6", "redhat-8-8", "redhat-9-0", "redhat-9-2"], + "olap": ["sles-15-3", "sles-15-4", "sles-15-5", "redhat-8-4", "redhat-8-6", "redhat-8-8", "redhat-9-0", "redhat-9-2"] + } + }, + "ux2d-metal-224x6144": { + "storage": { + "vg0": { + "disk_size": "23838", + "disk_count": "2", + "lvm": { + "vg": { + "vg_name": "vg0" + }, + "lv": [ + { + "lv_name": "hana_shared_lv", + "raid_type": "raid1", + "lv_size": "6144", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/shared", + "mount_options": "defaults", + "label": "HANA_SHARED" + }, + { + "lv_name": "hana_log_lv", + "raid_type": "raid1", + "lv_size": "512", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + }, + { + "lv_name": "hana_data_lv", + "raid_type": "raid1", + "lv_size": "100%FREE", + "fs_type": "xfs", + "fs_create_options": "-K", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-15-3", "sles-15-4", "sles-15-5", "redhat-8-4", "redhat-8-6", "redhat-8-8", "redhat-9-0", "redhat-9-2"], + "olap": ["sles-15-3", "sles-15-4", "sles-15-5", "redhat-8-4", "redhat-8-6", "redhat-8-8", "redhat-9-0", "redhat-9-2"] + } + } + } +} \ No newline at end of file diff --git a/modules/db-bms/output.tf b/modules/db-bms/output.tf new file mode 100644 index 0000000..f4e9fc7 --- /dev/null +++ b/modules/db-bms/output.tf @@ -0,0 +1,15 @@ +output "HOSTNAME" { + value = ibm_is_bare_metal_server.bms.name +} + +output "PRIVATE-IP" { + value = ibm_is_bare_metal_server.bms.primary_network_interface.0.primary_ip.0.address +} + +output "VPC" { + value = var.VPC +} + +output "STORAGE-LAYOUT" { + value = local.DISPLAY_CRT_STORAGE +} diff --git a/modules/db-bms/variables.tf b/modules/db-bms/variables.tf new file mode 100644 index 0000000..3871b29 --- /dev/null +++ b/modules/db-bms/variables.tf @@ -0,0 +1,63 @@ +variable "ZONE" { + type = string + description = "Cloud Zone" +} + +variable "VPC" { + type = string + description = "VPC name" +} + +variable "SUBNET" { + type = string + description = "Subnet name" +} + +variable "RESOURCE_GROUP" { + type = string + description = "Resource Group" +} + +variable "SECURITY_GROUP" { + type = string + description = "Security group name" +} + +variable "HOSTNAME" { + type = string + description = "VSI Hostname" +} + +variable "PROFILE" { + type = string + description = "DB VSI Profile" + # default = "mx2-16x128" +} + +variable "IMAGE" { + type = string + description = "VSI OS Image" +} + +variable "SSH_KEYS" { + type = list(string) + description = "List of SSH Keys to access the VSI" +} + +locals { + HANA_PROCESSING_TYPE = "all" + # HANA_PROCESSING_TYPE with accepted values: "all", "OLAP", "OLTP" "SAP Business One"- if needed for future development + ALL_HANA_CERTIFIED_STORAGE = jsondecode(file("${path.module}/files/hana_bm_volume_layout.json")) + HANA_PROCESSING_TYPE_JSON = replace(trimspace(lower(local.HANA_PROCESSING_TYPE)), " ", "_") + PROCESSING_TYPE_FOUND = local.HANA_PROCESSING_TYPE_JSON == "all" ? true : contains(keys(local.ALL_HANA_CERTIFIED_STORAGE["profiles"]["${var.PROFILE}"]["processing_type"]), local.HANA_PROCESSING_TYPE_JSON) + OS_FROM_IMAGE = replace(replace(trimspace(lower(var.IMAGE)), "ibm-", ""), "/-amd64-sap-hana-.*/", "") + ALL_OS_TYPES = [] + OS_FOR_ALL_PROCESSING_TYPES = local.PROCESSING_TYPE_FOUND == true ? flatten([ for k in keys(local.ALL_HANA_CERTIFIED_STORAGE["profiles"]["${var.PROFILE}"]["processing_type"]) : concat(local.ALL_OS_TYPES, local.ALL_HANA_CERTIFIED_STORAGE["profiles"]["${var.PROFILE}"]["processing_type"]["${k}"])]) : [] + OS_TYPE_FOUND = local.PROCESSING_TYPE_FOUND == true ? (local.HANA_PROCESSING_TYPE_JSON == "all" ? contains(local.OS_FOR_ALL_PROCESSING_TYPES, "${lower(local.OS_FROM_IMAGE)}") : contains(local.ALL_HANA_CERTIFIED_STORAGE["profiles"]["${var.PROFILE}"]["processing_type"]["${local.HANA_PROCESSING_TYPE_JSON}"], "${lower(local.OS_FROM_IMAGE)}")) : false + CURRENT_STORAGE_CERTIFIED = local.PROCESSING_TYPE_FOUND == true && local.OS_TYPE_FOUND == true ? local.ALL_HANA_CERTIFIED_STORAGE.profiles["${var.PROFILE}"]["storage"]: null + # Define VOLUMES_STRUCTURE tuple for preserving the order of the elements in hash (to make sure the order for the elements in VOLUME_SIZES and VOL_PROFILE is the same) + # VOLUMES_STRUCTURE = local.PROCESSING_TYPE_FOUND == true && local.OS_TYPE_FOUND == true ? flatten([ for k, v in local.CURRENT_STORAGE_CERTIFIED : v ]) : null + # VOLUME_SIZES = local.PROCESSING_TYPE_FOUND == true && local.OS_TYPE_FOUND == true ? flatten([ for k in range(length(local.VOLUMES_STRUCTURE)) : [ [for _ in range(local.VOLUMES_STRUCTURE[k]["disk_count"]) : local.VOLUMES_STRUCTURE[k]["disk_size"]]]]) : [] + # VOL_PROFILE = local.PROCESSING_TYPE_FOUND == true && local.OS_TYPE_FOUND == true ? flatten([ for k in range(length(local.VOLUMES_STRUCTURE)) : [ [for _ in range(local.VOLUMES_STRUCTURE[k]["disk_count"]) : local.VOLUMES_STRUCTURE[k]["iops"]]]]) : [] + DISPLAY_CRT_STORAGE = local.PROCESSING_TYPE_FOUND == true && local.OS_TYPE_FOUND == true ? { for k, v in local.CURRENT_STORAGE_CERTIFIED : k => { for j, m in v : j => m if j != "lvm" && j != "fs_type" && j != "mount_point" }} : null +} diff --git a/modules/db-bms/versions.tf b/modules/db-bms/versions.tf new file mode 100644 index 0000000..92adf1f --- /dev/null +++ b/modules/db-bms/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + ibm = { + source = "IBM-Cloud/ibm" + version = ">= 1.57.0" + } + } + required_version = ">= 1.5.7" +} \ No newline at end of file diff --git a/modules/db-vsi/files/hana_vm_volume_layout.json b/modules/db-vsi/files/hana_vm_volume_layout.json new file mode 100644 index 0000000..8689e65 --- /dev/null +++ b/modules/db-vsi/files/hana_vm_volume_layout.json @@ -0,0 +1,1847 @@ +{ + "profiles": { + "mx2-8x64": { + "storage": { + "hana_vg": { + "disk_size": "500", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64" + }, + { + "lv_name": "hana_shared_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%FREE", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] + } + }, + "mx2d-8x64": { + "storage": { + "hana_vg": { + "disk_size": "500", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64" + }, + { + "lv_name": "hana_shared_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%FREE", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] + } + }, + "mx2-16x128": { + "storage": { + "hana_vg": { + "disk_size": "500", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64" + }, + { + "lv_name": "hana_shared_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%FREE", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], + "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] + } + }, + "mx2d-16x128": { + "storage": { + "hana_vg": { + "disk_size": "500", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64" + }, + { + "lv_name": "hana_shared_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%FREE", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], + "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] + } + }, + "mx2-32x256": { + "storage": { + "hana_vg": { + "disk_size": "500", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64" + }, + { + "lv_name": "hana_shared_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%FREE", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], + "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] + } + }, + "mx2d-32x256": { + "storage": { + "hana_vg": { + "disk_size": "500", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64" + }, + { + "lv_name": "hana_shared_lv", + "lv_size": "256", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%FREE", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], + "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] + } + }, + "mx2-48x384": { + "storage": { + "hana_vg": { + "disk_size": "500", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_shared_lv", + "lv_size": "384", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%FREE", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64" + } + ] + } + }, + "log": { + "disk_size": "100", + "disk_count": "4", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "4", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], + "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] + } + }, + "mx2d-48x384": { + "storage": { + "hana_vg": { + "disk_size": "500", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_shared_lv", + "lv_size": "384", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%FREE", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64" + } + ] + } + }, + "log": { + "disk_size": "100", + "disk_count": "4", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "4", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], + "sap_business_one": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4"] + } + }, + "vx2d-16x224": { + "storage": { + "hana_vg": { + "disk_size": "1120", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "224", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + }, + { + "lv_name": "hana_shared_lv", + "lv_size": "224", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%VG", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "vx2d-44x616": { + "storage": { + "data": { + "disk_size": "1848", + "disk_count": "1", + "iops": "10iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + }, + "shared": { + "disk_size": "616", + "disk_count": "1", + "iops": "5iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + "log": { + "disk_size": "192", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], + "olap": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "vx2d-88x1232": { + "storage": { + "data": { + "disk_size": "3696", + "disk_count": "1", + "iops": "10iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + }, + "shared": { + "disk_size": "1232", + "disk_count": "1", + "iops": "5iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + "log": { + "disk_size": "192", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], + "olap": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "vx2d-144x2016": { + "storage": { + "data": { + "disk_size": "1024", + "disk_count": "4", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_data_vg" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "lv_size": "100%VG", + "lv_stripes": "4", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + }, + "log": { + "disk_size": "192", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "shared": { + "disk_size": "2016", + "disk_count": "1", + "iops": "5iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], + "olap": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "vx2d-176x2464": { + "storage": { + "data": { + "disk_size": "1280", + "disk_count": "4", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_data_vg" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "lv_size": "100%VG", + "lv_stripes": "4", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + }, + "log": { + "disk_size": "192", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "shared": { + "disk_size": "2464", + "disk_count": "1", + "iops": "5iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"], + "olap": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "ux2d-8x224": { + "storage": { + "hana_vg": { + "disk_size": "1120", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "224", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + }, + { + "lv_name": "hana_shared_lv", + "lv_size": "224", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%VG", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "ux2d-16x448": { + "storage": { + "hana_vg": { + "disk_size": "2240", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "448", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + }, + { + "lv_name": "hana_shared_lv", + "lv_size": "448", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + { + "lv_name": "hana_data_lv", + "lv_size": "100%VG", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "ux2d-36x1008": { + "storage": { + "data": { + "disk_size": "1008", + "disk_count": "2", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_data_vg" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "lv_size": "100%VG", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + }, + "log": { + "disk_size": "192", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "shared": { + "disk_size": "1008", + "disk_count": "1", + "iops": "5iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "ux2d-48x1344": { + "storage": { + "data": { + "disk_size": "1350", + "disk_count": "2", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_data_vg" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "lv_size": "100%VG", + "lv_stripes": "2", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + }, + "log": { + "disk_size": "192", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "shared": { + "disk_size": "1344", + "disk_count": "1", + "iops": "5iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "ux2d-72x2016": { + "storage": { + "data": { + "disk_size": "1024", + "disk_count": "4", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_data_vg" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "lv_size": "100%VG", + "lv_stripes": "4", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + }, + "log": { + "disk_size": "192", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "shared": { + "disk_size": "2016", + "disk_count": "1", + "iops": "5iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "ux2d-100x2800": { + "storage": { + "data": { + "disk_size": "2100", + "disk_count": "4", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_data_vg" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "lv_size": "100%VG", + "lv_stripes": "4", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + }, + "log": { + "disk_size": "192", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "shared": { + "disk_size": "2800", + "disk_count": "1", + "iops": "5iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + }, + "ux2d-200x5600": { + "storage": { + "data": { + "disk_size": "4200", + "disk_count": "4", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_data_vg" + }, + "lv": [ + { + "lv_name": "hana_data_lv", + "lv_size": "100%VG", + "lv_stripes": "4", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/data", + "mount_options": "defaults,largeio,swalloc,inode64", + "label": "HANA_DATA" + } + ] + } + }, + "log": { + "disk_size": "192", + "disk_count": "3", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "hana_log_vg" + }, + "lv": [ + { + "lv_name": "hana_log_lv", + "lv_size": "100%VG", + "lv_stripes": "3", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/hana/log", + "mount_options": "defaults,swalloc,inode64", + "label": "HANA_LOG" + } + ] + } + }, + "shared": { + "disk_size": "5600", + "disk_count": "1", + "iops": "5iops-tier", + "fs_type": "xfs", + "mount_point": "/hana/shared", + "mount_options": "defaults,inode64", + "label": "HANA_SHARED" + }, + "usr_sap": { + "disk_size": "50", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "usr_sap_vg" + }, + "lv": [ + { + "lv_name": "usr_sap_lv", + "lv_size": "100%FREE", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "xfs", + "mount_point": "/usr/sap" + } + ] + } + }, + "swap": { + "disk_size": "10", + "disk_count": "1", + "iops": "10iops-tier", + "lvm": { + "vg": { + "vg_name": "swap_vg" + }, + "lv": [ + { + "lv_name": "swap_lv", + "lv_size": "2", + "lv_stripes": "1", + "lv_stripe_size": "64", + "fs_type": "swap" + } + ] + } + } + }, + "processing_type": { + "oltp": ["sles-12-4", "sles-12-5", "sles-15-1", "sles-15-2", "sles-15-3", "sles-15-4", "redhat-7-6", "redhat-7-9", "redhat-8-1", "redhat-8-2", "redhat-8-4", "redhat-8-6"] + } + } + } +} \ No newline at end of file diff --git a/modules/db-vsi/output.tf b/modules/db-vsi/output.tf index 35b7dec..36dacef 100644 --- a/modules/db-vsi/output.tf +++ b/modules/db-vsi/output.tf @@ -6,6 +6,10 @@ output "PRIVATE-IP" { value = ibm_is_instance.vsi.primary_network_interface.0.primary_ip.0.address } +output "VPC" { + value = var.VPC +} + output "STORAGE-LAYOUT" { value = local.DISPLAY_CRT_STORAGE } diff --git a/modules/db-vsi/variables.tf b/modules/db-vsi/variables.tf index b75e7ea..8e51805 100644 --- a/modules/db-vsi/variables.tf +++ b/modules/db-vsi/variables.tf @@ -13,14 +13,14 @@ variable "SUBNET" { description = "Subnet name" } -variable "RESOURCE_GROUP" { +variable "SECURITY_GROUP" { type = string - description = "Resource Group" + description = "Security group name" } -variable "SECURITY_GROUP" { +variable "RESOURCE_GROUP" { type = string - description = "Security group name" + description = "Resource Group" } variable "HOSTNAME" { @@ -29,9 +29,9 @@ variable "HOSTNAME" { } variable "PROFILE" { - type = string - description = "DB VSI Profile" - default = "mx2-16x128" + type = string + description = "DB VSI Profile" + # default = "mx2-16x128" } variable "IMAGE" { @@ -47,7 +47,7 @@ variable "SSH_KEYS" { locals { HANA_PROCESSING_TYPE = "All" # HANA_PROCESSING_TYPE with accepted values: "All", "OLAP", "OLTP" "SAP Business One"- if needed for future development - ALL_HANA_CERTIFIED_STORAGE = jsondecode(file("${path.root}/files/hana_volume_layout.json")) + ALL_HANA_CERTIFIED_STORAGE = jsondecode(file("${path.module}/files/hana_vm_volume_layout.json")) HANA_PROCESSING_TYPE_JSON = replace(trimspace(lower(local.HANA_PROCESSING_TYPE)), " ", "_") PROCESSING_TYPE_FOUND = local.HANA_PROCESSING_TYPE_JSON == "all" ? true : contains(keys(local.ALL_HANA_CERTIFIED_STORAGE["profiles"]["${var.PROFILE}"]["processing_type"]), local.HANA_PROCESSING_TYPE_JSON) OS_FROM_IMAGE = replace(replace(trimspace(lower(var.IMAGE)), "ibm-", ""), "/-amd64-sap-hana-.*/", "") diff --git a/modules/db-vsi/vsi.tf b/modules/db-vsi/vsi.tf index a921278..c38741d 100644 --- a/modules/db-vsi/vsi.tf +++ b/modules/db-vsi/vsi.tf @@ -30,7 +30,7 @@ resource "ibm_is_instance" "vsi" { primary_network_interface { subnet = data.ibm_is_subnet.subnet.id - security_groups = [data.ibm_is_security_group.securitygroup.id] + security_groups = [ data.ibm_is_security_group.securitygroup.id ] } volumes = ibm_is_volume.vol[*].id diff --git a/output.tf b/output.tf index 2e639e1..2dc2c90 100644 --- a/output.tf +++ b/output.tf @@ -1,13 +1,13 @@ output "DB_HOSTNAME" { - value = module.db-vsi.HOSTNAME + value = lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? data.ibm_is_instance.db-vsi[0].name : data.ibm_is_bare_metal_server.db-bms[0].name } output "DB_PRIVATE_IP" { - value = module.db-vsi.PRIVATE-IP + value = lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? data.ibm_is_instance.db-vsi[0].primary_network_interface[0].primary_ip[0].address : data.ibm_is_bare_metal_server.db-bms[0].primary_network_interface[0].primary_ip[0].address } output "DB_STORAGE_LAYOUT" { - value = module.db-vsi.STORAGE-LAYOUT + value = lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? module.db-vsi[0].STORAGE-LAYOUT : module.db-bms[0].STORAGE-LAYOUT } output "APP_HOSTNAME" { @@ -22,8 +22,6 @@ output "VPC" { value = var.VPC } -output "ATR_INSTANCE_NAME" { - description = "Activity Tracker instance name." - value = var.ATR_NAME +output "APP_STORAGE_LAYOUT" { + value = module.app-vsi.STORAGE-LAYOUT } - diff --git a/variables.tf b/variables.tf index d2c9adb..e4bbd1d 100644 --- a/variables.tf +++ b/variables.tf @@ -4,7 +4,7 @@ variable "PRIVATE_SSH_KEY" { type = string - description = "The id_rsa private key content in OpenSSH format. This private key should be used only during the terraform provisioning and it is recommended to be changed after the SAP deployment." + description = "The id_rsa private SSH key content in OpenSSH format. This private SSH key should be used only during the terraform provisioning and it is recommended to be changed after the SAP deployment." nullable = false validation { condition = length(var.PRIVATE_SSH_KEY) >= 64 && var.PRIVATE_SSH_KEY != null && length(var.PRIVATE_SSH_KEY) != 0 || contains(["n.a"], var.PRIVATE_SSH_KEY ) @@ -15,15 +15,15 @@ variable "PRIVATE_SSH_KEY" { variable "ID_RSA_FILE_PATH" { default = "ansible/id_rsa" nullable = false - description = "The file path for ID_RSA_FILE_PATH will be automatically generated by default. If it is changed, it must contain the relative path from git repo folders. Examples: ansible/id_rsa_s4hana, ~/.ssh/id_rsa_s4hana , /root/.ssh/id_rsa" + description = "The file path for the private ssh key. It will be automatically generated. If it is changed, it must contain the relative path from git repo folders. Examples: ansible/id_rsa_s4hana, ~/.ssh/id_rsa_s4hana , /root/.ssh/id_rsa" } variable "SSH_KEYS" { type = list(string) - description = "List of SSH Keys UUIDs that are allowed to SSH as root to the VSI. Can contain one or more IDs. The list of SSH Keys is available here: https://cloud.ibm.com/vpc-ext/compute/sshKeys." + description = "List of SSH Keys UUIDs that are allowed to SSH as root to the server. Can contain one or more IDs. The list of SSH Keys is available here: https://cloud.ibm.com/vpc-ext/compute/sshKeys." validation { condition = var.SSH_KEYS == [] ? false : true && var.SSH_KEYS == [""] ? false : true - error_message = "At least one SSH KEY is needed to be able to access the VSI." + error_message = "At least one SSH KEY is needed to be able to access the server." } } @@ -39,7 +39,7 @@ variable "BASTION_FLOATING_IP" { variable "RESOURCE_GROUP" { type = string - description = "The name of an EXISTING Resource Group for VSIs and Volumes resources. Default value: \"Default\". The list of Resource Groups is available here: https://cloud.ibm.com/account/resource-groups." + description = "The name of an EXISTING Resource Group for servers and Volumes resources. Default value: \"Default\". The list of Resource Groups is available here: https://cloud.ibm.com/account/resource-groups." default = "Default" } @@ -90,7 +90,7 @@ variable "SECURITY_GROUP" { variable "DB_HOSTNAME" { type = string - description = "The Hostname for the HANA VSI. The hostname should be up to 13 characters as required by SAP. For more information on rules regarding hostnames for SAP systems, check SAP Note 611361: \"Hostnames of SAP ABAP Platform servers\"." + description = "The Hostname for SAP HANA Server. The hostname should be up to 13 characters as required by SAP. For more information on rules regarding hostnames for SAP systems, check SAP Note 611361: \"Hostnames of SAP ABAP Platform servers\"." validation { condition = length(var.DB_HOSTNAME) <= 13 && length(regexall("^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$", var.DB_HOSTNAME)) > 0 error_message = "The DB_HOSTNAME is not valid." @@ -99,24 +99,28 @@ variable "DB_HOSTNAME" { variable "DB_PROFILE" { type = string - description = "The instance profile used for the HANA VSI. The list of certified profiles for HANA VSIs is available here: https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc. Details about all x86 instance profiles are available here: https://cloud.ibm.com/docs/vpc?topic=vpc-profiles. For more information about supported DB/OS and IBM Gen 2 Virtual Server Instances (VSI), check SAP Note 2927211: \"SAP Applications on IBM Virtual Private Cloud\"." - default = "mx2-16x128" - validation { - condition = contains(keys(jsondecode(file("files/hana_volume_layout.json")).profiles), "${var.DB_PROFILE}") - error_message = "The chosen storage PROFILE for HANA VSI \"${var.DB_PROFILE}\" is not a certified storage profile. Please, chose the appropriate certified storage PROFILE for the HANA VSI from https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc . Make sure the selected PROFILE is certified for the selected OS type and for the proceesing type (SAP Business One, OLTP, OLAP)" - } + description = "The profile used for SAP HANA Server. The list of certified profiles for SAP HANA Virtual Servers is available here: https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc and for Bare Metal Servers here: https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-bm-vpc. Details about all x86 instance profiles are available here: https://cloud.ibm.com/docs/vpc?topic=vpc-profiles. Example of Virtual Server Instance profile for SAP HANA: \"mx2-16x128\". Example of Bare Metal profile for SAP HANA: \"bx2d-metal-96x384 \". For more information about supported DB/OS and IBM VPC, check SAP Note 2927211: \"SAP Applications on IBM Virtual Private Cloud\"." } variable "DB_IMAGE" { type = string - description = "The OS image used for HANA VSI. A list of images is available here: https://cloud.ibm.com/docs/vpc?topic=vpc-about-images." - default = "ibm-redhat-8-6-amd64-sap-hana-5" + description = "The OS image used for SAP HANA Server. A list of images is available here: https://cloud.ibm.com/docs/vpc?topic=vpc-about-images." + default = "ibm-redhat-8-6-amd64-sap-hana-6" validation { condition = length(regexall("^(ibm-redhat-8-(4|6)-amd64-sap-hana|ibm-sles-15-(3|4)-amd64-sap-hana)-[0-9][0-9]*", var.DB_IMAGE)) > 0 error_message = "The OS SAP DB_IMAGE must be one of \"ibm-sles-15-3-amd64-sap-hana-x\", \"ibm-sles-15-4-amd64-sap-hana-x\", \"ibm-redhat-8-4-amd64-sap-hana-x\" or \"ibm-redhat-8-6-amd64-sap-hana-x\"." } } +variable "HANA_SERVER_TYPE" { + type = string + description = "The type of SAP HANA Server. Allowed vales: \"virtual\" or \"bare metal\"." + validation { + condition = contains(["virtual", "bare metal"], var.HANA_SERVER_TYPE) + error_message = "The type of SAP HANA Server is not valid. The allowed values should be one of the following: \"virtual\" or \"bare metal\"" + } +} + variable "APP_HOSTNAME" { type = string description = "The Hostname for the SAP Application VSI. The hostname should be up to 13 characters as required by SAP. For more information on rules regarding hostnames for SAP systems, check SAP Note 611361: \"Hostnames of SAP ABAP Platform servers\"." @@ -135,7 +139,7 @@ variable "APP_PROFILE" { variable "APP_IMAGE" { type = string description = "The OS image used for SAP Application VSI. A list of images is available here: https://cloud.ibm.com/docs/vpc?topic=vpc-about-images." - default = "ibm-redhat-8-6-amd64-sap-applications-5" + default = "ibm-redhat-8-6-amd64-sap-applications-6" validation { condition = length(regexall("^(ibm-redhat-8-(4|6)-amd64-sap-applications|ibm-sles-15-(3|4)-amd64-sap-applications)-[0-9][0-9]*", var.APP_IMAGE)) > 0 error_message = "The OS SAP APP_IMAGE must be one of \"ibm-sles-15-3-amd64-sap-applications-x\", \"ibm-sles-15-4-amd64-sap-applications-x\", \"ibm-redhat-8-4-amd64-sap-applications-x\" or \"ibm-redhat-8-6-amd64-sap-applications-x\"." @@ -143,23 +147,32 @@ variable "APP_IMAGE" { } data "ibm_is_instance" "db-vsi" { - depends_on = [module.db-vsi] - name = var.DB_HOSTNAME + count = var.HANA_SERVER_TYPE == "virtual" ? 1 : 0 + depends_on = [module.db-vsi] + name = var.DB_HOSTNAME +} + +data "ibm_is_bare_metal_server" "db-bms" { + count = var.HANA_SERVER_TYPE != "virtual" ? 1 : 0 + depends_on = [module.db-bms] + name = var.DB_HOSTNAME } + data "ibm_is_instance" "app-vsi" { depends_on = [module.app-vsi] name = var.APP_HOSTNAME } -############################################################## -# The variables used in Activity Tracker service. -############################################################## - -variable "ATR_NAME" { - type = string - description = "The name of the EXISTING Activity Tracker instance, in the same region as HANA VSI. The list of available Activity Tracker is available here: https://cloud.ibm.com/observe/activitytracker" - default = "" +# HANA SERVER PROFILE +resource "null_resource" "check_profile" { + count = var.DB_PROFILE != "" ? 1 : 0 + lifecycle { + precondition { + condition = lower(trimspace(var.HANA_SERVER_TYPE)) == "virtual" ? contains(keys(jsondecode(file("${path.root}/modules/db-vsi/files/hana_vm_volume_layout.json")).profiles), "${var.DB_PROFILE}") : contains(keys(jsondecode(file("${path.root}/modules/db-bms/files/hana_bm_volume_layout.json")).profiles), "${var.DB_PROFILE}") + error_message = "The chosen storage PROFILE for SAP HANA Server \"${var.DB_PROFILE}\" is not a certified storage profile. Please, chose the appropriate certified storage PROFILE for the HANA VSI form https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-vs-vpc or for HANA BM Server from https://cloud.ibm.com/docs/sap?topic=sap-hana-iaas-offerings-profiles-intel-bm-vpc . Make sure the selected PROFILE is certified for the selected OS type and for the proceesing type (SAP Business One, OLTP, OLAP)" + } + } } ############################################################## @@ -186,6 +199,16 @@ variable "HANA_SID" { } } +variable "HANA_TENANT" { + type = string + description = "The name of the SAP HANA tenant." + default = "HDB" + validation { + condition = length(regexall("^[A-Za-z0-9-_]+$", var.HANA_TENANT)) > 0 && !contains(["ADD", "ALL", "AMD", "AND", "ANY", "ARE", "ASC", "AUX", "AVG", "BIT", "CDC", "COM", "CON", "DBA", "END", "EPS", "FOR", "GET", "GID", "IBM", "INT", "KEY", "LOG", "LPT", "MAP", "MAX", "MIN", "MON", "NIX", "NOT", "NUL", "OFF", "OLD", "OMS", "OUT", "PAD", "PRN", "RAW", "REF", "ROW", "SAP", "SET", "SGA", "SHG", "SID", "SQL", "SUM", "SYS", "TMP", "TOP", "UID", "USE", "USR", "VAR"], var.HANA_TENANT) + error_message = "The name of SAP HANA tenant HANA_TENANT is not valid." + } +} + variable "HANA_SYSNO" { type = string description = "Specifies the instance number of the SAP HANA system." @@ -229,7 +252,7 @@ variable "HANA_COMPONENTS" { variable "KIT_SAPHANA_FILE" { type = string description = "Path to SAP HANA ZIP file. As downloaded from SAP Support Portal." - default = "/storage/HANADB/51057281.ZIP" + default = "/storage/HANADB/SP07/Rev73/51057281.ZIP" } variable "SAP_SID" { @@ -335,25 +358,3 @@ variable "KIT_S4HANA_EXPORT" { description = "Path to S/4HANA Installation Export dir. The archives downloaded from SAP Support Portal should be present in this path." default = "/storage/S4HANA/2023" } - -# ATR variables and conditions -locals { - ATR_ENABLE = true -} - -resource "null_resource" "check_atr_name" { - count = local.ATR_ENABLE == true ? 1 : 0 - lifecycle { - precondition { - condition = var.ATR_NAME != "" && var.ATR_NAME != null - error_message = "The name of an EXISTENT Activity Tracker in the same region must be specified." - } - } -} - -data "ibm_resource_instance" "activity_tracker" { - count = local.ATR_ENABLE == true ? 1 : 0 - name = var.ATR_NAME - location = var.REGION - service = "logdnaat" -}