You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

238 lines
9.0 KiB

  1. import time
  2. import boto3
  3. from botocore.exceptions import ClientError
  4. ################################################################################################
  5. #
  6. # Configuration Parameters
  7. #
  8. ################################################################################################
  9. # place your credentials in ~/.aws/credentials, as mentioned in AWS Educate Classroom,
  10. # Account Details, AWC CLI -> Show (Copy and paste the following into ~/.aws/credentials)
  11. # changed to use us-east, to be able to use AWS Educate Classroom
  12. region = 'us-east-1'
  13. availabilityZone = 'us-east-1a'
  14. # region = 'eu-central-1'
  15. # availabilityZone = 'eu-central-1b'
  16. # AMI ID of Amazon Linux 2 image 64-bit x86 in us-east-1 (can be retrieved, e.g., at
  17. # https://console.aws.amazon.com/ec2/v2/home?region=us-east-1#LaunchInstanceWizard:)
  18. imageId = 'ami-0d5eff06f840b45e9'
  19. # for eu-central-1, AMI ID of Amazon Linux 2 would be:
  20. # imageId = 'ami-0cc293023f983ed53'
  21. # potentially change instanceType to t2.micro for "free tier" if using a regular account
  22. # for production, t3.nano seams better
  23. instanceType = 't2.nano'
  24. keyName = 'srieger-pub'
  25. ################################################################################################
  26. #
  27. # boto3 code
  28. #
  29. ################################################################################################
  30. client = boto3.setup_default_session(region_name=region)
  31. ec2Client = boto3.client("ec2")
  32. ec2Resource = boto3.resource('ec2')
  33. # if you only have one VPC, vpc_id can be retrieved using:
  34. response = ec2Client.describe_vpcs()
  35. vpc_id = response.get('Vpcs', [{}])[0].get('VpcId', '')
  36. # if you have more than one VPC, vpc_id should be specified, and code
  37. # top retrieve VPC id below needs to be commented out
  38. # vpc_id = 'vpc-eedd4187'
  39. subnet_id = ec2Client.describe_subnets(
  40. Filters=[
  41. {
  42. 'Name': 'availability-zone', 'Values': [availabilityZone]
  43. }
  44. ])['Subnets'][0]['SubnetId']
  45. print("Deleting old instance...")
  46. print("------------------------------------")
  47. response = ec2Client.describe_instances(Filters=[{'Name': 'tag-key', 'Values': ['tug-of-war']}])
  48. print(response)
  49. reservations = response['Reservations']
  50. for reservation in reservations:
  51. for instance in reservation['Instances']:
  52. if instance['State']['Name'] == "running" or instance['State']['Name'] == "pending":
  53. response = ec2Client.terminate_instances(InstanceIds=[instance['InstanceId']])
  54. print(response)
  55. instanceToTerminate = ec2Resource.Instance(instance['InstanceId'])
  56. instanceToTerminate.wait_until_terminated()
  57. print("Delete old security group...")
  58. print("------------------------------------")
  59. try:
  60. response = ec2Client.delete_security_group(GroupName='tug-of-war')
  61. except ClientError as e:
  62. print(e)
  63. print("Create security group...")
  64. print("------------------------------------")
  65. try:
  66. response = ec2Client.create_security_group(GroupName='tug-of-war',
  67. Description='tug-of-war',
  68. VpcId=vpc_id)
  69. security_group_id = response['GroupId']
  70. print('Security Group Created %s in vpc %s.' % (security_group_id, vpc_id))
  71. data = ec2Client.authorize_security_group_ingress(
  72. GroupId=security_group_id,
  73. IpPermissions=[
  74. {'IpProtocol': 'tcp',
  75. 'FromPort': 3306,
  76. 'ToPort': 3306,
  77. 'IpRanges': [{'CidrIp': '0.0.0.0/0'}]},
  78. {'IpProtocol': 'tcp',
  79. 'FromPort': 22,
  80. 'ToPort': 22,
  81. 'IpRanges': [{'CidrIp': '0.0.0.0/0'}]},
  82. {'IpProtocol': 'tcp',
  83. 'FromPort': 80,
  84. 'ToPort': 80,
  85. 'IpRanges': [{'CidrIp': '0.0.0.0/0'}]},
  86. {'IpProtocol': 'tcp',
  87. 'FromPort': 443,
  88. 'ToPort': 443,
  89. 'IpRanges': [{'CidrIp': '0.0.0.0/0'}]}
  90. ])
  91. print('Ingress Successfully Set %s' % data)
  92. except ClientError as e:
  93. print(e)
  94. userDataDB = ('#!/bin/bash\n'
  95. '# extra repo for RedHat rpms\n'
  96. 'yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm\n'
  97. '# essential tools\n'
  98. 'yum install -y joe htop git\n'
  99. '# mysql\n'
  100. 'yum install -y mariadb mariadb-server\n'
  101. '\n'
  102. 'service mariadb start\n'
  103. '\n'
  104. 'echo "create database cloud_tug_of_war" | mysql -u root\n'
  105. '\n'
  106. 'echo "create table clouds ( cloud_id INT AUTO_INCREMENT, name VARCHAR(255) NOT NULL, value INT, max_value INT, PRIMARY KEY (cloud_id))" | mysql -u root cloud_tug_of_war\n'
  107. '\n'
  108. 'echo "CREATE USER \'cloud_tug_of_war\'@\'%\' IDENTIFIED BY \'cloudpass\';" | mysql -u root\n'
  109. 'echo "GRANT ALL PRIVILEGES ON cloud_tug_of_war.* TO \'cloud_tug_of_war\'@\'%\';" | mysql -u root\n'
  110. 'echo "FLUSH PRIVILEGES" | mysql -u root\n'
  111. )
  112. # convert user-data from script with: cat install-mysql | sed "s/^/'/; s/$/\\\n'/"
  113. print("Running new DB instance...")
  114. print("------------------------------------")
  115. response = ec2Client.run_instances(
  116. ImageId=imageId,
  117. InstanceType=instanceType,
  118. Placement={'AvailabilityZone': availabilityZone, },
  119. KeyName=keyName,
  120. MinCount=1,
  121. MaxCount=1,
  122. UserData=userDataDB,
  123. SecurityGroupIds=[
  124. security_group_id,
  125. ],
  126. TagSpecifications=[
  127. {
  128. 'ResourceType': 'instance',
  129. 'Tags': [
  130. {'Key': 'Name', 'Value': 'tug-of-war-db1'},
  131. {'Key': 'tug-of-war', 'Value': 'db'}
  132. ],
  133. }
  134. ],
  135. )
  136. instanceIdDB = response['Instances'][0]['InstanceId']
  137. privateIpDB = response['Instances'][0]['PrivateIpAddress']
  138. # privateIpDB = response['Instances'][0]['NetworkInterfaces'][0]['NetworkInterfaceId']
  139. instance = ec2Resource.Instance(instanceIdDB)
  140. instance.wait_until_running()
  141. print(instanceIdDB)
  142. userDataWebServer = ('#!/bin/bash\n'
  143. '# extra repo for RedHat rpms\n'
  144. 'yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm\n'
  145. '# essential tools\n'
  146. 'yum install -y joe htop git\n'
  147. '# mysql\n'
  148. 'yum install -y httpd php php-mysql\n'
  149. '\n'
  150. 'service httpd start\n'
  151. '\n'
  152. # 'wget http://mmnet.informatik.hs-fulda.de/cloudcomp/tug-of-war-in-the-clouds.tar.gz\n'
  153. # 'cp tug-of-war-in-the-clouds.tar.gz /var/www/html/\n'
  154. # 'tar zxvf tug-of-war-in-the-clouds.tar.gz\n'
  155. 'cd /var/www/html\n'
  156. 'wget https://gogs.informatik.hs-fulda.de/srieger/cloud-computing-msc-ai-examples/raw/master/example-projects/tug-of-war-in-the-clouds/web-content/index.php\n'
  157. 'wget https://gogs.informatik.hs-fulda.de/srieger/cloud-computing-msc-ai-examples/raw/master/example-projects/tug-of-war-in-the-clouds/web-content/cloud.php\n'
  158. 'wget https://gogs.informatik.hs-fulda.de/srieger/cloud-computing-msc-ai-examples/raw/master/example-projects/tug-of-war-in-the-clouds/web-content/config.php\n'
  159. '\n'
  160. '# change hostname of db connection\n'
  161. 'sed -i s/localhost/' + privateIpDB + '/g /var/www/html/config.php\n'
  162. )
  163. for i in range(1, 3):
  164. print("Running new Web Server instance...")
  165. print("------------------------------------")
  166. response = ec2Client.run_instances(
  167. ImageId=imageId,
  168. InstanceType=instanceType,
  169. Placement={'AvailabilityZone': availabilityZone, },
  170. KeyName=keyName,
  171. MinCount=1,
  172. MaxCount=1,
  173. UserData=userDataWebServer,
  174. SecurityGroupIds=[
  175. security_group_id,
  176. ],
  177. TagSpecifications=[
  178. {
  179. 'ResourceType': 'instance',
  180. 'Tags': [
  181. {'Key': 'Name', 'Value': 'tug-of-war-webserver' + str(i)},
  182. {'Key': 'tug-of-war', 'Value': 'webserver'}
  183. ],
  184. }
  185. ],
  186. )
  187. instanceIdWeb = response['Instances'][0]['InstanceId']
  188. instance = ec2Resource.Instance(instanceIdWeb)
  189. instance.wait_until_running()
  190. instance.load()
  191. # sometimes even after reloading instance details, public IP cannot be retrieved using current boto3 version and
  192. # AWS Educate accounts, try for 10 secs, and ask user to get it from AWS console otherwise
  193. timeout = 10
  194. while instance.public_ip_address is None and timeout > 0:
  195. print("Waiting for public IP to become available...")
  196. instance.load()
  197. time.sleep(1)
  198. timeout -= 1
  199. if instance.public_ip_address is not None:
  200. print("tug-of-war-in-the-clouds can be accessed at: " + instance.public_ip_address)
  201. else:
  202. print("Could not get public IP using boto3, this is likely an AWS Educate problem. You can however lookup the "
  203. "public ip from the AWS management console.")