sparkle_formation 1.0.4 → 1.1.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/CHANGELOG.md +5 -0
- data/docs/README.md +28 -0
- data/docs/anatomy.md +205 -0
- data/docs/building-blocks.md +360 -0
- data/docs/compile-time-parameters.md +182 -0
- data/docs/helper-methods.md +157 -0
- data/docs/nested-stacks.md +425 -0
- data/docs/overview.md +54 -0
- data/docs/sparkle-packs.md +211 -0
- data/docs/sparkleformation-dsl.md +303 -0
- data/docs/stack-policies.md +90 -0
- data/docs/translation.md +64 -0
- data/docs/v/0.3.2/marked.js +1272 -0
- data/docs/v/bootstrap.min.css +7 -0
- data/docs/v/finalizer.css +6 -0
- data/docs/v/highlight.min.css +1 -0
- data/docs/v/highlight.min.js +2 -0
- data/docs/v/jquery-2.1.3.min.js +4 -0
- data/docs/v/loader.js +34 -0
- data/lib/sparkle_formation/sparkle.rb +4 -0
- data/lib/sparkle_formation/sparkle_formation.rb +75 -14
- data/lib/sparkle_formation/sparkle_struct.rb +17 -0
- data/lib/sparkle_formation/version.rb +1 -1
- data/sparkle_formation.gemspec +1 -1
- metadata +21 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 607eb52a5d461c5cf623e017888bb5dc113a3c7e
|
4
|
+
data.tar.gz: 45401a5dabb03744b24777538a9548a8ea0e06f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 565402fe9c3256b0ddcd028c4a1244350796d46d951c97d214f2d97ee7d532709b05654fb26f4a3b503e7316577d7745258f5944d7c2a07b6c1f362c838c6176
|
7
|
+
data.tar.gz: fe0d0a5f94ddaf1b5eac0a68840b980fb82990ccb388630ed9723c4e4ea10e9e88810767128b974824d28014e6289f06033c7628c213e1d5155e79dadc8f94ed
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## v1.1.0
|
2
|
+
* Add support for compile time parameters
|
3
|
+
* Fix usage of deprecated `SparkleFormation.insert` method
|
4
|
+
* Propagate parent stack parameter when output required output is in parent stack
|
5
|
+
|
1
6
|
## v1.0.4
|
2
7
|
* Fixes on testing (#66 #67 #68 thanks @matschaffer)
|
3
8
|
* Properly handle JSON templates within packs (#72)
|
data/docs/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
## Table of Contents
|
2
|
+
|
3
|
+
- [Getting Started](overview.md#getting-started)
|
4
|
+
- [Installation](overview.md#installation)
|
5
|
+
- [The DSL](sparkleformation-dsl.md)
|
6
|
+
- [Behavior](sparkleformation-dsl.md#behavior)
|
7
|
+
- [Features](sparkleformation-dsl.md#features)
|
8
|
+
- [Building Blocks](building-blocks.md)
|
9
|
+
- [Components](building-blocks.md#components)
|
10
|
+
- [Dynamics](building-blocks.md#dynamics)
|
11
|
+
- [Registry](building-blocks.md#registry)
|
12
|
+
- [Templates](building-blocks.md#templates)
|
13
|
+
- [Template Anatomy](anatomy.md)
|
14
|
+
- [Base Attributes](anatomy.md#base-attributes)
|
15
|
+
- [Parameters](anatomy.md#parameters)
|
16
|
+
- [Mappings](anatomy.md#mappings)
|
17
|
+
- [Conditions](anatomy.md#conditions)
|
18
|
+
- [Resources](anatomy.md#resources)
|
19
|
+
- [Outputs](anatomy.md#outputs)
|
20
|
+
- Library Features
|
21
|
+
- [Helper Methods](helper-methods.md)
|
22
|
+
- [Nested Stacks](nested-stacks.md)
|
23
|
+
- [Shallow Nesting](nested-stacks.md#shallow-nesting)
|
24
|
+
- [Deep Nesting](nested-stacks.md#deep-nesting)
|
25
|
+
- [Sparkle Packs](sparkle-packs.md)
|
26
|
+
- [Stack Policies](stack-policies.md)
|
27
|
+
- [Translation](translation.md)
|
28
|
+
- [Compile Time Parameters](compile-time-parameters.md)
|
data/docs/anatomy.md
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
---
|
2
|
+
title: "Template Anatomy"
|
3
|
+
category: "dsl"
|
4
|
+
weight: 4
|
5
|
+
anchors:
|
6
|
+
- title: "Parameters"
|
7
|
+
url: "#parameters"
|
8
|
+
- title: "Mappings"
|
9
|
+
url: "#mappings"
|
10
|
+
- title: "Conditions"
|
11
|
+
url: "#conditions"
|
12
|
+
- title: "Resources"
|
13
|
+
url: "#resources"
|
14
|
+
- title: "Outputs"
|
15
|
+
url: "#outputs"
|
16
|
+
---
|
17
|
+
|
18
|
+
## Template Anatomy
|
19
|
+
|
20
|
+
The anatomy of a template is dependent on the specific implementation that is
|
21
|
+
targeted. Due to the freeform nature of the SparkleFormation DSL any orchestration
|
22
|
+
API accepting a serialized document to describe resources is inherently supported.
|
23
|
+
Due to that fact, this document will focus directly on the AWS CloudFormation
|
24
|
+
style template as it is the most widely implemented.
|
25
|
+
|
26
|
+
### AWS CloudFormation in SparkleFormation
|
27
|
+
|
28
|
+
- [Base Attributes](#base-attributes)
|
29
|
+
- [Parameters](#parameters)
|
30
|
+
- [Mappings](#mappings)
|
31
|
+
- [Conditions](#conditions)
|
32
|
+
- [Resources](#resources)
|
33
|
+
- [Outputs](#outputs)
|
34
|
+
|
35
|
+
#### Base Attributes
|
36
|
+
|
37
|
+
All templates must begin with the expected API version and may include a description
|
38
|
+
and or metadata:
|
39
|
+
|
40
|
+
~~~ruby
|
41
|
+
SparkleFormation.new(:template) do
|
42
|
+
set!('AWSTemplateFormatVersion', '2010-09-09')
|
43
|
+
description 'My New Stack'
|
44
|
+
metadata.instances.description 'Awesome instances'
|
45
|
+
end
|
46
|
+
~~~
|
47
|
+
|
48
|
+
* [Format Version](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/format-version-structure.html)
|
49
|
+
* [Description](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-description-structure.html)
|
50
|
+
* [Metadata](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html)
|
51
|
+
|
52
|
+
#### Parameters
|
53
|
+
|
54
|
+
Parameters are named variables available within the template that users may
|
55
|
+
provide customized values when creating or updating a stack. This allows
|
56
|
+
"runtime" modifications to occur when the template is evaluated by the API.
|
57
|
+
|
58
|
+
~~~ruby
|
59
|
+
SparkleFormation.new(:template) do
|
60
|
+
parameters do
|
61
|
+
creator do
|
62
|
+
type 'String'
|
63
|
+
default ENV['USER']
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
~~~
|
68
|
+
|
69
|
+
* [Parameters](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html)
|
70
|
+
|
71
|
+
#### Mappings
|
72
|
+
|
73
|
+
Mappings are a nested key/value store. They provide an easy way to dynamically
|
74
|
+
specify what value should be used based on context available when the template
|
75
|
+
is evaluated by the API.
|
76
|
+
|
77
|
+
~~~ruby
|
78
|
+
SparkleFormation.new(:template) do
|
79
|
+
mappings.platforms.set!('us-west-2'._no_hump) do
|
80
|
+
centos6 'ami-b6bdde86'
|
81
|
+
centos7 'ami-c7d092f7'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
~~~
|
85
|
+
|
86
|
+
These can then be referenced using the `map!` helper method:
|
87
|
+
|
88
|
+
~~~ruby
|
89
|
+
SparkleFormation.new(:template) do
|
90
|
+
dynamic!(:ec2_instance, :foobar) do
|
91
|
+
properties.image_id map!(:platforms, region!, :centos7)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
~~~
|
95
|
+
|
96
|
+
* [Mappings](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html)
|
97
|
+
* [Fn::FindInMap](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-findinmap.html)
|
98
|
+
|
99
|
+
#### Conditions
|
100
|
+
|
101
|
+
Named conditions are defined in this section and then referenced
|
102
|
+
elsewhere in the template. Conditions can be used to customize resource
|
103
|
+
properties values or to allow/restrict the creation of resources and
|
104
|
+
outputs.
|
105
|
+
|
106
|
+
|
107
|
+
~~~ruby
|
108
|
+
SparkleFormation.new(:template) do
|
109
|
+
parameters.creator do
|
110
|
+
type 'String'
|
111
|
+
default 'spox'
|
112
|
+
end
|
113
|
+
conditions do
|
114
|
+
creator_is_spox equals!(ref!(:creator), 'spox')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
~~~
|
118
|
+
|
119
|
+
This condition can then be used to provide a custom value for a property:
|
120
|
+
|
121
|
+
~~~ruby
|
122
|
+
SparkleFormation.new(:template) do
|
123
|
+
parameters.creator do
|
124
|
+
type 'String'
|
125
|
+
default 'spox'
|
126
|
+
end
|
127
|
+
conditions do
|
128
|
+
creator_is_spox equals!(ref!(:creator), 'spox')
|
129
|
+
end
|
130
|
+
dynamic!(:ec2_instance, :fubar).properties do
|
131
|
+
key_name if!(:creator_is_spox, 'spox-key', 'default')
|
132
|
+
end
|
133
|
+
end
|
134
|
+
~~~
|
135
|
+
|
136
|
+
The condition can also be used to restrict the creation of a resource:
|
137
|
+
|
138
|
+
~~~ruby
|
139
|
+
SparkleFormation.new(:template) do
|
140
|
+
parameters.creator do
|
141
|
+
type 'String'
|
142
|
+
default 'spox'
|
143
|
+
end
|
144
|
+
conditions do
|
145
|
+
creator_is_spox equals!(ref!(:creator), 'spox')
|
146
|
+
end
|
147
|
+
dynamic!(:ec2_instance, :fubar) do
|
148
|
+
on_condition :creator_is_spox
|
149
|
+
end
|
150
|
+
end
|
151
|
+
~~~
|
152
|
+
|
153
|
+
* [Conditions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html)
|
154
|
+
* [Condition Functions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html)
|
155
|
+
|
156
|
+
#### Resources
|
157
|
+
|
158
|
+
Resources are the infrastructure items and configurations to be
|
159
|
+
provisioned by the orchestration API:
|
160
|
+
|
161
|
+
~~~ruby
|
162
|
+
SparkleFormation.new(:template) do
|
163
|
+
resources.my_instance do
|
164
|
+
type 'AWS::EC2::Instance'
|
165
|
+
properties do
|
166
|
+
key_name 'default'
|
167
|
+
...
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
~~~
|
172
|
+
|
173
|
+
* [Resources](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html)
|
174
|
+
|
175
|
+
#### Outputs
|
176
|
+
|
177
|
+
Outputs are resultant values from the provisioned infrastructure stack.
|
178
|
+
It generally contains information about specific resource attributes.
|
179
|
+
|
180
|
+
~~~ruby
|
181
|
+
SparkleFormation.new(:template) do
|
182
|
+
outputs do
|
183
|
+
instance_address do
|
184
|
+
description 'Public IP of my instance'
|
185
|
+
value attr!(:my_instance, :public_ip)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
~~~
|
190
|
+
|
191
|
+
Conditions can also be applied on outputs:
|
192
|
+
|
193
|
+
~~~ruby
|
194
|
+
SparkleFormation.new(:template) do
|
195
|
+
outputs do
|
196
|
+
instance_address do
|
197
|
+
description 'Public IP of my instance'
|
198
|
+
value attr!(:my_instance, :public_ip)
|
199
|
+
on_condition! :my_condition
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
~~~
|
204
|
+
|
205
|
+
* [Outputs](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html)
|
@@ -0,0 +1,360 @@
|
|
1
|
+
---
|
2
|
+
title: "SparkleFormation Building Blocks"
|
3
|
+
category: "dsl"
|
4
|
+
weight: 3
|
5
|
+
anchors:
|
6
|
+
- title: "Components"
|
7
|
+
url: "#components"
|
8
|
+
- title: "Dynamics"
|
9
|
+
url: "#dynamics"
|
10
|
+
- title: "Registry"
|
11
|
+
url: "#registry"
|
12
|
+
- title: "Templates"
|
13
|
+
url: "#templates"
|
14
|
+
---
|
15
|
+
|
16
|
+
## SparkleFormation Building Blocks
|
17
|
+
|
18
|
+
### Building Blocks
|
19
|
+
|
20
|
+
SparkleFormation provides a collection of building blocks to
|
21
|
+
assist in applying [DRY][1] concepts to template generation. The
|
22
|
+
building blocks provided by SparkleFormation are:
|
23
|
+
|
24
|
+
- [Components](#components)
|
25
|
+
- [Dynamics](#dynamics)
|
26
|
+
- [Registry](#registry)
|
27
|
+
- [Templates](#templates)
|
28
|
+
|
29
|
+
### Components
|
30
|
+
|
31
|
+
Components are static pieces of template that are inserted once.
|
32
|
+
They do not provide any dynamic functionality and are intended
|
33
|
+
for common static content. Components are the second set of items
|
34
|
+
loaded during template compilation and are evaluated in the order
|
35
|
+
defined.
|
36
|
+
|
37
|
+
An example component for an AWS CloudFormation based implementation
|
38
|
+
may contain the template versioning information and a common stack
|
39
|
+
output value:
|
40
|
+
|
41
|
+
~~~ruby
|
42
|
+
SparkleFormation.component(:common) do
|
43
|
+
set!('AWSTemplateFormatVersion', '2010-09-09')
|
44
|
+
|
45
|
+
outputs.creator do
|
46
|
+
description 'Stack creator'
|
47
|
+
value ENV['USER']
|
48
|
+
end
|
49
|
+
end
|
50
|
+
~~~
|
51
|
+
|
52
|
+
There are two supported ways of creating components:
|
53
|
+
|
54
|
+
* Path based components
|
55
|
+
* Name based components
|
56
|
+
|
57
|
+
#### Path based components
|
58
|
+
|
59
|
+
Path based components are components that infer their name based on
|
60
|
+
the base name of a file. These types of components use the `SparkleFormation.build`
|
61
|
+
method, which does not accept a name argument. For example:
|
62
|
+
|
63
|
+
~~~ruby
|
64
|
+
# components/common.rb
|
65
|
+
SparkleFormation.build do
|
66
|
+
...
|
67
|
+
end
|
68
|
+
~~~
|
69
|
+
|
70
|
+
The name of this component will be `common`.
|
71
|
+
|
72
|
+
#### Name based components
|
73
|
+
|
74
|
+
Name based components are components whose names are explicitly
|
75
|
+
defined. These types of components use the `SparkleFormation.component`
|
76
|
+
method, which accepts a name argument. For example:
|
77
|
+
|
78
|
+
~~~ruby
|
79
|
+
# components/my-common-component.rb
|
80
|
+
SparkleFormation.component(:core) do
|
81
|
+
...
|
82
|
+
end
|
83
|
+
~~~
|
84
|
+
|
85
|
+
The name of this component will be `core` as it is explicitly provided
|
86
|
+
when creating the component. These name based components are specifically
|
87
|
+
geared towards usage in "sparkle packs" or any other implementations where
|
88
|
+
a single file may provide multiple components or building blocks, or where
|
89
|
+
the file name may be required to be different from the name of the component.
|
90
|
+
|
91
|
+
### Dynamics
|
92
|
+
|
93
|
+
Dynamics are reusable blocks of code that can be applied multiple times
|
94
|
+
within the same template to provide multiple discrete sets of content.
|
95
|
+
They provide the ability to refactor common template content out into
|
96
|
+
reusable and configurable dynamics that can then be re-inserted using
|
97
|
+
customized naming structures. Dynamics _always_ explicitly define their
|
98
|
+
name when creating unlike components which optionally supports explict
|
99
|
+
naming.
|
100
|
+
|
101
|
+
Dynamics are registered blocks which accept two parameters:
|
102
|
+
|
103
|
+
1. Name for the dynamic call
|
104
|
+
2. Configuration Hash for the dynamic call
|
105
|
+
|
106
|
+
Here is an example dynamic:
|
107
|
+
|
108
|
+
~~~ruby
|
109
|
+
# dynamics/node.rb
|
110
|
+
SparkleFormation.dynamic(:node) do |_name, _config={}|
|
111
|
+
unless(_config[:ssh_key])
|
112
|
+
parameters.set!("#{_name}_ssh_key".to_sym) do
|
113
|
+
type 'String'
|
114
|
+
end
|
115
|
+
end
|
116
|
+
dynamic!(:ec2_instance, _name).properties do
|
117
|
+
key_name _config[:ssh_key] ? _config[:ssh_key] : ref!("#{_name}_ssh_key".to_sym)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
~~~
|
121
|
+
|
122
|
+
*NOTE: The underscore (`_`) prefix on the parameter names are simply a convention
|
123
|
+
and not required. It is a convention to make it easier to identify variables
|
124
|
+
used within the dynamic, and its usage is completely author dependent.*
|
125
|
+
|
126
|
+
The dynamic defines two parameters: `_name` and `_config`. The `_config`
|
127
|
+
parameter is defaulted to an empty Hash allowing the dynamic call to optionally
|
128
|
+
accept a configuration Hash. With this dynamic in place, it can be called
|
129
|
+
multiple times within a template:
|
130
|
+
|
131
|
+
~~~ruby
|
132
|
+
SparkleFormation.new(:node_stack) do
|
133
|
+
dynamic!(:node, :fubar)
|
134
|
+
dynamic!(:node, :foobar, :ssh_key => 'default')
|
135
|
+
end
|
136
|
+
~~~
|
137
|
+
|
138
|
+
#### Builtin Dynamics
|
139
|
+
|
140
|
+
SparkleFormation includes a lookup of known AWS resources which can be accessed
|
141
|
+
using the `dynamic!` method. This lookup is provided simply as a convenience
|
142
|
+
to speed development and compact implementations. When a builtin is inserted,
|
143
|
+
it will automatically set the `type` of the resource and evaluate an optionally
|
144
|
+
provided block within the resource. The following templates will generate
|
145
|
+
equivalent results when compiled:
|
146
|
+
|
147
|
+
~~~ruby
|
148
|
+
SparkleFormation.new(:with_dynamic) do
|
149
|
+
dynamic!(:ec2_instance, :fubar).properties.key_name 'default'
|
150
|
+
end
|
151
|
+
~~~
|
152
|
+
|
153
|
+
~~~ruby
|
154
|
+
SparkleFormation.new(:without_dynamic) do
|
155
|
+
resources.fubar_ec2_instance do
|
156
|
+
type 'AWS::EC2::Instance'
|
157
|
+
properties.key_name 'default'
|
158
|
+
end
|
159
|
+
end
|
160
|
+
~~~
|
161
|
+
|
162
|
+
##### Builtin Lookup Behavior
|
163
|
+
|
164
|
+
Builtin lookups are based on the resource type. Resource matching is performed
|
165
|
+
using a *suffix based* match. When searching for matching types, the _first_
|
166
|
+
match is used. For example:
|
167
|
+
|
168
|
+
~~~ruby
|
169
|
+
SparkleFormation.new(:class_only) do
|
170
|
+
dynamic!(:instance, :foobar)
|
171
|
+
end
|
172
|
+
~~~
|
173
|
+
|
174
|
+
When the lookup is performed, this will match the `AWS::EC2::Instance` resource.
|
175
|
+
This may not be the correct match, however, since there is also an
|
176
|
+
`AWS::OpsWorks::Instance` resource type. The correct lookup can be forced (if
|
177
|
+
the `OpsWorks` resource is the desired resource) by providing the namespace
|
178
|
+
prefix:
|
179
|
+
|
180
|
+
~~~ruby
|
181
|
+
SparkleFormation.new(:with_namespace) do
|
182
|
+
dynamic!(:opsworks_instance, :foobar)
|
183
|
+
end
|
184
|
+
~~~
|
185
|
+
|
186
|
+
This can also be taken a step further by including the `AWS` namespace as well:
|
187
|
+
|
188
|
+
~~~ruby
|
189
|
+
SparkleFormation.new(:with_namespace) do
|
190
|
+
dynamic!(:aws_opsworks_instance, :foobar)
|
191
|
+
end
|
192
|
+
~~~
|
193
|
+
|
194
|
+
but will likely be a bit superfluous. It is also important to note the name
|
195
|
+
of the generated resource is dependent on the value of the first parameter.
|
196
|
+
The resultant resource names from the above three examples will be:
|
197
|
+
|
198
|
+
* FoobarInstance
|
199
|
+
* FoobarOpsworksInstance
|
200
|
+
* FoobarAwsOpsworksInstance
|
201
|
+
|
202
|
+
The value used for the suffix of the resource name can be provided with
|
203
|
+
the `dynamic!` call:
|
204
|
+
|
205
|
+
~~~ruby
|
206
|
+
SparkleFormation.new(:with_namespace) do
|
207
|
+
dynamic!(:aws_opsworks_instance, :foobar,
|
208
|
+
:resource_suffix_name => :instance
|
209
|
+
)
|
210
|
+
end
|
211
|
+
~~~
|
212
|
+
|
213
|
+
which will result in a resource name: `FoobarInstance`
|
214
|
+
|
215
|
+
##### Dynamic Return Context
|
216
|
+
|
217
|
+
When defining custom dynamics, the result of the dynamic block is important.
|
218
|
+
A dynamic can make multiple modifications to a template when inserted. For
|
219
|
+
example, addition of parameters, resources, and/or outputs. It is important
|
220
|
+
to use the values returned from the dynamic block to prevent surprises.
|
221
|
+
When the `dynamic!` is called and provided a block, the block is evaluated
|
222
|
+
within the context returned from the `dynamic!`.
|
223
|
+
|
224
|
+
For example, this is an improper implementation of a dynamic:
|
225
|
+
|
226
|
+
~~~ruby
|
227
|
+
SparkleFormation.dynamic(:bad_dynamic) do |_name, _config|
|
228
|
+
dynamic!(:ec2_instance, _name)
|
229
|
+
outputs do
|
230
|
+
address.value attr!("#{_name}_ec2_instance".to_sym, :public_ip)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
~~~
|
234
|
+
|
235
|
+
If a template attempts to use this dynamic and make an override modification
|
236
|
+
to the instance:
|
237
|
+
|
238
|
+
~~~ruby
|
239
|
+
SparkleFormation.new(:failed_template) do
|
240
|
+
dynamic!(:bad_dynamic, :foobar) do
|
241
|
+
properties.key_name 'default'
|
242
|
+
end
|
243
|
+
end
|
244
|
+
~~~
|
245
|
+
|
246
|
+
The `properties.key_name` will be evaluated within the context of the `outputs`
|
247
|
+
because it is the returned value of the dynamic block. Instead the dynamic should
|
248
|
+
return the context of the referenced resource (if applicable). To make the
|
249
|
+
dynamic act as expected, the resource must be returned from the block.
|
250
|
+
|
251
|
+
~~~ruby
|
252
|
+
SparkleFormation.dynamic(:good_dynamic) do |_name, _config|
|
253
|
+
_resource = dynamic!(:ec2_instance, _name)
|
254
|
+
outputs do
|
255
|
+
address.value attr!("#{_name}_ec2_instance".to_sym, :public_ip)
|
256
|
+
end
|
257
|
+
_resource
|
258
|
+
end
|
259
|
+
~~~
|
260
|
+
|
261
|
+
This will ensure the instance resource is the context returned. The blocks provided
|
262
|
+
will work as expected:
|
263
|
+
|
264
|
+
~~~ruby
|
265
|
+
SparkleFormation.new(:successful_template) do
|
266
|
+
dynamic!(:good_dynamic, :foobar) do
|
267
|
+
properties.key_name 'default'
|
268
|
+
end
|
269
|
+
end
|
270
|
+
~~~
|
271
|
+
|
272
|
+
##### Dynamic Lookup Behavior
|
273
|
+
|
274
|
+
Dynamics can be loaded from multiple locations. When SparkleFormation performs
|
275
|
+
a dynamic lookup, the following locations are checked in order of precedence:
|
276
|
+
|
277
|
+
1. Implementation local `dynamics` directory
|
278
|
+
2. SparklePack dynamics with reverse load order precedence
|
279
|
+
3. Builtin dynamics lookup table
|
280
|
+
|
281
|
+
### Registry
|
282
|
+
|
283
|
+
Registry entries are lightweight dynamics that are useful for storing items that
|
284
|
+
may be used in multiple locations. For example, the valid sizes of an instance
|
285
|
+
within an infrastructure will generally be restricted to a specific list.
|
286
|
+
This list can be stored within a registry to provide a single point of
|
287
|
+
contact for any changes:
|
288
|
+
|
289
|
+
~~~ruby
|
290
|
+
SfnRegistry.register(:instance_sizes) do
|
291
|
+
[
|
292
|
+
'm3.large',
|
293
|
+
'm3.medium',
|
294
|
+
't2.medium'
|
295
|
+
]
|
296
|
+
end
|
297
|
+
SfnRegistry.register(:instance_size_default){ 'm3.medium' }
|
298
|
+
~~~
|
299
|
+
|
300
|
+
With the array registered as `registry!(:instance_sizes)`, we can now reference it:
|
301
|
+
|
302
|
+
~~~ruby
|
303
|
+
SparkleFormation.new(:instance_stack) do
|
304
|
+
parameters.instance_size do
|
305
|
+
type 'String'
|
306
|
+
allowed_values registry!(:instance_sizes)
|
307
|
+
default registry!(:instance_size_default)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
~~~
|
311
|
+
|
312
|
+
### Templates
|
313
|
+
|
314
|
+
Templates are the files that pull all the building blocks together to produce
|
315
|
+
a final data structure that will be serialized into a document. This data structure
|
316
|
+
can be submitted to an orchestration API.
|
317
|
+
|
318
|
+
There are three stages of template compilation:
|
319
|
+
|
320
|
+
1. Evaluate optional block given on instantiation
|
321
|
+
2. Evaluate any loaded components
|
322
|
+
3. Evaluate `override` block
|
323
|
+
|
324
|
+
#### Instantiation Block
|
325
|
+
|
326
|
+
A block provided on instantiation is the first block evaluated:
|
327
|
+
|
328
|
+
~~~ruby
|
329
|
+
SparkleFormation.new(:my_template) do
|
330
|
+
dynamic!(:ec2_instance, :foobar)
|
331
|
+
end
|
332
|
+
~~~
|
333
|
+
|
334
|
+
#### Loaded Components
|
335
|
+
|
336
|
+
Components are evaluated in the order they are added to the template via
|
337
|
+
the `load` method:
|
338
|
+
|
339
|
+
~~~ruby
|
340
|
+
SparkleFormation.new(:my_template) do
|
341
|
+
dynamic!(:ec2_instance, :foobar)
|
342
|
+
end.load(:common, :special)
|
343
|
+
~~~
|
344
|
+
|
345
|
+
On compilation, this will evaluate the instantiation block first, the `common`
|
346
|
+
component second, and finally the `special` component.
|
347
|
+
|
348
|
+
#### Overrides
|
349
|
+
|
350
|
+
Override blocks are the final blocks evaluated during compilation:
|
351
|
+
|
352
|
+
~~~ruby
|
353
|
+
SparkleFormation.new(:my_template) do
|
354
|
+
dynamic!(:ec2_instance, :foobar)
|
355
|
+
end.load(:common, :special).overrides do
|
356
|
+
resources.foobar_ec2_instance.properties.key_name 'default'
|
357
|
+
end
|
358
|
+
~~~
|
359
|
+
|
360
|
+
[1]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
|