Command Line Creation of an AWS Instance for SAP HANA

The bash script shown here allows to create SAP HANA instances from the command line. It uses the AWS CLI. The aws command needs to be in the search path.

Consider to use the AWS Quick Start for HANA deployment. It installs the AWS instance as well the HANA software.

The script below will create an AWS instance only. The script solves a number of issues for administrators:

  • It tags the instance and all instance volumes. This simplifies the complete deletion of the instance
  • All volumes are getting marked to be deleted when the instance gets deleted
  • It takes a private IP address to be used as input parameter
  • It takes the CIDR of the subnet in which the instance is supposed to be created.
  • It enabled detailed monitoring (as requested by SAP)
  • it will use the ebs-optimized flag to expedite IO

The limitations

  • The script creates instances with a private IP address in a VPC.
  • It doesn't check whether the IP address matches the CIDR
  • It is currently using a disk configuration for r3.8xlarge SAP compliant systems
  • It doesn't create VPS or subnets.
  • It will use the region of the current profile of the AWC CLI

The script requires a file with the name disks.json. This file is currently configured to create a boot disk and 4 gp2 disks with 667GB.

Warning

This script will create AWS resources AWS will charge you for. Be careful using this script. I don't warrant anything

Preconditions

  • Have the AWS Command Line Interface (CLI) installed on your system.
  • Configure a AWS user in your AWS CLI profile which has the appropriate IAM profile to create EC2 instances and use a number of describe aws commands
  • Have the bash shell installed on your system

Download

Using the Script

Provide all parameter when calling it in the following format:

./createHANA.sh ami-id pem-name instance-type ip-address cidr security-group "name tag"

Example:

./createHana.sh ami-6b5a5601 myPEM r3.4xlarge 10.79.7.95 10.79.7.0/24 mySecGroup "my-HANA-System95"

*** 1. Prequisites checking
*** 1.1 OK: requested IP address 10.79.7.95 is available
*** 1.2 OK: requested CIDR 10.79.7.0/24 belongs to subnet-6b964f32 in us-east-1c , vpc-2e976742
*** 1.3 Warning: No check whether 10.79.7.95 fits into CIDR 10.79.7.0/24 !
*** 1.4 OK: requested security group mySecGroup is sg-582eec37 (Connect toLab)
*** 1.5 OK: requested PEM myPEM exists.
*** 1.6 OK: AMI ami-6b5a5601 exists (amazon/suse-sles-12-sp1-v20160322-hvm-ssd-x86_64)
Do you want to create this instance? (y/n) Yes
*** 2. About to create the instance
*** 2.1 Created system with Id: i-9dd0e707
*** 2.2 Tagged system with Id: i-9dd0e707 with Name: my-HANA-System95
*** 2.3.1 Tagged all volumes from system with Id: i-9dd0e707 with Name: my-HANA-System95
*** 2.4 The created instance: i-9dd0e707 with Name: my-HANA-System95
RESERVATIONS 752040392274 r-684b74d9
INSTANCES 0 x86_64 None True xen ami-6b5a5601 i-9dd0e707 r3.4xlarge myPEM 2016-06-24T13:47:25.000Z None 10.79.7.95 None /dev/sda1 ebs True None subnet-6b964f32 hvm vpc-2e976742
BLOCKDEVICEMAPPINGS /dev/sda1
EBS 2016-06-24T13:47:26.000Z True attaching vol-8c836528
BLOCKDEVICEMAPPINGS /dev/sdf
EBS 2016-06-24T13:47:26.000Z True attaching vol-0f8365ab
BLOCKDEVICEMAPPINGS /dev/sdg
EBS 2016-06-24T13:47:26.000Z True attaching vol-0e8365aa
BLOCKDEVICEMAPPINGS /dev/sdh
EBS 2016-06-24T13:47:26.000Z True attaching vol-fe83655a
BLOCKDEVICEMAPPINGS /dev/sdi
EBS 2016-06-24T13:47:26.000Z True attaching vol-e983654d
BLOCKDEVICEMAPPINGS /dev/sdj
EBS 2016-06-24T13:47:26.000Z True attaching vol-ac836508
MONITORING pending
NETWORKINTERFACES None 0e:0f:2c:30:0b:b7 eni-522c1700 752040392274 10.79.7.95 True in-use subnet-6b964f32 vpc-2e976742
ATTACHMENT 2016-06-24T13:47:25.000Z eni-attach-c0de2d15 True 0 attaching
GROUPS sg-582eec37 mySecGroup
PRIVATEIPADDRESSES True 10.79.7.95
PLACEMENT us-east-1c None default
SECURITYGROUPS sg-582eec37 mySecGroup
STATE 0 pending
TAGS Name my-HANA-System95

The second option to use the script is the interactive dialog:

