sparkle_formation 0.2.0 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|