bora 1.1.1 → 1.2.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 +36 -1
- data/lib/bora/cli.rb +12 -1
- data/lib/bora/parameter_resolver.rb +44 -14
- data/lib/bora/stack.rb +4 -1
- data/lib/bora/template.rb +11 -3
- data/lib/bora/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 741e43489dd8279e5b9a2fa73068bd45bbfcc7de
|
4
|
+
data.tar.gz: 708c036c31038bec8dc57a61541af3065f4bf2c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 85b831a26bb9876db1a32a00238b1d489582a5f87adcb105d5103414d1274d175f53bc8123287a603a811e0f43ee2e336b0704e71107d85698507cbd84e176ac
|
7
|
+
data.tar.gz: 957e597af2294f73976630840ef64dbcdb2f078ea2085b39e0aa9d4d2e9950168ac7c292b1aa67fc9d394ee52abcade685573070d7e7ff419c7a5fda6349eb11
|
data/README.md
CHANGED
@@ -102,7 +102,7 @@ templates:
|
|
102
102
|
# If you don't supply this, the name will be the template
|
103
103
|
# name concatenated with the stack name as defined in this file,
|
104
104
|
# eg: "app-prod".
|
105
|
-
|
105
|
+
cfn_stack_name: prod-application-stack
|
106
106
|
|
107
107
|
# Optional. Default region for this stack.
|
108
108
|
# Overrides "default_region" at the template level.
|
@@ -219,6 +219,17 @@ There are a number of resolvers that come with Bora (documented below),
|
|
219
219
|
or you can write your own.
|
220
220
|
|
221
221
|
|
222
|
+
### Parameter Lookup
|
223
|
+
Any substitution that does not specify a "scheme" is treated as a reference to another parameter value.
|
224
|
+
For example:
|
225
|
+
|
226
|
+
```yaml
|
227
|
+
params:
|
228
|
+
domain: example.com
|
229
|
+
url: http://${domain}/foo
|
230
|
+
```
|
231
|
+
|
232
|
+
|
222
233
|
### Stack Output Lookup
|
223
234
|
|
224
235
|
You can look up outputs from stacks in the same region.
|
@@ -280,6 +291,30 @@ $ rake web-uat:apply[instance_type=t2.micro,ami=ami-11032472]
|
|
280
291
|
```
|
281
292
|
|
282
293
|
|
294
|
+
## Creating Multiple Instances of a Stack
|
295
|
+
Sometimes it can be useful to create multiple instances of a single stack.
|
296
|
+
For example, you may define a single "qa" stack with all the settings for a testing environment.
|
297
|
+
Then you might want to stand up this stack multiple times so you can have multiple testing environments,
|
298
|
+
eg "qa1", "qa2", etc.
|
299
|
+
|
300
|
+
Bora makes this possible by allowing you to override the name of the stack that gets created in CloudFormation.
|
301
|
+
For example:
|
302
|
+
|
303
|
+
```bash
|
304
|
+
$ bora apply web-qa --cfn-stack-name "web-qa-1"
|
305
|
+
$ bora apply web-qa --cfn-stack-name "web-qa-2"
|
306
|
+
```
|
307
|
+
|
308
|
+
Remember that if you use this functionality you must remember to pass in the stack name to *every* command or you will get unexepected results.
|
309
|
+
|
310
|
+
```bash
|
311
|
+
$ bora outputs web-qa --cfn-stack-name "web-qa-1"
|
312
|
+
```
|
313
|
+
|
314
|
+
Work is underway to improve how Bora handles this use case.
|
315
|
+
If this is of interest to you, please have a look at the [GitHub issue](https://github.com/ampedandwired/bora/issues/10) for this functionality.
|
316
|
+
|
317
|
+
|
283
318
|
## Related Projects
|
284
319
|
The following projects provided inspiration for Bora:
|
285
320
|
* [CfnDsl](https://github.com/stevenjack/cfndsl) - A Ruby DSL for CloudFormation templates
|
data/lib/bora/cli.rb
CHANGED
@@ -15,6 +15,12 @@ class Bora
|
|
15
15
|
default: nil,
|
16
16
|
desc: "The region to use for the stack operation. Overrides any regions specified in the Bora config file."
|
17
17
|
|
18
|
+
class_option "cfn-stack-name",
|
19
|
+
type: :string,
|
20
|
+
aliases: :c,
|
21
|
+
default: nil,
|
22
|
+
desc: "The name to give the stack in CloudFormation. Overrides any CFN stack name setting in the Bora config file."
|
23
|
+
|
18
24
|
desc "list", "Lists the available stacks"
|
19
25
|
def list
|
20
26
|
templates = bora(options.file).templates
|
@@ -84,7 +90,12 @@ class Bora
|
|
84
90
|
|
85
91
|
def stack(config_file, stack_name)
|
86
92
|
region = options.region
|
87
|
-
|
93
|
+
cfn_stack_name = options["cfn-stack-name"]
|
94
|
+
|
95
|
+
override_config = {}
|
96
|
+
override_config["default_region"] = region if region
|
97
|
+
override_config["cfn_stack_name"] = cfn_stack_name if cfn_stack_name
|
98
|
+
|
88
99
|
bora = bora(config_file, override_config)
|
89
100
|
stack = bora.stack(stack_name)
|
90
101
|
if !stack
|
@@ -3,6 +3,10 @@ require 'bora/parameter_resolver_loader'
|
|
3
3
|
|
4
4
|
class Bora
|
5
5
|
class ParameterResolver
|
6
|
+
UnresolvedSubstitutionError = Class.new(StandardError)
|
7
|
+
|
8
|
+
PLACEHOLDER_REGEX = /\${[^}]+}/
|
9
|
+
|
6
10
|
def initialize(stack)
|
7
11
|
@stack = stack
|
8
12
|
@loader = ParameterResolverLoader.new
|
@@ -10,26 +14,49 @@ class Bora
|
|
10
14
|
end
|
11
15
|
|
12
16
|
def resolve(params)
|
13
|
-
|
17
|
+
unresolved_placeholders_still_remain = true
|
18
|
+
while unresolved_placeholders_still_remain
|
19
|
+
unresolved_placeholders_still_remain = false
|
20
|
+
placeholders_were_substituted = false
|
21
|
+
params.each do |k, v|
|
22
|
+
resolved_value = process_param_substitutions(v, params)
|
23
|
+
unresolved_placeholders_still_remain ||= has_unresolved_placeholder?(resolved_value)
|
24
|
+
placeholders_were_substituted ||= resolved_value != v
|
25
|
+
params[k] = resolved_value
|
26
|
+
end
|
27
|
+
if unresolved_placeholders_still_remain && !placeholders_were_substituted
|
28
|
+
raise UnresolvedSubstitutionError, "Parameter substitutions could not be resolved:\n#{unresolved_placeholders_as_string(params)}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
params
|
14
32
|
end
|
15
33
|
|
16
34
|
|
17
35
|
private
|
18
36
|
|
19
|
-
def process_param_substitutions(val)
|
37
|
+
def process_param_substitutions(val, params)
|
20
38
|
return val unless val.is_a? String
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
39
|
+
val.gsub(PLACEHOLDER_REGEX) do |placeholder|
|
40
|
+
process_placeholder(placeholder, params)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def process_placeholder(placeholder, params)
|
45
|
+
uri = parse_uri(placeholder[2..-2])
|
46
|
+
if !uri.scheme
|
47
|
+
# This token refers to another parameter, rather than a resolver
|
48
|
+
value_to_substitute = params[uri.path]
|
49
|
+
!value_to_substitute || has_unresolved_placeholder?(value_to_substitute) ? placeholder : value_to_substitute
|
50
|
+
else
|
51
|
+
# This token needs to be resolved by a resolver
|
52
|
+
resolver_name = uri.scheme
|
53
|
+
resolver = @resolver_cache[resolver_name] || @loader.load_resolver(resolver_name).new(@stack)
|
54
|
+
resolver.resolve(uri)
|
31
55
|
end
|
32
|
-
|
56
|
+
end
|
57
|
+
|
58
|
+
def has_unresolved_placeholder?(val)
|
59
|
+
val =~ PLACEHOLDER_REGEX
|
33
60
|
end
|
34
61
|
|
35
62
|
def parse_uri(s)
|
@@ -40,9 +67,12 @@ class Bora
|
|
40
67
|
if !uri.scheme && uri.path && uri.path.count("/") == 2
|
41
68
|
uri = URI("cfn://#{s}")
|
42
69
|
end
|
43
|
-
|
44
70
|
uri
|
45
71
|
end
|
46
72
|
|
73
|
+
def unresolved_placeholders_as_string(params)
|
74
|
+
params.select { |k, v| has_unresolved_placeholder?(v) }.to_a.map { |k, v| "#{k}: #{v}" }.join("\n")
|
75
|
+
end
|
76
|
+
|
47
77
|
end
|
48
78
|
end
|
data/lib/bora/stack.rb
CHANGED
@@ -18,7 +18,10 @@ class Bora
|
|
18
18
|
|
19
19
|
def initialize(stack_name, template_file, stack_config)
|
20
20
|
@stack_name = stack_name
|
21
|
-
@cfn_stack_name = stack_config['stack_name'] || @stack_name
|
21
|
+
@cfn_stack_name = stack_config['cfn_stack_name'] || stack_config['stack_name'] || @stack_name
|
22
|
+
if stack_config['stack_name']
|
23
|
+
puts "DEPRECATED: The 'stack_name' setting is deprecated. Please use 'cfn_stack_name' instead."
|
24
|
+
end
|
22
25
|
@template_file = template_file
|
23
26
|
@stack_config = stack_config
|
24
27
|
@region = @stack_config['default_region']
|
data/lib/bora/template.rb
CHANGED
@@ -2,16 +2,20 @@ require 'bora/stack'
|
|
2
2
|
|
3
3
|
class Bora
|
4
4
|
class Template
|
5
|
+
# These are properties that you can define on the template, but which can also be defined in the stack
|
5
6
|
INHERITABLE_PROPERTIES = ["capabilities", "default_region"]
|
6
7
|
|
8
|
+
# These are properties that can be passed in from the command line to override what's defined inthe stack
|
9
|
+
OVERRIDABLE_PROPERTIES = ["cfn_stack_name"]
|
10
|
+
|
7
11
|
def initialize(template_name, template_config, override_config = {})
|
8
12
|
@template_name = template_name
|
9
13
|
@template_config = template_config
|
10
14
|
@stacks = {}
|
11
15
|
template_config['stacks'].each do |stack_name, stack_config|
|
12
16
|
stack_name = "#{template_name}-#{stack_name}"
|
13
|
-
|
14
|
-
@stacks[stack_name] = Stack.new(stack_name, template_config['template_file'],
|
17
|
+
resolved_config = resolve_stack_config(template_config, stack_config, override_config)
|
18
|
+
@stacks[stack_name] = Stack.new(stack_name, template_config['template_file'], resolved_config)
|
15
19
|
end
|
16
20
|
end
|
17
21
|
|
@@ -31,12 +35,16 @@ class Bora
|
|
31
35
|
private
|
32
36
|
|
33
37
|
def resolve_stack_config(template_config, stack_config, override_config)
|
34
|
-
inheritable_properties(template_config).merge(stack_config).merge(
|
38
|
+
inheritable_properties(template_config).merge(stack_config).merge(overridable_properties(override_config))
|
35
39
|
end
|
36
40
|
|
37
41
|
def inheritable_properties(config)
|
38
42
|
config.select { |k| INHERITABLE_PROPERTIES.include?(k) }
|
39
43
|
end
|
40
44
|
|
45
|
+
def overridable_properties(config)
|
46
|
+
config.select { |k| INHERITABLE_PROPERTIES.include?(k) || OVERRIDABLE_PROPERTIES.include?(k) }
|
47
|
+
end
|
48
|
+
|
41
49
|
end
|
42
50
|
end
|
data/lib/bora/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bora
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charles Blaxland
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|