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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 4fa355433ba85a929315e560ceb2eb5c0d933093d7d53243bee7cb0f950ad23f
4
- data.tar.gz: 055db78da9179b184cddb7f9ad127892c9a3e7ab667c8166f7ef1257d5cee9d6
2
+ SHA1:
3
+ metadata.gz: 13212e4e880e6d908c22fcc1f173037533cbd3a7
4
+ data.tar.gz: 8866a2e5a070e3a72ddd43888e3d217c8c4d145d
5
5
  SHA512:
6
- metadata.gz: 73c1c4d092f6d66c5a07da6faf71b7915f1b52d6d68cd274fc9797d7227f1f13028c94134681c4738052b5ec2f2daa3360880ff1a9aaa56914d30802e7dfc048
7
- data.tar.gz: e9504f28cf57a390f450bfabd71939e38e96dfbabb7da1461cc5a2c46eac054afcb89853294413fdddfdb7bf35d0341f717a9c1dc4eff9238da5207d652b6057
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 yet...")
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.3.1
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: '1'
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: '1'
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.7.6
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