SparkleFormation provides a number of builtin resources using the
dynamic!
helper. These known resources are collected when SparkleFormation
is released. Because this is a static list of resource types it is
common for new resources to be introduced within a cloud provider
and not be available within SparkleFormation. Since the new resource
types will not be available within SparkleFormation until the next
release, stubbing the builtin will provide the same behavior as if
it were included within the builtin list.
For example, lets assume that AWS CloudFormation introduces a new
resource type named AWS::JVM::Instance
. To stub this resource a
new dynamic can be created locally:
SparkleFormation.dynamic(:jvm_instance) do |name|
resources.set!("#{name}_jvm_instance".to_sym) do
type "AWS::JVM::Instance"
end
end
With this dynamic defined it will behave the same as if it were defined in the builtin list:
SparkleFormation.new(:test) do
dynamic!(:jvm_instance, :test) do
properties.memory 512
end
end
which results in:
{
"Resources": {
"TestJvmInstance": {
"Type": "AWS::JVM::Instance",
"Properties": {
"Memory": 512
}
}
}
}
Once the AWS::JVM::Instance
becomes available in the builtin
list within SparkleFormation the custom stub dynamic can be deleted.
Resource conflicts can occur when the same resource name is used
in multiple resource namespaces. If a template has created resources
using the dynamic!
helper and not included the resource’s namespace,
conflicts will occur when the new resource becomes available. An
example of this is the AWS::ElasticLoadBalancing::LoadBalancer
resource.
Assume that the following template is in use:
SparkleFormation.new(:lb) do
dynamic!(:load_balancer, :app)
end
and it generates:
{
"Resources": {
"AppLoadBalancer": {
"Type": "AWS::ElasticLoadBalancing::LoadBalancer"
}
}
}
Now, AWS releases a new resource with a conflicting name
AWS::ElasticLoadBalancingV2::LoadBalancer
and SparkleFormation’s internal
resource list has been updated. When the template is run again, it returns
an error about conflicting resource names. One solution is to update the
dynamic!
call to include the namespace:
SparkleFormation.new(:lb) do
dynamic!(:elastic_load_balancing_load_balancer, :app)
end
and it will then generate:
{
"Resources": {
"AppElasticLoadBalancingLoadBalancer": {
"Type": "AWS::ElasticLoadBalancing::LoadBalancer"
}
}
}
This resolves the conflict issue, yet in practice the modification of the
resource name will likely cause issues in complex templates where the
resource is being referenced in other locations. To allow templates to
remain unchanged, a new dynamic can be introduced which will force matching
of the :load_balancer
name to the local dynamic:
SparkleFormation.dynamic(:load_balancer) do |name|
dynamic!(:elastic_load_balancing_load_balancer, name, :resource_name_suffix => :load_balancer)
end
With this dynamic in place, all original templates will continue to behave as expected without individual modifications.