SAP-as-a-Service with OpenStack Cloud – Part 1: Creating a HEAT Template for SAP Services
This content was based on work originally carried out by Phani Arava from SAT Infotech.
SAP Provides Cloud Appliance Library http://cal.sap.com. But here are the issues with it.
- Fixed SID. Cannot be used in Production. Most of the landscapes have to register their SIDs in the Solution manager to identify the machine. If it’s a SAP Service Provider, having the same SID for all customers would be a challenge.
- Appliances are available for AWS / Azure, but not for OpenStack.
- Appliances are not customized with databases of your choice. (Most of the time it’s SYBASE / HANA.)
We will look at the problem from a different perspective and try to create a HEAT template for automating the installation of SAP Systems (Unattended Installation). Though this approach is time-intensive, it gives a lot more flexibility and dependability.
The input requirements of the HEAT Template would be the following:
- Give a facility to select the SAP Instance Type (ECCEHP7, ECCEHP6, NW7.5, NW7.4 etc.)
- Give a facility to select the Database (SAPDB, SYBASE, DB2, Oracle, HANA etc.)
- Place to Enter the SID
The HEAT template should accomplish the following:
- Create a nova instance.
- Attach two block storages. The sizes of which will depend on the SAP Instance Type choosen. For ex: NW7.4, block sizes of 40G and 75GB are attached. The intention is to have separate disks for sapdata (/usr/sap, /sapmnt) and dbdata (Depends on the DB Selected. If its SYBASE, mount point will be /sybase)
- Create LVM Volume Groups of sapdata and dbdata.
- Create LVM Logical Volumes, Format and mount them.
Assumptions in using the HEAT Template.
- You have first created a SUSE for SAP OpenStack Cloud Image with cloud-init. If you haven’t, please use: https://www.suse.com/communities/blog/building-suse-sap-cloud-image-using-kiwi/to create one.
- You have installed OpenStack HEAT Services.
- You are running OpenStack with libvirt based virtualization platforms (Tested on KVM).
The HEAT file:
heat_template_version: 2015-04-30 description: > A template showing how to create a Nova instance, a Cinder volume and attach the volume to the instance. The template uses only Heat OpenStack native resource types. parameters: sapinstance_type: type: string label: SAP Instance Type description: SAP Instance Type Ex ECCEHP7, ECCEHP6, NW74 constraints: - allowed_values: [ ECCEHP6, NW74, S4HANA ] sapinstance_db_type: type: string label: SAP DB Type description: SAP Database Type Ex SAPDB, SYB, DB2, HANA, ORA constraints: - allowed_values: [ SAPDB, SYB, DB2, HANA, ORA ] sapinstance_sid: type: string label: SAP Instance SID description: SAP Instance SID constraints: - length: {min: 3, max: 3} description: SID should be of 3 Characters - allowed_pattern: "[A-Z][A-Z0-9][A-Z0-9]" resources: floating_ip: type: OS::Nova::FloatingIP properties: pool: floating nova_instance: type: OS::Nova::Server properties: image: 'SUSEforSAP' flavor: 'm1.sapsmall' key_name: 'cloud' name: 'sapserver' networks: - network: 'fixed' user_data_format: RAW user_data: str_replace: template: | #!/bin/bash disk1_id='%voldata1_id%' disk2_id='%voldata2_id%' disk1_size='%voldata1_size%' disk2_size='%voldata2_size%' disk1_size_mb=$(( $disk1_size * 1024 )) disk2_size_mb=$(( $disk2_size * 1024 )) db_mount_point='%dbmountpoint%' voldata1_dev="/dev/disk/by-id/virtio-$(echo ${disk1_id} | cut -c -20)" voldata2_dev="/dev/disk/by-id/virtio-$(echo ${disk2_id} | cut -c -20)" while [ ! -e ${voldata1_dev} ]; do echo Waiting for volume to attach; sleep 1; done while [ ! -e ${voldata2_dev} ]; do echo Waiting for volume to attach; sleep 1; done parted -s ${voldata1_dev} mklabel msdos parted -s ${voldata1_dev} mkpart primary ext3 1 ${disk1_size_mb} parted -s ${voldata1_dev} set 1 lvm on parted -s ${voldata2_dev} mklabel msdos parted -s ${voldata2_dev} mkpart primary ext3 1 ${disk2_size_mb} parted -s ${voldata2_dev} set 1 lvm on partprobe vgcreate sapdata ${voldata1_dev}-part1 vgcreate dbdata ${voldata2_dev}-part1 #The creation of Logical Volumes sapdata. Right now very simple. We will make it complex as we go. lvcreate -L+5G -n usrsap sapdata lvcreate -L+5G -n sapmnt sapdata lvcreate -L+20G -n sapdump sapdata #The creation of Logical Volumes dbdata. We will just minus 5G from disk2 size (to counter LVM extenrs). Again need to make some proper calculations. lvcreate -L+$(( $disk2_size - 5 ))G -n ${db_mount_point} dbdata mkfs.ext4 /dev/sapdata/usrsap mkfs.ext4 /dev/sapdata/sapmnt mkfs.ext4 /dev/sapdata/sapdump mkfs.ext4 /dev/dbdata/${db_mount_point} mkdir -p /usr/sap mkdir -p /sapmnt mkdir -p /sapdump mkdir -p /${db_mount_point} mount /dev/sapdata/usrsap /usr/sap mount /dev/sapdata/sapmnt /sapmnt mount /dev/sapdata/sapdump /sapdump mount /dev/dbdata/${db_mount_point} ${db_mount_point} params: "%voldata1_id%": { get_resource: cinder_volume1 } "%voldata2_id%": { get_resource: cinder_volume2 } "%voldata1_size%": { "Fn::Select" : [ {get_param: sapinstance_type} , { "ECCEHP7" : 50, "ECCEHP6" : 50, "NW74" : 40 } ] } "%voldata2_size%": { "Fn::Select" : [ {get_param: sapinstance_type} , { "ECCEHP7" : 200, "ECCEHP6" : 200, "NW74" : 75 } ] } "%dbmountpoint%": { "Fn::Select" : [ {get_param: sapinstance_db_type} , { "DB2" : "db2", "SYB" : "sybase", "SAPDB" : "sapdb" } ] } cinder_volume1: type: OS::Cinder::Volume properties: size: { "Fn::Select" : [ {get_param: sapinstance_type} , { "ECCEHP7" : 50, "ECCEHP6" : 50, "NW74" : 40 } ] } cinder_volume2: type: OS::Cinder::Volume properties: size: { "Fn::Select" : [ {get_param: sapinstance_type} , { "ECCEHP7" : 200, "ECCEHP6" : 200, "NW74" : 75 } ] } volume_attachment1: type: OS::Cinder::VolumeAttachment properties: volume_id: { get_resource: cinder_volume1 } instance_uuid: { get_resource: nova_instance } mountpoint: /dev/vdc volume_attachment2: type: OS::Cinder::VolumeAttachment properties: volume_id: { get_resource: cinder_volume2 } instance_uuid: { get_resource: nova_instance } mountpoint: /dev/vdd association: type: OS::Nova::FloatingIPAssociation properties: floating_ip: { get_resource: floating_ip } server_id: { get_resource: nova_instance } outputs: instance_ip: description: Public IP address of the newly created Nova instance. value: { get_attr: [nova_instance, first_address] }
Related Articles
Aug 25th, 2022
Navigate your SAP Journey with Dell Technologies and SUSE
Feb 15th, 2023
No comments yet