stackup 1.4.3 → 1.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +21 -0
- data/README.md +43 -4
- data/bin/stackup +11 -1
- data/lib/stackup/change_set.rb +3 -0
- data/lib/stackup/rake_tasks.rb +2 -2
- data/lib/stackup/source.rb +1 -1
- data/lib/stackup/stack.rb +19 -8
- data/lib/stackup/version.rb +1 -1
- data/spec/stackup/rake_tasks_spec.rb +8 -0
- data/spec/stackup/source_spec.rb +10 -0
- data/spec/stackup/stack_spec.rb +20 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a60dfe3184679f98c43d28590feadf40faa968bf5b75531951510d96d38a02f
|
4
|
+
data.tar.gz: ab5010d36407547ba7c1f5b09e190c776023303227b72881ea80b2b49a41b717
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf63917e39f450c29d98e420f872aa5f1d7bd00fbd2543eece6d81795ec64ec349e66ba507230e212d30961a390a8a9f587c0dc45e08b823c78c518f700425ff
|
7
|
+
data.tar.gz: 15a86e361a985ca59c7714025fa47308a4e165b5abdf2f0bf8e3020d13a73636e219a6693b208f6d51e4fed8aa28587e7dbd1dda03a654d471a8a432ca4e4632
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,26 @@
|
|
1
1
|
# CHANGES
|
2
2
|
|
3
|
+
## 1.5.1 (2020-11-16)
|
4
|
+
|
5
|
+
* Fix: Recognise that template is in S3 when URL is formatted like `s3.REGION.amazonaws.com`
|
6
|
+
|
7
|
+
## 1.5.0 (2020-04-21)
|
8
|
+
|
9
|
+
* Feature: --preserve-template-formatting
|
10
|
+
|
11
|
+
## 1.4.6 (2019-12-09)
|
12
|
+
|
13
|
+
* Fix: Don't error out when receiving tags in AWS style (array of hashes) from YAML or JSON file
|
14
|
+
|
15
|
+
## 1.4.5 (2019-10-03)
|
16
|
+
|
17
|
+
* Fix: Tags in RakeTasks
|
18
|
+
|
19
|
+
## 1.4.4 (2019-10-03)
|
20
|
+
|
21
|
+
* Fix: Loading RakeTasks
|
22
|
+
* Removes CI support for older rubies
|
23
|
+
|
3
24
|
## 1.4.3 (2019-09-05)
|
4
25
|
|
5
26
|
* Add support for CloudFormation capabilities via CLI and Rake
|
data/README.md
CHANGED
@@ -78,10 +78,12 @@ For more details on usage, see
|
|
78
78
|
|
79
79
|
### Specifying parameters
|
80
80
|
|
81
|
-
Stack parameters can be
|
81
|
+
Stack parameters can be read from a file, e.g.
|
82
82
|
|
83
83
|
$ stackup myapp-test up -t template.json -p parameters.json
|
84
84
|
|
85
|
+
These files can be either JSON or YAML format, see [YAML support](#yaml-support) for more information.
|
86
|
+
|
85
87
|
Parameters can be specified as simple key-value pairs:
|
86
88
|
|
87
89
|
```json
|
@@ -116,11 +118,48 @@ Or, you can specify one or more override parameters on the command-line, using `
|
|
116
118
|
-o IndexDoc=index-override.html
|
117
119
|
-o ContentDoc=content-override.html
|
118
120
|
|
121
|
+
### Specifying tags
|
122
|
+
|
123
|
+
Stack tags can be read from a file, e.g.
|
124
|
+
|
125
|
+
$ stackup myapp-test up -t template.json --tags tags.json
|
126
|
+
|
127
|
+
These files can be either JSON or YAML format, see [YAML support](#yaml-support) for more information.
|
128
|
+
|
129
|
+
Tags are specified as simple key-value pairs:
|
130
|
+
|
131
|
+
```json
|
132
|
+
{
|
133
|
+
"environment": "dev"
|
134
|
+
}
|
135
|
+
```
|
136
|
+
|
137
|
+
### Acknowledging Capabilities
|
138
|
+
|
139
|
+
CloudFormation requires that some stacks explicitly acknowledge certain capabilities before creation. This helps to prevent the creation of stacks with unintended privileges.
|
140
|
+
|
141
|
+
If your stack includes IAM resources, you must specify either the `CAPABILITY_IAM` capability, or the `CAPABILITY_NAMED_IAM` capability if they have custom names.
|
142
|
+
|
143
|
+
If your stack template contains macros or nested stacks, you must specify the `CAPABILITY_AUTO_EXPAND` capability.
|
144
|
+
|
145
|
+
Capabilities can be provided via the `--capability` CLI option.
|
146
|
+
|
147
|
+
$ stackup myapp-test up -t template.json \
|
148
|
+
--capability CAPABILITY_NAMED_IAM \
|
149
|
+
--capability CAPABILITY_AUTO_EXPAND
|
150
|
+
|
151
|
+
`stackup` includes defaults to including `CAPABILITY_NAMED_IAM` capability if, and only if, no capabilities are specified.
|
152
|
+
This is to provide backwards compatibility with previously deployed stacks and may be removed in a future release.
|
153
|
+
|
119
154
|
### YAML support
|
120
155
|
|
121
156
|
`stackup` supports input files (template, parameters, tags) in YAML format, as well as JSON.
|
122
157
|
|
123
|
-
It also supports the [abbreviated YAML syntax for Cloudformation functions](https://aws.amazon.com/blogs/aws/aws-cloudformation-update-yaml-cross-stack-references-simplified-substitution/), though unlike the [AWS CLI](https://aws.amazon.com/cli/), Stackup normalises YAML input to JSON before invoking CloudFormation APIs.
|
158
|
+
It also supports the [abbreviated YAML syntax for Cloudformation functions](https://aws.amazon.com/blogs/aws/aws-cloudformation-update-yaml-cross-stack-references-simplified-substitution/), though unlike the [AWS CLI](https://aws.amazon.com/cli/), Stackup (by default) normalises YAML input to JSON before invoking CloudFormation APIs.
|
159
|
+
|
160
|
+
If you don't want normalisation of the YAML input to JSON, then use the `--preserve-template-formatting` flag to the `up` or `change-set create` commands.
|
161
|
+
|
162
|
+
Note: normalisation of S3 / HTTP URL stored templates is never done, as Cloudformation collects these directly.
|
124
163
|
|
125
164
|
### AWS credentials
|
126
165
|
|
@@ -268,11 +307,11 @@ The release process will push tags to GitHub, push the gem to rubygems and push
|
|
268
307
|
Prerequisites:
|
269
308
|
|
270
309
|
* logged into dockerhub via `docker login`. Your user must have permission to push to `realestate/stackup`
|
271
|
-
*
|
310
|
+
* You must have a rubygems account with permission to push to the `stackup` gem. (`auto/release` will ask for your username and password)
|
311
|
+
* You must have cloned this repo via HTTPS and have a github account with permission to push. (`auto/release` will ask for your username and a GitHub personal access token)
|
272
312
|
|
273
313
|
To release:
|
274
314
|
|
275
315
|
```
|
276
|
-
bundle install
|
277
316
|
auto/release
|
278
317
|
```
|
data/bin/stackup
CHANGED
@@ -41,7 +41,7 @@ Clamp do
|
|
41
41
|
option ["--[no-]wait"], :flag, "wait for stack updates to complete",
|
42
42
|
:default => true
|
43
43
|
|
44
|
-
option ["--wait-poll-interval"], "N", "polling interval while waiting for updates",
|
44
|
+
option ["--wait-poll-interval"], "N", "polling interval (in seconds) while waiting for updates",
|
45
45
|
:default => 5, &method(:Integer)
|
46
46
|
|
47
47
|
option "--debug", :flag, "enable debugging"
|
@@ -181,6 +181,9 @@ Clamp do
|
|
181
181
|
option ["-T", "--use-previous-template"], :flag,
|
182
182
|
"reuse the existing template"
|
183
183
|
|
184
|
+
option ["-P", "--preserve-template-formatting"], :flag,
|
185
|
+
"do not normalise the template when calling the Cloudformation APIs; useful for preserving YAML and comments"
|
186
|
+
|
184
187
|
include HasParameters
|
185
188
|
|
186
189
|
option "--tags", "FILE", "stack tags file",
|
@@ -214,6 +217,7 @@ Clamp do
|
|
214
217
|
options[:template_url] = template_source.location
|
215
218
|
else
|
216
219
|
options[:template] = template_source.data
|
220
|
+
options[:template_orig] = template_source.body
|
217
221
|
end
|
218
222
|
end
|
219
223
|
options[:on_failure] = on_failure
|
@@ -229,6 +233,7 @@ Clamp do
|
|
229
233
|
options[:role_arn] = service_role_arn if service_role_arn
|
230
234
|
options[:use_previous_template] = use_previous_template?
|
231
235
|
options[:capabilities] = capability_list
|
236
|
+
options[:preserve] = preserve_template_formatting?
|
232
237
|
report_change do
|
233
238
|
stack.create_or_update(options)
|
234
239
|
end
|
@@ -274,6 +279,9 @@ Clamp do
|
|
274
279
|
option ["-T", "--use-previous-template"], :flag,
|
275
280
|
"reuse the existing template"
|
276
281
|
|
282
|
+
option ["-P", "--preserve-template-formatting"], :flag,
|
283
|
+
"do not normalise the template when calling the Cloudformation APIs; useful for preserving YAML and comments"
|
284
|
+
|
277
285
|
option ["--force"], :flag,
|
278
286
|
"replace existing change-set of the same name"
|
279
287
|
|
@@ -296,6 +304,7 @@ Clamp do
|
|
296
304
|
options[:template_url] = template_source.location
|
297
305
|
else
|
298
306
|
options[:template] = template_source.data
|
307
|
+
options[:template_orig] = template_source.body
|
299
308
|
end
|
300
309
|
end
|
301
310
|
options[:parameters] = parameters
|
@@ -304,6 +313,7 @@ Clamp do
|
|
304
313
|
options[:use_previous_template] = use_previous_template?
|
305
314
|
options[:force] = force?
|
306
315
|
options[:capabilities] = capability_list
|
316
|
+
options[:preserve] = preserve_template_formatting?
|
307
317
|
report_change do
|
308
318
|
change_set.create(options)
|
309
319
|
end
|
data/lib/stackup/change_set.rb
CHANGED
@@ -57,6 +57,9 @@ module Stackup
|
|
57
57
|
options[:change_set_type] = stack.exists? ? "UPDATE" : "CREATE"
|
58
58
|
force = options.delete(:force)
|
59
59
|
options[:template_body] = MultiJson.dump(options.delete(:template)) if options[:template]
|
60
|
+
# optionally override template_body with the original template to preserve formatting (& comments in YAML)
|
61
|
+
template_orig = options.delete(:template_orig)
|
62
|
+
options[:template_body] = template_orig if options.delete(:preserve)
|
60
63
|
options[:parameters] = Parameters.new(options[:parameters]).to_a if options[:parameters]
|
61
64
|
options[:tags] = normalize_tags(options[:tags]) if options[:tags]
|
62
65
|
options[:capabilities] ||= ["CAPABILITY_NAMED_IAM"]
|
data/lib/stackup/rake_tasks.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "rake/tasklib"
|
2
2
|
require "tempfile"
|
3
3
|
require "yaml"
|
4
|
-
require "
|
4
|
+
require "pathname"
|
5
5
|
|
6
6
|
module Stackup
|
7
7
|
|
@@ -42,7 +42,7 @@ module Stackup
|
|
42
42
|
data_options = []
|
43
43
|
data_options << DataOption.for("--template", template)
|
44
44
|
data_options << DataOption.for("--parameters", parameters) if parameters
|
45
|
-
data_options << DataOption.for("--tags", tags) if
|
45
|
+
data_options << DataOption.for("--tags", tags) if tags
|
46
46
|
|
47
47
|
desc "Update #{stack} stack"
|
48
48
|
task "up" => data_options.grep(DataOptionFile).map(&:argument) do
|
data/lib/stackup/source.rb
CHANGED
data/lib/stackup/stack.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "aws-sdk-cloudformation"
|
2
4
|
require "logger"
|
3
5
|
require "multi_json"
|
@@ -16,10 +18,10 @@ module Stackup
|
|
16
18
|
DEFAULT_WAIT_POLL_INTERVAL = 5 # seconds
|
17
19
|
|
18
20
|
def initialize(name, client = {}, options = {})
|
19
|
-
client
|
20
|
-
@name
|
21
|
+
client = Aws::CloudFormation::Client.new(client) if client.is_a?(Hash)
|
22
|
+
@name = name
|
21
23
|
@cf_client = client
|
22
|
-
@wait
|
24
|
+
@wait = true
|
23
25
|
options.each do |key, value|
|
24
26
|
public_send("#{key}=", value)
|
25
27
|
end
|
@@ -117,6 +119,9 @@ module Stackup
|
|
117
119
|
if (template_data = options.delete(:template))
|
118
120
|
options[:template_body] = MultiJson.dump(template_data)
|
119
121
|
end
|
122
|
+
# optionally override template_body with the original template to preserve formatting (& comments in YAML)
|
123
|
+
template_orig = options.delete(:template_orig)
|
124
|
+
options[:template_body] = template_orig if options.delete(:preserve)
|
120
125
|
if (parameters = options[:parameters])
|
121
126
|
options[:parameters] = Parameters.new(parameters).to_a
|
122
127
|
end
|
@@ -282,7 +287,7 @@ module Stackup
|
|
282
287
|
end
|
283
288
|
|
284
289
|
def create(options)
|
285
|
-
options
|
290
|
+
options = options.dup
|
286
291
|
options[:stack_name] = name
|
287
292
|
options.delete(:stack_policy_during_update_body)
|
288
293
|
options.delete(:stack_policy_during_update_url)
|
@@ -312,7 +317,7 @@ module Stackup
|
|
312
317
|
def event_handler
|
313
318
|
@event_handler ||= lambda do |e|
|
314
319
|
fields = [e.logical_resource_id, e.resource_status, e.resource_status_reason]
|
315
|
-
time
|
320
|
+
time = e.timestamp.localtime.strftime("%H:%M:%S")
|
316
321
|
logger.info("[#{time}] #{fields.compact.join(' - ')}")
|
317
322
|
end
|
318
323
|
end
|
@@ -369,7 +374,13 @@ module Stackup
|
|
369
374
|
{ :key => key, :value => value.to_s }
|
370
375
|
end
|
371
376
|
else
|
372
|
-
tags
|
377
|
+
tags.map do |tag|
|
378
|
+
if tag.key?("Key")
|
379
|
+
{ :key => tag["Key"], :value => tag["Value"].to_s }
|
380
|
+
else
|
381
|
+
{ :key => tag[:key], :value => tag[:value].to_s }
|
382
|
+
end
|
383
|
+
end
|
373
384
|
end
|
374
385
|
end
|
375
386
|
|
@@ -384,8 +395,8 @@ module Stackup
|
|
384
395
|
handling_cf_errors do
|
385
396
|
{}.tap do |result|
|
386
397
|
cf_stack.public_send(collection_name).each do |item|
|
387
|
-
key
|
388
|
-
value
|
398
|
+
key = item.public_send(key_name)
|
399
|
+
value = item.public_send(value_name)
|
389
400
|
result[key] = value
|
390
401
|
end
|
391
402
|
end
|
data/lib/stackup/version.rb
CHANGED
data/spec/stackup/source_spec.rb
CHANGED
@@ -124,6 +124,16 @@ describe Stackup::Source do
|
|
124
124
|
|
125
125
|
end
|
126
126
|
|
127
|
+
context "with dot separated bucket and region" do
|
128
|
+
|
129
|
+
let(:s3_url) { "https://bucket.s3.us-east-1.amazonaws.com/cfn/template.yml" }
|
130
|
+
|
131
|
+
it "is S3" do
|
132
|
+
expect(subject).to be_s3
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
127
137
|
end
|
128
138
|
|
129
139
|
end
|
data/spec/stackup/stack_spec.rb
CHANGED
@@ -260,6 +260,26 @@ describe Stackup::Stack do
|
|
260
260
|
|
261
261
|
end
|
262
262
|
|
263
|
+
context "with :tags in SDK form as they arrive from file" do
|
264
|
+
|
265
|
+
before do
|
266
|
+
options[:tags] = [
|
267
|
+
{ "Key" => "foo", "Value" => "bar" }
|
268
|
+
]
|
269
|
+
end
|
270
|
+
|
271
|
+
it "converts them to an Array, that uses symbols as keys" do
|
272
|
+
expected_tags = [
|
273
|
+
{ :key => "foo", :value => "bar" }
|
274
|
+
]
|
275
|
+
create_or_update
|
276
|
+
expect(cf_client).to have_received(:create_stack) do |options|
|
277
|
+
expect(options[:tags]).to eq(expected_tags)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
282
|
+
|
263
283
|
context "with :tags in SDK form" do
|
264
284
|
|
265
285
|
before do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stackup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Williams
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-11-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: aws-sdk-cloudformation
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- lib/stackup/yaml.rb
|
111
111
|
- spec/spec_helper.rb
|
112
112
|
- spec/stackup/parameters_spec.rb
|
113
|
+
- spec/stackup/rake_tasks_spec.rb
|
113
114
|
- spec/stackup/source_spec.rb
|
114
115
|
- spec/stackup/stack_spec.rb
|
115
116
|
- spec/stackup/stack_watcher_spec.rb
|
@@ -141,6 +142,7 @@ summary: Manage CloudFormation stacks
|
|
141
142
|
test_files:
|
142
143
|
- spec/spec_helper.rb
|
143
144
|
- spec/stackup/parameters_spec.rb
|
145
|
+
- spec/stackup/rake_tasks_spec.rb
|
144
146
|
- spec/stackup/source_spec.rb
|
145
147
|
- spec/stackup/stack_spec.rb
|
146
148
|
- spec/stackup/stack_watcher_spec.rb
|