aws-sdk-utils 0.0.5 → 0.0.6

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
2
  SHA1:
3
- metadata.gz: cd63040fe954adff72101373ea6976cf5344a14a
4
- data.tar.gz: 58dc77c2acf00dd5a5751998666b7f147ab5dd1e
3
+ metadata.gz: dcde772fb63322ea4c57c8f4578898dc05e2aa8a
4
+ data.tar.gz: ec27fb8da8367e39837598da893fad40be6cc959
5
5
  SHA512:
6
- metadata.gz: 8b6c27bece1ac6dd0803699e83983e6b9e2006e2509f6c170f10eff6f9b07e077d9e8a6370f0fee0169c699433fae178a3390e9c2d113ff7623873ce8dcb84e1
7
- data.tar.gz: 652018550f25932a05c904907be5977f070c9c5dd0a66abb1866f872f6afbdbaa94e5b7a93faaabdd5a2cc89f6ddbf1ae13f2cfc42f39524e2637efcc31b2226
6
+ metadata.gz: 93204c776fc345624600d8fc18147f3d0307fb7abb72ecb1f9ecb9724240366c9e8457c669f4997da7e4428c7aa178a1369f18f6a39813db450a0b15fd2624c4
7
+ data.tar.gz: f61f02e3d0a141c1de16c1a797cfd28292b3978a9bc7bcad6ef20c48dedb86258adeaf04541abef977b4f697c96bfd6340f55978c05f0f19d1e07dd112528a93
data/bin/cfndsl_converge CHANGED
@@ -7,12 +7,14 @@ opts = Trollop::options do
7
7
  opt :path_to_stack, '', type: :string, required: true
8
8
  opt :stack_name, '', type: :string, required: true
9
9
  opt :path_to_yaml, '', type: :string, required: false
10
+ opt :fail_on_changes_to_immutable_resource, '', type: :boolean, default: false, required: false
10
11
  end
11
12
 
12
13
  bindings = opts[:path_to_yaml].nil? ? nil : YAML.load_file(opts[:path_to_yaml])
13
14
 
14
15
  outputs = CfndslConverger.new.converge(stack_name: opts[:stack_name],
15
16
  path_to_stack: opts[:path_to_stack],
16
- bindings: bindings)
17
+ bindings: bindings,
18
+ fail_on_changes_to_immutable_resource: opts[:fail_on_changes_to_immutable_resource])
17
19
 
18
20
  puts outputs.to_yaml
data/lib/aws-sdk-utils.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  require_relative 'cloudformation_converger'
2
2
  require_relative 'lambda_alias_switcher'
3
- require_relative 'waf_util'
3
+ require_relative 'waf_util'
4
+ require_relative 'cfndsl_converger'
@@ -1,6 +1,7 @@
1
1
  require 'aws-sdk'
2
2
  require 'cfndsl'
3
3
  require 'tempfile'
4
+ require 'changeset_util'
4
5
 
5
6
  class CfndslConverger
6
7
 
@@ -18,7 +19,8 @@ class CfndslConverger
18
19
 
19
20
  def converge(stack_name:,
20
21
  path_to_stack:,
21
- bindings: nil)
22
+ bindings: nil,
23
+ fail_on_changes_to_immutable_resource: false)
22
24
  extras = []
23
25
  unless bindings.nil?
24
26
  temp_file = Tempfile.new('cfnstackfortesting')
@@ -33,8 +35,19 @@ class CfndslConverger
33
35
  extras,
34
36
  verbose)
35
37
 
36
- outputs = converge_stack stack_name: stack_name,
37
- stack_body: model.to_json
38
+ if fail_on_changes_to_immutable_resource
39
+ unsafe_logical_resource_id = ChangesetUtil.new.immutable_resources_that_would_change stack_name: stack_name,
40
+ template_body: model.to_json
41
+ if unsafe_logical_resource_id.nil?
42
+ outputs = converge_stack stack_name: stack_name,
43
+ stack_body: model.to_json
44
+ else
45
+ raise "update would modify or delete immutable resource #{unsafe_logical_resource_id}"
46
+ end
47
+ else
48
+ outputs = converge_stack stack_name: stack_name,
49
+ stack_body: model.to_json
50
+ end
38
51
  outputs
39
52
  end
40
53
 
