sparkle_formation 0.2.0 → 0.2.2
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 +7 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +2 -4
- data/docs/README.md +177 -0
- data/docs/anatomy.md +203 -0
- data/docs/building-blocks.md +275 -0
- data/docs/examples/cloudformation/components/base.rb +25 -0
- data/docs/examples/cloudformation/dynamics/elb.rb +23 -0
- data/docs/examples/cloudformation/templates/website.rb +30 -0
- data/docs/examples/template_json/website.json +88 -0
- data/docs/examples/website.rb +74 -0
- data/docs/functions.md +41 -0
- data/docs/properties.md +32 -0
- data/docs/provisioning.md +82 -0
- data/docs/resource-reference.md +49 -0
- data/lib/sparkle_formation/sparkle_formation.rb +1 -1
- data/lib/sparkle_formation/translation/heat.rb +84 -1
- data/lib/sparkle_formation/translation/rackspace.rb +355 -11
- data/lib/sparkle_formation/translation.rb +109 -12
- data/lib/sparkle_formation/version.rb +2 -3
- metadata +45 -39
@@ -0,0 +1,25 @@
|
|
1
|
+
SparkleFormation.build do
|
2
|
+
set!('AWSTemplateFormatVersion', '2010-09-09')
|
3
|
+
|
4
|
+
resources.cfn_user do
|
5
|
+
type 'AWS::IAM::User'
|
6
|
+
properties.path '/'
|
7
|
+
properties.policies _array(
|
8
|
+
-> {
|
9
|
+
policy_name 'cfn_access'
|
10
|
+
policy_document.statement _array(
|
11
|
+
-> {
|
12
|
+
effect 'Allow'
|
13
|
+
action 'cloudformation:DescribeStackResource'
|
14
|
+
resource '*'
|
15
|
+
}
|
16
|
+
)
|
17
|
+
}
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
resources.cfn_keys do
|
22
|
+
type 'AWS::IAM::AccessKey'
|
23
|
+
properties.user_name ref!(:cfn_user)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
SparkleFormation.dynamic(:elb) do |_name, _config={}|
|
2
|
+
resources("#{_name}_elb".to_sym) do
|
3
|
+
type 'AWS::ElasticLoadBalancing::LoadBalancer'
|
4
|
+
properties do
|
5
|
+
availability_zones._set('Fn::GetAZs', '')
|
6
|
+
listeners _array(
|
7
|
+
-> {
|
8
|
+
load_balancer_port _config[:load_balancer_port] || '80'
|
9
|
+
protocol _config[:protocol] || 'HTTP'
|
10
|
+
instance_port _config[:instance_port] || '80'
|
11
|
+
instance_protocol _config[:instance_protocol] || 'HTTP'
|
12
|
+
}
|
13
|
+
)
|
14
|
+
health_check do
|
15
|
+
target _config[:target] || 'HTTP:80/'
|
16
|
+
healthy_threshold _config[:healthy_threshold] || '3'
|
17
|
+
unhealthy_threshold _config[:unhealthy_threshold] || '3'
|
18
|
+
interval _config[:interval] || '5'
|
19
|
+
timeout _config[:timeout] || '15'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
SparkleFormation.new(:website).load(:base).overrides do
|
2
|
+
|
3
|
+
description 'Supercool Website'
|
4
|
+
|
5
|
+
parameters.web_nodes do
|
6
|
+
type 'Number'
|
7
|
+
description 'Number of web nodes for ASG.'
|
8
|
+
default 2
|
9
|
+
end
|
10
|
+
|
11
|
+
resources.website_autoscale do
|
12
|
+
type 'AWS::AutoScaling::AutoScalingGroup'
|
13
|
+
properties do
|
14
|
+
availability_zones({'Fn::GetAZs' => ''})
|
15
|
+
launch_configuration_name ref!(:website_launch_config)
|
16
|
+
min_size ref!(:web_nodes)
|
17
|
+
max_size ref!(:web_nodes)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
resources.website_launch_config do
|
22
|
+
type 'AWS::AutoScaling::LaunchConfiguration'
|
23
|
+
properties do
|
24
|
+
image_id 'ami-123456'
|
25
|
+
instance_type 'm3.medium'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
dynamic!(:elb, 'website')
|
30
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
{
|
2
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
3
|
+
"Description": "Supercool Website",
|
4
|
+
"Resources": {
|
5
|
+
"CfnUser": {
|
6
|
+
"Type": "AWS::IAM::User",
|
7
|
+
"Properties": {
|
8
|
+
"Path": "/",
|
9
|
+
"Policies": [
|
10
|
+
{
|
11
|
+
"PolicyName": "cfn_access",
|
12
|
+
"PolicyDocument": {
|
13
|
+
"Statement": [
|
14
|
+
{
|
15
|
+
"Effect": "Allow",
|
16
|
+
"Action": "cloudformation:DescribeStackResource",
|
17
|
+
"Resource": "*"
|
18
|
+
}
|
19
|
+
]
|
20
|
+
}
|
21
|
+
}
|
22
|
+
]
|
23
|
+
}
|
24
|
+
},
|
25
|
+
"CfnKeys": {
|
26
|
+
"Type": "AWS::IAM::AccessKey",
|
27
|
+
"Properties": {
|
28
|
+
"UserName": {
|
29
|
+
"Ref": "CfnUser"
|
30
|
+
}
|
31
|
+
}
|
32
|
+
},
|
33
|
+
"WebsiteAutoscale": {
|
34
|
+
"Type": "AWS::AutoScaling::AutoScalingGroup",
|
35
|
+
"Properties": {
|
36
|
+
"AvailabilityZones": {
|
37
|
+
"Fn::GetAZs": ""
|
38
|
+
},
|
39
|
+
"LaunchConfigurationName": {
|
40
|
+
"Ref": "WebsiteLaunchConfig"
|
41
|
+
},
|
42
|
+
"MinSize": {
|
43
|
+
"Ref": "WebNodes"
|
44
|
+
},
|
45
|
+
"MaxSize": {
|
46
|
+
"Ref": "WebNodes"
|
47
|
+
}
|
48
|
+
}
|
49
|
+
},
|
50
|
+
"WebsiteLaunchConfig": {
|
51
|
+
"Type": "AWS::AutoScaling::LaunchConfiguration",
|
52
|
+
"Properties": {
|
53
|
+
"ImageId": "ami-123456",
|
54
|
+
"InstanceType": "m3.medium"
|
55
|
+
}
|
56
|
+
},
|
57
|
+
"WebsiteElb": {
|
58
|
+
"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
|
59
|
+
"Properties": {
|
60
|
+
"AvailabilityZones": {
|
61
|
+
"Fn::GetAZs": ""
|
62
|
+
},
|
63
|
+
"Listeners": [
|
64
|
+
{
|
65
|
+
"LoadBalancerPort": "80",
|
66
|
+
"Protocol": "HTTP",
|
67
|
+
"InstancePort": "80",
|
68
|
+
"InstanceProtocol": "HTTP"
|
69
|
+
}
|
70
|
+
],
|
71
|
+
"HealthCheck": {
|
72
|
+
"Target": "HTTP:80/",
|
73
|
+
"HealthyThreshold": "3",
|
74
|
+
"UnhealthyThreshold": "3",
|
75
|
+
"Interval": "5",
|
76
|
+
"Timeout": "15"
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
},
|
81
|
+
"Parameters": {
|
82
|
+
"WebNodes": {
|
83
|
+
"Type": "Number",
|
84
|
+
"Description": "Number of web nodes for ASG.",
|
85
|
+
"Default": "2"
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
SparkleFormation.new('website') do
|
2
|
+
|
3
|
+
set!('AWSTemplateFormatVersion', '2010-09-09')
|
4
|
+
|
5
|
+
description 'Supercool Website'
|
6
|
+
|
7
|
+
resources.cfn_user do
|
8
|
+
type 'AWS::IAM::User'
|
9
|
+
properties.path '/'
|
10
|
+
properties.policies _array(
|
11
|
+
-> {
|
12
|
+
policy_name 'cfn_access'
|
13
|
+
policy_document.statement _array(
|
14
|
+
-> {
|
15
|
+
effect 'Allow'
|
16
|
+
action 'cloudformation:DescribeStackResource'
|
17
|
+
resource '*'
|
18
|
+
}
|
19
|
+
)
|
20
|
+
}
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
resources.cfn_keys do
|
25
|
+
type 'AWS::IAM::AccessKey'
|
26
|
+
properties.user_name ref!(:cfn_user)
|
27
|
+
end
|
28
|
+
|
29
|
+
parameters.web_nodes do
|
30
|
+
type 'Number'
|
31
|
+
description 'Number of web nodes for ASG.'
|
32
|
+
default 2
|
33
|
+
end
|
34
|
+
|
35
|
+
resources.website_autoscale do
|
36
|
+
type 'AWS::AutoScaling::AutoScalingGroup'
|
37
|
+
properties do
|
38
|
+
availability_zones({'Fn::GetAZs' => ''})
|
39
|
+
launch_configuration_name ref!(:website_launch_config)
|
40
|
+
min_size ref!(:web_nodes)
|
41
|
+
max_size ref!(:web_nodes)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
resources.website_launch_config do
|
46
|
+
type 'AWS::AutoScaling::LaunchConfiguration'
|
47
|
+
properties do
|
48
|
+
image_id 'ami-123456'
|
49
|
+
instance_type 'm3.medium'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
resources.website_elb do
|
54
|
+
type 'AWS::ElasticLoadBalancing::LoadBalancer'
|
55
|
+
properties do
|
56
|
+
availability_zones._set('Fn::GetAZs', '')
|
57
|
+
listeners _array(
|
58
|
+
-> {
|
59
|
+
load_balancer_port '80'
|
60
|
+
protocol 'HTTP'
|
61
|
+
instance_port '80'
|
62
|
+
instance_protocol 'HTTP'
|
63
|
+
}
|
64
|
+
)
|
65
|
+
health_check do
|
66
|
+
target 'HTTP:80/'
|
67
|
+
healthy_threshold '3'
|
68
|
+
unhealthy_threshold '3'
|
69
|
+
interval '5'
|
70
|
+
timeout '15'
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/docs/functions.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
## Intrinsic Functions
|
2
|
+
The following are all intrinsic AWS Cloudformation functions that are
|
3
|
+
supported with special syntax in SparkleFormation. Note that these may
|
4
|
+
not be implemented for all providers.
|
5
|
+
|
6
|
+
### Ref
|
7
|
+
Ref allows you to reference parameter and resource values. We did this
|
8
|
+
earlier with the autoscaling group size:
|
9
|
+
```ruby
|
10
|
+
parameters.web_nodes do
|
11
|
+
type 'Number'
|
12
|
+
description 'Number of web nodes for ASG.'
|
13
|
+
default '2'
|
14
|
+
end
|
15
|
+
|
16
|
+
...
|
17
|
+
|
18
|
+
min_size ref!(:web_nodes)
|
19
|
+
```
|
20
|
+
It also works for resource names. The following returns the name of
|
21
|
+
the launch configuration so we can use it in the autoscaling group
|
22
|
+
properties.
|
23
|
+
```ruby
|
24
|
+
ref!(:website_launch_config)
|
25
|
+
```
|
26
|
+
|
27
|
+
### Join
|
28
|
+
A Join combines strings. You can use Refs and Mappings within a Join.
|
29
|
+
```ruby
|
30
|
+
join!(ref!(:environment), '-', map!(:region_map, ref!('AWS::Region'), :ami))
|
31
|
+
```
|
32
|
+
Would return 'development-us-east-1', if we built a stack in the
|
33
|
+
AWS Virgnia region and provided 'development' for the environment
|
34
|
+
parameter.
|
35
|
+
|
36
|
+
### Attr
|
37
|
+
Certain resources attributes can be retrieved directly. To access an
|
38
|
+
IAM user's (in this case, :cfn_user) secret key:
|
39
|
+
```ruby
|
40
|
+
attr!(:cfn_user, :secret_access_key)
|
41
|
+
```
|
data/docs/properties.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
## Universal Properties
|
2
|
+
|
3
|
+
### Tags
|
4
|
+
Tags can be applied to most resources. These make it easy to track
|
5
|
+
resource usage across stacks. They may be used for cost tracking as
|
6
|
+
well as configuration tools that are cloud-infrastructure aware. Tags
|
7
|
+
are provided as key/value pairs within an array. In this example we
|
8
|
+
provide the stack name and a contact email:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
resources.website_autoscale do
|
12
|
+
type 'AWS::AutoScaling::AutoScalingGroup'
|
13
|
+
properties do
|
14
|
+
availability_zones({ 'Fn::GetAZs' => '' })
|
15
|
+
tags _array(
|
16
|
+
-> {
|
17
|
+
key 'StackName'
|
18
|
+
value ref!('AWS::StackName'))
|
19
|
+
propagate_at_launch true
|
20
|
+
},
|
21
|
+
-> {
|
22
|
+
key 'ContactEmail'
|
23
|
+
value 'support@hw-ops.com'
|
24
|
+
propagate_at_launch true
|
25
|
+
}
|
26
|
+
)
|
27
|
+
launch_configuration_name ref!(:website_launch_config)
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
Please check the relevant reference documentation to confirm that tags
|
32
|
+
are available for a specific resource type.
|
@@ -0,0 +1,82 @@
|
|
1
|
+
## Provisioning SparkleFormations
|
2
|
+
|
3
|
+
### JSON Templates
|
4
|
+
|
5
|
+
Generating JSON from a SparkleFormation template is as simple as
|
6
|
+
calling `SparkleFormation.compile()` on the template file. Here's a simple
|
7
|
+
script to output a JSON template from a supplied
|
8
|
+
SparkeFormation template:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
#!/usr/bin/env ruby
|
12
|
+
require 'sparkle_formation'
|
13
|
+
require 'json'
|
14
|
+
|
15
|
+
puts SparkleFormation.compile(ARGV[0])
|
16
|
+
```
|
17
|
+
|
18
|
+
The output can be written to a file and uploaded to the provider using
|
19
|
+
the method of your choice.
|
20
|
+
|
21
|
+
For a more legible template:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
puts JSON.pretty_generate(SparkleFormation.compile(ARGV[0]))
|
25
|
+
```
|
26
|
+
|
27
|
+
Note: The output from this command may not be usable with cloud providers,
|
28
|
+
as the many spaces and newlines may exceed the cloudformation
|
29
|
+
character limit. However, it is much easier to read.
|
30
|
+
|
31
|
+
### Knife Cloudformation
|
32
|
+
knife-cloudformation [knife-cloudformation plugin](https://rubygems.org/gems/knife-cloudformation) is a plugin for
|
33
|
+
knife that provisions cloudformation stacks. It can be used with
|
34
|
+
SparkleFormation to build stacks without the intermediary steps of
|
35
|
+
writing a JSON template to file and uploading the template to the provider.
|
36
|
+
|
37
|
+
#### Processing SparkleFormation Templates
|
38
|
+
To build a stack directly from a SparkleFormation template, use the
|
39
|
+
`create` command with the `--file` and `--processing` flags:
|
40
|
+
|
41
|
+
```
|
42
|
+
knife cloudformation create my-web-stack --file templates/website.rb --processing
|
43
|
+
```
|
44
|
+
|
45
|
+
`--file` directs knife to a file under the `cloudformation` directory,
|
46
|
+
and `--processing` tells knife to render JSON from the
|
47
|
+
SparkleFormation template before passing it to the provider.
|
48
|
+
|
49
|
+
#### Applying Stacks
|
50
|
+
You can also apply an existing stack's outputs to the stack you are
|
51
|
+
building. Using the `--apply-stack` flag sets parameters to the
|
52
|
+
values of any matching outputs.
|
53
|
+
|
54
|
+
Consider that you have built a database stack (`db-stack-01`) that includes an output for the
|
55
|
+
database endpoint:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
outputs do
|
59
|
+
database_endpoint do
|
60
|
+
value attr!(:database_elb, 'DNSName')
|
61
|
+
description "Database ELB Endpoint for client connections"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
```
|
65
|
+
|
66
|
+
Next, you build a website stack (`web-stack-01`) that needs to connect to the
|
67
|
+
database. The SparkleFormation for this stack includes a parameter to
|
68
|
+
prompt for the database endpoint:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
parameters.database_endpoint do
|
72
|
+
type 'String'
|
73
|
+
description 'Database endpoint to connect to'
|
74
|
+
default 'localhost'
|
75
|
+
end
|
76
|
+
```
|
77
|
+
|
78
|
+
Using knife-cloudformation, you apply the database stack in order to
|
79
|
+
automatically provide the correct database endpoint:
|
80
|
+
|
81
|
+
`knife cloudformation create web-stack-01 --file templates/website.rb --processing --apply-stack db-stack-01`
|
82
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
## Resource Reference
|
2
|
+
|
3
|
+
This is a best-effort list of commonly used cloudformation resources and their
|
4
|
+
availability/feature set in supported cloud providers. This list does
|
5
|
+
not cover everything that may be offered by a specific provider, and
|
6
|
+
is not intended as a comparison of cloud providers.
|
7
|
+
|
8
|
+
#### Auto Scaling Groups
|
9
|
+
|
10
|
+
|Provider |Available |Caveats & Limitations |
|
11
|
+
|------------|----------|-----------------------------------------------------------------------------|
|
12
|
+
|AWS |Yes |EC2 Classic and VPC use mutually exclusive properties. |
|
13
|
+
|Rackspace |Yes |Autoscaling will not replace lost instances, only does policy based scaling. |
|
14
|
+
|
15
|
+
#### Compute Instances
|
16
|
+
|
17
|
+
|Provider |Available |Caveats & Limitations |
|
18
|
+
|------------|----------|-----------------------------------------------------------------------------|
|
19
|
+
|AWS |Yes | |
|
20
|
+
|Rackspace |Yes | |
|
21
|
+
|
22
|
+
#### Load Balancers
|
23
|
+
|
24
|
+
|Provider |Available |Caveats & Limitations |
|
25
|
+
|------------|----------|-----------------------------------------------------------------------------|
|
26
|
+
|AWS |Yes |Security Group Ingress is not automatic. Must be defined separately. |
|
27
|
+
|Rackspace |Yes |Multiple ports generates new template resources. |
|
28
|
+
|
29
|
+
#### Security Groups
|
30
|
+
|
31
|
+
|Provider |Available |Caveats & Limitations |
|
32
|
+
|------------|----------|-----------------------------------------------------------------------------|
|
33
|
+
|AWS |Yes | |
|
34
|
+
|Rackspace |No | |
|
35
|
+
|
36
|
+
#### Storage
|
37
|
+
|
38
|
+
|Provider |Available |Caveats & Limitations |
|
39
|
+
|------------|----------|-----------------------------------------------------------------------------|
|
40
|
+
|AWS |Yes | |
|
41
|
+
|Rackspace |No | |
|
42
|
+
|
43
|
+
|
44
|
+
#### Stack Users
|
45
|
+
|
46
|
+
|Provider |Available |Caveats & Limitations |
|
47
|
+
|------------|----------|-----------------------------------------------------------------------------|
|
48
|
+
|AWS |Yes | |
|
49
|
+
|Rackspace |No | |
|
@@ -154,7 +154,7 @@ class SparkleFormation
|
|
154
154
|
#
|
155
155
|
# @param name [String, Symbol] name of dynamic
|
156
156
|
# @param args [Hash] dynamic metadata
|
157
|
-
# @
|
157
|
+
# @option args [Hash] :parameters description of _config parameters
|
158
158
|
# @example
|
159
159
|
# metadata describes dynamic parameters for _config hash:
|
160
160
|
# :item_name => {:description => 'Defines item name', :type => 'String'}
|
@@ -3,6 +3,66 @@ class SparkleFormation
|
|
3
3
|
# Translation for Heat (HOT)
|
4
4
|
class Heat < Translation
|
5
5
|
|
6
|
+
# Translate stack definition
|
7
|
+
#
|
8
|
+
# @return [TrueClass]
|
9
|
+
# @note this is an override to return in proper HOT format
|
10
|
+
# @todo still needs replacements of functions and pseudo-params
|
11
|
+
def translate!
|
12
|
+
super
|
13
|
+
cache = MultiJson.load(MultiJson.dump(translated))
|
14
|
+
# top level
|
15
|
+
cache.each do |k,v|
|
16
|
+
translated.delete(k)
|
17
|
+
translated[snake(k).to_s] = v
|
18
|
+
end
|
19
|
+
# params
|
20
|
+
cache.fetch('Parameters', {}).each do |k,v|
|
21
|
+
translated['parameters'][k] = Hash[
|
22
|
+
v.map do |key, value|
|
23
|
+
if(key == 'Type')
|
24
|
+
[snake(key).to_s, value.downcase]
|
25
|
+
elsif(key == 'AllowedValues')
|
26
|
+
# @todo fix this up to properly build constraints
|
27
|
+
['constraints', [{'allowed_values' => value}]]
|
28
|
+
else
|
29
|
+
[snake(key).to_s, value]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
]
|
33
|
+
end
|
34
|
+
# resources
|
35
|
+
cache.fetch('Resources', {}).each do |r_name, r_value|
|
36
|
+
translated['resources'][r_name] = Hash[
|
37
|
+
r_value.map do |k,v|
|
38
|
+
[snake(k).to_s, v]
|
39
|
+
end
|
40
|
+
]
|
41
|
+
end
|
42
|
+
# outputs
|
43
|
+
cache.fetch('Outputs', {}).each do |o_name, o_value|
|
44
|
+
translated['outputs'][o_name] = Hash[
|
45
|
+
o_value.map do |k,v|
|
46
|
+
[snake(k).to_s, v]
|
47
|
+
end
|
48
|
+
]
|
49
|
+
end
|
50
|
+
translated.delete('awstemplate_format_version')
|
51
|
+
translated['heat_template_version'] = '2013-05-23'
|
52
|
+
# no HOT support for mappings, so remove and clean pseudo
|
53
|
+
# params in refs
|
54
|
+
if(translated['resources'])
|
55
|
+
translated['resources'] = dereference_processor(translated['resources'], ['Fn::FindInMap', 'Ref'])
|
56
|
+
translated['resources'] = rename_processor(translated['resources'])
|
57
|
+
end
|
58
|
+
if(translated['outputs'])
|
59
|
+
translated['outputs'] = dereference_processor(translated['outputs'], ['Fn::FindInMap', 'Ref'])
|
60
|
+
translated['outputs'] = rename_processor(translated['outputs'])
|
61
|
+
end
|
62
|
+
translated.delete('mappings')
|
63
|
+
true
|
64
|
+
end
|
65
|
+
|
6
66
|
# Custom mapping for block device
|
7
67
|
#
|
8
68
|
# @param value [Object] original property value
|
@@ -49,7 +109,19 @@ class SparkleFormation
|
|
49
109
|
if(files = config['files'])
|
50
110
|
files.each do |key, args|
|
51
111
|
if(args['source'])
|
52
|
-
args['source'].
|
112
|
+
if(args['source'].is_a?(String))
|
113
|
+
args['source'].replace("\"#{args['source']}\"")
|
114
|
+
else
|
115
|
+
args['source'] = {
|
116
|
+
'Fn::Join' => [
|
117
|
+
"", [
|
118
|
+
"\"",
|
119
|
+
args['source'],
|
120
|
+
"\""
|
121
|
+
]
|
122
|
+
]
|
123
|
+
}
|
124
|
+
end
|
53
125
|
end
|
54
126
|
end
|
55
127
|
end
|
@@ -126,6 +198,17 @@ class SparkleFormation
|
|
126
198
|
}
|
127
199
|
}
|
128
200
|
|
201
|
+
REF_MAPPING = {
|
202
|
+
'AWS::StackName' => 'OS::stack_name',
|
203
|
+
'AWS::StackId' => 'OS::stack_id',
|
204
|
+
'AWS::Region' => 'OS::stack_id' # @todo i see it set in source, but no function. wat
|
205
|
+
}
|
206
|
+
|
207
|
+
FN_MAPPING = {
|
208
|
+
'Fn::GetAtt' => 'get_attr',
|
209
|
+
'Fn::Join' => 'list_join' # @todo why is this not working?
|
210
|
+
}
|
211
|
+
|
129
212
|
end
|
130
213
|
end
|
131
214
|
end
|