aws-sdk-utils 0.0.5 → 0.0.6
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 +4 -4
- data/bin/cfndsl_converge +3 -1
- data/lib/aws-sdk-utils.rb +2 -1
- data/lib/cfndsl_converger.rb +16 -3
- data/lib/changeset_util.rb +76 -0
- data/lib/cloudformation_tag_parser.rb +22 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dcde772fb63322ea4c57c8f4578898dc05e2aa8a
|
4
|
+
data.tar.gz: ec27fb8da8367e39837598da893fad40be6cc959
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/lib/cfndsl_converger.rb
CHANGED
@@ -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
|
-
|
37
|
-
|
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.
|
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-
|
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.
|
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.
|
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
|