@@ -0,0 +1,76 @@
1
+ require_relative 'cloudformation_tag_parser'
2
+ require 'aws-sdk'
3
+
4
+ class ChangesetUtil
5
+
6
+ def immutable_resources_that_would_change(stack_name:,
7
+ template_body:)
8
+
9
+ potentially_unsafe_changes = changes_that_modify_or_remove stack_name: stack_name,
10
+ template_body: template_body
11
+
12
+ logical_resource_ids = potentially_unsafe_changes.map { |change| change.resource_change.logical_resource_id }
13
+
14
+ logical_resource_ids.each do |logical_resource_id|
15
+ tags = CloudFormationTagParser.new.tags cloudformation_json: template_body,
16
+ logical_resource_id: logical_resource_id
17
+ if tags.find { |tag| tag['Key'] == 'immutable' and tag['Value'] == 'true' }
18
+ return logical_resource_id
19
+ end
20
+ end
21
+ nil
22
+ end
23
+
24
+
25
+ ##
26
+ # hmmmm how to handle parameters? if it uses the previous value...?
27
+ #
28
+ def changes_that_modify_or_remove(stack_name:,
29
+ template_body:,
30
+ parameters: [])
31
+
32
+ change_set_name = "changeSet#{Time.now.to_i}"
33
+ client_token = "clientToken#{Time.now.to_i}"
34
+
35
+ create_change_set_response = cloudformation_client.create_change_set stack_name: stack_name,
36
+ template_body: template_body,
37
+ capabilities: %w(CAPABILITY_IAM),
38
+ change_set_name: change_set_name,
39
+ client_token: client_token,
40
+ parameters: convert_parameters(parameters)
41
+
42
+ change_set_id = create_change_set_response.id
43
+
44
+ describe_change_set_response = describe_change_set change_set_id: change_set_id
45
+
46
+ describe_change_set_response.changes.select { |change| %w(Modify Remove).include? change.resource_change.action }
47
+ end
48
+
49
+ private
50
+
51
+ def describe_change_set(change_set_id:)
52
+ done = false
53
+ while not done
54
+ describe_change_set_response = cloudformation_client.describe_change_set change_set_name: change_set_id
55
+ done = %w(CREATE_COMPLETE FAILED).include?(describe_change_set_response.status)
56
+ sleep 10 unless done
57
+ end
58
+ describe_change_set_response
59
+ end
60
+
61
+ def cloudformation_client
62
+ Aws::CloudFormation::Client.new
63
+ end
64
+
65
+ def convert_parameters(parameters)
66
+ result = []
67
+ parameters.each do |key, value|
68
+ result << {
69
+ parameter_key: key,
70
+ parameter_value: value,
71
+ use_previous_value: false
72
+ }
73
+ end
74
+ result
75
+ end
76
+ end
@@ -0,0 +1,22 @@
1
+ require 'json'
2
+
3
+ class CloudFormationTagParser
4
+
5
+ def tags(cloudformation_json:,
6
+ logical_resource_id:)
7
+
8
+ cloudformation = JSON.load(cloudformation_json)
9
+ if cloudformation['Resources'].nil?
10
+ raise 'malformed json, must have Resources key at least'
11
+ end
12
+
13
+ resource = cloudformation['Resources'][logical_resource_id]
14
+ if resource.nil?
15
+ raise "logical resource id #{logical_resource_id} is not found"
16
+ end
17
+
18
+ # Properties isn't there is a blow error, but jsut ignore that... need a better all-round parser for cfn in the first place
19
+ tags = resource['Properties']['Tags']
20
+ tags.nil? ? [] : tags
21
+ end
22
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aws-sdk-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - someguy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-22 00:00:00.000000000 Z
11
+ date: 2016-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 2.2.17
19
+ version: 2.2.31
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 2.2.17
26
+ version: 2.2.31
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: cfndsl
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -64,7 +64,9 @@ files:
64
64
  - bin/yaml_get
65
65
  - lib/aws-sdk-utils.rb
66
66
  - lib/cfndsl_converger.rb
67
+ - lib/changeset_util.rb
67
68
  - lib/cloudformation_converger.rb
69
+ - lib/cloudformation_tag_parser.rb
68
70
  - lib/lambda_alias_switcher.rb
69
71
  - lib/waf_util.rb
70
72
  homepage: https://github.com/stelligent/aws-sdk-utils