cfn_monitor 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/.travis.yml +18 -0
- data/Dockerfile +7 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +424 -0
- data/Rakefile +9 -0
- data/cfn_monitor.gemspec +39 -0
- data/exe/cfn_monitor +4 -0
- data/lib/cfn_monitor/deploy.rb +47 -0
- data/lib/cfn_monitor/generate.rb +186 -0
- data/lib/cfn_monitor/query.rb +135 -0
- data/lib/cfn_monitor/utils.rb +42 -0
- data/lib/cfn_monitor/version.rb +3 -0
- data/lib/cfn_monitor.rb +66 -0
- data/lib/config/config.yml +14 -0
- data/lib/config/templates.yml +428 -0
- data/lib/ext/alarms.rb +33 -0
- data/lib/lambda/getEnvironmentName.py +39 -0
- data/lib/lambda/getPhysicalId.py +67 -0
- data/lib/templates/alarms.rb +178 -0
- data/lib/templates/endpoints.rb +66 -0
- data/lib/templates/hosts.rb +126 -0
- data/lib/templates/master.rb +213 -0
- data/lib/templates/resources.rb +82 -0
- data/lib/templates/services.rb +138 -0
- metadata +250 -0
@@ -0,0 +1,428 @@
|
|
1
|
+
templates:
|
2
|
+
HttpCheck:
|
3
|
+
EndpointAvailable:
|
4
|
+
AlarmActions: crit
|
5
|
+
Namespace: HttpCheck
|
6
|
+
ComparisonOperator: LessThanThreshold
|
7
|
+
Dimensions: [ { Name: 'Endpoint', Value: { 'Fn::Sub': ['${endpoint}', {'env': { Ref: 'EnvironmentName' } } ] } } ]
|
8
|
+
Statistic: Maximum
|
9
|
+
Threshold: 1
|
10
|
+
Period: 60
|
11
|
+
EvaluationPeriods: 2
|
12
|
+
MetricName: Available
|
13
|
+
EndpointTimeTaken:
|
14
|
+
AlarmActions: crit
|
15
|
+
Namespace: HttpCheck
|
16
|
+
ComparisonOperator: GreaterThanThreshold
|
17
|
+
Dimensions: [ { Name: 'Endpoint', Value: { 'Fn::Sub': ['${endpoint}', {'env': { Ref: 'EnvironmentName' } } ] } } ]
|
18
|
+
Statistic: Minimum
|
19
|
+
Threshold: 1000
|
20
|
+
Period: 300
|
21
|
+
EvaluationPeriods: 1
|
22
|
+
MetricName: TimeTaken
|
23
|
+
EndpointStatusCodeMatch:
|
24
|
+
AlarmActions: crit
|
25
|
+
Namespace: HttpCheck
|
26
|
+
ComparisonOperator: LessThanThreshold
|
27
|
+
Dimensions: [ { Name: 'Endpoint', Value: { 'Fn::Sub': ['${endpoint}', {'env': { Ref: 'EnvironmentName' } } ] } } ]
|
28
|
+
Statistic: Maximum
|
29
|
+
Threshold: 1
|
30
|
+
Period: 60
|
31
|
+
EvaluationPeriods: 2
|
32
|
+
MetricName: StatusCodeMatch
|
33
|
+
HttpCheckBody:
|
34
|
+
EndpointResponseBodyRegexMatch:
|
35
|
+
AlarmActions: crit
|
36
|
+
Namespace: HttpCheck
|
37
|
+
ComparisonOperator: LessThanThreshold
|
38
|
+
Dimensions: [ { Name: 'Endpoint', Value: { 'Fn::Sub': ['${endpoint}', {'env': { Ref: 'EnvironmentName' } } ] } } ]
|
39
|
+
Statistic: Maximum
|
40
|
+
Threshold: 1
|
41
|
+
Period: 60
|
42
|
+
EvaluationPeriods: 2
|
43
|
+
MetricName: ResponseBodyRegexMatch
|
44
|
+
Services:
|
45
|
+
FailedService:
|
46
|
+
AlarmActions: warn
|
47
|
+
Namespace: ServiceChecks
|
48
|
+
ComparisonOperator: GreaterThanThreshold
|
49
|
+
Dimensions: [ { Name: 'Service', Value: '${resource}' }, { Name: 'Environment', Value: { Ref: 'EnvironmentName' } } ]
|
50
|
+
Statistic: Maximum
|
51
|
+
Threshold: 0
|
52
|
+
Period: 60
|
53
|
+
EvaluationPeriods: 2
|
54
|
+
MetricName: Failed_Service
|
55
|
+
AlarmDescription: { 'Fn::Join': [ ' ', [ Ref: 'MonitoredStack', { 'Fn::Sub': ['${resource}', {'env': { Ref: 'EnvironmentName' } } ] }, '${alarmName}' ] ] }
|
56
|
+
TreatMissingData: notBreaching
|
57
|
+
# FailedSSMAgent:
|
58
|
+
# AlarmActions: warn
|
59
|
+
# Namespace: ServiceChecks
|
60
|
+
# ComparisonOperator: GreaterThanThreshold
|
61
|
+
# Dimensions: [ { Name: 'Environment', Value: { Ref: 'EnvironmentName' } } ]
|
62
|
+
# Statistic: Maximum
|
63
|
+
# Threshold: 0
|
64
|
+
# Period: 60
|
65
|
+
# EvaluationPeriods: 2
|
66
|
+
# MetricName: Failed_SSM_Agent
|
67
|
+
# AlarmDescription: { 'Fn::Join': [ ' ', [ Ref: 'MonitoredStack', { 'Fn::Sub': ['${resource}', {'env': { Ref: 'EnvironmentName' } } ] }, '${alarmName}' ] ] }
|
68
|
+
# TreatMissingData: notBreaching
|
69
|
+
Nrpe:
|
70
|
+
Warn:
|
71
|
+
AlarmActions: warn
|
72
|
+
Namespace: NRPE
|
73
|
+
ComparisonOperator: GreaterThanThreshold
|
74
|
+
Dimensions: [ { Name: 'Host', Value: { 'Fn::Join': [ '-', [ { 'Fn::Sub': ['${env}', {'env': { Ref: 'EnvironmentName' } } ] }, '${resource}' ] ] } } ]
|
75
|
+
Statistic: Maximum
|
76
|
+
Threshold: 0
|
77
|
+
Period: 60
|
78
|
+
EvaluationPeriods: 2
|
79
|
+
MetricName: ${cmd}
|
80
|
+
TreatMissingData: breaching
|
81
|
+
AlarmDescription: { 'Fn::Join': [ ' ', [ Ref: 'MonitoredStack', { 'Fn::Sub': ['${resource}', {'env': { Ref: 'EnvironmentName' } } ] }, '${templateName}', '${cmd}', '${alarmName}' ] ] }
|
82
|
+
Crit:
|
83
|
+
AlarmActions: crit
|
84
|
+
Namespace: NRPE
|
85
|
+
ComparisonOperator: GreaterThanThreshold
|
86
|
+
Dimensions: [ { Name: 'Host', Value: { 'Fn::Join': [ '-', [ { 'Fn::Sub': ['${env}', {'env': { Ref: 'EnvironmentName' } } ] }, '${resource}' ] ] } } ]
|
87
|
+
Statistic: Maximum
|
88
|
+
Threshold: 1
|
89
|
+
Period: 60
|
90
|
+
EvaluationPeriods: 2
|
91
|
+
MetricName: ${cmd}
|
92
|
+
AlarmDescription: { 'Fn::Join': [ ' ', [ Ref: 'MonitoredStack', { 'Fn::Sub': ['${resource}', {'env': { Ref: 'EnvironmentName' } } ] }, '${templateName}', '${cmd}', '${alarmName}' ] ] }
|
93
|
+
LambdaMetrics: # Lambda Functions deployed with a Function Name
|
94
|
+
Errors:
|
95
|
+
AlarmActions: crit
|
96
|
+
Namespace: AWS/Lambda
|
97
|
+
ComparisonOperator: GreaterThanThreshold
|
98
|
+
Dimensions: [ { Name: 'FunctionName', Value: { 'Fn::Sub': ['${metric}', {'env': { Ref: 'EnvironmentName' } } ] } } ]
|
99
|
+
Statistic: Average
|
100
|
+
Threshold: 0.5
|
101
|
+
Period: 60
|
102
|
+
EvaluationPeriods: 5
|
103
|
+
MetricName: Errors
|
104
|
+
TreatMissingData: notBreaching
|
105
|
+
ElasticLoadBalancer: # AWS::ElasticLoadBalancing::LoadBalancer
|
106
|
+
HealthyHosts:
|
107
|
+
AlarmActions: crit
|
108
|
+
Namespace: AWS/ELB
|
109
|
+
MetricName: HealthyHostCount
|
110
|
+
ComparisonOperator: LessThanThreshold
|
111
|
+
DimensionsName: LoadBalancerName
|
112
|
+
Statistic: Minimum
|
113
|
+
Threshold: 2
|
114
|
+
Threshold.development: 1
|
115
|
+
EvaluationPeriods: 1
|
116
|
+
TreatMissingData: notBreaching
|
117
|
+
UnHealthyHosts:
|
118
|
+
AlarmActions: warn
|
119
|
+
Namespace: AWS/ELB
|
120
|
+
MetricName: UnHealthyHostCount
|
121
|
+
ComparisonOperator: GreaterThanThreshold
|
122
|
+
DimensionsName: LoadBalancerName
|
123
|
+
Statistic: Maximum
|
124
|
+
Threshold: 0
|
125
|
+
EvaluationPeriods: 10
|
126
|
+
TreatMissingData: notBreaching
|
127
|
+
ApplicationELBTargetGroup: # AWS::ElasticLoadBalancingV2::TargetGroup / AWS::ElasticLoadBalancingV2::LoadBalancer where type: application
|
128
|
+
HealthyHosts:
|
129
|
+
AlarmActions: crit
|
130
|
+
Namespace: AWS/ApplicationELB
|
131
|
+
MetricName: HealthyHostCount
|
132
|
+
ComparisonOperator: LessThanThreshold
|
133
|
+
DimensionsName: TargetGroup/LoadBalancer
|
134
|
+
Statistic: Minimum
|
135
|
+
Threshold: 2
|
136
|
+
Threshold.development: 1
|
137
|
+
EvaluationPeriods: 1
|
138
|
+
TreatMissingData: breaching
|
139
|
+
UnHealthyHosts:
|
140
|
+
AlarmActions: warn
|
141
|
+
Namespace: AWS/ApplicationELB
|
142
|
+
MetricName: UnHealthyHostCount
|
143
|
+
ComparisonOperator: GreaterThanThreshold
|
144
|
+
DimensionsName: TargetGroup/LoadBalancer
|
145
|
+
Statistic: Maximum
|
146
|
+
Threshold: 0
|
147
|
+
EvaluationPeriods: 10
|
148
|
+
TreatMissingData: notBreaching
|
149
|
+
TargetResponseTime:
|
150
|
+
AlarmActions: crit
|
151
|
+
Namespace: AWS/ApplicationELB
|
152
|
+
MetricName: TargetResponseTime
|
153
|
+
ComparisonOperator: GreaterThanThreshold
|
154
|
+
DimensionsName: TargetGroup/LoadBalancer
|
155
|
+
Statistic: Average
|
156
|
+
Threshold: 5
|
157
|
+
EvaluationPeriods: 5
|
158
|
+
TreatMissingData: notBreaching
|
159
|
+
NetworkELBTargetGroup: # AWS::ElasticLoadBalancingV2::TargetGroup / AWS::ElasticLoadBalancingV2::LoadBalancer where type: network
|
160
|
+
HealthyHosts:
|
161
|
+
AlarmActions: crit
|
162
|
+
Namespace: AWS/NetworkELB
|
163
|
+
MetricName: HealthyHostCount
|
164
|
+
ComparisonOperator: LessThanThreshold
|
165
|
+
DimensionsName: TargetGroup/LoadBalancer
|
166
|
+
Statistic: Minimum
|
167
|
+
Threshold: 2
|
168
|
+
Threshold.development: 1
|
169
|
+
EvaluationPeriods: 1
|
170
|
+
TreatMissingData: breaching
|
171
|
+
UnHealthyHosts:
|
172
|
+
AlarmActions: warn
|
173
|
+
Namespace: AWS/NetworkELB
|
174
|
+
MetricName: UnHealthyHostCount
|
175
|
+
ComparisonOperator: GreaterThanThreshold
|
176
|
+
DimensionsName: TargetGroup/LoadBalancer
|
177
|
+
Statistic: Maximum
|
178
|
+
Threshold: 0
|
179
|
+
EvaluationPeriods: 10
|
180
|
+
TreatMissingData: notBreaching
|
181
|
+
TargetResponseTime:
|
182
|
+
AlarmActions: crit
|
183
|
+
Namespace: AWS/NetworkELB
|
184
|
+
MetricName: TargetResponseTime
|
185
|
+
ComparisonOperator: GreaterThanThreshold
|
186
|
+
DimensionsName: TargetGroup/LoadBalancer
|
187
|
+
Statistic: Average
|
188
|
+
Threshold: 5
|
189
|
+
EvaluationPeriods: 5
|
190
|
+
TreatMissingData: notBreaching
|
191
|
+
AutoScalingGroup: # AWS::AutoScaling::AutoScalingGroup
|
192
|
+
CPUUtilizationHighBase:
|
193
|
+
AlarmActions: warn
|
194
|
+
Namespace: AWS/EC2
|
195
|
+
MetricName: CPUUtilization
|
196
|
+
ComparisonOperator: GreaterThanThreshold
|
197
|
+
DimensionsName: AutoScalingGroupName
|
198
|
+
Statistic: Minimum
|
199
|
+
Threshold: 75
|
200
|
+
EvaluationPeriods: 60
|
201
|
+
TreatMissingData: notBreaching
|
202
|
+
StatusCheckFailed:
|
203
|
+
AlarmActions: warn
|
204
|
+
Namespace: AWS/EC2
|
205
|
+
MetricName: StatusCheckFailed
|
206
|
+
ComparisonOperator: GreaterThanThreshold
|
207
|
+
DimensionsName: AutoScalingGroupName
|
208
|
+
Statistic: Maximum
|
209
|
+
Threshold: 0
|
210
|
+
EvaluationPeriods: 10
|
211
|
+
Ec2Instance: # AWS::EC2::Instance
|
212
|
+
CPUUtilizationHigh:
|
213
|
+
AlarmActions: crit
|
214
|
+
Namespace: AWS/EC2
|
215
|
+
MetricName: CPUUtilization
|
216
|
+
ComparisonOperator: GreaterThanThreshold
|
217
|
+
DimensionsName: InstanceId
|
218
|
+
Statistic: Minimum
|
219
|
+
Threshold: 90
|
220
|
+
EvaluationPeriods: 10
|
221
|
+
StatusCheckFailed:
|
222
|
+
AlarmActions: crit
|
223
|
+
Namespace: AWS/EC2
|
224
|
+
MetricName: StatusCheckFailed
|
225
|
+
ComparisonOperator: GreaterThanThreshold
|
226
|
+
DimensionsName: InstanceId
|
227
|
+
Statistic: Maximum
|
228
|
+
Threshold: 0
|
229
|
+
EvaluationPeriods: 10
|
230
|
+
RDSInstance: # AWS::RDS::DBInstance
|
231
|
+
FreeStorageSpaceCrit:
|
232
|
+
AlarmActions: crit
|
233
|
+
Namespace: AWS/RDS
|
234
|
+
MetricName: FreeStorageSpace
|
235
|
+
ComparisonOperator: LessThanThreshold
|
236
|
+
DimensionsName: DBInstanceIdentifier
|
237
|
+
Statistic: Minimum
|
238
|
+
Threshold: 50000000000
|
239
|
+
Threshold.development: 10000000000
|
240
|
+
EvaluationPeriods: 1
|
241
|
+
FreeStorageSpaceTask:
|
242
|
+
AlarmActions: task
|
243
|
+
Namespace: AWS/RDS
|
244
|
+
MetricName: FreeStorageSpace
|
245
|
+
ComparisonOperator: LessThanThreshold
|
246
|
+
DimensionsName: DBInstanceIdentifier
|
247
|
+
Statistic: Minimum
|
248
|
+
Threshold: 100000000000
|
249
|
+
Threshold.development: 20000000000
|
250
|
+
EvaluationPeriods: 1
|
251
|
+
CPUUtilizationHighSpike:
|
252
|
+
AlarmActions: crit
|
253
|
+
Namespace: AWS/RDS
|
254
|
+
MetricName: CPUUtilization
|
255
|
+
ComparisonOperator: GreaterThanThreshold
|
256
|
+
DimensionsName: DBInstanceIdentifier
|
257
|
+
Statistic: Minimum
|
258
|
+
Threshold: 95
|
259
|
+
EvaluationPeriods: 10
|
260
|
+
CPUUtilizationHighBase:
|
261
|
+
AlarmActions: warn
|
262
|
+
Namespace: AWS/RDS
|
263
|
+
MetricName: CPUUtilization
|
264
|
+
ComparisonOperator: GreaterThanThreshold
|
265
|
+
DimensionsName: DBInstanceIdentifier
|
266
|
+
Statistic: Minimum
|
267
|
+
Threshold: 75
|
268
|
+
EvaluationPeriods: 60
|
269
|
+
DBCluster: # AWS::RDS::DBCluster
|
270
|
+
CPUUtilizationHighSpike:
|
271
|
+
AlarmActions: crit
|
272
|
+
Namespace: AWS/RDS
|
273
|
+
MetricName: CPUUtilization
|
274
|
+
ComparisonOperator: GreaterThanThreshold
|
275
|
+
DimensionsName: DBClusterIdentifier
|
276
|
+
Statistic: Minimum
|
277
|
+
Threshold: 95
|
278
|
+
EvaluationPeriods: 10
|
279
|
+
CPUUtilizationHighBase:
|
280
|
+
AlarmActions: warn
|
281
|
+
Namespace: AWS/RDS
|
282
|
+
MetricName: CPUUtilization
|
283
|
+
ComparisonOperator: GreaterThanThreshold
|
284
|
+
DimensionsName: DBClusterIdentifier
|
285
|
+
Statistic: Minimum
|
286
|
+
Threshold: 75
|
287
|
+
EvaluationPeriods: 60
|
288
|
+
RedshiftCluster: # AWS::Redshift::Cluster
|
289
|
+
CPUUtilizationHighSpike:
|
290
|
+
AlarmActions: crit
|
291
|
+
Namespace: AWS/Redshift
|
292
|
+
MetricName: CPUUtilization
|
293
|
+
ComparisonOperator: GreaterThanThreshold
|
294
|
+
DimensionsName: ClusterIdentifier
|
295
|
+
Statistic: Minimum
|
296
|
+
Threshold: 95
|
297
|
+
EvaluationPeriods: 10
|
298
|
+
CPUUtilizationHighBase:
|
299
|
+
AlarmActions: warn
|
300
|
+
Namespace: AWS/Redshift
|
301
|
+
MetricName: CPUUtilization
|
302
|
+
ComparisonOperator: GreaterThanThreshold
|
303
|
+
DimensionsName: ClusterIdentifier
|
304
|
+
Statistic: Minimum
|
305
|
+
Threshold: 75
|
306
|
+
EvaluationPeriods: 60
|
307
|
+
UnHealthyCluster:
|
308
|
+
AlarmActions: crit
|
309
|
+
Namespace: AWS/Redshift
|
310
|
+
MetricName: HealthStatus
|
311
|
+
ComparisonOperator: GreaterThanThreshold
|
312
|
+
DimensionsName: ClusterIdentifier
|
313
|
+
Statistic: Maximum
|
314
|
+
Threshold: 0
|
315
|
+
EvaluationPeriods: 10
|
316
|
+
TreatMissingData: notBreaching
|
317
|
+
ECSCluster: # AWS::ECS::Cluster
|
318
|
+
MemoryUtilizationWarn:
|
319
|
+
AlarmActions: warn
|
320
|
+
Namespace: AWS/ECS
|
321
|
+
MetricName: MemoryUtilization
|
322
|
+
ComparisonOperator: GreaterThanThreshold
|
323
|
+
DimensionsName: ClusterName
|
324
|
+
Statistic: Maximum
|
325
|
+
Threshold: 75
|
326
|
+
EvaluationPeriods: 10
|
327
|
+
MemoryUtilizationCrit:
|
328
|
+
AlarmActions: crit
|
329
|
+
Namespace: AWS/ECS
|
330
|
+
MetricName: MemoryUtilization
|
331
|
+
ComparisonOperator: GreaterThanThreshold
|
332
|
+
DimensionsName: ClusterName
|
333
|
+
Statistic: Maximum
|
334
|
+
Threshold: 95
|
335
|
+
EvaluationPeriods: 10
|
336
|
+
CPUUtilizationHighBase:
|
337
|
+
AlarmActions: warn
|
338
|
+
Namespace: AWS/ECS
|
339
|
+
MetricName: CPUUtilization
|
340
|
+
ComparisonOperator: GreaterThanThreshold
|
341
|
+
DimensionsName: ClusterName
|
342
|
+
Statistic: Minimum
|
343
|
+
Threshold: 75
|
344
|
+
EvaluationPeriods: 10
|
345
|
+
ECSService: #AWS::ECS::Service
|
346
|
+
UnHealthyTask:
|
347
|
+
AlarmActions: crit
|
348
|
+
MetricName: MemoryUtilization
|
349
|
+
Namespace: AWS/ECS
|
350
|
+
Statistic: SampleCount
|
351
|
+
DimensionsName: ServiceName/ClusterName
|
352
|
+
Period: 60
|
353
|
+
EvaluationPeriods: 10
|
354
|
+
DatapointsToAlarm: 8
|
355
|
+
Threshold: 0.0
|
356
|
+
ComparisonOperator: LessThanOrEqualToThreshold
|
357
|
+
TreatMissingData: breaching
|
358
|
+
ECSTasks:
|
359
|
+
UnHealthyTaskWarn:
|
360
|
+
AlarmActions: warn
|
361
|
+
MetricName: MemoryUtilization
|
362
|
+
Namespace: AWS/ECS
|
363
|
+
Statistic: SampleCount
|
364
|
+
DimensionsName: ServiceName/ClusterName
|
365
|
+
Period: 60
|
366
|
+
EvaluationPeriods: 10
|
367
|
+
DatapointsToAlarm: 10
|
368
|
+
Threshold: 1.0
|
369
|
+
ComparisonOperator: LessThanOrEqualToThreshold
|
370
|
+
TreatMissingData: breaching
|
371
|
+
ElastiCacheReplicationGroup: # AWS::ElastiCache::ReplicationGroup
|
372
|
+
FreeableMemoryWarn:
|
373
|
+
AlarmActions: warn
|
374
|
+
Namespace: AWS/ElastiCache
|
375
|
+
MetricName: FreeableMemory
|
376
|
+
ComparisonOperator: LessThanThreshold
|
377
|
+
DimensionsName: CacheClusterId
|
378
|
+
Statistic: Maximum
|
379
|
+
Threshold: 100000000
|
380
|
+
EvaluationPeriods: 10
|
381
|
+
CPUUtilizationHighBase:
|
382
|
+
AlarmActions: warn
|
383
|
+
Namespace: AWS/ElastiCache
|
384
|
+
MetricName: CPUUtilization
|
385
|
+
ComparisonOperator: GreaterThanThreshold
|
386
|
+
DimensionsName: CacheClusterId
|
387
|
+
Statistic: Minimum
|
388
|
+
Threshold: 75
|
389
|
+
EvaluationPeriods: 10
|
390
|
+
ElasticFileSystem: # AWS::EFS::FileSystem
|
391
|
+
PercentIOLimitHigh:
|
392
|
+
AlarmActions: crit
|
393
|
+
Namespace: AWS/EFS
|
394
|
+
MetricName: PercentIOLimit
|
395
|
+
ComparisonOperator: GreaterThanThreshold
|
396
|
+
DimensionsName: FileSystemId
|
397
|
+
Statistic: Minimum
|
398
|
+
Threshold: 90
|
399
|
+
EvaluationPeriods: 5
|
400
|
+
ApiGateway: #AWS:ApiGateway
|
401
|
+
ApiEndpoint5xx:
|
402
|
+
AlarmActions: crit
|
403
|
+
Namespace: AWS/ApiGateway
|
404
|
+
MetricName: 5XXError
|
405
|
+
ComparisonOperator: GreaterThanThreshold
|
406
|
+
DimensionsName: ApiName
|
407
|
+
Statistic: Sum
|
408
|
+
Threshold: 5
|
409
|
+
EvaluationPdyneriods: 2
|
410
|
+
DynamoDBTable: #AWS::DynamoDB::Table
|
411
|
+
DynamoDBReadUsage:
|
412
|
+
AlarmActions: warn
|
413
|
+
Namespace: AWS/DynamoDB
|
414
|
+
MetricName: ConsumedReadCapacityUnits
|
415
|
+
ComparisonOperator: GreaterThanThreshold
|
416
|
+
DimensionsName: TableName
|
417
|
+
Statistic: Sum
|
418
|
+
Threshold: 80
|
419
|
+
EvaluationPeriods: 2
|
420
|
+
DynamoDBWriteUsage:
|
421
|
+
AlarmActions: warn
|
422
|
+
Namespace: AWS/DynamoDB
|
423
|
+
MetricName: ConsumedWriteCapacityUnits
|
424
|
+
ComparisonOperator: GreaterThanThreshold
|
425
|
+
DimensionsName: TableName
|
426
|
+
Statistic: Sum
|
427
|
+
Threshold: 80
|
428
|
+
EvaluationPeriods: 2
|
data/lib/ext/alarms.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
def replace_vars(hash,find,replace)
|
2
|
+
if hash.is_a?(Hash)
|
3
|
+
hash.each do |k, v|
|
4
|
+
replace_vars(v,find,replace)
|
5
|
+
end
|
6
|
+
elsif hash.is_a?(Array)
|
7
|
+
hash.each do |e|
|
8
|
+
replace_vars(e,find,replace)
|
9
|
+
end
|
10
|
+
elsif hash.is_a?(String) && hash == find
|
11
|
+
hash.replace replace
|
12
|
+
end
|
13
|
+
hash
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_param_mappings(params,template_envs,alarmHash)
|
17
|
+
mappings = {}
|
18
|
+
params.each do |key,value|
|
19
|
+
if !key.include? '.'
|
20
|
+
if [String, Integer, Float, Fixnum, TrueClass].member?(value.class)
|
21
|
+
mappings[key] = {}
|
22
|
+
template_envs.each do |env|
|
23
|
+
if !params["#{key}.#{env}"].nil? && [String, Integer, Float, Fixnum, TrueClass].member?(params["#{key}.#{env}"].class)
|
24
|
+
mappings[key][env] = params["#{key}.#{env}"]
|
25
|
+
else
|
26
|
+
mappings[key][env] = value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
Mapping("#{alarmHash}", mappings)
|
33
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import json
|
2
|
+
import cfnresponse
|
3
|
+
import boto3
|
4
|
+
from botocore.exceptions import ClientError
|
5
|
+
import time
|
6
|
+
|
7
|
+
def getEnvironmentName(client,stackName):
|
8
|
+
time.sleep(5)
|
9
|
+
max_retries = 5
|
10
|
+
sleep_time = 1
|
11
|
+
for i in range(max_retries):
|
12
|
+
try:
|
13
|
+
response = client.describe_stacks(StackName=stackName)
|
14
|
+
except ClientError as e:
|
15
|
+
print e
|
16
|
+
time.sleep(sleep_time)
|
17
|
+
sleep_time += sleep_time
|
18
|
+
continue
|
19
|
+
else:
|
20
|
+
break
|
21
|
+
else:
|
22
|
+
return stackName
|
23
|
+
if 'Parameters' in response['Stacks'][0]:
|
24
|
+
for r in response['Stacks'][0]['Parameters']:
|
25
|
+
if r['ParameterKey'] == 'EnvironmentName':
|
26
|
+
return r['ParameterValue']
|
27
|
+
return stackName
|
28
|
+
else:
|
29
|
+
return stackName
|
30
|
+
|
31
|
+
|
32
|
+
def handler(event, context):
|
33
|
+
stackName = event['ResourceProperties']['StackName']
|
34
|
+
region = event['ResourceProperties']['Region']
|
35
|
+
client = boto3.client('cloudformation',region_name=region)
|
36
|
+
|
37
|
+
responseData = {}
|
38
|
+
responseData['EnvironmentName'] = getEnvironmentName(client,stackName)
|
39
|
+
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import json
|
2
|
+
import cfnresponse
|
3
|
+
import boto3
|
4
|
+
from botocore.exceptions import ClientError
|
5
|
+
import time
|
6
|
+
|
7
|
+
def findNestedStack(client,resource):
|
8
|
+
if len(resource) == 2:
|
9
|
+
return resource
|
10
|
+
else:
|
11
|
+
max_retries = 20
|
12
|
+
sleep_time = 1
|
13
|
+
for i in range(max_retries):
|
14
|
+
try:
|
15
|
+
response = client.list_stack_resources(StackName=resource[0])
|
16
|
+
except ClientError as e:
|
17
|
+
print e
|
18
|
+
time.sleep(sleep_time)
|
19
|
+
sleep_time += 1
|
20
|
+
continue
|
21
|
+
else:
|
22
|
+
break
|
23
|
+
else:
|
24
|
+
return
|
25
|
+
for r in response['StackResourceSummaries']:
|
26
|
+
if r['ResourceType'] == 'AWS::CloudFormation::Stack':
|
27
|
+
if r['LogicalResourceId'] == resource[1]:
|
28
|
+
resource[1] = r['PhysicalResourceId']
|
29
|
+
del resource[0]
|
30
|
+
return findNestedStack(client,resource)
|
31
|
+
|
32
|
+
def findResource(client,resource):
|
33
|
+
time.sleep(5)
|
34
|
+
if resource:
|
35
|
+
max_retries = 20
|
36
|
+
sleep_time = 1
|
37
|
+
for i in range(max_retries):
|
38
|
+
try:
|
39
|
+
paginator = client.get_paginator('list_stack_resources')
|
40
|
+
page_iterator = paginator.paginate(StackName=resource[0])
|
41
|
+
response = []
|
42
|
+
for page in page_iterator:
|
43
|
+
response = response + page['StackResourceSummaries']
|
44
|
+
except ClientError as e:
|
45
|
+
print e
|
46
|
+
time.sleep(sleep_time)
|
47
|
+
sleep_time += 1
|
48
|
+
continue
|
49
|
+
else:
|
50
|
+
break
|
51
|
+
else:
|
52
|
+
return
|
53
|
+
for r in response:
|
54
|
+
if r['LogicalResourceId'] == resource[1]:
|
55
|
+
return r['PhysicalResourceId']
|
56
|
+
else:
|
57
|
+
return
|
58
|
+
|
59
|
+
def handler(event, context):
|
60
|
+
resource = event['ResourceProperties']['LogicalResourceId'].split(".")
|
61
|
+
region = event['ResourceProperties']['Region']
|
62
|
+
client = boto3.client('cloudformation',region_name=region)
|
63
|
+
|
64
|
+
responseData = {}
|
65
|
+
responseData['PhysicalResourceId'] = findResource(client,findNestedStack(client,resource))
|
66
|
+
cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
|
67
|
+
|