-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcloudformation.yml
334 lines (313 loc) · 8.3 KB
/
cloudformation.yml
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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
---
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 'iot stack, includes RDS for iot data and 1 lambda to import data from enphase'
Parameters:
enphaseUserId:
Type: String
enphaseKey:
Type: String
enphaseSystemId:
Type: String
timezone:
Type: String
sleepBetweenRequests:
Type: String
startDate:
Type: String
endDate:
Type: String
dbUser:
Type: String
dbPassword:
Type: String
dbPort:
Type: String
dbName:
Type: String
Resources:
vpc:
Type: "AWS::EC2::VPC"
Properties:
CidrBlock: 172.32.0.0/16
EnableDnsSupport: true
EnableDnsHostnames: true
InstanceTenancy: default
Tags:
- Key: Name
Value: iot-vpc
# Subnetting and routing
privateSubnet1:
Type: "AWS::EC2::Subnet"
Properties:
CidrBlock: 172.32.96.0/20
VpcId: !Ref vpc
AvailabilityZone: ap-southeast-2c
Tags:
- Key: Name
Value: private-subnet-1
privateSubnet2:
Type: "AWS::EC2::Subnet"
Properties:
CidrBlock: 172.32.128.0/20
VpcId: !Ref vpc
AvailabilityZone: ap-southeast-2a
Tags:
- Key: Name
Value: private-subnet-2
publicSubnet1:
Type: "AWS::EC2::Subnet"
Properties:
CidrBlock: 172.32.144.0/20
VpcId: !Ref vpc
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: public-subnet-1
routeTablePublic:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref vpc
Tags:
- Key: Name
Value: route-table-public
routeTablePrivate:
Type: "AWS::EC2::RouteTable"
Properties:
VpcId: !Ref vpc
Tags:
- Key: Name
Value: route-table-private
allowAllRoutePrivate:
Type: AWS::EC2::Route
DependsOn:
- natGateway
Properties:
RouteTableId: !Ref routeTablePrivate
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref natGateway
allowAllRoutePublic:
Type: AWS::EC2::Route
DependsOn:
- internetGateway
Properties:
RouteTableId: !Ref routeTablePublic
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref internetGateway
routeTablePrivateSubnet1:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref routeTablePrivate
SubnetId: !Ref privateSubnet1
routeTablePrivateSubnet2:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref routeTablePrivate
SubnetId: !Ref privateSubnet2
routeTablePublicSubnet1:
Type: "AWS::EC2::SubnetRouteTableAssociation"
Properties:
RouteTableId: !Ref routeTablePublic
SubnetId: !Ref publicSubnet1
# Gateways
publicEip:
Type: "AWS::EC2::EIP"
Properties:
Domain: vpc
internetGateway:
Type: "AWS::EC2::InternetGateway"
Properties:
Tags:
- Key: Name
Value: internet gateway
natGateway:
Type: "AWS::EC2::NatGateway"
Properties:
AllocationId: !GetAtt publicEip.AllocationId
SubnetId: !Ref publicSubnet1
attachGateway:
Type: "AWS::EC2::VPCGatewayAttachment"
Properties:
VpcId: !Ref vpc
InternetGatewayId: !Ref internetGateway
securityGroupRds:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupName: rds-iotdb
GroupDescription: RDS security group iotdb
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '3306'
ToPort: '3306'
CidrIp: 172.32.96.0/20
- IpProtocol: tcp
FromPort: '3306'
ToPort: '3306'
CidrIp: 172.32.128.0/20
Tags:
- Key: Name
Value: sg-rds-iotdb
VpcId: !Ref vpc
securityGroupBastion:
Type: "AWS::EC2::SecurityGroup"
DependsOn:
- securityGroupRds
Properties:
GroupName: bastion
GroupDescription: Bastion security group
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: '3306'
ToPort: '3306'
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: '22'
ToPort: '22'
DestinationSecurityGroupId: !Ref securityGroupRds
- IpProtocol: tcp
FromPort: '3306'
ToPort: '3306'
DestinationSecurityGroupId: !Ref securityGroupRds
Tags:
- Key: Name
Value: sg-bastion
VpcId: !Ref vpc
securityGroupIngressRdsFromBastion:
Type: "AWS::EC2::SecurityGroupIngress"
DependsOn:
- securityGroupRds
- securityGroupBastion
Properties:
IpProtocol: tcp
FromPort: '3306'
ToPort: '3306'
Description: RDS inbound from bastion
GroupId: !Ref securityGroupRds
SourceSecurityGroupId: !Ref securityGroupBastion
bastionInstance:
Type: "AWS::EC2::Instance"
DependsOn:
- securityGroupBastion
- publicSubnet1
- routeTablePublic
Properties:
InstanceType: t2.micro
ImageId: ami-ff4ea59d
KeyName: bastion-keypair
NetworkInterfaces:
- AssociatePublicIpAddress: true
DeleteOnTermination: true
Description: Public IP
DeviceIndex: 0
GroupSet:
- !Ref securityGroupBastion
SubnetId: !Ref publicSubnet1
SourceDestCheck: true
Tags:
- Key: Name
Value: bastion-host
Tenancy: default
dbSubnetGroup:
Type: "AWS::RDS::DBSubnetGroup"
DependsOn:
- privateSubnet1
- privateSubnet2
Properties:
DBSubnetGroupDescription: private subnets for rds
SubnetIds:
- !Ref privateSubnet1
- !Ref privateSubnet2
Tags:
- Key: Name
Value: private-subnet
FunctionIAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaENIManagementAccess
- arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess
- arn:aws:iam::aws:policy/AmazonRDSFullAccess
- arn:aws:iam::aws:policy/AWSLambdaFullAccess
Policies:
- PolicyName: 'custom-policy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- rds:*
Resource:
- arn:aws:rds:::*
- Effect: Allow
Action:
- s3:*
Resource:
- arn:aws:s3:::iotdb-bucket
mysql:
Type: "AWS::RDS::DBInstance"
Properties:
DBName: !Ref dbName
DBInstanceClass: db.t2.micro
DBInstanceIdentifier: !Ref dbName
Engine: "MySQL"
EngineVersion: "5.7.19"
AllocatedStorage: 20
StorageType: gp2
MasterUsername: !Ref dbUser
MasterUserPassword: !Ref dbPassword
DBSubnetGroupName: !Ref dbSubnetGroup
VPCSecurityGroups:
- !Ref securityGroupRds
Tags:
- Key: "Name"
Value: !Ref dbName
Function:
Type: AWS::Serverless::Function
DependsOn:
- FunctionIAMRole
Properties:
Handler: stats_to_db.lambda_handler
Runtime: python3.6
CodeUri: ./node-importer.zip
MemorySize: 128
Timeout: 30
Role: !GetAtt FunctionIAMRole.Arn
FunctionName: enphase-stats-to-db
VpcConfig:
SecurityGroupIds:
- !Ref securityGroupRds
SubnetIds:
- !Ref privateSubnet1
- !Ref privateSubnet2
Environment:
Variables:
ENHPASE_USER_ID: !Ref enphaseUserId
ENPHASE_KEY: !Ref enphaseKey
ENPHASE_SYSTEM_ID: !Ref enphaseSystemId
TIME_ZONE: !Ref timezone
SLEEP_BETWEEN_REQUESTS: !Ref sleepBetweenRequests
START_DATE: !Ref startDate
END_DATE: !Ref endDate
DB_HOST: !GetAtt mysql.Endpoint.Address
DB_USER: !Ref dbUser
DB_PASSWORD: !Ref dbPassword
DB_PORT: !Ref dbPort
DB_NAME: !Ref dbName
Events:
ScheduleEvent:
Type: Schedule
Properties:
Schedule: rate(1 hour)