-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Make CloudFormation easier to compose #127
Comments
I've never used goformation myself, but it definitely look promising and I am generally against having too many big yamls that gets too complicated... so going "code first" would be IMO a very good thing (once your PR upstream is merged). |
I have started on this in #132, here is what it begins to look like: func makeRef(refName string) interface{} {
return map[string]string{"Ref": refName}
}
type clusterResourceSet struct {
template *cloudformation.Template
vpcRefs *resourceRefsForVPC
}
type resourceRefsForVPC struct {
vpc interface{}
subnets []interface{}
securityGroups []interface{}
}
func newClusterResourceSet() *clusterResourceSet {
return &clusterResourceSet{
template: cloudformation.NewTemplate(),
}
}
func (c *clusterResourceSet) newResource(name string, resource interface{}) interface{} {
c.template.Resources[name] = resource
return makeRef(name)
}
func (c *clusterResourceSet) addResourcesForVPC(globalCIDR *net.IPNet, subnets map[string]*net.IPNet) {
refs := &resourceRefsForVPC{}
refs.vpc = c.newResource("VPC", &cloudformation.UntypedAWSEC2VPC{
CidrBlock: globalCIDR.String(),
EnableDnsSupport: true,
EnableDnsHostnames: true,
})
refIG := c.newResource("InternetGateway", &cloudformation.AWSEC2InternetGateway{})
c.newResource("VPCGatewayAttachment", &cloudformation.UntypedAWSEC2VPCGatewayAttachment{
InternetGatewayId: refIG,
VpcId: refs.vpc,
})
refRT := c.newResource("RouteTable", &cloudformation.UntypedAWSEC2RouteTable{
VpcId: refs.vpc,
})
c.newResource("Route", &cloudformation.UntypedAWSEC2Route{
RouteTableId: refRT,
DestinationCidrBlock: "0.0.0.0/0",
GatewayId: makeRef("InternetGateway"),
})
for az, subnet := range subnets {
refSubnet := c.newResource("Subnet_"+az, &cloudformation.UntypedAWSEC2Subnet{
AvailabilityZone: az,
CidrBlock: subnet.String(),
VpcId: refs.vpc,
})
c.newResource("RouteTableAssociation_"+az, &cloudformation.UntypedAWSEC2SubnetRouteTableAssociation{
SubnetId: refSubnet,
RouteTableId: refRT,
})
refs.subnets = append(refs.subnets, refSubnet)
}
refSG := c.newResource("ControlPlaneSecurityGroup", &cloudformation.UntypedAWSEC2SecurityGroup{
GroupDescription: "Cluster communication with worker nodes",
VpcId: refs.vpc,
})
refs.securityGroups = []interface{}{refSG}
c.vpcRefs = refs
} So as you can see, we can probably avoid most of parameter passing and substitute parameters directly, and only use references where it's absolutely necessary. |
+1, This seems like it would be really useful as things get more complicated. |
I think this approach is good, its better for composability and testing. I'm wondering if we could you use a 'builder' and/or fluent interface around goformat for composing the the template? |
@richardcase if you have any specific thoughts around that, please comment in #132. |
Remove unsupported MULTI_NODE_READER_ONLY volume capability
At the moment we have a number of issues where compassable CloudFormation would help (#42, #69, #120, #122).
Managing templates as YAML and embedding them in Go using
bindata
is not particularly delightful, but not an issue per-se. What's hard is piecing together Go code and any logic that is implemented with CloudFormation intrinsic functions, stack parameters and conditions.Additionally, it would be much more convenient if we have a single stack composed of optional parts (VPC, IAM role, control plane), and separate (nested?) stacks for nodegroups. This would simplify much of our code.
So we could either invent something ourselves, if we wanted to, but I found that goformation already does what's needed (and I made an improvement (
awslabs/goformation#95, awslabs/goformation#103) to it that allows to useRef
s and other intrinsics).The idea would be to compose the stack using Go structs. First of all we would use Go instead of CloudFormation for conditionals, as it's much easier to grasp all the parameters. We would leverage some CloudFormation runtime functionality to the minimum extended needed, but anything that would take more then one nested intrinsic function would be done in Go, unless information is only available inside of CloudFormation runtime (e.g. resource IDs for VPCs, subnets etc).
The text was updated successfully, but these errors were encountered: