stackup 1.4.3 → 1.5.1
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/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
|