cfn_manage 0.3.1 → 0.4.0
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 +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
|