hibernate 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/hibernate +81 -21
- data/lib/hibernate/cloud_watch_event_manager.rb +135 -14
- data/lib/hibernate/ec2_manager.rb +70 -11
- data/lib/hibernate/version.rb +4 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21e7dde6cd66464fa7aff8bc01d5f1338e65ba5f180d27c6d7fc176fcf9dbff5
|
4
|
+
data.tar.gz: 84a9f6eb6fd06373cbe68b686048107636cb2821eee5284b9a408062378e05f8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 250624e8f6984ca9cee0685c8d99a990e6fb45c66a88a16a9fd1bc68f430d252c1377d55ca31f1b95806250748e1b8be683fef73f374e1dc708bbba77b65f8e0
|
7
|
+
data.tar.gz: 5495ddec8a33acf9c2b4a8eeb8026f762d8f37716912bb238d6c797587403e62f0bb8023202d1755b522f6e09292146bc298e97e1bd335febed73124d54a7658
|
data/bin/hibernate
CHANGED
@@ -12,28 +12,57 @@ class HibernateCLI
|
|
12
12
|
if ARGV.include?('setup')
|
13
13
|
command = :setup
|
14
14
|
ARGV.delete('setup')
|
15
|
-
elsif ARGV.include?('
|
15
|
+
elsif ARGV.include?('rule')
|
16
16
|
command = :manage_ec2
|
17
|
-
ARGV.delete('
|
18
|
-
elsif ARGV.include?('remove')
|
19
|
-
command = :remove_ec2
|
20
|
-
ARGV.delete('remove')
|
17
|
+
ARGV.delete('rule')
|
21
18
|
end
|
22
19
|
|
23
20
|
parser = OptionParser.new do |parser|
|
24
21
|
parser.banner = "Usage: hibernate [command] [options]"
|
25
22
|
|
26
|
-
parser.on('--
|
23
|
+
parser.on('--instance-name=<INSTANCE_NAME>', 'Specify the EC2 instance name') do |instance_name|
|
27
24
|
options[:instance_name] = instance_name
|
28
25
|
end
|
29
26
|
|
30
|
-
parser.on('--
|
27
|
+
parser.on('--start-expression=<START_CRON>', 'Specify the cron expression to start the instance') do |start_cron|
|
31
28
|
options[:start_cron] = start_cron
|
32
29
|
end
|
33
30
|
|
34
|
-
parser.on('--
|
31
|
+
parser.on('--stop-expression=<STOP_CRON>', 'Specify the cron expression to stop the instance') do |stop_cron|
|
35
32
|
options[:stop_cron] = stop_cron
|
36
33
|
end
|
34
|
+
|
35
|
+
parser.on('--start-instance=<true/false>', 'Filter start rules') do |start_instance|
|
36
|
+
options[:start_instance] = start_instance == 'true'
|
37
|
+
end
|
38
|
+
|
39
|
+
parser.on('--stop-instance=<true/false>', 'Filter stop rules') do |stop_instance|
|
40
|
+
options[:stop_instance] = stop_instance == 'true'
|
41
|
+
end
|
42
|
+
|
43
|
+
parser.on('--rule-name=<RULE Name>', 'Specify the rule name to remove or update') do |rule_name|
|
44
|
+
options[:rule_name] = rule_name
|
45
|
+
end
|
46
|
+
|
47
|
+
parser.on('--update', 'Update an existing rule') do
|
48
|
+
options[:update] = true
|
49
|
+
end
|
50
|
+
|
51
|
+
parser.on('--remove', 'Remove an existing rule') do
|
52
|
+
options[:remove] = true
|
53
|
+
end
|
54
|
+
|
55
|
+
parser.on('--create', 'Create a new rule') do
|
56
|
+
options[:create] = true
|
57
|
+
end
|
58
|
+
|
59
|
+
parser.on('--list', 'List rules') do
|
60
|
+
options[:list] = true
|
61
|
+
end
|
62
|
+
|
63
|
+
parser.on('--state=<enable/disable>', 'Set rule state to either enable or disable') do |state|
|
64
|
+
options[:state] = state
|
65
|
+
end
|
37
66
|
end
|
38
67
|
|
39
68
|
begin
|
@@ -54,9 +83,15 @@ class HibernateCLI
|
|
54
83
|
when :setup
|
55
84
|
create_lambda_function
|
56
85
|
when :manage_ec2
|
57
|
-
|
58
|
-
|
59
|
-
|
86
|
+
if options[:update]
|
87
|
+
update_ec2_rule_command(options)
|
88
|
+
elsif options[:remove]
|
89
|
+
remove_ec2_rule_command(options)
|
90
|
+
elsif options[:create]
|
91
|
+
create_ec2_rule_command(options)
|
92
|
+
elsif options[:list]
|
93
|
+
list_ec2_rule_command(options)
|
94
|
+
end
|
60
95
|
end
|
61
96
|
end
|
62
97
|
|
@@ -64,25 +99,50 @@ class HibernateCLI
|
|
64
99
|
LambdaSetup.new.run
|
65
100
|
end
|
66
101
|
|
67
|
-
def self.
|
102
|
+
def self.create_ec2_rule_command(options)
|
68
103
|
if options[:instance_name].nil? || (options[:start_cron].nil? && options[:stop_cron].nil?)
|
69
104
|
puts "Please provide the instance name, and at least one cron expression (start or stop)."
|
70
|
-
puts "Usage: hibernate
|
105
|
+
puts "Usage: hibernate rule --create --instance-name=<INSTANCE_NAME> --start-expression=<START_CRON> --stop-expression=<STOP_CRON>"
|
71
106
|
exit
|
72
107
|
else
|
73
|
-
ec2_manager = EC2Manager.new(options[:instance_name]
|
74
|
-
ec2_manager.create_event_rule
|
108
|
+
ec2_manager = EC2Manager.new(options[:instance_name])
|
109
|
+
ec2_manager.create_event_rule(options[:start_cron], options[:stop_cron])
|
75
110
|
end
|
76
111
|
end
|
77
112
|
|
78
|
-
def self.
|
79
|
-
if options[:
|
80
|
-
puts "Please provide the
|
81
|
-
puts "Usage: hibernate
|
113
|
+
def self.remove_ec2_rule_command(options)
|
114
|
+
if options[:rule_name].nil?
|
115
|
+
puts "Please provide the rule name to remove."
|
116
|
+
puts "Usage: hibernate rule --remove --rule-name=<RULE NAME>"
|
117
|
+
exit
|
118
|
+
else
|
119
|
+
ec2_manager = EC2Manager.new(options[:instance_name])
|
120
|
+
ec2_manager.remove_event_rule(options[:rule_name])
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.list_ec2_rule_command(options)
|
125
|
+
ec2_manager = EC2Manager.new(options[:instance_name])
|
126
|
+
ec2_manager.list_event_rules(options)
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.update_ec2_rule_command(options)
|
130
|
+
if options[:rule_name].nil?
|
131
|
+
puts "Please provide the rule name to update."
|
132
|
+
puts "Usage: hibernate rule --update --rule-name=<RULE_NAME> [--start-expression=<START_CRON>] [--stop-expression=<STOP_CRON>] [--state=<enable/disable>]"
|
133
|
+
exit
|
134
|
+
elsif options[:start_cron].nil? && options[:stop_cron].nil? && options[:state].nil?
|
135
|
+
puts "Please provide atleast one attribute to update."
|
136
|
+
puts "Usage: hibernate rule --update --rule-name=<RULE_NAME> [--start-expression=<START_CRON>] [--stop-expression=<STOP_CRON>] [--state=<enable/disable>]"
|
82
137
|
exit
|
83
138
|
else
|
84
|
-
ec2_manager = EC2Manager.new(options[:instance_name]
|
85
|
-
ec2_manager.
|
139
|
+
ec2_manager = EC2Manager.new(options[:instance_name])
|
140
|
+
ec2_manager.update_event_rule(
|
141
|
+
rule_name: options[:rule_name],
|
142
|
+
start_cron: options[:start_cron],
|
143
|
+
stop_cron: options[:stop_cron],
|
144
|
+
state: options[:state]
|
145
|
+
)
|
86
146
|
end
|
87
147
|
end
|
88
148
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'aws-sdk-cloudwatchevents'
|
2
2
|
require 'json'
|
3
3
|
require 'dotenv/load'
|
4
|
+
require 'digest'
|
4
5
|
|
5
6
|
class CloudWatchEventManager
|
6
|
-
def initialize(events_client, instance_id, instance_name, lambda_function_arn)
|
7
|
+
def initialize(events_client, instance_id = nil, instance_name = nil, lambda_function_arn)
|
7
8
|
@events_client = events_client
|
8
9
|
@instance_id = instance_id
|
9
10
|
@instance_name = instance_name
|
@@ -13,38 +14,110 @@ class CloudWatchEventManager
|
|
13
14
|
@lambda_client = Aws::Lambda::Client.new(region: @aws_region)
|
14
15
|
end
|
15
16
|
|
17
|
+
attr_writer :instance_id, :instance_name
|
18
|
+
|
16
19
|
def create_start_rule(cron_expression)
|
20
|
+
rule_name = "StartInstanceRule-#{@instance_id}-#{cron_expression_hash(cron_expression)}"
|
17
21
|
create_rule(
|
18
|
-
|
22
|
+
rule_name,
|
19
23
|
cron_expression,
|
20
24
|
{ instance_id: @instance_id, action: 'start' },
|
21
|
-
|
25
|
+
'start'
|
22
26
|
)
|
23
27
|
end
|
24
28
|
|
25
29
|
def create_stop_rule(cron_expression)
|
30
|
+
rule_name = "StopInstanceRule-#{@instance_id}-#{cron_expression_hash(cron_expression)}"
|
26
31
|
create_rule(
|
27
|
-
|
32
|
+
rule_name,
|
28
33
|
cron_expression,
|
29
34
|
{ instance_id: @instance_id, action: 'stop' },
|
30
|
-
|
35
|
+
'stop'
|
31
36
|
)
|
32
37
|
end
|
33
38
|
|
34
|
-
def
|
35
|
-
rule_name
|
36
|
-
remove_rule(rule_name)
|
39
|
+
def remove_rule(rule_name)
|
40
|
+
remove_rule_by_name(rule_name)
|
37
41
|
remove_lambda_permission(rule_name)
|
38
42
|
end
|
39
43
|
|
40
|
-
def
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
def list_event_rules(options)
|
45
|
+
next_token = nil
|
46
|
+
|
47
|
+
column_widths = {
|
48
|
+
rule_name: 40,
|
49
|
+
instance_id: 22,
|
50
|
+
schedule: 30,
|
51
|
+
state: 10,
|
52
|
+
action: 10
|
53
|
+
}
|
54
|
+
|
55
|
+
print_header(column_widths)
|
56
|
+
|
57
|
+
loop do
|
58
|
+
response = @events_client.list_rules(next_token: next_token)
|
59
|
+
|
60
|
+
response.rules.each do |rule|
|
61
|
+
process_rule(rule, options, column_widths)
|
62
|
+
end
|
63
|
+
|
64
|
+
next_token = response.next_token
|
65
|
+
break if next_token.nil?
|
66
|
+
end
|
67
|
+
|
68
|
+
print_footer(column_widths)
|
69
|
+
end
|
70
|
+
|
71
|
+
def update_rule_state(rule_name, state)
|
72
|
+
state = state == 'enable' ? 'ENABLED' : 'DISABLED'
|
73
|
+
|
74
|
+
rule_details = @events_client.describe_rule({ name: rule_name })
|
75
|
+
|
76
|
+
params = {
|
77
|
+
name: rule_name,
|
78
|
+
state: state,
|
79
|
+
description: rule_details.description
|
80
|
+
}
|
81
|
+
|
82
|
+
if rule_details.schedule_expression
|
83
|
+
params[:schedule_expression] = rule_details.schedule_expression
|
84
|
+
elsif rule_details.event_pattern
|
85
|
+
params[:event_pattern] = rule_details.event_pattern
|
86
|
+
else
|
87
|
+
puts "No ScheduleExpression or EventPattern found for rule '#{rule_name}'."
|
88
|
+
exit 1
|
89
|
+
end
|
90
|
+
|
91
|
+
@events_client.put_rule(params)
|
92
|
+
end
|
93
|
+
|
94
|
+
def get_instance_id_from_rule(rule_name)
|
95
|
+
response = @events_client.list_targets_by_rule({ rule: rule_name })
|
96
|
+
return nil if response.targets.empty?
|
97
|
+
|
98
|
+
target_input = response.targets[0].input
|
99
|
+
parsed_input = JSON.parse(target_input)
|
100
|
+
parsed_input['instance_id'] if parsed_input.key?('instance_id')
|
101
|
+
rescue Aws::CloudWatchEvents::Errors::ResourceNotFoundException => e
|
102
|
+
puts "Error fetching targets for rule: #{rule_name} - #{e.message}"
|
103
|
+
nil
|
104
|
+
end
|
105
|
+
|
106
|
+
def rule_exists?(rule_name)
|
107
|
+
begin
|
108
|
+
response = @events_client.describe_rule({ name: rule_name })
|
109
|
+
return true unless response.nil?
|
110
|
+
rescue Aws::CloudWatchEvents::Errors::ResourceNotFoundException
|
111
|
+
return false
|
112
|
+
end
|
44
113
|
end
|
45
114
|
|
46
115
|
private
|
47
116
|
|
117
|
+
def cron_expression_hash(cron_expression)
|
118
|
+
Digest::SHA256.hexdigest(cron_expression)[0..7]
|
119
|
+
end
|
120
|
+
|
48
121
|
def create_rule(rule_name, cron_expression, input_data, action)
|
49
122
|
@events_client.put_rule({
|
50
123
|
name: rule_name,
|
@@ -85,7 +158,7 @@ class CloudWatchEventManager
|
|
85
158
|
end
|
86
159
|
end
|
87
160
|
|
88
|
-
def
|
161
|
+
def remove_rule_by_name(rule_name)
|
89
162
|
@events_client.remove_targets({
|
90
163
|
rule: rule_name,
|
91
164
|
ids: ['1']
|
@@ -94,7 +167,7 @@ class CloudWatchEventManager
|
|
94
167
|
name: rule_name
|
95
168
|
})
|
96
169
|
|
97
|
-
puts "Removed rule '#{rule_name}'
|
170
|
+
puts "Removed rule '#{rule_name}'"
|
98
171
|
end
|
99
172
|
|
100
173
|
def remove_lambda_permission(rule_name)
|
@@ -108,4 +181,52 @@ class CloudWatchEventManager
|
|
108
181
|
puts "Permission not found: #{e.message}"
|
109
182
|
end
|
110
183
|
end
|
184
|
+
|
185
|
+
def print_header(column_widths)
|
186
|
+
total_width = column_widths.values.sum + 8
|
187
|
+
puts "-" * total_width
|
188
|
+
puts "| #{'Rule Name'.ljust(column_widths[:rule_name])} | " \
|
189
|
+
"#{ 'Instance ID'.ljust(column_widths[:instance_id])} | " \
|
190
|
+
"#{ 'Schedule (UTC)'.ljust(column_widths[:schedule])} | " \
|
191
|
+
"#{ 'State'.ljust(column_widths[:state])} | " \
|
192
|
+
"#{ 'Action'.ljust(column_widths[:action])} |"
|
193
|
+
puts "-" * total_width
|
194
|
+
end
|
195
|
+
|
196
|
+
def print_footer(column_widths)
|
197
|
+
total_width = column_widths.values.sum + 8
|
198
|
+
puts '-' * total_width
|
199
|
+
end
|
200
|
+
|
201
|
+
def process_rule(rule, options, column_widths)
|
202
|
+
targets = @events_client.list_targets_by_rule(rule: rule.name).targets
|
203
|
+
target = targets.find { |t| t.arn == @lambda_function_arn }
|
204
|
+
|
205
|
+
return unless target
|
206
|
+
|
207
|
+
input = JSON.parse(target.input)
|
208
|
+
action = input['action']
|
209
|
+
rule_instance_id = input['instance_id']
|
210
|
+
|
211
|
+
if matches_criteria?(rule_instance_id, action, options)
|
212
|
+
print_rule(rule, rule_instance_id, action, column_widths)
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def matches_criteria?(rule_instance_id, action, options)
|
217
|
+
instance_id_match = options[:instance_id].nil? || options[:instance_id] == rule_instance_id
|
218
|
+
action_match = (options[:start_instance] && action == 'start') ||
|
219
|
+
(options[:stop_instance] && action == 'stop') ||
|
220
|
+
(options[:start_instance].nil? && options[:stop_instance].nil?)
|
221
|
+
|
222
|
+
instance_id_match && action_match
|
223
|
+
end
|
224
|
+
|
225
|
+
def print_rule(rule, rule_instance_id, action, column_widths)
|
226
|
+
puts "| #{rule.name.ljust(column_widths[:rule_name])} | " \
|
227
|
+
"#{rule_instance_id.ljust(column_widths[:instance_id])} | " \
|
228
|
+
"#{rule.schedule_expression.ljust(column_widths[:schedule])} | " \
|
229
|
+
"#{rule.state.ljust(column_widths[:state])} | " \
|
230
|
+
"#{action.capitalize.ljust(column_widths[:action])} |"
|
231
|
+
end
|
111
232
|
end
|
@@ -4,10 +4,8 @@ require 'json'
|
|
4
4
|
require_relative 'cloud_watch_event_manager' # Adjust the path to where the new class is located
|
5
5
|
|
6
6
|
class EC2Manager
|
7
|
-
def initialize(instance_name
|
7
|
+
def initialize(instance_name = nil)
|
8
8
|
@instance_name = instance_name
|
9
|
-
@start_cron = start_cron
|
10
|
-
@stop_cron = stop_cron
|
11
9
|
@aws_region = ENV['AWS_REGION']
|
12
10
|
@account_id = ENV['ACCOUNT_ID']
|
13
11
|
|
@@ -16,11 +14,13 @@ class EC2Manager
|
|
16
14
|
|
17
15
|
@lambda_function_name = "ec2_auto_shutdown_start_function"
|
18
16
|
@lambda_function_arn = construct_lambda_function_arn
|
19
|
-
@instance_id = get_instance_id_by_name
|
17
|
+
@instance_id = get_instance_id_by_name unless @instance_name.nil?
|
20
18
|
|
21
19
|
@cloudwatch_event_manager = CloudWatchEventManager.new(@events_client, @instance_id, @instance_name, @lambda_function_arn)
|
22
20
|
end
|
23
21
|
|
22
|
+
attr_writer :instance_name, :instance_id
|
23
|
+
|
24
24
|
def get_instance_id_by_name
|
25
25
|
response = @ec2_client.describe_instances({
|
26
26
|
filters: [
|
@@ -39,16 +39,58 @@ class EC2Manager
|
|
39
39
|
instance_id
|
40
40
|
end
|
41
41
|
|
42
|
-
def create_event_rule
|
43
|
-
@cloudwatch_event_manager.create_start_rule(
|
44
|
-
@cloudwatch_event_manager.create_stop_rule(
|
42
|
+
def create_event_rule(start_cron, stop_cron)
|
43
|
+
@cloudwatch_event_manager.create_start_rule(start_cron) unless start_cron.nil?
|
44
|
+
@cloudwatch_event_manager.create_stop_rule(stop_cron) unless stop_cron.nil?
|
45
45
|
puts "CloudWatch Events created for instance '#{@instance_name}' (ID: #{@instance_id})."
|
46
46
|
end
|
47
47
|
|
48
|
-
def remove_event_rule
|
49
|
-
@cloudwatch_event_manager.
|
50
|
-
|
51
|
-
|
48
|
+
def remove_event_rule(rule_name)
|
49
|
+
@cloudwatch_event_manager.remove_rule(rule_name)
|
50
|
+
puts "CloudWatch Events removed for rule: #{rule_name}."
|
51
|
+
end
|
52
|
+
|
53
|
+
def list_event_rules(options)
|
54
|
+
options[:instance_id] = @instance_id unless @instance_id.nil?
|
55
|
+
@cloudwatch_event_manager.list_event_rules(options)
|
56
|
+
end
|
57
|
+
|
58
|
+
def update_event_rule(rule_name:, start_cron:, stop_cron:, state:)
|
59
|
+
rule_exists = @cloudwatch_event_manager.rule_exists?(rule_name)
|
60
|
+
|
61
|
+
unless rule_exists
|
62
|
+
puts "Rule '#{rule_name}' does not exist."
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
|
66
|
+
target_instance_id = @cloudwatch_event_manager.get_instance_id_from_rule(rule_name)
|
67
|
+
if target_instance_id.nil?
|
68
|
+
puts "No targets found for the rule '#{rule_name}'."
|
69
|
+
exit 1
|
70
|
+
end
|
71
|
+
|
72
|
+
instance_name = get_instance_name_by_id(target_instance_id)
|
73
|
+
|
74
|
+
@cloudwatch_event_manager.instance_id = target_instance_id
|
75
|
+
@cloudwatch_event_manager.instance_name = instance_name
|
76
|
+
|
77
|
+
self.instance_id = target_instance_id
|
78
|
+
self.instance_name = instance_name
|
79
|
+
|
80
|
+
puts "Found instance ID: #{@instance_id} from the rule: #{rule_name}"
|
81
|
+
|
82
|
+
if start_cron || stop_cron
|
83
|
+
puts "Removing old rule: #{rule_name} as cron expression is being updated."
|
84
|
+
remove_event_rule(rule_name)
|
85
|
+
|
86
|
+
create_event_rule(start_cron, stop_cron)
|
87
|
+
puts "Created new rule with updated cron expression for instance '#{@instance_name}' (ID: #{@instance_id})."
|
88
|
+
end
|
89
|
+
|
90
|
+
return if state.nil?
|
91
|
+
|
92
|
+
@cloudwatch_event_manager.update_rule_state(rule_name, state)
|
93
|
+
puts "Rule '#{rule_name}' has been #{state == 'enable' ? 'enabled' : 'disabled'}."
|
52
94
|
end
|
53
95
|
|
54
96
|
private
|
@@ -56,4 +98,21 @@ class EC2Manager
|
|
56
98
|
def construct_lambda_function_arn
|
57
99
|
"arn:aws:lambda:#{@aws_region}:#{@account_id}:function:#{@lambda_function_name}"
|
58
100
|
end
|
101
|
+
|
102
|
+
def get_instance_name_by_id(instance_id)
|
103
|
+
response = @ec2_client.describe_instances({
|
104
|
+
instance_ids: [instance_id]
|
105
|
+
})
|
106
|
+
|
107
|
+
if response.reservations.empty?
|
108
|
+
puts "No instance found with ID '#{instance_id}'."
|
109
|
+
return nil
|
110
|
+
end
|
111
|
+
|
112
|
+
instance = response.reservations[0].instances[0]
|
113
|
+
tags = instance.tags || []
|
114
|
+
|
115
|
+
name_tag = tags.find { |tag| tag.key == 'Name' }
|
116
|
+
name_tag&.value
|
117
|
+
end
|
59
118
|
end
|
data/lib/hibernate/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hibernate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Manish Sharma
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-ec2
|