cfn-guardian 0.1.0 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.dockerignore +1 -0
- data/.github/workflows/build-gem.yml +25 -0
- data/.github/workflows/release-gem.yml +25 -0
- data/.github/workflows/release-image.yml +33 -0
- data/.rspec +1 -0
- data/Dockerfile +19 -0
- data/Gemfile.lock +39 -21
- data/README.md +9 -378
- data/cfn-guardian.gemspec +7 -5
- data/docs/alarm_templates.md +130 -0
- data/docs/cli.md +182 -0
- data/docs/composite_alarms.md +24 -0
- data/docs/custom_checks/azure_file_check.md +28 -0
- data/docs/custom_checks/domain_expiry.md +10 -0
- data/docs/custom_checks/http.md +59 -0
- data/docs/custom_checks/log_group_metric_filters.md +27 -0
- data/docs/custom_checks/nrpe.md +29 -0
- data/docs/custom_checks/port.md +40 -0
- data/docs/custom_checks/sftp.md +73 -0
- data/docs/custom_checks/sql.md +44 -0
- data/docs/custom_checks/tls.md +25 -0
- data/docs/custom_metrics.md +71 -0
- data/docs/event_subscriptions.md +67 -0
- data/docs/maintenance_mode.md +85 -0
- data/docs/notifiers.md +33 -0
- data/docs/overview.md +22 -0
- data/docs/resources.md +93 -0
- data/docs/variables.md +58 -0
- data/lib/cfnguardian.rb +325 -37
- data/lib/cfnguardian/cloudwatch.rb +132 -0
- data/lib/cfnguardian/codecommit.rb +54 -0
- data/lib/cfnguardian/codepipeline.rb +138 -0
- data/lib/cfnguardian/compile.rb +142 -18
- data/lib/cfnguardian/config/defaults.yaml +103 -0
- data/lib/cfnguardian/deploy.rb +2 -16
- data/lib/cfnguardian/display_formatter.rb +163 -0
- data/lib/cfnguardian/drift.rb +79 -0
- data/lib/cfnguardian/error.rb +4 -0
- data/lib/cfnguardian/log.rb +0 -1
- data/lib/cfnguardian/models/alarm.rb +193 -59
- data/lib/cfnguardian/models/check.rb +128 -33
- data/lib/cfnguardian/models/composite.rb +21 -0
- data/lib/cfnguardian/models/event.rb +201 -49
- data/lib/cfnguardian/models/event_subscription.rb +96 -0
- data/lib/cfnguardian/models/metric_filter.rb +28 -0
- data/lib/cfnguardian/resources/amazonmq_rabbitmq.rb +136 -0
- data/lib/cfnguardian/resources/application_targetgroup.rb +2 -0
- data/lib/cfnguardian/resources/azure_file.rb +20 -0
- data/lib/cfnguardian/resources/base.rb +155 -33
- data/lib/cfnguardian/resources/ec2_instance.rb +11 -0
- data/lib/cfnguardian/resources/ecs_service.rb +2 -2
- data/lib/cfnguardian/resources/http.rb +17 -1
- data/lib/cfnguardian/resources/internal_http.rb +74 -0
- data/lib/cfnguardian/resources/internal_port.rb +33 -0
- data/lib/cfnguardian/resources/internal_sftp.rb +58 -0
- data/lib/cfnguardian/resources/log_group.rb +26 -0
- data/lib/cfnguardian/resources/network_targetgroup.rb +1 -0
- data/lib/cfnguardian/resources/port.rb +25 -0
- data/lib/cfnguardian/resources/rds_cluster.rb +14 -0
- data/lib/cfnguardian/resources/rds_instance.rb +73 -0
- data/lib/cfnguardian/resources/redshift_cluster.rb +2 -2
- data/lib/cfnguardian/resources/sftp.rb +50 -0
- data/lib/cfnguardian/resources/sql.rb +3 -3
- data/lib/cfnguardian/resources/tls.rb +66 -0
- data/lib/cfnguardian/s3.rb +3 -2
- data/lib/cfnguardian/stacks/main.rb +94 -72
- data/lib/cfnguardian/stacks/resources.rb +111 -43
- data/lib/cfnguardian/string.rb +12 -0
- data/lib/cfnguardian/version.rb +1 -1
- metadata +133 -10
@@ -4,8 +4,8 @@ require 'cfnguardian/string'
|
|
4
4
|
module CfnGuardian::Resource
|
5
5
|
class Sql < Base
|
6
6
|
|
7
|
-
def initialize(resource)
|
8
|
-
super(resource)
|
7
|
+
def initialize(resource, override_group = nil)
|
8
|
+
super(resource, override_group)
|
9
9
|
@resource_list = resource['Hosts']
|
10
10
|
@environment = resource['Environment']
|
11
11
|
end
|
@@ -24,7 +24,7 @@ module CfnGuardian::Resource
|
|
24
24
|
def default_events()
|
25
25
|
@resource_list.each do |host|
|
26
26
|
host['Queries'].each do |query|
|
27
|
-
@events.push(CfnGuardian::Models::SqlEvent.new(host,query['Query']))
|
27
|
+
@events.push(CfnGuardian::Models::SqlEvent.new(host,query['Query'],@environment))
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module CfnGuardian::Resource
|
2
|
+
class TLS < Base
|
3
|
+
|
4
|
+
def default_alarms
|
5
|
+
|
6
|
+
versions = @resource.fetch('Versions',['SSLv2','SSLv3','TLSv1','TLSv1.1','TLSv1.2'])
|
7
|
+
|
8
|
+
if versions.include? "SSLv2"
|
9
|
+
alarm = CfnGuardian::Models::TLSAlarm.new(@resource)
|
10
|
+
alarm.name = "TLSVersionSSLv2"
|
11
|
+
alarm.metric_name = "SSLv2"
|
12
|
+
alarm.comparison_operator = 'GreaterThanThreshold'
|
13
|
+
alarm.threshold = 0
|
14
|
+
@alarms.push(alarm)
|
15
|
+
end
|
16
|
+
|
17
|
+
if versions.include? "SSLv3"
|
18
|
+
alarm = CfnGuardian::Models::TLSAlarm.new(@resource)
|
19
|
+
alarm.name = "TLSVersionSSLv3"
|
20
|
+
alarm.metric_name = "SSLv3"
|
21
|
+
alarm.comparison_operator = 'GreaterThanThreshold'
|
22
|
+
alarm.threshold = 0
|
23
|
+
@alarms.push(alarm)
|
24
|
+
end
|
25
|
+
|
26
|
+
if versions.include? "SSLv3"
|
27
|
+
alarm = CfnGuardian::Models::TLSAlarm.new(@resource)
|
28
|
+
alarm.name = "TLSVersionTLSv1"
|
29
|
+
alarm.metric_name = "TLSv1"
|
30
|
+
@alarms.push(alarm)
|
31
|
+
end
|
32
|
+
|
33
|
+
if versions.include? "SSLv3"
|
34
|
+
alarm = CfnGuardian::Models::TLSAlarm.new(@resource)
|
35
|
+
alarm.name = "TLSVersionTLSv1.1"
|
36
|
+
alarm.metric_name = "TLSv1.1"
|
37
|
+
@alarms.push(alarm)
|
38
|
+
end
|
39
|
+
|
40
|
+
if versions.include? "SSLv3"
|
41
|
+
alarm = CfnGuardian::Models::TLSAlarm.new(@resource)
|
42
|
+
alarm.name = "TLSVersionTLSv1.2"
|
43
|
+
alarm.metric_name = "TLSv1.2"
|
44
|
+
@alarms.push(alarm)
|
45
|
+
end
|
46
|
+
|
47
|
+
if @resource.has_key?('CheckMax')
|
48
|
+
alarm = CfnGuardian::Models::TLSAlarm.new(@resource)
|
49
|
+
alarm.name = "TLSVersionMax"
|
50
|
+
alarm.metric_name = 'MaxVersion'
|
51
|
+
alarm.threshold = 3
|
52
|
+
alarm.evaluation_periods = 2
|
53
|
+
@alarms.push(alarm)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def default_events
|
58
|
+
@events.push(CfnGuardian::Models::TLSEvent.new(@resource))
|
59
|
+
end
|
60
|
+
|
61
|
+
def default_checks
|
62
|
+
@checks.push(CfnGuardian::Models::TLSCheck.new(@resource))
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
data/lib/cfnguardian/s3.rb
CHANGED
@@ -4,10 +4,11 @@ module CfnGuardian
|
|
4
4
|
class S3
|
5
5
|
include Logging
|
6
6
|
|
7
|
-
attr_reader :bucket
|
7
|
+
attr_reader :bucket, :path
|
8
8
|
|
9
|
-
def initialize(bucket)
|
9
|
+
def initialize(bucket,path='')
|
10
10
|
@bucket = set_bucket_name(bucket)
|
11
|
+
@path = path
|
11
12
|
end
|
12
13
|
|
13
14
|
def set_bucket_name(bucket)
|
@@ -5,31 +5,87 @@ module CfnGuardian
|
|
5
5
|
class Main
|
6
6
|
include CfnDsl::CloudFormation
|
7
7
|
|
8
|
-
|
8
|
+
attr_reader :parameters, :template
|
9
|
+
|
10
|
+
def initialize()
|
11
|
+
@parameters = []
|
9
12
|
@template = CloudFormation("Guardian main stack")
|
10
|
-
|
11
|
-
|
13
|
+
end
|
14
|
+
|
15
|
+
def build_template(stacks,checks,topics,maintenance_groups,ssm_parameters)
|
16
|
+
parameters = {}
|
17
|
+
|
18
|
+
topics.each do |name, sns|
|
12
19
|
parameter = @template.Parameter(name)
|
13
20
|
parameter.Type 'String'
|
14
21
|
parameter.Description "SNS topic ARN for #{name} notifications"
|
22
|
+
parameter.Default sns
|
23
|
+
parameters[name] = Ref(name)
|
15
24
|
end
|
16
25
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
build_iam_role()
|
26
|
+
maintenance_groups.each do |group|
|
27
|
+
topic = @template.SNS_Topic(group)
|
28
|
+
topic.TopicName group
|
29
|
+
topic.Tags([{ Key: 'Environment', Value: 'guardian' }])
|
30
|
+
parameters[group] = Ref(group)
|
31
|
+
end
|
25
32
|
|
26
|
-
|
27
|
-
|
33
|
+
add_iam_role(ssm_parameters)
|
34
|
+
|
35
|
+
checks.each {|check| parameters["#{check.name}Function#{check.environment}"] = add_lambda(check)}
|
36
|
+
stacks.each {|stack| add_stack(stack['Name'],stack['TemplateURL'],parameters,stack['Reference'])}
|
28
37
|
|
29
|
-
|
38
|
+
@parameters = parameters.keys
|
30
39
|
end
|
31
40
|
|
32
|
-
def
|
41
|
+
def add_iam_role(ssm_parameters)
|
42
|
+
policies = []
|
43
|
+
policies << {
|
44
|
+
PolicyName: 'logging',
|
45
|
+
PolicyDocument: {
|
46
|
+
Version: '2012-10-17',
|
47
|
+
Statement: [{
|
48
|
+
Effect: 'Allow',
|
49
|
+
Action: [ 'logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents' ],
|
50
|
+
Resource: 'arn:aws:logs:*:*:*'
|
51
|
+
}]
|
52
|
+
}
|
53
|
+
}
|
54
|
+
policies << {
|
55
|
+
PolicyName: 'metrics',
|
56
|
+
PolicyDocument: {
|
57
|
+
Version: '2012-10-17',
|
58
|
+
Statement: [{
|
59
|
+
Effect: 'Allow',
|
60
|
+
Action: [ 'cloudwatch:PutMetricData' ],
|
61
|
+
Resource: '*'
|
62
|
+
}]
|
63
|
+
}
|
64
|
+
}
|
65
|
+
policies << {
|
66
|
+
PolicyName: 'attach-network-interface',
|
67
|
+
PolicyDocument: {
|
68
|
+
Version: '2012-10-17',
|
69
|
+
Statement: [{
|
70
|
+
Effect: 'Allow',
|
71
|
+
Action: [ 'ec2:CreateNetworkInterface', 'ec2:DescribeNetworkInterfaces', 'ec2:DeleteNetworkInterface' ],
|
72
|
+
Resource: '*'
|
73
|
+
}]
|
74
|
+
}
|
75
|
+
}
|
76
|
+
if ssm_parameters.any?
|
77
|
+
policies << {
|
78
|
+
PolicyName: 'ssm-parameters',
|
79
|
+
PolicyDocument: {
|
80
|
+
Version: '2012-10-17',
|
81
|
+
Statement: [{
|
82
|
+
Effect: 'Allow',
|
83
|
+
Action: [ 'ssm:GetParameter', 'ssm:GetParametersByPath', 'ssm:GetParameters' ],
|
84
|
+
Resource: ssm_parameters.map {|param| FnSub("arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter#{param}") }
|
85
|
+
}]
|
86
|
+
}
|
87
|
+
}
|
88
|
+
end
|
33
89
|
@template.declare do
|
34
90
|
IAM_Role(:LambdaExecutionRole) do
|
35
91
|
AssumeRolePolicyDocument({
|
@@ -40,42 +96,8 @@ module CfnGuardian
|
|
40
96
|
Action: [ 'sts:AssumeRole' ]
|
41
97
|
}]
|
42
98
|
})
|
43
|
-
Path '/'
|
44
|
-
Policies(
|
45
|
-
{
|
46
|
-
PolicyName: 'logging',
|
47
|
-
PolicyDocument: {
|
48
|
-
Version: '2012-10-17',
|
49
|
-
Statement: [{
|
50
|
-
Effect: 'Allow',
|
51
|
-
Action: [ 'logs:CreateLogGroup', 'logs:CreateLogStream', 'logs:PutLogEvents' ],
|
52
|
-
Resource: 'arn:aws:logs:*:*:*'
|
53
|
-
}]
|
54
|
-
}
|
55
|
-
},
|
56
|
-
{
|
57
|
-
PolicyName: 'metrics',
|
58
|
-
PolicyDocument: {
|
59
|
-
Version: '2012-10-17',
|
60
|
-
Statement: [{
|
61
|
-
Effect: 'Allow',
|
62
|
-
Action: [ 'cloudwatch:PutMetricData' ],
|
63
|
-
Resource: '*'
|
64
|
-
}]
|
65
|
-
}
|
66
|
-
},
|
67
|
-
{
|
68
|
-
PolicyName: 'attach-network-interface',
|
69
|
-
PolicyDocument: {
|
70
|
-
Version: '2012-10-17',
|
71
|
-
Statement: [{
|
72
|
-
Effect: 'Allow',
|
73
|
-
Action: [ 'ec2:CreateNetworkInterface', 'ec2:DescribeNetworkInterfaces', 'ec2:DeleteNetworkInterface' ],
|
74
|
-
Resource: '*'
|
75
|
-
}]
|
76
|
-
}
|
77
|
-
}
|
78
|
-
])
|
99
|
+
Path '/guardian/'
|
100
|
+
Policies(policies)
|
79
101
|
Tags([
|
80
102
|
{ Key: 'Name', Value: 'guardian-lambda-role' },
|
81
103
|
{ Key: 'Environment', Value: 'guardian' }
|
@@ -86,59 +108,59 @@ module CfnGuardian
|
|
86
108
|
|
87
109
|
def add_lambda(check)
|
88
110
|
vpc_config = {}
|
89
|
-
|
90
|
-
if check.has_key?(:vpc)
|
111
|
+
if !check.vpc.nil?
|
91
112
|
@template.declare do
|
92
|
-
EC2_SecurityGroup("#{check
|
93
|
-
VpcId check
|
94
|
-
GroupDescription "Guardian lambda function #{check
|
113
|
+
EC2_SecurityGroup("#{check.name}SecurityGroup#{check.environment}") do
|
114
|
+
VpcId check.vpc
|
115
|
+
GroupDescription "Guardian lambda function #{check.group} check"
|
95
116
|
Tags([
|
96
|
-
{ Key: 'Name', Value: "guardian-#{check
|
117
|
+
{ Key: 'Name', Value: "guardian-#{check.name}-#{check.environment}" },
|
97
118
|
{ Key: 'Environment', Value: 'guardian' }
|
98
119
|
])
|
99
120
|
end
|
100
121
|
end
|
101
122
|
|
102
|
-
vpc_config[:SecurityGroupIds] = Ref("#{check
|
103
|
-
vpc_config[:SubnetIds] = check
|
123
|
+
vpc_config[:SecurityGroupIds] = [Ref("#{check.name}SecurityGroup#{check.environment}")]
|
124
|
+
vpc_config[:SubnetIds] = check.subnets
|
104
125
|
end
|
105
126
|
|
106
127
|
@template.declare do
|
107
|
-
Lambda_Function("#{check
|
128
|
+
Lambda_Function("#{check.name}Function#{check.environment}") do
|
108
129
|
Code({
|
109
|
-
S3Bucket: FnSub("base2.lambda.${AWS::Region}"),
|
110
|
-
S3Key: "#{check
|
130
|
+
S3Bucket: FnSub("base2.guardian.lambda.checks.${AWS::Region}"),
|
131
|
+
S3Key: "#{check.package}/master/#{check.version}.zip"
|
111
132
|
})
|
112
|
-
Handler check
|
113
|
-
MemorySize
|
114
|
-
Runtime check
|
115
|
-
Timeout
|
133
|
+
Handler check.handler
|
134
|
+
MemorySize check.memory
|
135
|
+
Runtime check.runtime
|
136
|
+
Timeout check.timeout
|
116
137
|
Role FnGetAtt(:LambdaExecutionRole, :Arn)
|
117
138
|
VpcConfig vpc_config unless vpc_config.empty?
|
118
139
|
Tags([
|
119
|
-
{ Key: 'Name', Value: "guardian-#{check
|
140
|
+
{ Key: 'Name', Value: "guardian-#{check.name}-#{check.group}" },
|
120
141
|
{ Key: 'Environment', Value: 'guardian' }
|
121
142
|
])
|
122
143
|
end
|
123
144
|
|
124
|
-
Lambda_Permission("#{check
|
125
|
-
FunctionName Ref("#{check
|
145
|
+
Lambda_Permission("#{check.name}Permissions#{check.environment}") do
|
146
|
+
FunctionName Ref("#{check.name}Function#{check.environment}")
|
126
147
|
Action 'lambda:InvokeFunction'
|
127
148
|
Principal 'events.amazonaws.com'
|
128
149
|
end
|
129
150
|
end
|
130
151
|
|
131
|
-
return FnGetAtt("#{check
|
152
|
+
return FnGetAtt("#{check.name}Function#{check.environment}", :Arn)
|
132
153
|
end
|
133
154
|
|
134
|
-
def add_stack(name,url,stack_parameters)
|
155
|
+
def add_stack(name,url,stack_parameters,stack_id)
|
135
156
|
@template.declare do
|
136
157
|
CloudFormation_Stack(name) do
|
137
158
|
Parameters stack_parameters
|
138
159
|
TemplateURL url
|
139
160
|
TimeoutInMinutes 15
|
140
161
|
Tags([
|
141
|
-
{ Key: 'Name', Value: "guardian-stack-#{name}" }
|
162
|
+
{ Key: 'Name', Value: "guardian-stack-#{name}" },
|
163
|
+
{ Key: 'guardian:stack-id', Value: "stk#{stack_id}"}
|
142
164
|
])
|
143
165
|
end
|
144
166
|
end
|
@@ -1,80 +1,148 @@
|
|
1
1
|
require 'cfndsl'
|
2
|
+
require 'digest/md5'
|
3
|
+
require 'cfnguardian/cloudwatch'
|
2
4
|
|
3
5
|
module CfnGuardian
|
4
6
|
module Stacks
|
5
7
|
class Resources
|
6
8
|
include CfnDsl::CloudFormation
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
attr_reader :template
|
11
|
+
|
12
|
+
def initialize(parameters,stack_id)
|
13
|
+
@stack_id = stack_id
|
14
|
+
|
15
|
+
@template = CloudFormation("Guardian nested - stack-id:stk#{@stack_id}")
|
16
|
+
parameters.each do |name|
|
12
17
|
parameter = @template.Parameter(name)
|
13
18
|
parameter.Type 'String'
|
14
|
-
parameter.Description "SNS topic ARN for #{name} notifications"
|
15
19
|
end
|
16
|
-
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_template(resources)
|
17
23
|
resources.each do |resource|
|
18
|
-
case resource
|
24
|
+
case resource.type
|
19
25
|
when 'Alarm'
|
20
26
|
add_alarm(resource)
|
21
27
|
when 'Event'
|
22
28
|
add_event(resource)
|
29
|
+
when 'Composite'
|
30
|
+
add_composite_alarm(resource)
|
31
|
+
when 'MetricFilter'
|
32
|
+
add_metric_filter(resource)
|
33
|
+
when 'EventSubscription'
|
34
|
+
add_event_subscription(resource)
|
23
35
|
else
|
24
|
-
puts "Warn: #{resource
|
36
|
+
puts "Warn: #{resource.type} is a unsuported resource type"
|
25
37
|
end
|
26
38
|
end
|
27
|
-
|
28
|
-
return @template
|
29
39
|
end
|
30
|
-
|
31
|
-
def add_alarm(
|
40
|
+
|
41
|
+
def add_alarm(alarm)
|
42
|
+
actions = alarm.alarm_action.kind_of?(Array) ? alarm.alarm_action.map{|action| Ref(action)} : [Ref(alarm.alarm_action)]
|
43
|
+
actions.concat alarm.maintenance_groups.map {|mg| Ref(mg)} if alarm.maintenance_groups.any?
|
44
|
+
stack_id = @stack_id
|
45
|
+
|
32
46
|
@template.declare do
|
33
|
-
CloudWatch_Alarm("#{
|
47
|
+
CloudWatch_Alarm("#{alarm.resource_hash}#{alarm.group}#{alarm.name.gsub(/[^0-9a-zA-Z]/i, '')}#{alarm.type}"[0..255]) do
|
34
48
|
ActionsEnabled true
|
35
|
-
AlarmDescription "Guardian alarm #{
|
36
|
-
AlarmName "#{
|
37
|
-
ComparisonOperator
|
38
|
-
Dimensions
|
39
|
-
EvaluationPeriods
|
40
|
-
Statistic
|
41
|
-
Period
|
42
|
-
Threshold
|
43
|
-
MetricName
|
44
|
-
Namespace
|
45
|
-
AlarmActions
|
46
|
-
OKActions
|
47
|
-
TreatMissingData
|
48
|
-
DatapointsToAlarm
|
49
|
-
ExtendedStatistic
|
50
|
-
EvaluateLowSampleCountPercentile
|
51
|
-
Unit
|
49
|
+
AlarmDescription "Guardian alarm #{alarm.name} for the resource #{alarm.resource_id} in alarm group #{alarm.group}"
|
50
|
+
AlarmName CfnGuardian::CloudWatch.get_alarm_name(alarm) + "-stk#{stack_id}"
|
51
|
+
ComparisonOperator alarm.comparison_operator
|
52
|
+
Dimensions alarm.dimensions.map {|k,v| {Name: k, Value: v}} unless alarm.dimensions.nil?
|
53
|
+
EvaluationPeriods alarm.evaluation_periods
|
54
|
+
Statistic alarm.statistic if alarm.extended_statistic.nil?
|
55
|
+
Period alarm.period
|
56
|
+
Threshold alarm.threshold
|
57
|
+
MetricName alarm.metric_name
|
58
|
+
Namespace alarm.namespace
|
59
|
+
AlarmActions actions
|
60
|
+
OKActions actions
|
61
|
+
TreatMissingData alarm.treat_missing_data unless alarm.treat_missing_data.nil?
|
62
|
+
DatapointsToAlarm alarm.datapoints_to_alarm unless alarm.datapoints_to_alarm.nil?
|
63
|
+
ExtendedStatistic alarm.extended_statistic unless alarm.extended_statistic.nil?
|
64
|
+
EvaluateLowSampleCountPercentile alarm.evaluate_low_sample_count_percentile unless alarm.evaluate_low_sample_count_percentile.nil?
|
65
|
+
Unit alarm.unit unless alarm.unit.nil?
|
52
66
|
end
|
53
67
|
end
|
54
68
|
end
|
55
69
|
|
56
|
-
def add_event(
|
57
|
-
@template.declare do
|
58
|
-
|
59
|
-
Type 'String'
|
60
|
-
Description "Lamba funtion Arn for #{resource[:class]} #{resource[:type]}"
|
61
|
-
end
|
62
|
-
|
63
|
-
Events_Rule("#{resource[:class]}#{resource[:type]}#{resource[:hash]}"[0..255]) do
|
70
|
+
def add_event(event)
|
71
|
+
@template.declare do
|
72
|
+
Events_Rule("#{event.group}#{event.type}#{event.hash}"[0..255]) do
|
64
73
|
State 'ENABLED'
|
65
|
-
Description "Guardian scheduled #{
|
66
|
-
ScheduleExpression "cron(#{
|
74
|
+
Description "Guardian scheduled #{event.group} #{event.type}"
|
75
|
+
ScheduleExpression "cron(#{event.cron})"
|
67
76
|
Targets([
|
68
77
|
{
|
69
|
-
Arn: Ref(
|
70
|
-
Id:
|
71
|
-
Input: FnSub(
|
78
|
+
Arn: Ref(event.target),
|
79
|
+
Id: event.hash,
|
80
|
+
Input: FnSub(event.payload)
|
72
81
|
}
|
73
82
|
])
|
74
83
|
end
|
75
84
|
end
|
76
85
|
end
|
77
86
|
|
87
|
+
def add_composite_alarm(alarm)
|
88
|
+
stack_id = @stack_id
|
89
|
+
|
90
|
+
@template.declare do
|
91
|
+
CloudWatch_CompositeAlarm(alarm.name.gsub(/[^0-9a-zA-Z]/i, '')) do
|
92
|
+
|
93
|
+
AlarmDescription alarm.description
|
94
|
+
AlarmName "guardian-#{alarm.name}-stk#{stack_id}"
|
95
|
+
AlarmRule alarm.rule
|
96
|
+
|
97
|
+
unless alarm.alarm_action.nil?
|
98
|
+
ActionsEnabled true
|
99
|
+
AlarmActions [Ref(alarm.alarm_action)]
|
100
|
+
# InsufficientDataActions [Ref(alarm.alarm_action)]
|
101
|
+
# OKActions [Ref(alarm.alarm_action)]
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def add_metric_filter(filter)
|
109
|
+
@template.declare do
|
110
|
+
Logs_MetricFilter("#{filter.name.gsub(/[^0-9a-zA-Z]/i, '')}#{filter.type}") do
|
111
|
+
LogGroupName filter.log_group
|
112
|
+
FilterPattern filter.pattern
|
113
|
+
MetricTransformations([
|
114
|
+
{
|
115
|
+
MetricValue: filter.metric_value,
|
116
|
+
MetricName: filter.metric_name,
|
117
|
+
MetricNamespace: filter.metric_namespace
|
118
|
+
}
|
119
|
+
])
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_event_subscription(subscription)
|
125
|
+
event_pattern = {}
|
126
|
+
event_pattern['detail-type'] = [subscription.detail_type]
|
127
|
+
event_pattern['source'] = [subscription.source]
|
128
|
+
event_pattern['resources'] = [subscription.resource_arn] unless subscription.resource_arn.empty?
|
129
|
+
event_pattern['detail'] = subscription.detail unless subscription.detail.empty?
|
130
|
+
|
131
|
+
@template.declare do
|
132
|
+
Events_Rule("#{subscription.group}#{subscription.name}#{subscription.hash}"[0..255]) do
|
133
|
+
State subscription.enabled ? 'ENABLED' : 'DISABLED'
|
134
|
+
Description "Guardian event subscription #{subscription.group} #{subscription.name} for resource #{subscription.resource_id}"
|
135
|
+
EventPattern event_pattern
|
136
|
+
Targets [
|
137
|
+
{
|
138
|
+
Arn: Ref(subscription.topic),
|
139
|
+
Id: "#{subscription.topic}Notifier"
|
140
|
+
}
|
141
|
+
]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
78
146
|
end
|
79
147
|
end
|
80
148
|
end
|