./createHANA.sh
Enter AMI name:
ami-6b5a5601
Enter name of security key:
myPEM
Enter instance type:
r3.4xlarge
Enter IP address:
10.79.7.94
Enter CIDR n the format xxx..xxx.xxx.xxx/yy:
10.79.7.0/24
Enter security group name:
mySecGroup
Enter name tags for instance and volumes:
my-HANA-System94
*** 1. Prequisites checking
*** 1.1 OK: requested IP address 10.79.7.94 is available
*** 1.2 OK: requested CIDR 10.79.7.0/24 belongs to subnet-6b964f32 in us-east-1c , vpc-2e976742
*** 1.3 Warning: No check whether 10.79.7.94 fits into CIDR 10.79.7.0/24 !
*** 1.4 OK: requested security group mySecGroup is sg-582eec37 (Connect to Lab)
*** 1.5 OK: requested PEM myPEM exists.
*** 1.6 OK: AMI ami-6b5a5601 exists (amazon/suse-sles-12-sp1-v20160322-hvm-ssd-x86_64)
Do you want to create this instance? (y/n) Yes
*** 2. About to create the instance
*** 2.1 Created system with Id: i-30ddeaaa
*** 2.2 Tagged system with Id: i-30ddeaaa with Name: my-HANA-System94
*** 2.3.1 Tagged all volumes from system with Id: i-30ddeaaa with Name: my-HANA-System94
*** 2.4 The created instance: i-30ddeaaa with Name: my-HANA-System94
RESERVATIONS 752040392274 r-2a49769b
INSTANCES 0 x86_64 None True xen ami-6b5a5601 i-30ddeaaa r3.4xlarge myPEM 2016-06-24T13:53:11.000Z None 10.79.7.94 None /dev/sda1 ebs True None subnet-6b964f32 hvm vpc-2e976742
BLOCKDEVICEMAPPINGS /dev/sda1
EBS 2016-06-24T13:53:12.000Z True attaching vol-5a8d6bfe
BLOCKDEVICEMAPPINGS /dev/sdf
EBS 2016-06-24T13:53:12.000Z True attaching vol-b38a6c17
BLOCKDEVICEMAPPINGS /dev/sdg
EBS 2016-06-24T13:53:12.000Z True attaching vol-b28a6c16
BLOCKDEVICEMAPPINGS /dev/sdh
EBS 2016-06-24T13:53:12.000Z True attaching vol-5b8d6bff
BLOCKDEVICEMAPPINGS /dev/sdi
EBS 2016-06-24T13:53:12.000Z True attaching vol-4e8d6bea
BLOCKDEVICEMAPPINGS /dev/sdj
EBS 2016-06-24T13:53:12.000Z True attaching vol-198d6bbd
MONITORING pending
NETWORKINTERFACES None 0e:cc:0c:19:f4:b1 eni-621c2730 752040392274 10.79.7.94 True in-use subnet-6b964f32 vpc-2e976742
ATTACHMENT 2016-06-24T13:53:11.000Z eni-attach-0ec635db True 0 attaching
GROUPS sg-582eec37 mySecGroup
PRIVATEIPADDRESSES True 10.79.7.94
PLACEMENT us-east-1c None default
SECURITYGROUPS sg-582eec37 mySecGroup
STATE 0 pending
TAGS Name my-HANA-System94

The script createHANA.sh

#!/bin/bash
# version 1.0 June 24, 2016
# This script is using the AWS cli.
# It assumes that the aws command is part of the search path
AMI=$1
PEM=$2
INSTANCETYPE=$3
IP=$4
CIDR=$5
SGNAME=$6
NAMETAG=$7
case $1 in
-h | -help)p
echo "Use this command with the following options:"
echo "$0 -h : to obtain this output"
echo "$0 -help : to obtain this output"
echo "$0 : enter information through a dialog"
echo "$0 ami-id pem-name instance-type ip-address cidr security-group \"name tag\" "
echo "Example:"
echo " ./createHana.sh ami-6b5a5601 myPEM r3.4xlarge 10.79.7.96 10.79.7.0/24 mySecGroup \"my-HANA-System96\""
exit
;;
esac
if [[ -z $AMI ]]; then
echo "Enter AMI name:"
read AMI
fi
if [[ -z $PEM ]]; then
echo "Enter name of security key:"
read PEM
fi
if [[ -z $INSTANCETYPE ]]; then
echo "Enter instance type:"
read INSTANCETYPE
fi
if [[ -z $IP ]]; then
echo "Enter IP address:"
read IP
fi
if [[ -z $CIDR ]]; then
echo "Enter CIDR n the format xxx..xxx.xxx.xxx/yy:"
read CIDR
fi
if [[ -z $SGNAME ]]; then
echo "Enter security group name:"
read SGNAME
fi
if [[ -z $NAMETAG ]]; then
echo "Enter name tags for instance and volumes:"
read NAMETAG
fi


