-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathcreate-env.py
191 lines (165 loc) · 7.44 KB
/
create-env.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#!/usr/bin/python
# Use example
# python create-env.py --key-pair mykey --security-group sg-rtw54sd --subnet-id subnet-56dfd21
import os, argparse, json, time
# Measure how long the script takes
from datetime import datetime
startTime = datetime.now()
################################################
# #
# COMMAND CONFIGURATION WITH ARGUMENTPARSER #
# #
################################################
parser = argparse.ArgumentParser(description="Script that automates the creation of Blockchain+IoT project.")
# python create-env.py --key-pair 1 --security-group 2 --subnet-id 3 --iam-role 4
parser.add_argument('--composer-instance-id', '-cid', required=False, help="ID of the EC2 instance that runs the blockchain. ")
parser.add_argument('--key-pair', '-key', required=True, help="Name of the key pair to access the instances.")
parser.add_argument('--security-group', '-secgroup', required=True, help="ID of the security group that the instances will be in. Needs to open port 8000.")
parser.add_argument('--subnet-id', '-subnetid', required=True, help="ID of the subnet for the autoscaling group. You need to use the one assigned to us-east-2a.")
args = parser.parse_args()
print(args)
print('\n')
################################################
# #
# GLOBAL VALUES #
# #
################################################
# Local files for internal operations
AUX_FILE = 'auxfile.sh'
JSON_OUTPUT = 'output.json'
WEBAPP_REPOSITORY = 'https://github.com/pacoard/TFM_2017-18.git'
# AWS parameters
ELB_NAME = 'diot-frontend-elb'
ELB_DNS = '' # to be set when ELB is up and running
AWS_KEY_PAIR = args.key_pair
SECURITY_GROUP = args.security_group
AVAILABILITY_ZONE = os.popen('aws configure get region').read().replace('\n', '')
AMI_ID = 'ami-aa0030cf' # image of an instance that has the node dependencies installed
SUBNET_ID = args.subnet_id
# Autoscaling parameters
AUTOSCALING_CONFIGURATION = 'diot-frontend-autoscaling-config'
AUTOSCALING_GROUP = 'diot-frontend-autoscaling-group'
# Blockchain paramenters
BLOCKCHAIN_NETWORK_NAME = 'diot-biz-network'
BLOCKCHAIN_INSTANCE_ID = 'i-0bfba0dd9763a17c8' #args.composer_instance_id
BLOCKCHAIN_DNS = '' # to be retrieved from blockchain's EC2 instance
# GLOBAL FUNCTIONS
def execCommand(commandString):
print('=> Running command: ' + commandString + '\n')
os.system(commandString)
def extractJSON():
jsondict = {}
with open(JSON_OUTPUT) as jsonfile:
jsondict = json.load(jsonfile)
os.remove(JSON_OUTPUT)
return jsondict
# Create auxiliar file for commands to run when instances are created:
def createUserData():
fileData = (
'#!/bin/bash\n'
'cd /home/ubuntu\n'
'runuser -l ubuntu -c \'git clone ' + WEBAPP_REPOSITORY + ' diot\'\n'
'cd diot/frontend/\n'
'cp /home/ubuntu/node_modules -r .\n'
# PASSING DATA BY REPLACING VALUES IN THE SERVER SOURCE FILES
# ubuntu@ip-172-31-46-186:~$ sed -i "s/t_HOSTNAME/$(curl -s http://169.254.169.254/latest/meta-data/public-hostname)/g" package.json webpack.config.js
'sed -i "s/t_HOSTNAME/0.0.0.0/g" package.json webpack.config.js\n'
"sed -i 's/t_BLOCKCHAIN_DNS/"+ BLOCKCHAIN_DNS.replace('/', '\/') +"/g' app/constants/constants.jsx\n"
'npm start\n')
print('=============================== FRONTEND USER DATA FILE ===============================\n')
print(fileData)
print('=======================================================================================\n')
with open(AUX_FILE, 'w') as f:
f.write(fileData)
os.system('chmod +x ' + AUX_FILE)
return AUX_FILE
# Check that the blockchain instance is running and get its DNS address
print('Checking if blockchain is online...')
execCommand('aws ec2 wait instance-status-ok'
' --instance-ids ' + BLOCKCHAIN_INSTANCE_ID)
print('Blockchain online.')
# Get DNS of blockchain
execCommand('aws ec2 describe-instances'
+ ' --filters Name=instance-id,Values=' + BLOCKCHAIN_INSTANCE_ID
+ ' > ' + JSON_OUTPUT)
BLOCKCHAIN_DNS = extractJSON()['Reservations'][0]['Instances'][0]['PublicDnsName']
print('####################################################################################\n')
print('\n')
################################################
# #
# FRONTEND SERVERS SETUP #
# #
################################################
# Autoscaling launch configuration
execCommand('aws autoscaling create-launch-configuration'
+ ' --launch-configuration-name ' + AUTOSCALING_CONFIGURATION
+ ' --key-name ' + AWS_KEY_PAIR
+ ' --security-groups ' + SECURITY_GROUP
#+ ' --iam-instance-profile ' + IAM_ROLE
+ ' --image-id ' + AMI_ID
+ ' --instance-type t2.micro'
+ ' --user-data file://' + createUserData())
# Autoscaling group creation
execCommand('aws autoscaling create-auto-scaling-group'
+ ' --auto-scaling-group-name ' + AUTOSCALING_GROUP
+ ' --launch-configuration-name ' + AUTOSCALING_CONFIGURATION
+ ' --availability-zones ' + AVAILABILITY_ZONE + 'a'
+ ' --desired-capacity 2'
+ ' --min-size 1'
+ ' --max-size 2'
+ ' --vpc-zone-identifier ' + SUBNET_ID)
print('####################################################################################\n')
print('\n')
################################################
# #
# LOAD BALANCER SETUP #
# #
################################################
# Load balancer creation, with listener for the webapp
execCommand('aws elb create-load-balancer'
+ ' --load-balancer-name ' + ELB_NAME
+ ' --listeners "Protocol=HTTP,LoadBalancerPort=80,InstanceProtocol=HTTP,InstancePort=3000"'
+ ' --availability-zones ' + AVAILABILITY_ZONE + 'a'
+ ' --security-groups ' + SECURITY_GROUP
+ ' > ' + JSON_OUTPUT)
ELB_DNS = extractJSON()['DNSName'] # get ELB's DNS in order to access the service
# Attach load balancer to the autoscaling group
execCommand('aws autoscaling attach-load-balancers'
+ ' --load-balancer-names ' + ELB_NAME
+ ' --auto-scaling-group-name ' + AUTOSCALING_GROUP)
# Create load balancer stickiness policy
execCommand('aws elb create-lb-cookie-stickiness-policy'
+ ' --load-balancer-name ' + ELB_NAME
+ ' --policy-name my-duration-cookie-policy'
+ ' --cookie-expiration-period 60')
# Set policy
execCommand('aws elb set-load-balancer-policies-of-listener'
+ ' --load-balancer-name ' + ELB_NAME
+ ' --load-balancer-port 80'
+ ' --policy-names my-duration-cookie-policy')
print('####################################################################################\n')
print('\n')
################################################
# #
# WAIT FOR SERVICE TO BE READY #
# #
################################################
print('####################################################################################\n')
print('####################################################################################\n')
print('####################################################################################\n')
print('\n')
################################################
# #
# END OF SCRIPT #
# #
################################################
print('Waiting for the service to get up and running...')
execCommand('aws elb wait any-instance-in-service'
' --load-balancer-name ' + ELB_NAME)
print('The service is ready to use. Go to the browser and use the ELB DNS address: \n')
print(ELB_DNS+'\n')
print('The blockchain\'s DNS address is: \n')
print(BLOCKCHAIN_DNS + ':3000\n')
print('\n')
print('Execution time: ')
print(datetime.now() - startTime)