stack_master 0.6.0 → 0.7.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 +4 -4
- data/README.md +22 -0
- data/features/apply.feature +1 -1
- data/features/apply_with_s3.feature +106 -0
- data/features/step_definitions/stack_steps.rb +5 -0
- data/features/support/env.rb +1 -0
- data/lib/stack_master.rb +78 -58
- data/lib/stack_master/aws_driver/s3.rb +66 -0
- data/lib/stack_master/cli.rb +1 -0
- data/lib/stack_master/commands/apply.rb +52 -5
- data/lib/stack_master/commands/init.rb +2 -0
- data/lib/stack_master/commands/list_stacks.rb +2 -0
- data/lib/stack_master/commands/outputs.rb +2 -0
- data/lib/stack_master/commands/status.rb +3 -0
- data/lib/stack_master/parameter_resolver.rb +1 -1
- data/lib/stack_master/parameter_resolvers/secret.rb +2 -0
- data/lib/stack_master/stack.rb +20 -13
- data/lib/stack_master/stack_definition.rb +63 -13
- data/lib/stack_master/stack_differ.rb +2 -0
- data/lib/stack_master/stack_events/fetcher.rb +1 -1
- data/lib/stack_master/stack_events/presenter.rb +1 -1
- data/lib/stack_master/stack_events/streamer.rb +1 -1
- data/lib/stack_master/template_compiler.rb +3 -1
- data/lib/stack_master/template_compilers/cfndsl.rb +4 -2
- data/lib/stack_master/template_compilers/json.rb +4 -0
- data/lib/stack_master/template_compilers/sparkle_formation.rb +5 -0
- data/lib/stack_master/template_compilers/yaml.rb +4 -0
- data/lib/stack_master/test_driver/cloud_formation.rb +50 -36
- data/lib/stack_master/test_driver/s3.rb +34 -0
- data/lib/stack_master/testing.rb +1 -0
- data/lib/stack_master/utils.rb +19 -0
- data/lib/stack_master/version.rb +1 -1
- data/spec/fixtures/stack_master.yml +4 -1
- data/spec/stack_master/aws_driver/s3_spec.rb +130 -0
- data/spec/stack_master/commands/apply_spec.rb +26 -0
- data/spec/stack_master/config_spec.rb +8 -1
- data/spec/stack_master/parameter_resolver_spec.rb +5 -0
- data/spec/stack_master/sparkle_formation/user_data_file_spec.rb +2 -0
- data/spec/stack_master/stack_events/presenter_spec.rb +1 -1
- data/spec/stack_master/stack_spec.rb +23 -5
- data/spec/stack_master/template_compiler_spec.rb +1 -0
- data/spec/stack_master/template_compilers/cfndsl_spec.rb +2 -0
- data/spec/stack_master/test_driver/s3_spec.rb +17 -0
- data/stack_master.gemspec +0 -1
- metadata +10 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24f9543391ced08e41349c5cd75aaecacce6aab2
|
4
|
+
data.tar.gz: 0130dc01c3bfacea757155caf6896aef4daaebaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 95bf919587f2d04956c97ef82caa0f9d79747b2272e1c97075549950a5d5606dbf084cfba5ef65a4e61935a4d3c11fd13c06183f02e9305f55e8f98353ded7be
|
7
|
+
data.tar.gz: d5523800109d4f3ac1a5a04a4f2f3246ad51d2014b76234c2b35c54f18e39b24a8b7fe4e5b9696682d1b299f8bf5b969961b0d49355c54381d2cc247e7cde26d
|
data/README.md
CHANGED
@@ -95,6 +95,28 @@ stacks:
|
|
95
95
|
purpose: vpc
|
96
96
|
```
|
97
97
|
|
98
|
+
## S3
|
99
|
+
|
100
|
+
StackMaster can optionally use S3 to store the templates before creating a stack.
|
101
|
+
This requires to configure an S3 bucket in stack_master.yml:
|
102
|
+
|
103
|
+
```yaml
|
104
|
+
stack_defaults:
|
105
|
+
s3:
|
106
|
+
bucket: my_bucket_name
|
107
|
+
prefix: cfn_templates/my-awesome-app
|
108
|
+
region: us-west-2
|
109
|
+
```
|
110
|
+
|
111
|
+
Additional files can be configured to be uploaded to S3 alongside the templates:
|
112
|
+
```yaml
|
113
|
+
stacks:
|
114
|
+
production:
|
115
|
+
myapp-vpc:
|
116
|
+
template: myapp_vpc.rb
|
117
|
+
files:
|
118
|
+
- userdata.sh
|
119
|
+
```
|
98
120
|
## Directories
|
99
121
|
|
100
122
|
- `templates` - CloudFormation, SparkleFormation or CfnDsl templates.
|
data/features/apply.feature
CHANGED
@@ -90,7 +90,7 @@ Feature: Apply command
|
|
90
90
|
| Parameters diff: |
|
91
91
|
| KeyName: my-key |
|
92
92
|
| aborted |
|
93
|
-
And the output should not match /2020-10-29 00:00:00 \+[0-9]{4} myapp-vpc AWS::CloudFormation::Stack CREATE_COMPLETE/
|
93
|
+
And the output should not match /2020-10-29 00:00:00 \+[0-9]{4} myapp-vpc AWS::CloudFormation::Stack CREATE_COMPLETE/
|
94
94
|
Then the exit status should be 0
|
95
95
|
|
96
96
|
Scenario: Run apply with region only and create 2 stacks
|
@@ -0,0 +1,106 @@
|
|
1
|
+
Feature: Apply command
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a file named "stack_master.yml" with:
|
5
|
+
"""
|
6
|
+
stack_defaults:
|
7
|
+
s3:
|
8
|
+
bucket: my-bucket
|
9
|
+
region: us-east-1
|
10
|
+
prefix: cfn_templates/my-app
|
11
|
+
stacks:
|
12
|
+
us_east_1:
|
13
|
+
myapp_vpc:
|
14
|
+
template: myapp_vpc.rb
|
15
|
+
files:
|
16
|
+
- user_data.sh
|
17
|
+
"""
|
18
|
+
And a directory named "parameters"
|
19
|
+
And a file named "parameters/myapp_vpc.yml" with:
|
20
|
+
"""
|
21
|
+
KeyName: my-key
|
22
|
+
"""
|
23
|
+
And a file named "parameters/myapp_web.yml" with:
|
24
|
+
"""
|
25
|
+
VpcId: vpc-blah
|
26
|
+
"""
|
27
|
+
And a directory named "templates"
|
28
|
+
And a file named "files/user_data.sh" with:
|
29
|
+
"""
|
30
|
+
#!/bin/bash
|
31
|
+
echo "HI"
|
32
|
+
"""
|
33
|
+
And a file named "templates/myapp_vpc.rb" with:
|
34
|
+
"""
|
35
|
+
SparkleFormation.new(:myapp_vpc) do
|
36
|
+
description "Test template"
|
37
|
+
set!('AWSTemplateFormatVersion', '2010-09-09')
|
38
|
+
|
39
|
+
parameters.key_name do
|
40
|
+
description 'Key name'
|
41
|
+
type 'String'
|
42
|
+
end
|
43
|
+
|
44
|
+
resources.vpc do
|
45
|
+
type 'AWS::EC2::VPC'
|
46
|
+
properties do
|
47
|
+
cidr_block '10.200.0.0/16'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
outputs do
|
52
|
+
vpc_id do
|
53
|
+
description 'A VPC ID'
|
54
|
+
value ref!(:vpc)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
"""
|
59
|
+
|
60
|
+
Scenario: Run apply and create a new stack
|
61
|
+
Given I stub the following stack events:
|
62
|
+
| stack_id | event_id | stack_name | logical_resource_id | resource_status | resource_type | timestamp |
|
63
|
+
| 1 | 1 | myapp-vpc | TestSg | CREATE_COMPLETE | AWS::EC2::SecurityGroup | 2020-10-29 00:00:00 |
|
64
|
+
| 1 | 1 | myapp-vpc | myapp-vpc | CREATE_COMPLETE | AWS::CloudFormation::Stack | 2020-10-29 00:00:00 |
|
65
|
+
When I run `stack_master apply us-east-1 myapp-vpc --trace`
|
66
|
+
And the output should contain all of these lines:
|
67
|
+
| Stack diff: |
|
68
|
+
| + "Vpc": { |
|
69
|
+
| Parameters diff: |
|
70
|
+
| KeyName: my-key |
|
71
|
+
And the output should match /2020-10-29 00:00:00 \+[0-9]{4} myapp-vpc AWS::CloudFormation::Stack CREATE_COMPLETE/
|
72
|
+
And an S3 file in bucket "my-bucket" with key "cfn_templates/my-app/myapp_vpc.json" exists with content:
|
73
|
+
"""
|
74
|
+
{
|
75
|
+
"Description": "Test template",
|
76
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
77
|
+
"Parameters": {
|
78
|
+
"KeyName": {
|
79
|
+
"Description": "Key name",
|
80
|
+
"Type": "String"
|
81
|
+
}
|
82
|
+
},
|
83
|
+
"Resources": {
|
84
|
+
"Vpc": {
|
85
|
+
"Type": "AWS::EC2::VPC",
|
86
|
+
"Properties": {
|
87
|
+
"CidrBlock": "10.200.0.0/16"
|
88
|
+
}
|
89
|
+
}
|
90
|
+
},
|
91
|
+
"Outputs": {
|
92
|
+
"VpcId": {
|
93
|
+
"Description": "A VPC ID",
|
94
|
+
"Value": {
|
95
|
+
"Ref": "Vpc"
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
}
|
100
|
+
"""
|
101
|
+
And an S3 file in bucket "my-bucket" with key "cfn_templates/my-app/user_data.sh" exists with content:
|
102
|
+
"""
|
103
|
+
#!/bin/bash
|
104
|
+
echo "HI"
|
105
|
+
"""
|
106
|
+
Then the exit status should be 0
|
@@ -64,3 +64,8 @@ end
|
|
64
64
|
Given(/^I stub CloudFormation validate calls to fail validation with message "([^"]*)"$/) do |message|
|
65
65
|
allow(StackMaster.cloud_formation_driver).to receive(:validate_template).and_raise(Aws::CloudFormation::Errors::ValidationError.new('', message))
|
66
66
|
end
|
67
|
+
|
68
|
+
When(/^an S3 file in bucket "([^"]*)" with key "([^"]*)" exists with content:$/) do |bucket, key, body|
|
69
|
+
file = StackMaster.s3_driver.find_file(bucket: bucket, object_key: key)
|
70
|
+
expect(file).to eq body
|
71
|
+
end
|
data/features/support/env.rb
CHANGED
data/lib/stack_master.rb
CHANGED
@@ -1,69 +1,82 @@
|
|
1
1
|
require "commander"
|
2
2
|
require "yaml"
|
3
|
-
require "virtus"
|
4
3
|
require "aws-sdk"
|
5
|
-
require "diffy"
|
6
4
|
require "colorize"
|
7
|
-
require "table_print"
|
8
5
|
require 'active_support/core_ext/string'
|
9
|
-
require "erb"
|
10
|
-
require 'sparkle_formation'
|
11
|
-
require 'dotgpg'
|
12
|
-
require 'ruby-progressbar'
|
13
|
-
|
14
|
-
require "stack_master/ctrl_c"
|
15
|
-
require "stack_master/sparkle_formation/user_data_file"
|
16
|
-
require "stack_master/command"
|
17
|
-
require "stack_master/version"
|
18
|
-
require "stack_master/stack"
|
19
|
-
require "stack_master/prompter"
|
20
|
-
require "stack_master/aws_driver/cloud_formation"
|
21
|
-
require "stack_master/test_driver/cloud_formation"
|
22
|
-
require "stack_master/stack_events/fetcher"
|
23
|
-
require "stack_master/stack_events/presenter"
|
24
|
-
require "stack_master/stack_events/streamer"
|
25
|
-
require "stack_master/stack_states"
|
26
|
-
require "stack_master/stack_status"
|
27
|
-
require "stack_master/sns_topic_finder"
|
28
|
-
require "stack_master/security_group_finder"
|
29
|
-
require "stack_master/parameter_loader"
|
30
|
-
require "stack_master/parameter_resolver"
|
31
|
-
require "stack_master/resolver_array"
|
32
|
-
require "stack_master/parameter_resolvers/ami_finder"
|
33
|
-
require "stack_master/parameter_resolvers/stack_output"
|
34
|
-
require "stack_master/parameter_resolvers/secret"
|
35
|
-
require "stack_master/parameter_resolvers/sns_topic_name"
|
36
|
-
require "stack_master/parameter_resolvers/security_group"
|
37
|
-
require "stack_master/parameter_resolvers/latest_ami_by_tags"
|
38
|
-
require "stack_master/parameter_resolvers/latest_ami"
|
39
|
-
require "stack_master/utils"
|
40
|
-
require "stack_master/config"
|
41
|
-
require "stack_master/paged_response_accumulator"
|
42
|
-
require "stack_master/stack_definition"
|
43
|
-
require "stack_master/template_compiler"
|
44
|
-
require "stack_master/template_compilers/sparkle_formation"
|
45
|
-
require "stack_master/template_compilers/json"
|
46
|
-
require "stack_master/template_compilers/yaml"
|
47
|
-
require "stack_master/template_compilers/cfndsl"
|
48
|
-
require "stack_master/commands/terminal_helper"
|
49
|
-
require "stack_master/commands/apply"
|
50
|
-
require "stack_master/change_set"
|
51
|
-
require "stack_master/commands/events"
|
52
|
-
require "stack_master/commands/outputs"
|
53
|
-
require "stack_master/commands/init"
|
54
|
-
require "stack_master/commands/diff"
|
55
|
-
require "stack_master/commands/list_stacks"
|
56
|
-
require "stack_master/commands/validate"
|
57
|
-
require "stack_master/commands/resources"
|
58
|
-
require "stack_master/commands/delete"
|
59
|
-
require "stack_master/commands/status"
|
60
|
-
require "stack_master/stack_differ"
|
61
|
-
require "stack_master/validator"
|
62
|
-
require "stack_master/cli"
|
63
6
|
|
64
7
|
module StackMaster
|
65
8
|
extend self
|
66
9
|
|
10
|
+
autoload :Initializable, 'stack_master/utils/initializable'
|
11
|
+
autoload :ChangeSet, 'stack_master/change_set'
|
12
|
+
autoload :CLI, 'stack_master/cli'
|
13
|
+
autoload :CtrlC, 'stack_master/ctrl_c'
|
14
|
+
autoload :Command, 'stack_master/command'
|
15
|
+
autoload :Version, 'stack_master/version'
|
16
|
+
autoload :Stack, 'stack_master/stack'
|
17
|
+
autoload :Prompter, 'stack_master/prompter'
|
18
|
+
autoload :StackStates, 'stack_master/stack_states'
|
19
|
+
autoload :StackStatus, 'stack_master/stack_status'
|
20
|
+
autoload :SnsTopicFinder, 'stack_master/sns_topic_finder'
|
21
|
+
autoload :SecurityGroupFinder, 'stack_master/security_group_finder'
|
22
|
+
autoload :ParameterLoader, 'stack_master/parameter_loader'
|
23
|
+
autoload :ParameterResolver, 'stack_master/parameter_resolver'
|
24
|
+
autoload :ResolverArray, 'stack_master/resolver_array'
|
25
|
+
autoload :Resolver, 'stack_master/resolver_array'
|
26
|
+
autoload :Utils, 'stack_master/utils'
|
27
|
+
autoload :Config, 'stack_master/config'
|
28
|
+
autoload :PagedResponseAccumulator, 'stack_master/paged_response_accumulator'
|
29
|
+
autoload :StackDefinition, 'stack_master/stack_definition'
|
30
|
+
autoload :TemplateCompiler, 'stack_master/template_compiler'
|
31
|
+
|
32
|
+
autoload :StackDiffer, 'stack_master/stack_differ'
|
33
|
+
autoload :Validator, 'stack_master/validator'
|
34
|
+
|
35
|
+
require 'stack_master/template_compilers/sparkle_formation'
|
36
|
+
require 'stack_master/template_compilers/json'
|
37
|
+
require 'stack_master/template_compilers/yaml'
|
38
|
+
require 'stack_master/template_compilers/cfndsl'
|
39
|
+
|
40
|
+
module Commands
|
41
|
+
autoload :TerminalHelper, 'stack_master/commands/terminal_helper'
|
42
|
+
autoload :Apply, 'stack_master/commands/apply'
|
43
|
+
autoload :Events, 'stack_master/commands/events'
|
44
|
+
autoload :Outputs, 'stack_master/commands/outputs'
|
45
|
+
autoload :Init, 'stack_master/commands/init'
|
46
|
+
autoload :Diff, 'stack_master/commands/diff'
|
47
|
+
autoload :ListStacks, 'stack_master/commands/list_stacks'
|
48
|
+
autoload :Validate, 'stack_master/commands/validate'
|
49
|
+
autoload :Resources, 'stack_master/commands/resources'
|
50
|
+
autoload :Delete, 'stack_master/commands/delete'
|
51
|
+
autoload :Status, 'stack_master/commands/status'
|
52
|
+
end
|
53
|
+
|
54
|
+
module ParameterResolvers
|
55
|
+
autoload :AmiFinder, 'stack_master/parameter_resolvers/ami_finder'
|
56
|
+
autoload :StackOutput, 'stack_master/parameter_resolvers/stack_output'
|
57
|
+
autoload :Secret, 'stack_master/parameter_resolvers/secret'
|
58
|
+
autoload :SnsTopicName, 'stack_master/parameter_resolvers/sns_topic_name'
|
59
|
+
autoload :SecurityGroup, 'stack_master/parameter_resolvers/security_group'
|
60
|
+
autoload :LatestAmiByTags, 'stack_master/parameter_resolvers/latest_ami_by_tags'
|
61
|
+
autoload :LatestAmi, 'stack_master/parameter_resolvers/latest_ami'
|
62
|
+
end
|
63
|
+
|
64
|
+
module AwsDriver
|
65
|
+
autoload :CloudFormation, 'stack_master/aws_driver/cloud_formation'
|
66
|
+
autoload :S3, 'stack_master/aws_driver/s3'
|
67
|
+
end
|
68
|
+
|
69
|
+
module TestDriver
|
70
|
+
autoload :CloudFormation, 'stack_master/test_driver/cloud_formation'
|
71
|
+
autoload :S3, 'stack_master/test_driver/s3'
|
72
|
+
end
|
73
|
+
|
74
|
+
module StackEvents
|
75
|
+
autoload :Fetcher, 'stack_master/stack_events/fetcher'
|
76
|
+
autoload :Presenter, 'stack_master/stack_events/presenter'
|
77
|
+
autoload :Streamer, 'stack_master/stack_events/streamer'
|
78
|
+
end
|
79
|
+
|
67
80
|
def interactive?
|
68
81
|
!non_interactive?
|
69
82
|
end
|
@@ -106,6 +119,14 @@ module StackMaster
|
|
106
119
|
@cloud_formation_driver = value
|
107
120
|
end
|
108
121
|
|
122
|
+
def s3_driver
|
123
|
+
@s3_driver ||= AwsDriver::S3.new
|
124
|
+
end
|
125
|
+
|
126
|
+
def s3_driver=(value)
|
127
|
+
@s3_driver = value
|
128
|
+
end
|
129
|
+
|
109
130
|
def stdout
|
110
131
|
@stdout || $stdout
|
111
132
|
end
|
@@ -126,4 +147,3 @@ module StackMaster
|
|
126
147
|
@stderr = io
|
127
148
|
end
|
128
149
|
end
|
129
|
-
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module StackMaster
|
4
|
+
module AwsDriver
|
5
|
+
class S3ConfigurationError < StandardError; end
|
6
|
+
|
7
|
+
class S3
|
8
|
+
def set_region(region)
|
9
|
+
@region = region
|
10
|
+
@s3 = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def upload_files(bucket: nil, prefix: nil, region: nil, files: {})
|
14
|
+
raise StackMaster::AwsDriver::S3ConfigurationError, 'A bucket must be specified in order to use S3' unless bucket
|
15
|
+
|
16
|
+
return if files.empty?
|
17
|
+
|
18
|
+
s3 = new_s3_client(region: region)
|
19
|
+
|
20
|
+
current_objects = s3.list_objects(
|
21
|
+
prefix: prefix,
|
22
|
+
bucket: bucket
|
23
|
+
).map(&:contents).flatten.inject({}){|h,obj|
|
24
|
+
h.merge(obj.key => obj)
|
25
|
+
}
|
26
|
+
|
27
|
+
StackMaster.stdout.puts "Uploading files to S3:"
|
28
|
+
|
29
|
+
files.each do |template, file|
|
30
|
+
body = file.fetch(:body)
|
31
|
+
path = file.fetch(:path)
|
32
|
+
object_key = template.dup
|
33
|
+
object_key.prepend("#{prefix}/") if prefix
|
34
|
+
compiled_template_md5 = Digest::MD5.hexdigest(body).to_s
|
35
|
+
s3_md5 = current_objects[object_key] ? current_objects[object_key].etag.gsub("\"", '') : nil
|
36
|
+
|
37
|
+
next if compiled_template_md5 == s3_md5
|
38
|
+
s3_uri = "s3://#{bucket}/#{object_key}"
|
39
|
+
StackMaster.stdout.print "- #{File.basename(path)} => #{s3_uri} "
|
40
|
+
|
41
|
+
s3.put_object(
|
42
|
+
bucket: bucket,
|
43
|
+
key: object_key,
|
44
|
+
body: body,
|
45
|
+
metadata: { md5: compiled_template_md5 }
|
46
|
+
)
|
47
|
+
StackMaster.stdout.puts "done."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def url(bucket:, prefix:, region:, template:)
|
52
|
+
if region == 'us-east-1'
|
53
|
+
["https://s3.amazonaws.com", bucket, prefix, template].compact.join('/')
|
54
|
+
else
|
55
|
+
["https://s3-#{region}.amazonaws.com", bucket, prefix, template].compact.join('/')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def new_s3_client(region: nil)
|
62
|
+
Aws::S3::Client.new(region: region || @region)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/stack_master/cli.rb
CHANGED
@@ -4,10 +4,11 @@ module StackMaster
|
|
4
4
|
include Command
|
5
5
|
include Commander::UI
|
6
6
|
include StackMaster::Prompter
|
7
|
-
TEMPLATE_TOO_LARGE_ERROR_MESSAGE = 'The (space compressed) stack is larger than the limit set by AWS. See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html'
|
7
|
+
TEMPLATE_TOO_LARGE_ERROR_MESSAGE = 'The (space compressed) stack is larger than the limit set by AWS. See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html'.freeze
|
8
8
|
|
9
9
|
def initialize(config, stack_definition, options = {})
|
10
10
|
@config = config
|
11
|
+
@s3_config = stack_definition.s3
|
11
12
|
@stack_definition = stack_definition
|
12
13
|
@from_time = Time.now
|
13
14
|
end
|
@@ -26,6 +27,10 @@ module StackMaster
|
|
26
27
|
@cf ||= StackMaster.cloud_formation_driver
|
27
28
|
end
|
28
29
|
|
30
|
+
def s3
|
31
|
+
@s3 ||= StackMaster.s3_driver
|
32
|
+
end
|
33
|
+
|
29
34
|
def stack
|
30
35
|
@stack ||= Stack.find(region, stack_name)
|
31
36
|
end
|
@@ -38,6 +43,10 @@ module StackMaster
|
|
38
43
|
!stack.nil?
|
39
44
|
end
|
40
45
|
|
46
|
+
def use_s3?
|
47
|
+
!@s3_config.empty?
|
48
|
+
end
|
49
|
+
|
41
50
|
def diff_stacks
|
42
51
|
StackDiffer.new(proposed_stack, stack).output_diff
|
43
52
|
end
|
@@ -51,9 +60,10 @@ module StackMaster
|
|
51
60
|
end
|
52
61
|
|
53
62
|
def create_stack
|
54
|
-
unless ask?(
|
63
|
+
unless ask?('Create stack (y/n)? ')
|
55
64
|
failed!("Stack creation aborted")
|
56
65
|
end
|
66
|
+
upload_files
|
57
67
|
cf.create_stack(stack_options.merge(tags: proposed_stack.aws_tags))
|
58
68
|
end
|
59
69
|
|
@@ -73,17 +83,54 @@ module StackMaster
|
|
73
83
|
ChangeSet.delete(@change_set.id)
|
74
84
|
halt! "Stack update aborted"
|
75
85
|
end
|
86
|
+
upload_files
|
76
87
|
execute_change_set
|
77
88
|
end
|
78
89
|
|
90
|
+
def upload_files
|
91
|
+
return unless use_s3?
|
92
|
+
s3.upload_files(s3_options)
|
93
|
+
end
|
94
|
+
|
95
|
+
def template_method
|
96
|
+
use_s3? ? :template_url : :template_body
|
97
|
+
end
|
98
|
+
|
99
|
+
def template_value
|
100
|
+
if use_s3?
|
101
|
+
s3.url(bucket: @s3_config['bucket'], prefix: @s3_config['prefix'], region: @s3_config['region'], template: @stack_definition.s3_template_file_name)
|
102
|
+
else
|
103
|
+
proposed_stack.maybe_compressed_template_body
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def files_to_upload
|
108
|
+
return {} unless use_s3?
|
109
|
+
@stack_definition.s3_files.tap do |files|
|
110
|
+
files[@stack_definition.s3_template_file_name] = {
|
111
|
+
path: @stack_definition.template_file_path,
|
112
|
+
body: proposed_stack.maybe_compressed_template_body
|
113
|
+
}
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
79
117
|
def stack_options
|
80
118
|
{
|
81
119
|
stack_name: stack_name,
|
82
|
-
template_body: proposed_stack.maybe_compressed_template_body,
|
83
120
|
parameters: proposed_stack.aws_parameters,
|
84
121
|
capabilities: ['CAPABILITY_IAM'],
|
85
122
|
notification_arns: proposed_stack.notification_arns,
|
86
|
-
stack_policy_body: proposed_stack.stack_policy_body
|
123
|
+
stack_policy_body: proposed_stack.stack_policy_body,
|
124
|
+
template_method => template_value
|
125
|
+
}
|
126
|
+
end
|
127
|
+
|
128
|
+
def s3_options
|
129
|
+
{
|
130
|
+
bucket: @s3_config['bucket'],
|
131
|
+
prefix: @s3_config['prefix'],
|
132
|
+
region: @s3_config['region'],
|
133
|
+
files: files_to_upload
|
87
134
|
}
|
88
135
|
end
|
89
136
|
|
@@ -110,7 +157,7 @@ module StackMaster
|
|
110
157
|
end
|
111
158
|
|
112
159
|
def ensure_valid_template_body_size!
|
113
|
-
if proposed_stack.too_big?
|
160
|
+
if proposed_stack.too_big?(use_s3?)
|
114
161
|
failed! TEMPLATE_TOO_LARGE_ERROR_MESSAGE
|
115
162
|
end
|
116
163
|
end
|