cfn_manage 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/bin/cfn_manage.rb +11 -2
- data/bin/usage.txt +4 -1
- data/lib/aurora_cluster_start_stop_handler.rb +89 -0
- data/lib/cf_start_stop_environment.rb +5 -0
- data/lib/rds_start_stop_handler.rb +9 -2
- data/lib/start_stop_handler_factory.rb +5 -1
- metadata +7 -7
- data/lib/dynamodb_start_stop_handler.rb +0 -53
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 13212e4e880e6d908c22fcc1f173037533cbd3a7
|
4
|
+
data.tar.gz: 8866a2e5a070e3a72ddd43888e3d217c8c4d145d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aaca5c44073d61fdb8e6583038e221cc9ba49bfa2353ada7f8f235ff1fe244b5ca91315cc29cf9ee545194a7ce02faef6a1b9ec9068b72fb44466a9ae9e4775a
|
7
|
+
data.tar.gz: 8bb07d3fd3e24f7fbd56acbe01445853b03522ab1926ed4c71cf9bee9c66309867f08860759cbdab433ad417ac057fdf7fdbb2c028c81fd128ea29f3c25b6948
|
data/bin/cfn_manage.rb
CHANGED
@@ -46,6 +46,10 @@ OptionParser.new do |opts|
|
|
46
46
|
$options['RDS_INSTANCE_ID'] = asg
|
47
47
|
end
|
48
48
|
|
49
|
+
opts.on('--aurora-cluster-id [AURORA_CLUSTER_ID]') do |asg|
|
50
|
+
$options['AURORA_CLUSTER_ID'] = asg
|
51
|
+
end
|
52
|
+
|
49
53
|
opts.on('--stack-name [STACK_NAME]') do |asg|
|
50
54
|
$options['STACK_NAME'] = asg
|
51
55
|
end
|
@@ -90,10 +94,15 @@ case command
|
|
90
94
|
when 'start-rds'
|
91
95
|
Base2::CloudFormation::EnvironmentRunStop.new().start_stop_rds('start', $options['RDS_INSTANCE_ID'])
|
92
96
|
|
97
|
+
# aurora cluster commands
|
98
|
+
when 'stop-aurora-cluster'
|
99
|
+
Base2::CloudFormation::EnvironmentRunStop.new().start_stop_aurora_cluster('stop', $options['AURORA_CLUSTER_ID'])
|
100
|
+
when 'start-aurora-cluster'
|
101
|
+
Base2::CloudFormation::EnvironmentRunStop.new().start_stop_aurora_cluster('start', $options['AURORA_CLUSTER_ID'])
|
102
|
+
|
93
103
|
# stack commands
|
94
|
-
# rds commands
|
95
104
|
when 'stop-environment'
|
96
105
|
Base2::CloudFormation::EnvironmentRunStop.new().stop_environment($options['STACK_NAME'])
|
97
106
|
when 'start-environment'
|
98
107
|
Base2::CloudFormation::EnvironmentRunStop.new().start_environment($options['STACK_NAME'])
|
99
|
-
end
|
108
|
+
end
|
data/bin/usage.txt
CHANGED
@@ -14,6 +14,9 @@ cfn_manage stop-rds --rds-instance-id [RDS_INSTANCE_ID]
|
|
14
14
|
|
15
15
|
cfn_manage start-rds --rds-instance-id [RDS_INSTANCE_ID]
|
16
16
|
|
17
|
+
cfn_manage stop-aurora-cluster --aurora-cluster-id [AURORA_CLUSTER_ID]
|
18
|
+
|
19
|
+
cfn_manage start-aurora-cluster --aurora-cluster-id [AURORA_CLUSTER_ID]
|
17
20
|
|
18
21
|
General options
|
19
22
|
|
@@ -46,4 +49,4 @@ General options
|
|
46
49
|
Applicable only to [start|stop-environment] commands. If there is problem with stopping a resource,
|
47
50
|
(e.g. cloudformation stack not being synced or manual resource deletion) script will continue it's
|
48
51
|
operation. By defult script stops when there is problem with starting/stopping resource, and expects
|
49
|
-
manual intervention to fix the root cause for failure.
|
52
|
+
manual intervention to fix the root cause for failure.
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require_relative '../lib/aws_credentials'
|
2
|
+
|
3
|
+
module Base2
|
4
|
+
|
5
|
+
class AuroraClusterStartStopHandler
|
6
|
+
|
7
|
+
def initialize(cluster_id)
|
8
|
+
@cluster_id = cluster_id
|
9
|
+
|
10
|
+
credentials = Base2::AWSCredentials.get_session_credentials("startstopcluster_#{cluster_id}")
|
11
|
+
@rds_client = Aws::RDS::Client.new(retry_limit: 20)
|
12
|
+
if credentials != nil
|
13
|
+
@rds_client = Aws::RDS::Client.new(credentials: credentials, retry_limit: 20)
|
14
|
+
end
|
15
|
+
rds = Aws::RDS::Resource.new(client: @rds_client)
|
16
|
+
@rds_cluster = rds.db_cluster(cluster_id)
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
def start(configuration)
|
21
|
+
if @rds_cluster.status == 'available'
|
22
|
+
$log.info("Aurora Cluster #{@cluster_id} is already in available state")
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
# start rds cluster
|
27
|
+
if @rds_cluster.status == 'stopped'
|
28
|
+
$log.info("Starting Aurora cluster #{@cluster_id}")
|
29
|
+
@rds_client.start_db_cluster({ db_cluster_identifier: @cluster_id })
|
30
|
+
|
31
|
+
# wait cluster to become available
|
32
|
+
$log.info("Waiting Aurora cluster to become available #{@cluster_id}")
|
33
|
+
wait_rds_cluster_states( %w(starting available))
|
34
|
+
else
|
35
|
+
$log.info("Aurora Cluster #{@cluster_id} is not in a stopped state. State: #{@rds_cluster.status}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def stop
|
40
|
+
if @rds_cluster.status == 'stopped'
|
41
|
+
$log.info("Aurora Cluster #{@cluster_id} is already stopped")
|
42
|
+
return {}
|
43
|
+
end
|
44
|
+
|
45
|
+
if @rds_cluster.status != 'available'
|
46
|
+
$log.info("Aurora Cluster #{@cluster_id} is not in a available state. State: #{@rds_cluster.status}")
|
47
|
+
return {}
|
48
|
+
end
|
49
|
+
|
50
|
+
# stop rds cluster and wait for it to be fully stopped
|
51
|
+
$log.info("Stopping aurora cluster #{@cluster_id}")
|
52
|
+
@rds_client.stop_db_cluster({ db_cluster_identifier: @cluster_id })
|
53
|
+
$log.info("Waiting aurora cluster to be stopped #{@cluster_id}")
|
54
|
+
wait_rds_cluster_states(%w(stopping stopped))
|
55
|
+
|
56
|
+
return {}
|
57
|
+
end
|
58
|
+
|
59
|
+
def wait_rds_cluster_states(wait_states=[])
|
60
|
+
wait_states.each do |state|
|
61
|
+
# reached state must be steady, at least a minute.
|
62
|
+
state_count = 0
|
63
|
+
steady_count = 4
|
64
|
+
attempts = 0
|
65
|
+
rds = Aws::RDS::Resource.new(client: @rds_client)
|
66
|
+
until attempts == (max_attempts = 60*6) do
|
67
|
+
cluster = rds.db_cluster(@cluster_id)
|
68
|
+
$log.info("Aurora Cluster #{cluster.db_cluster_identifier} state: #{cluster.status}, waiting for #{state}")
|
69
|
+
|
70
|
+
if cluster.status == "#{state}"
|
71
|
+
state_count = state_count + 1
|
72
|
+
$log.info("#{state_count}/#{steady_count}")
|
73
|
+
else
|
74
|
+
state_count = 0
|
75
|
+
end
|
76
|
+
break if state_count == steady_count
|
77
|
+
attempts = attempts + 1
|
78
|
+
sleep(15)
|
79
|
+
end
|
80
|
+
|
81
|
+
if attempts == max_attempts
|
82
|
+
$log.error("RDS Aurora Cluster #{@cluster_id} did not enter #{state} state, however continuing operations...")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
@@ -25,6 +25,7 @@ module Base2
|
|
25
25
|
|
26
26
|
@@resource_start_priorities = {
|
27
27
|
'AWS::RDS::DBInstance' => '100',
|
28
|
+
'AWS::RDS::DBCluster' => '100',
|
28
29
|
'AWS::AutoScaling::AutoScalingGroup' => '200',
|
29
30
|
'AWS::EC2::Instance' => '200',
|
30
31
|
'AWS::EC2::SpotFleet' => '200',
|
@@ -42,6 +43,10 @@ module Base2
|
|
42
43
|
end
|
43
44
|
@dry_run = (ENV.key?('DRY_RUN') and ENV['DRY_RUN'] == '1')
|
44
45
|
@continue_on_error = (ENV.key? 'CFN_CONTINUE_ON_ERROR' and ENV['CFN_CONTINUE_ON_ERROR'] == '1')
|
46
|
+
rescue NoMethodError => e
|
47
|
+
puts "Got No Method Error on CloudFormation::initialize, this often means that you're missing a AWS_DEFAULT_REGION"
|
48
|
+
rescue Aws::Sigv4::Errors::MissingCredentialsError => e
|
49
|
+
puts "Got Missing Credentials Error on CloudFormation::initialize, this often means that AWS_PROFILE is unset, or no default credentials were provided."
|
45
50
|
end
|
46
51
|
|
47
52
|
|
@@ -18,6 +18,13 @@ module Base2
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def start(configuration)
|
21
|
+
# RDS list of exluded engines that don't support RDS stop start
|
22
|
+
excluded_engines = %w(aurora aurora-mysql aurora-postgresql)
|
23
|
+
if excluded_engines.include? @rds_instance.engine
|
24
|
+
$log.info("RDS Instance #{@instance_id} engine is #{@rds_instance.engine} and cannot be started by instance.")
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
21
28
|
if @rds_instance.db_instance_status == 'available'
|
22
29
|
$log.info("RDS Instance #{@instance_id} is already in available state")
|
23
30
|
end
|
@@ -47,9 +54,9 @@ module Base2
|
|
47
54
|
is_multi_az: @rds_instance.multi_az
|
48
55
|
}
|
49
56
|
# RDS list of exluded engines that don't support RDS stop start
|
50
|
-
excluded_engines = %w(aurora aurora-mysql)
|
57
|
+
excluded_engines = %w(aurora aurora-mysql aurora-postgresql)
|
51
58
|
if excluded_engines.include? @rds_instance.engine
|
52
|
-
$log.info("RDS Instance #{@instance_id} engine is #{@rds_instance.engine} and cannot be stoped
|
59
|
+
$log.info("RDS Instance #{@instance_id} engine is #{@rds_instance.engine} and cannot be stoped by instance.")
|
53
60
|
return configuration
|
54
61
|
end
|
55
62
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative '../lib/asg_start_stop_handler'
|
2
2
|
require_relative '../lib/ec2_start_stop_handler'
|
3
3
|
require_relative '../lib/rds_start_stop_handler'
|
4
|
+
require_relative '../lib/aurora_cluster_start_stop_handler'
|
4
5
|
require_relative '../lib/alarm_start_stop_handler'
|
5
6
|
require_relative '../lib/spot_fleet_start_stop_handler'
|
6
7
|
|
@@ -22,6 +23,9 @@ module Base2
|
|
22
23
|
when 'AWS::RDS::DBInstance'
|
23
24
|
return Base2::RdsStartStopHandler.new(resource_id)
|
24
25
|
|
26
|
+
when 'AWS::RDS::DBCluster'
|
27
|
+
return Base2::AuroraClusterStartStopHandler.new(resource_id)
|
28
|
+
|
25
29
|
when 'AWS::CloudWatch::Alarm'
|
26
30
|
return Base2::AlarmStartStopHandler.new(resource_id)
|
27
31
|
|
@@ -32,4 +36,4 @@ module Base2
|
|
32
36
|
end
|
33
37
|
end
|
34
38
|
end
|
35
|
-
end
|
39
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cfn_manage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Base2Services
|
@@ -95,9 +95,9 @@ dependencies:
|
|
95
95
|
name: aws-sdk-rds
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
97
97
|
requirements:
|
98
|
-
- - "
|
98
|
+
- - ">="
|
99
99
|
- !ruby/object:Gem::Version
|
100
|
-
version:
|
100
|
+
version: 1.31.0
|
101
101
|
- - "<"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '2'
|
@@ -105,9 +105,9 @@ dependencies:
|
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
110
|
+
version: 1.31.0
|
111
111
|
- - "<"
|
112
112
|
- !ruby/object:Gem::Version
|
113
113
|
version: '2'
|
@@ -183,11 +183,11 @@ files:
|
|
183
183
|
- bin/usage.txt
|
184
184
|
- lib/alarm_start_stop_handler.rb
|
185
185
|
- lib/asg_start_stop_handler.rb
|
186
|
+
- lib/aurora_cluster_start_stop_handler.rb
|
186
187
|
- lib/aws_credentials.rb
|
187
188
|
- lib/cf_common.rb
|
188
189
|
- lib/cf_progress_tracker.rb
|
189
190
|
- lib/cf_start_stop_environment.rb
|
190
|
-
- lib/dynamodb_start_stop_handler.rb
|
191
191
|
- lib/ec2_start_stop_handler.rb
|
192
192
|
- lib/rds_start_stop_handler.rb
|
193
193
|
- lib/spot_fleet_start_stop_handler.rb
|
@@ -212,7 +212,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
212
212
|
version: '0'
|
213
213
|
requirements: []
|
214
214
|
rubyforge_project:
|
215
|
-
rubygems_version: 2.
|
215
|
+
rubygems_version: 2.6.13
|
216
216
|
signing_key:
|
217
217
|
specification_version: 4
|
218
218
|
summary: Manage AWS Cloud Formation stacks
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require_relative '../lib/aws_credentials'
|
2
|
-
|
3
|
-
module Base2
|
4
|
-
|
5
|
-
class DynamoDbStartStopHandler
|
6
|
-
|
7
|
-
@table
|
8
|
-
@table_name
|
9
|
-
@gsi_names
|
10
|
-
|
11
|
-
def initialize(table_name)
|
12
|
-
credentials = Base2::AWSCredentials.get_session_credentials("stoprun_#{instance_id}")
|
13
|
-
ec2_client = Aws::DynamoDB::Client.new(credentials: credentials)
|
14
|
-
@table = Aws::DynamoDB::Resource.new(client: ec2_client).table(table_name)
|
15
|
-
@table_name = table_name
|
16
|
-
@table.global_secondary_indexes.each do |gsi|
|
17
|
-
@gsi_names << gsi.index_name
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def start(configuration)
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
def stop
|
26
|
-
configuration = {
|
27
|
-
read_capacity: @table.provisioned_throughput.read_capacity_units,
|
28
|
-
write_capacity: @table.provisioned_throughput.write_capacity_units
|
29
|
-
}
|
30
|
-
|
31
|
-
$log.info("Current dynamo table #{@table.name} capacity: #{configuration}")
|
32
|
-
|
33
|
-
# check if environment vairable set for
|
34
|
-
if ENV.key? ('cfn_manage_dynamodb_stop_capacity')
|
35
|
-
stop_capacity = ENV['cfn_manage_dynamodb_stop_capacity'].to_i
|
36
|
-
|
37
|
-
$log.info("Downsizing read/write capacity to #{stop_capacity}")
|
38
|
-
@table.update({
|
39
|
-
provisioned_throughput: {
|
40
|
-
read_capacity_units: stop_capacity, # required
|
41
|
-
write_capacity_units: stop_capacity, # required
|
42
|
-
}
|
43
|
-
})
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
configuration
|
49
|
-
end
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
end
|