cfn-guardian 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build-gem.yml +8 -4
- data/.github/workflows/push.yml +1 -1
- data/.github/workflows/release-gem.yml +3 -3
- data/.github/workflows/release-image.yml +1 -1
- data/Gemfile.lock +43 -33
- data/cfn-guardian.gemspec +7 -5
- data/docs/custom_checks/ecs_container_instance_check.md +1 -1
- data/lib/cfnguardian/cloudwatch.rb +1 -1
- data/lib/cfnguardian/compile.rb +17 -6
- data/lib/cfnguardian/models/check.rb +2 -2
- data/lib/cfnguardian/resources/base.rb +8 -1
- data/lib/cfnguardian/resources/ec2_instance.rb +9 -0
- data/lib/cfnguardian/resources/ecs_cluster.rb +2 -2
- data/lib/cfnguardian/resources/elastic_search.rb +2 -0
- data/lib/cfnguardian/resources/lambda.rb +6 -0
- data/lib/cfnguardian/resources/network_targetgroup.rb +1 -0
- data/lib/cfnguardian/resources/rds_cluster.rb +14 -0
- data/lib/cfnguardian/resources/rds_instance.rb +16 -0
- data/lib/cfnguardian/stacks/main.rb +11 -0
- data/lib/cfnguardian/tagger.rb +9 -4
- data/lib/cfnguardian/version.rb +1 -1
- data/lib/cfnguardian.rb +6 -3
- metadata +52 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 597eff7904e03dd773f5d3b2c5e9928b03ce3081f76c7dd0cf33d95e0020af3e
|
4
|
+
data.tar.gz: 97ad25a41db6e7c6b88d4afd5c02560a2a114e6343ad27a001ca4dde87eeef97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8f6556b639e720418edf32faf4e19e1421636ef9835e85b2f6a61de40a26712affd4d4d9f63f4d1e83f6fad6da1461c7ffcd7fb845a16f4dfffda8c285b7853
|
7
|
+
data.tar.gz: '068ddd35b4996594a05189ca9d6c3c232e362c951b37405e2ed9dbb0f747b77967637595a4f584177404814a77fe48268a71ce484621c42903723326bb6a0e1f'
|
@@ -11,15 +11,19 @@ jobs:
|
|
11
11
|
runs-on: ubuntu-latest
|
12
12
|
|
13
13
|
steps:
|
14
|
-
-
|
15
|
-
|
16
|
-
|
14
|
+
- name: Check out the repo
|
15
|
+
uses: actions/checkout@v3
|
16
|
+
|
17
|
+
- name: Set up ruby 2.7
|
18
|
+
uses: ruby/setup-ruby@v1
|
17
19
|
with:
|
18
|
-
ruby-version: 2.7
|
20
|
+
ruby-version: 2.7
|
21
|
+
|
19
22
|
- name: rspec
|
20
23
|
run: |
|
21
24
|
gem install rspec
|
22
25
|
rspec
|
26
|
+
|
23
27
|
- name: build gem
|
24
28
|
run: |
|
25
29
|
gem build cfn-guardian.gemspec
|
data/.github/workflows/push.yml
CHANGED
@@ -11,12 +11,12 @@ jobs:
|
|
11
11
|
|
12
12
|
steps:
|
13
13
|
- name: Check out the repo
|
14
|
-
uses: actions/checkout@
|
14
|
+
uses: actions/checkout@v3
|
15
15
|
|
16
16
|
- name: Set up ruby 2.7
|
17
|
-
uses:
|
17
|
+
uses: ruby/setup-ruby@v1
|
18
18
|
with:
|
19
|
-
ruby-version: 2.7
|
19
|
+
ruby-version: 2.7
|
20
20
|
|
21
21
|
- name: Publish gem
|
22
22
|
uses: dawidd6/action-publish-gem@v1
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cfn-guardian (0.
|
5
|
-
aws-sdk-cloudformation (~> 1.
|
6
|
-
aws-sdk-cloudwatch (~> 1.
|
7
|
-
aws-sdk-codecommit (~> 1.
|
8
|
-
aws-sdk-codepipeline (~> 1.
|
9
|
-
aws-sdk-
|
4
|
+
cfn-guardian (0.10.4)
|
5
|
+
aws-sdk-cloudformation (~> 1.76, < 2)
|
6
|
+
aws-sdk-cloudwatch (~> 1.72, < 2)
|
7
|
+
aws-sdk-codecommit (~> 1.53, < 2)
|
8
|
+
aws-sdk-codepipeline (~> 1.55, < 2)
|
9
|
+
aws-sdk-ec2 (~> 1.371, < 2)
|
10
|
+
aws-sdk-rds (~> 1.174, < 2)
|
11
|
+
aws-sdk-s3 (~> 1.119, < 2)
|
10
12
|
cfndsl (~> 1.0, < 2)
|
13
|
+
rexml
|
11
14
|
term-ansicolor (~> 1, < 2)
|
12
15
|
terminal-table (~> 1, < 2)
|
13
16
|
thor (~> 0.20)
|
@@ -15,51 +18,58 @@ PATH
|
|
15
18
|
GEM
|
16
19
|
remote: https://rubygems.org/
|
17
20
|
specs:
|
18
|
-
aws-eventstream (1.
|
19
|
-
aws-partitions (1.
|
20
|
-
aws-sdk-cloudformation (1.
|
21
|
-
aws-sdk-core (~> 3, >= 3.
|
21
|
+
aws-eventstream (1.2.0)
|
22
|
+
aws-partitions (1.737.0)
|
23
|
+
aws-sdk-cloudformation (1.76.0)
|
24
|
+
aws-sdk-core (~> 3, >= 3.165.0)
|
22
25
|
aws-sigv4 (~> 1.1)
|
23
|
-
aws-sdk-cloudwatch (1.
|
24
|
-
aws-sdk-core (~> 3, >= 3.
|
26
|
+
aws-sdk-cloudwatch (1.72.0)
|
27
|
+
aws-sdk-core (~> 3, >= 3.165.0)
|
25
28
|
aws-sigv4 (~> 1.1)
|
26
|
-
aws-sdk-codecommit (1.
|
27
|
-
aws-sdk-core (~> 3, >= 3.
|
29
|
+
aws-sdk-codecommit (1.53.0)
|
30
|
+
aws-sdk-core (~> 3, >= 3.165.0)
|
28
31
|
aws-sigv4 (~> 1.1)
|
29
|
-
aws-sdk-codepipeline (1.
|
30
|
-
aws-sdk-core (~> 3, >= 3.
|
32
|
+
aws-sdk-codepipeline (1.55.0)
|
33
|
+
aws-sdk-core (~> 3, >= 3.165.0)
|
31
34
|
aws-sigv4 (~> 1.1)
|
32
|
-
aws-sdk-core (3.
|
35
|
+
aws-sdk-core (3.171.0)
|
33
36
|
aws-eventstream (~> 1, >= 1.0.2)
|
34
|
-
aws-partitions (~> 1, >= 1.
|
37
|
+
aws-partitions (~> 1, >= 1.651.0)
|
38
|
+
aws-sigv4 (~> 1.5)
|
39
|
+
jmespath (~> 1, >= 1.6.1)
|
40
|
+
aws-sdk-ec2 (1.371.0)
|
41
|
+
aws-sdk-core (~> 3, >= 3.165.0)
|
35
42
|
aws-sigv4 (~> 1.1)
|
36
|
-
|
37
|
-
|
38
|
-
aws-sdk-core (~> 3, >= 3.109.0)
|
43
|
+
aws-sdk-kms (1.63.0)
|
44
|
+
aws-sdk-core (~> 3, >= 3.165.0)
|
39
45
|
aws-sigv4 (~> 1.1)
|
40
|
-
aws-sdk-
|
41
|
-
aws-sdk-core (~> 3, >= 3.
|
42
|
-
aws-sdk-kms (~> 1)
|
46
|
+
aws-sdk-rds (1.174.0)
|
47
|
+
aws-sdk-core (~> 3, >= 3.165.0)
|
43
48
|
aws-sigv4 (~> 1.1)
|
44
|
-
aws-
|
49
|
+
aws-sdk-s3 (1.119.2)
|
50
|
+
aws-sdk-core (~> 3, >= 3.165.0)
|
51
|
+
aws-sdk-kms (~> 1)
|
52
|
+
aws-sigv4 (~> 1.4)
|
53
|
+
aws-sigv4 (1.5.2)
|
45
54
|
aws-eventstream (~> 1, >= 1.0.2)
|
46
|
-
cfndsl (1.
|
55
|
+
cfndsl (1.6.0)
|
47
56
|
hana (~> 1.3)
|
48
|
-
hana (1.3.
|
49
|
-
jmespath (1.6.
|
50
|
-
rake (13.0.
|
57
|
+
hana (1.3.7)
|
58
|
+
jmespath (1.6.2)
|
59
|
+
rake (13.0.6)
|
60
|
+
rexml (3.2.5)
|
51
61
|
sync (0.5.0)
|
52
62
|
term-ansicolor (1.7.1)
|
53
63
|
tins (~> 1.0)
|
54
64
|
terminal-table (1.8.0)
|
55
65
|
unicode-display_width (~> 1.1, >= 1.1.1)
|
56
66
|
thor (0.20.3)
|
57
|
-
tins (1.
|
67
|
+
tins (1.32.1)
|
58
68
|
sync
|
59
|
-
unicode-display_width (1.
|
69
|
+
unicode-display_width (1.8.0)
|
60
70
|
|
61
71
|
PLATFORMS
|
62
|
-
|
72
|
+
x86_64-darwin-21
|
63
73
|
|
64
74
|
DEPENDENCIES
|
65
75
|
bundler (~> 2.0)
|
@@ -67,4 +77,4 @@ DEPENDENCIES
|
|
67
77
|
rake (~> 13.0)
|
68
78
|
|
69
79
|
BUNDLED WITH
|
70
|
-
2.
|
80
|
+
2.3.19
|
data/cfn-guardian.gemspec
CHANGED
@@ -30,11 +30,13 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_dependency 'cfndsl', '~> 1.0', '<2'
|
31
31
|
spec.add_dependency "terminal-table", '~> 1', '<2'
|
32
32
|
spec.add_dependency 'term-ansicolor', '~> 1', '<2'
|
33
|
-
spec.add_dependency 'aws-sdk-s3', '~> 1.
|
34
|
-
spec.add_dependency 'aws-sdk-
|
35
|
-
spec.add_dependency 'aws-sdk-
|
36
|
-
spec.add_dependency 'aws-sdk-
|
37
|
-
spec.add_dependency 'aws-sdk-
|
33
|
+
spec.add_dependency 'aws-sdk-s3', '~> 1.119', '<2'
|
34
|
+
spec.add_dependency 'aws-sdk-ec2', '~> 1.371', '<2'
|
35
|
+
spec.add_dependency 'aws-sdk-rds', '~> 1.174', '<2'
|
36
|
+
spec.add_dependency 'aws-sdk-cloudformation', '~> 1.76', '<2'
|
37
|
+
spec.add_dependency 'aws-sdk-cloudwatch', '~> 1.72', '<2'
|
38
|
+
spec.add_dependency 'aws-sdk-codecommit', '~> 1.53', '<2'
|
39
|
+
spec.add_dependency 'aws-sdk-codepipeline', '~> 1.55', '<2'
|
38
40
|
|
39
41
|
spec.add_runtime_dependency('rexml', '>= 0')
|
40
42
|
|
data/lib/cfnguardian/compile.rb
CHANGED
@@ -60,7 +60,7 @@ module CfnGuardian
|
|
60
60
|
|
61
61
|
attr_reader :cost, :resources, :topics, :global_tags
|
62
62
|
|
63
|
-
def initialize(config_file)
|
63
|
+
def initialize(config_file, check_resources_exist)
|
64
64
|
config = YAML.load_file(config_file)
|
65
65
|
|
66
66
|
@resource_groups = config.fetch('Resources',{})
|
@@ -70,6 +70,8 @@ module CfnGuardian
|
|
70
70
|
@maintenance_groups = config.fetch('MaintenanceGroups', {})
|
71
71
|
@event_subscriptions = config.fetch('EventSubscriptions', {})
|
72
72
|
@global_tags = config.fetch('GlobalTags', {})
|
73
|
+
@check_resources_exist = check_resources_exist
|
74
|
+
@errors = []
|
73
75
|
|
74
76
|
# Make sure the default topics exist if they aren't supplied in the alarms.yaml
|
75
77
|
%w(Critical Warning Task Informational Events).each do |topic|
|
@@ -87,6 +89,10 @@ module CfnGuardian
|
|
87
89
|
def get_resources
|
88
90
|
@resource_groups.each do |group,resources|
|
89
91
|
resources.each do |resource|
|
92
|
+
if !resource.has_key?('Id')
|
93
|
+
@errors << "CfnGuardian::NoIdKeyForResourceError - resource: #{resource} in resource group: #{group} doesn't have the `Id:` key"
|
94
|
+
next
|
95
|
+
end
|
90
96
|
|
91
97
|
begin
|
92
98
|
resource_class = Kernel.const_get("CfnGuardian::Resource::#{group}").new(resource)
|
@@ -104,6 +110,10 @@ module CfnGuardian
|
|
104
110
|
next
|
105
111
|
end
|
106
112
|
end
|
113
|
+
|
114
|
+
if @check_resources_exist && !resource_class.resource_exists?
|
115
|
+
@errors << "CfnGuardian::ResourceNotExistsError - #{group} #{resource['Id']} doesn't exist"
|
116
|
+
end
|
107
117
|
|
108
118
|
template_overides = @templates.has_key?(group) ? @templates[group] : {}
|
109
119
|
@resources.concat resource_class.get_alarms(group,template_overides)
|
@@ -131,7 +141,7 @@ module CfnGuardian
|
|
131
141
|
res = @resources.find {|r|
|
132
142
|
(r.type == 'Alarm') &&
|
133
143
|
(r.group == group && r.name == alarm) &&
|
134
|
-
(r.resource_id == resource['Id'] || r.resource_name == resource['Name'])}
|
144
|
+
(r.resource_id == resource['Id'] || (!resource['Name'].nil? && r.resource_name == resource['Name']))}
|
135
145
|
|
136
146
|
unless res.nil?
|
137
147
|
res.maintenance_groups.append("#{maintenance_group}MaintenanceGroup")
|
@@ -150,6 +160,10 @@ module CfnGuardian
|
|
150
160
|
@ssm_parameters = @resources.select {|resource| resource.type == 'Event'}.map {|event| event.ssm_parameters}.flatten.uniq
|
151
161
|
|
152
162
|
validate_resources()
|
163
|
+
|
164
|
+
if @errors.any?
|
165
|
+
raise CfnGuardian::ValidationError, "#{@errors.size} errors found\n[*] #{@errors.join("\n[*] ")}"
|
166
|
+
end
|
153
167
|
end
|
154
168
|
|
155
169
|
def alarms
|
@@ -157,13 +171,12 @@ module CfnGuardian
|
|
157
171
|
end
|
158
172
|
|
159
173
|
def validate_resources()
|
160
|
-
errors = []
|
161
174
|
@resources.each do |resource|
|
162
175
|
case resource.type
|
163
176
|
when 'Alarm'
|
164
177
|
%w(metric_name namespace).each do |property|
|
165
178
|
if resource.send(property).nil?
|
166
|
-
errors << "
|
179
|
+
@errors << "CfnGuardian::AlarmPropertyError - alarm #{resource.name} for resource #{resource.resource_id} has nil value for property #{property.to_camelcase}. This could be due to incorrect spelling of a default alarm name or missing property #{property.to_camelcase} on a new alarm."
|
167
180
|
end
|
168
181
|
end
|
169
182
|
when 'Check'
|
@@ -178,8 +191,6 @@ module CfnGuardian
|
|
178
191
|
# no validation check yet
|
179
192
|
end
|
180
193
|
end
|
181
|
-
|
182
|
-
raise CfnGuardian::ValidationError, "#{errors.size} errors found\n[*] #{errors.join("\n[*] ")}" if errors.any?
|
183
194
|
end
|
184
195
|
|
185
196
|
def compile_templates(template_file)
|
@@ -163,9 +163,9 @@ module CfnGuardian
|
|
163
163
|
super(resource)
|
164
164
|
@group = 'ContainerInstance'
|
165
165
|
@name = 'ContainerInstanceCheck'
|
166
|
-
@package = 'ecs-
|
166
|
+
@package = 'ecs-container-instance-check'
|
167
167
|
@handler = 'handler.run_check'
|
168
|
-
@version = '
|
168
|
+
@version = '387446fbe2eb18fb4f75462c27cc07caad4a26b8'
|
169
169
|
@runtime = 'python3.7'
|
170
170
|
end
|
171
171
|
end
|
@@ -84,8 +84,11 @@ module CfnGuardian::Resource
|
|
84
84
|
|
85
85
|
alarms = find_alarms(name)
|
86
86
|
|
87
|
-
if alarms.empty?
|
87
|
+
if alarms.empty? && !['LogGroup'].any?(group)
|
88
88
|
# if the alarm doesn't exist and it's not being inherited from another alarm create a new alarm
|
89
|
+
# and is a supported a resource group.
|
90
|
+
# unsupported resource groups
|
91
|
+
# - LogGroup: this is not required as alarms are defined in the Metric Filters object in the resource group
|
89
92
|
resources = @resource.has_key?('Hosts') ? @resource['Hosts'] : [@resource]
|
90
93
|
resources.each do |res|
|
91
94
|
alarm = Kernel.const_get("CfnGuardian::Models::#{self.class.to_s.split('::').last}Alarm").new(res)
|
@@ -211,6 +214,10 @@ module CfnGuardian::Resource
|
|
211
214
|
def get_cost()
|
212
215
|
return @alarms.length * 0.10
|
213
216
|
end
|
217
|
+
|
218
|
+
def resource_exists?
|
219
|
+
return true
|
220
|
+
end
|
214
221
|
|
215
222
|
private
|
216
223
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'aws-sdk-ec2'
|
2
|
+
|
1
3
|
module CfnGuardian
|
2
4
|
module Resource
|
3
5
|
class Ec2Instance < Base
|
@@ -42,6 +44,13 @@ module CfnGuardian
|
|
42
44
|
@event_subscriptions.push(event_subscription)
|
43
45
|
end
|
44
46
|
|
47
|
+
def resource_exists?
|
48
|
+
client = Aws::EC2::Client.new
|
49
|
+
resource = Aws::EC2::Resource.new(client: client)
|
50
|
+
instance = resource.instance(@resource['Id'])
|
51
|
+
return instance.exists?
|
52
|
+
end
|
53
|
+
|
45
54
|
end
|
46
55
|
end
|
47
56
|
end
|
@@ -23,8 +23,8 @@ module CfnGuardian::Resource
|
|
23
23
|
|
24
24
|
alarm = CfnGuardian::Models::ECSClusterAlarm.new(@resource)
|
25
25
|
alarm.namespace = 'EcsCICheck'
|
26
|
-
alarm.name = '
|
27
|
-
alarm.metric_name = '
|
26
|
+
alarm.name = 'ECSContainerInstancesDisconnected'
|
27
|
+
alarm.metric_name = 'ECSContainerInstancesDisconnected'
|
28
28
|
alarm.alarm_action = 'Critical'
|
29
29
|
alarm.threshold = 0
|
30
30
|
alarm.period = 300
|
@@ -20,6 +20,7 @@ module CfnGuardian::Resource
|
|
20
20
|
alarm.evaluation_periods = 5
|
21
21
|
alarm.datapoints_to_alarm = 3
|
22
22
|
alarm.alarm_action = 'Warning'
|
23
|
+
alarm.enabled = false
|
23
24
|
@alarms.push(alarm)
|
24
25
|
|
25
26
|
alarm = CfnGuardian::Models::ElasticSearchAlarm.new(@resource)
|
@@ -28,6 +29,7 @@ module CfnGuardian::Resource
|
|
28
29
|
alarm.threshold = 92
|
29
30
|
alarm.evaluation_periods = 5
|
30
31
|
alarm.alarm_action = 'Critical'
|
32
|
+
alarm.enabled = false
|
31
33
|
@alarms.push(alarm)
|
32
34
|
|
33
35
|
alarm = CfnGuardian::Models::ElasticSearchAlarm.new(@resource)
|
@@ -6,18 +6,24 @@ module CfnGuardian::Resource
|
|
6
6
|
alarm.name = 'LambdaErrors'
|
7
7
|
alarm.metric_name = 'Errors'
|
8
8
|
alarm.threshold = 0.5
|
9
|
+
alarm.evaluation_periods = 1
|
10
|
+
alarm.datapoints_to_alarm = 1
|
9
11
|
@alarms.push(alarm)
|
10
12
|
|
11
13
|
alarm = CfnGuardian::Models::LambdaAlarm.new(@resource)
|
12
14
|
alarm.name = 'Throttles'
|
13
15
|
alarm.metric_name = 'Throttles'
|
14
16
|
alarm.threshold = 0.5
|
17
|
+
alarm.evaluation_periods = 1
|
18
|
+
alarm.datapoints_to_alarm = 1
|
15
19
|
@alarms.push(alarm)
|
16
20
|
|
17
21
|
alarm = CfnGuardian::Models::LambdaAlarm.new(@resource)
|
18
22
|
alarm.name = 'DeadLetterErrors'
|
19
23
|
alarm.metric_name = 'DeadLetterErrors'
|
20
24
|
alarm.threshold = 0.5
|
25
|
+
alarm.evaluation_periods = 1
|
26
|
+
alarm.datapoints_to_alarm = 1
|
21
27
|
@alarms.push(alarm)
|
22
28
|
|
23
29
|
alarm = CfnGuardian::Models::LambdaAlarm.new(@resource)
|
@@ -16,6 +16,20 @@ module CfnGuardian::Resource
|
|
16
16
|
@event_subscriptions.push(event_subscription)
|
17
17
|
end
|
18
18
|
|
19
|
+
def resource_exists?
|
20
|
+
client = Aws::RDS::Client.new
|
21
|
+
resource = Aws::RDS::Resource.new(client: client)
|
22
|
+
instance = resource.db_cluster(@resource['Id'])
|
23
|
+
|
24
|
+
begin
|
25
|
+
instance.load
|
26
|
+
rescue Aws::RDS::Errors::DBClusterNotFoundFault
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
|
30
|
+
return true
|
31
|
+
end
|
32
|
+
|
19
33
|
end
|
20
34
|
end
|
21
35
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'aws-sdk-rds'
|
2
|
+
|
1
3
|
module CfnGuardian::Resource
|
2
4
|
class RDSInstance < Base
|
3
5
|
|
@@ -123,5 +125,19 @@ module CfnGuardian::Resource
|
|
123
125
|
@event_subscriptions.push(event_subscription)
|
124
126
|
end
|
125
127
|
|
128
|
+
def resource_exists?
|
129
|
+
client = Aws::RDS::Client.new
|
130
|
+
resource = Aws::RDS::Resource.new(client: client)
|
131
|
+
instance = resource.db_instance(@resource['Id'])
|
132
|
+
|
133
|
+
begin
|
134
|
+
instance.load
|
135
|
+
rescue Aws::RDS::Errors::DBInstanceNotFound
|
136
|
+
return false
|
137
|
+
end
|
138
|
+
|
139
|
+
return true
|
140
|
+
end
|
141
|
+
|
126
142
|
end
|
127
143
|
end
|
@@ -81,6 +81,17 @@ module CfnGuardian
|
|
81
81
|
}]
|
82
82
|
}
|
83
83
|
}
|
84
|
+
policies << {
|
85
|
+
PolicyName: 'container-instance-check',
|
86
|
+
PolicyDocument: {
|
87
|
+
Version: '2012-10-17',
|
88
|
+
Statement: [{
|
89
|
+
Effect: 'Allow',
|
90
|
+
Action: [ 'ecs:ListContainerInstances','ecs:DescribeContainerInstances' ],
|
91
|
+
Resource: '*'
|
92
|
+
}]
|
93
|
+
}
|
94
|
+
}
|
84
95
|
if ssm_parameters.any?
|
85
96
|
policies << {
|
86
97
|
PolicyName: 'ssm-parameters',
|
data/lib/cfnguardian/tagger.rb
CHANGED
@@ -27,10 +27,15 @@ module CfnGuardian
|
|
27
27
|
|
28
28
|
if tags_changed?(current_tags, new_tags)
|
29
29
|
logger.debug "Updating tags on alarm #{alarm_arn}"
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
new_tags.delete_if {|key, value| value.include?('?')}
|
31
|
+
begin
|
32
|
+
@client.tag_resource({
|
33
|
+
resource_arn: alarm_arn,
|
34
|
+
tags: new_tags.map {|key,value| {key: key, value: value}}
|
35
|
+
})
|
36
|
+
rescue Aws::CloudWatch::Errors::InvalidParameterValue => e
|
37
|
+
logger.debug "Failed due to invalid character in tags for: #{alarm_arn}"
|
38
|
+
end
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|
data/lib/cfnguardian/version.rb
CHANGED
data/lib/cfnguardian.rb
CHANGED
@@ -45,6 +45,7 @@ module CfnGuardian
|
|
45
45
|
method_option :sns_informational, type: :string, desc: "sns topic arn for the informational alarms"
|
46
46
|
method_option :sns_events, type: :string, desc: "sns topic arn for the informational alarms"
|
47
47
|
method_option :template_file, type: :string, default: 'guardian.compiled.yaml', desc: "name of the compiled cloudformation template file"
|
48
|
+
method_option :check_resources_exist, type: :boolean, default: true, desc: "check each resource exists in the aws account"
|
48
49
|
|
49
50
|
def compile
|
50
51
|
set_log_level(options[:debug])
|
@@ -54,7 +55,7 @@ module CfnGuardian
|
|
54
55
|
|
55
56
|
clean_out_directory()
|
56
57
|
|
57
|
-
compiler = CfnGuardian::Compile.new(options[:config])
|
58
|
+
compiler = CfnGuardian::Compile.new(options[:config], options[:check_resources_exist])
|
58
59
|
compiler.get_resources
|
59
60
|
compiler.compile_templates(options[:template_file])
|
60
61
|
logger.info "Cloudformation templates compiled successfully in out/ directory"
|
@@ -92,6 +93,7 @@ module CfnGuardian
|
|
92
93
|
method_option :role_arn, type: :string, desc: "IAM role arn that CloudFormation assumes when executing the change set"
|
93
94
|
method_option :template_file, type: :string, default: 'guardian.compiled.yaml', desc: "name of the compiled cloudformation template file"
|
94
95
|
method_option :fail_empty_change_set, type: :boolean, default: true, desc: "fail a cloudformation changeset if it contains no changes"
|
96
|
+
method_option :check_resources_exist, type: :boolean, default: true, desc: "check each resource exists in the aws account"
|
95
97
|
|
96
98
|
def deploy
|
97
99
|
set_log_level(options[:debug])
|
@@ -101,7 +103,7 @@ module CfnGuardian
|
|
101
103
|
|
102
104
|
clean_out_directory()
|
103
105
|
|
104
|
-
compiler = CfnGuardian::Compile.new(options[:config])
|
106
|
+
compiler = CfnGuardian::Compile.new(options[:config], options[:check_resources_exist])
|
105
107
|
compiler.get_resources
|
106
108
|
compiler.compile_templates(options[:template_file])
|
107
109
|
parameters = compiler.load_parameters(options)
|
@@ -137,6 +139,7 @@ module CfnGuardian
|
|
137
139
|
method_option :tags, type: :hash, desc: "additional tags on the cloudformation stack"
|
138
140
|
method_option :role_arn, type: :string, desc: "IAM role arn that CloudFormation assumes when executing the change set"
|
139
141
|
method_option :fail_empty_change_set, type: :boolean, default: true, desc: "fail a cloudformation changeset if it contains no changes"
|
142
|
+
method_option :check_resources_exist, type: :boolean, default: true, desc: "check each resource exists in the aws account"
|
140
143
|
|
141
144
|
def bulk_deploy
|
142
145
|
set_log_level(options[:debug])
|
@@ -156,7 +159,7 @@ module CfnGuardian
|
|
156
159
|
guardian_name = config_basename == "alarms.yaml" ? "" : "-#{config_basename}"
|
157
160
|
template_file = "guardian#{guardian_name}.#{template_file_suffix}"
|
158
161
|
|
159
|
-
compiler = CfnGuardian::Compile.new(config)
|
162
|
+
compiler = CfnGuardian::Compile.new(config, options[:check_resources_exist])
|
160
163
|
compiler.get_resources
|
161
164
|
compiler.compile_templates(template_file)
|
162
165
|
logger.info "compiled template to out/#{template_file} from yaml config #{config}"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cfn-guardian
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guslington
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -90,7 +90,7 @@ dependencies:
|
|
90
90
|
requirements:
|
91
91
|
- - "~>"
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: '1.
|
93
|
+
version: '1.119'
|
94
94
|
- - "<"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '2'
|
@@ -100,7 +100,47 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: '1.
|
103
|
+
version: '1.119'
|
104
|
+
- - "<"
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '2'
|
107
|
+
- !ruby/object:Gem::Dependency
|
108
|
+
name: aws-sdk-ec2
|
109
|
+
requirement: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '1.371'
|
114
|
+
- - "<"
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '2'
|
117
|
+
type: :runtime
|
118
|
+
prerelease: false
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '1.371'
|
124
|
+
- - "<"
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '2'
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: aws-sdk-rds
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - "~>"
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '1.174'
|
134
|
+
- - "<"
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '2'
|
137
|
+
type: :runtime
|
138
|
+
prerelease: false
|
139
|
+
version_requirements: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - "~>"
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '1.174'
|
104
144
|
- - "<"
|
105
145
|
- !ruby/object:Gem::Version
|
106
146
|
version: '2'
|
@@ -110,7 +150,7 @@ dependencies:
|
|
110
150
|
requirements:
|
111
151
|
- - "~>"
|
112
152
|
- !ruby/object:Gem::Version
|
113
|
-
version: '1.
|
153
|
+
version: '1.76'
|
114
154
|
- - "<"
|
115
155
|
- !ruby/object:Gem::Version
|
116
156
|
version: '2'
|
@@ -120,7 +160,7 @@ dependencies:
|
|
120
160
|
requirements:
|
121
161
|
- - "~>"
|
122
162
|
- !ruby/object:Gem::Version
|
123
|
-
version: '1.
|
163
|
+
version: '1.76'
|
124
164
|
- - "<"
|
125
165
|
- !ruby/object:Gem::Version
|
126
166
|
version: '2'
|
@@ -130,7 +170,7 @@ dependencies:
|
|
130
170
|
requirements:
|
131
171
|
- - "~>"
|
132
172
|
- !ruby/object:Gem::Version
|
133
|
-
version: '1.
|
173
|
+
version: '1.72'
|
134
174
|
- - "<"
|
135
175
|
- !ruby/object:Gem::Version
|
136
176
|
version: '2'
|
@@ -140,7 +180,7 @@ dependencies:
|
|
140
180
|
requirements:
|
141
181
|
- - "~>"
|
142
182
|
- !ruby/object:Gem::Version
|
143
|
-
version: '1.
|
183
|
+
version: '1.72'
|
144
184
|
- - "<"
|
145
185
|
- !ruby/object:Gem::Version
|
146
186
|
version: '2'
|
@@ -150,7 +190,7 @@ dependencies:
|
|
150
190
|
requirements:
|
151
191
|
- - "~>"
|
152
192
|
- !ruby/object:Gem::Version
|
153
|
-
version: '1.
|
193
|
+
version: '1.53'
|
154
194
|
- - "<"
|
155
195
|
- !ruby/object:Gem::Version
|
156
196
|
version: '2'
|
@@ -160,7 +200,7 @@ dependencies:
|
|
160
200
|
requirements:
|
161
201
|
- - "~>"
|
162
202
|
- !ruby/object:Gem::Version
|
163
|
-
version: '1.
|
203
|
+
version: '1.53'
|
164
204
|
- - "<"
|
165
205
|
- !ruby/object:Gem::Version
|
166
206
|
version: '2'
|
@@ -170,7 +210,7 @@ dependencies:
|
|
170
210
|
requirements:
|
171
211
|
- - "~>"
|
172
212
|
- !ruby/object:Gem::Version
|
173
|
-
version: '1.
|
213
|
+
version: '1.55'
|
174
214
|
- - "<"
|
175
215
|
- !ruby/object:Gem::Version
|
176
216
|
version: '2'
|
@@ -180,7 +220,7 @@ dependencies:
|
|
180
220
|
requirements:
|
181
221
|
- - "~>"
|
182
222
|
- !ruby/object:Gem::Version
|
183
|
-
version: '1.
|
223
|
+
version: '1.55'
|
184
224
|
- - "<"
|
185
225
|
- !ruby/object:Gem::Version
|
186
226
|
version: '2'
|