echo "*** 1. Prequisites checking"
EXISTINGIP=$(aws ec2 describe-network-interfaces --filter Name=private-ip-address,Values=$IP | awk -F\t '/PRIVATEIPADDRESSES/ {print $3}' | grep $IP)
if [ $EXISTINGIP ]
then
INSTID=$(aws ec2 describe-network-interfaces --filter Name=private-ip-address,Values=$IP | awk -F\t '/ATTACHMENT/ {print $6}')
echo "*** 1.1 ERROR: requested IP address $IP is already in use by instance $INSTID. Will stop here..."
exit 1
else
echo "*** 1.1 OK: requested IP address $IP is available"
fi
SUBNET=$(aws ec2 describe-subnets --filter Name=cidrBlock,Values=$CIDR | awk -F\t '/SUBNETS/ {print $8}')
AZ=$(aws ec2 describe-subnets --filter Name=cidrBlock,Values=$CIDR | awk -F\t '/SUBNETS/ {print $2}')
VPC=$(aws ec2 describe-subnets --filter Name=cidrBlock,Values=$CIDR | awk -F\t '/SUBNETS/ {print $9}')
if [ $SUBNET ]
then
echo "*** 1.2 OK: requested CIDR $CIDR belongs to $SUBNET in $AZ , $VPC"
else
echo "*** 1.2 ERROR: no subnet found for CIDR $CIDR . Will stop here..."
exit 1
fi
echo "*** 1.3 Warning: No check whether $IP fits into CIDR $CIDR !"
SECURITY=$(aws ec2 describe-security-groups --filters Name=group-name,Values=${SGNAME} | awk -F\t '/SECURITYGROUPS/ {print $3}')
SECURITYTEXT=$(aws ec2 describe-security-groups --filters Name=group-name,Values=${SGNAME} | awk -F\t '/SECURITYGROUPS/ {print $2}')
if [ $SECURITY ]
then
echo "*** 1.4 OK: requested security group $SGNAME is $SECURITY ($SECURITYTEXT)"
else
echo "*** 1.4 ERROR: requested security group $SGNAME not found. Will stop here"
exit 1
fi
PEMRESULT=$(aws ec2 describe-key-pairs --filters Name=key-name,Values=$PEM| awk -F\t '/KEYPAIRS/ {print $3}')
if [ $PEMRESULT ]
then
echo "*** 1.5 OK: requested PEM $PEM exists."
else
echo "*** 1.5 ERROR: requested PEM $PEM not found. Will stop here"
exit 1
fi
AMINAME=$(aws ec2 describe-images --image-ids $AMI | awk -F\t '/IMAGES/ {print $6}')
if [ $AMINAME ]
then
echo "*** 1.6 OK: AMI $AMI exists ($AMINAME)"
else
echo "*** 1.6 ERROR: AMI $AMI does not exist. Will stop here"
exit 1
fi
echo -n "Do you want to create this instance? (y/n) "
old_stty_cfg=$(stty -g)
stty raw -echo ; answer=$(head -c 1) ; stty $old_stty_cfg # Care playing with stty
if echo "$answer" | grep -iq "^y" ;then
echo Yes
else
echo No
exit
fi
echo "*** 2. About to create the instance"
ID=$(aws ec2 run-instances \
--key-name $PEM \
--instance-type $INSTANCETYPE \
--count 1 \
--block-device-mappings file://disks.json \
--image-id $AMI \
--monitoring Enabled=true \
--instance-initiated-shutdown-behavior stop \
--security-group-ids $SECURITY \
--subnet-id $SUBNET \
--private-ip-address $IP \
--ebs-optimized | \
awk '/INSTANCES/ {print $8}' \
)
echo "*** 2.1 Created system with Id: $ID"
aws ec2 create-tags --resources $ID --tags Key=Name,Value=${NAMETAG}
echo "*** 2.2 Tagged system with Id: $ID with Name: $NAMETAG "
#echo "*** 2.3.0 will sleep for 2s before tagging the volumes with $NAMETAG "
#sleep 2
aws ec2 describe-instances --instance-ids $ID | awk '/EBS/ {print "aws ec2 create-tags --resources " $5 " --tags Key=Name,Value='"$NAMETAG"'" }' | bash -
echo "*** 2.3.1 Tagged all volumes from system with Id: $ID with Name: $NAMETAG "
echo "*** 2.4 The created instance: $ID with Name: $NAMETAG "
aws ec2 describe-instances --instance-ids $ID

The file disks.json

This file has to be in the directory in which the script is called

[ 
{"DeviceName":"/dev/sda1",
"Ebs":{"VolumeSize":200,"VolumeType":"gp2",
"DeleteOnTermination":true}},
{"DeviceName":"/dev/sdf",
"Ebs":{"VolumeSize":667,"VolumeType":"gp2",
"DeleteOnTermination":true}},
{"DeviceName":"/dev/sdg",
"Ebs":{"VolumeSize":667,"VolumeType":"gp2",
"DeleteOnTermination":true}},
{"DeviceName":"/dev/sdh","Ebs":{"VolumeSize":667,"VolumeType":"gp2",
"DeleteOnTermination":true}},
{"DeviceName":"/dev/sdi","Ebs":{"VolumeSize":667,"VolumeType":"gp2",
"DeleteOnTermination":true}},
{"DeviceName":"/dev/sdj","Ebs":{"VolumeSize":50,"VolumeType":"gp2",
"DeleteOnTermination":true}}
]

 Feedback

The script is limited. Leave a comment to get in touch with me. I'll be happy to improve the script and integrate a better coding.