Closed autarchprinceps closed 5 years ago
Hi. There's two options you can do. The first is by checking if value already exists, and then add to the array, or set the value depending on existence. For example:
SparkleFormation.dynamic(:group1) do
metadata.parameter_groups array!(
->{
label.set!("default"._no_hump, 'Network Configuration')
parameters ['VPCID', 'SubnetId', 'SecurityGroupID']
}
)
end
SparkleFormation.dynamic(:group2) do
metadata do |current|
if current.parameter_groups.nil?
current.parameter_groups array!(
->{
label.set!("default"._no_hump, 'Amazon EC2 Configuration')
parameters ['InstanceType', 'KeyName']
}
)
else
current.parameter_groups += array!(
->{
label.set!("default"._no_hump, 'Amazon EC2 Configuration')
parameters ['InstanceType', 'KeyName']
}
)
end
end
end
Then in the template you add them and you get the expected result:
SparkleFormation.new(:example) do
dynamic!(:group1)
dynamic!(:group2)
end
Which results in:
{
"Metadata": {
"ParameterGroups": [
[
{
"Label": {
"default": "Network Configuration"
},
"Parameters": [
"VPCID",
"SubnetId",
"SecurityGroupID"
]
}
],
[
{
"Label": {
"default": "Amazon EC2 Configuration"
},
"Parameters": [
"InstanceType",
"KeyName"
]
}
]
]
}
}
Now, you can also get around having to do existence checks by using a feature in AttributeStruct library called value collapsing. This instructs the parent structure to combine multiple values set to the same key into an array automatically rather than overwriting. To do that, you need to set the value collapse flag on the struct before adding any values to it. So, we could change the group2
dynamic to be structure in the generic way group1
is (without the existence check):
SparkleFormation.dynamic(:group2) do
metadata.parameter_groups array!(
->{
label.set!("default"._no_hump, 'Amazon EC2 Configuration')
parameters ['InstanceType', 'KeyName']
}
)
end
and in the template, we can flag the structure so that as the dynamics are called to build, it will collapse the values into an array instead of overwriting them:
SparkleFormation.new(:example) do
metadata.set_state!(:value_collapse => true)
dynamic!(:group1)
dynamic!(:group2)
end
which gives us the same result:
{
"Metadata": {
"ParameterGroups": [
[
{
"Label": {
"default": "Network Configuration"
},
"Parameters": [
"VPCID",
"SubnetId",
"SecurityGroupID"
]
}
],
[
{
"Label": {
"default": "Amazon EC2 Configuration"
},
"Parameters": [
"InstanceType",
"KeyName"
]
}
]
]
}
}
As with most things, there's no "right" way to do it, simply what makes the most sense for your use case. Hope that helps!
I was trying to get CloudFormation Parameter Groups to work with sparkleformation and dynamics, but it always overwrites instead of merging. The problem is, that parameter groups are an array of objects. If I define a new array in a different dynamic, this overrides my previously defined one.
The following is the example from CloudFormation. Image that I want to define the first parameter group in let's say a vpc dynamic and the second in a ec2 one. How would I do this in sparkleformation? "Metadata" : { "AWS::CloudFormation::Interface" : { "ParameterGroups" : [ { "Label" : { "default" : "Network Configuration" }, "Parameters" : [ "VPCID", "SubnetId", "SecurityGroupID" ] }, { "Label" : { "default":"Amazon EC2 Configuration" }, "Parameters" : [ "InstanceType", "KeyName" ] } ] } }