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 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