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

heat_1

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.

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] }
To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply