SparkleFormation supports generating templates for multiple
orchestration APIs. By default all building blocks are assigned
:aws
as a provider. As a template is compiled and building
block items are requested, the provider restriction is enforced
during lookup. This restriction helps to enforce correctly structured
template by only allowing building blocks with like providers to
interact with each other ensuring a properly compiled template.
Provider restrictions are set using a common pattern among all building blocks:
SparkleFormation.new(:my_template, :provider => :azure) do
...
SparkleFormation.component(:my_component, :provider => :azure) do
...
SparkleFormation.dynamic(:my_dynamic, :provider => :azure) do
...
SfnRegistry.register(:my_item, :provider => :azure) do
...
The uniqueness of a building block is based on the combination of
the building block’s name and defined provider. This allows common
naming schemes to be applied for multiple providers within the same
runtime. For example, given a template named :network
defined
as:
SparkleFormation.new(:network) do
...
the uniqueness of this template is defined by :network
within
the :aws
provider (because the :aws
provider is the default). This
means that defining another template with the provider explicitly defined
for :aws
will fail:
SparkleFormation.new(:network, :provider => :aws) do
...
The failure is due to the fact that the names of these two templates is effectively equivalent.
Using the previous example of a :network
template, we can define our
template and explicitly set the provider for clarity:
SparkleFormation.new(:network, :provider => :aws) do
...
Now if we want to provide a template for a different provider (OpenStack for instance) we can use the same template name but specify a different target provider:
SparkleFormation.new(:network, :provider => :heat) do
...
Two templates with a common name (:network
) now exist within our runtime
because while the name is common, the providers are different. This functionality
applies to all the SparkleFormation building blocks and is important for allowing
a common interface for user interactions while allowing provider specific implementations.
Building blocks may not always need to be restricted to a specific provider. The provider value used for building block lookup can be overridden. Using this override functionality allows for sharing building blocks between providers. For example, lets define a pseudo-template for AWS that sets a value using a registry item:
SfnRegistry.register(:creator) do
'spox'
end
SparkleFormation.new(:template) do
owner registry!(:creator)
end
Now if the same pseudo-template with a provider set to :azure
is defined:
SparkleFormation.new(:template, :provider => :azure) do
owner registry!(:creator)
end
it will fail. The failure is due to the implicitly set provider (:aws
) on the registry
item. To allow sharing of the registry item, we can override the lookup to use
:aws
as the provider:
SparkleFormation.new(:template, :provider => :azure) do
owner registry!(:creator, :provider => :aws)
end
but this doesn’t make logical sense within the layout as the registry item itself isn’t restricted to the AWS provider in any way. A better approach would be defining a shared provider and using that value for the override. Refactoring would provide a registry item:
SfnRegistry.register(:creator, :provider => :shared) do
'spox'
end
With the provider set, the two templates can now be updated to use the override:
SparkleFormation.new(:template) do
owner registry!(:creator, :provider => :shared)
end
and:
SparkleFormation.new(:template, :provider => :azure) do
owner registry!(:creator, :provider => :shared)
end