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.

154 lines
6.2 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-1b'
  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. # TODO update to recent version of Amazon Linux 2 AMI?
  19. imageId = 'ami-0d5eff06f840b45e9'
  20. # for eu-central-1, AMI ID of Amazon Linux 2 would be:
  21. # imageId = 'ami-0cc293023f983ed53'
  22. # potentially change instanceType to t2.micro for "free tier" if using a regular account
  23. # for production, t3.nano seams better
  24. # as of SoSe 2022 t2.nano seams to be a bit too low on memory, mariadb first start can fail
  25. # due to innodb cache out of memory, therefore t2.micro or swap in t2.nano currently recommended
  26. # instanceType = 't2.nano'
  27. instanceType = 't2.micro'
  28. # keyName = 'srieger-pub'
  29. keyName = 'vockey'
  30. ################################################################################################
  31. #
  32. # boto3 code
  33. #
  34. ################################################################################################
  35. client = boto3.setup_default_session(region_name=region)
  36. ec2Client = boto3.client("ec2")
  37. ec2Resource = boto3.resource('ec2')
  38. elbv2Client = boto3.client('elbv2')
  39. response = ec2Client.describe_security_groups(Filters=[{'Name': 'group-name', 'Values': ['tug-of-war']}])
  40. security_group_id = response.get('SecurityGroups', [{}])[0].get('GroupId', '')
  41. print("Getting DB IP...")
  42. print("------------------------------------")
  43. response = ec2Client.describe_instances(Filters=[{'Name': 'tag:tug-of-war', 'Values': ['db']}])
  44. print(response)
  45. reservations = response['Reservations']
  46. for reservation in reservations:
  47. for instance in reservation['Instances']:
  48. if instance['State']['Name'] == "running" or instance['State']['Name'] == "pending":
  49. instanceDB = ec2Resource.Instance(instance['InstanceId'])
  50. privateIpDB = instanceDB.private_ip_address
  51. userDataWebServer = ('#!/bin/bash\n'
  52. '# extra repo for RedHat rpms\n'
  53. 'yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm\n'
  54. '# essential tools\n'
  55. 'yum install -y joe htop git\n'
  56. '# mysql\n'
  57. 'yum install -y httpd php php-mysql\n'
  58. '\n'
  59. 'service httpd start\n'
  60. '\n'
  61. # 'wget http://mmnet.informatik.hs-fulda.de/cloudcomp/tug-of-war-in-the-clouds.tar.gz\n'
  62. # 'cp tug-of-war-in-the-clouds.tar.gz /var/www/html/\n'
  63. # 'tar zxvf tug-of-war-in-the-clouds.tar.gz\n'
  64. 'cd /var/www/html\n'
  65. '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'
  66. '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'
  67. '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'
  68. '\n'
  69. '# change hostname of db connection\n'
  70. 'sed -i s/localhost/' + privateIpDB + '/g /var/www/html/config.php\n'
  71. )
  72. for i in range(3, 4):
  73. print("Running new Web Server instance (in additional availability zone)...")
  74. print("-----------------------------------------------------------------------------------------")
  75. response = ec2Client.run_instances(
  76. ImageId=imageId,
  77. InstanceType=instanceType,
  78. Placement={'AvailabilityZone': availabilityZone, },
  79. KeyName=keyName,
  80. MinCount=1,
  81. MaxCount=1,
  82. UserData=userDataWebServer,
  83. SecurityGroupIds=[
  84. security_group_id,
  85. ],
  86. TagSpecifications=[
  87. {
  88. 'ResourceType': 'instance',
  89. 'Tags': [
  90. {'Key': 'Name', 'Value': 'tug-of-war-webserver' + str(i)},
  91. {'Key': 'tug-of-war', 'Value': 'webserver'}
  92. ],
  93. }
  94. ],
  95. )
  96. instanceIdWeb = response['Instances'][0]['InstanceId']
  97. instance = ec2Resource.Instance(instanceIdWeb)
  98. instance.wait_until_running()
  99. instance.load()
  100. # sometimes even after reloading instance details, public IP cannot be retrieved using current boto3 version and
  101. # AWS Educate accounts, try for 10 secs, and ask user to get it from AWS console otherwise
  102. timeout = 10
  103. while instance.public_ip_address is None and timeout > 0:
  104. print("Waiting for public IP to become available...")
  105. instance.load()
  106. time.sleep(1)
  107. timeout -= 1
  108. if instance.public_ip_address is not None:
  109. print("tug-of-war-in-the-clouds can be accessed at: http://" + instance.public_ip_address)
  110. else:
  111. print("Could not get public IP using boto3, this is likely an AWS Educate problem. You can however lookup the "
  112. "public ip from the AWS management console.")
  113. print("Registering instance in load balancer, load balancer has to be already created...")
  114. print("-----------------------------------------------------------------------------------------")
  115. try:
  116. response = elbv2Client.describe_target_groups(Names=['tug-of-war-targetgroup'])
  117. targetgroup_arn = response.get('TargetGroups', [{}])[0].get('TargetGroupArn', '')
  118. except ClientError as e:
  119. print(e)
  120. response = elbv2Client.register_targets(
  121. TargetGroupArn=targetgroup_arn,
  122. Targets=[
  123. {
  124. 'Id': instanceIdWeb,
  125. },
  126. ],
  127. )