Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Define Value interface #103

Closed
wants to merge 7 commits into from

Conversation

errordeveloper
Copy link

@errordeveloper errordeveloper commented Jul 24, 2018

This is to allow passing references and other intrinsics when constructing a template.

To keep things simple to start with, I've implemented this as a breaking change. We can settle on how it should be done once we have a clearer idea of the exact approach.

Replaces #95.

@errordeveloper
Copy link
Author

So I guess there is one obvious thing here, we need more types and some kind of place-holder type.

Besides that, in eksctl I've encountered that I need this:

  NodeGroup:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      DesiredCapacity: !Ref NodeAutoScalingGroupMaxSize
      LaunchConfigurationName: !Ref NodeLaunchConfig
      MinSize: !Ref NodeAutoScalingGroupMinSize
      MaxSize: !Ref NodeAutoScalingGroupMaxSize
      VPCZoneIdentifier:
        !Ref Subnets
      Tags:
      - Key: Name
        Value: !Sub "${ClusterName}-${NodeGroupName}-Node"
        PropagateAtLaunch: 'true'
      - Key: !Sub 'kubernetes.io/cluster/${ClusterName}'
        Value: 'owned'
        PropagateAtLaunch: 'true'
    UpdatePolicy:
      AutoScalingRollingUpdate:
        MinInstancesInService: '1'
        MaxBatchSize: '1'

First up, cloudformation.Tag doesn't have PropagateAtLaunch. Secondly, VPCZoneIdentifier is currently []string, and with this PR it becomes []*cloudformation.StringIntrinsic... What we need is something that would allow slice of strings, or an an intrinsic... Not sure what is the right answer at the moment. In my code I've simply defined all properties as a map.

@errordeveloper
Copy link
Author

I have finished implementing all of what we need in eksctl-io/eksctl#132. It would be great to hear how we could go about changes akin to what's shown here.

errordeveloper added a commit to eksctl-io/eksctl that referenced this pull request Aug 2, 2018
errordeveloper added a commit to eksctl-io/eksctl that referenced this pull request Aug 7, 2018
Copy link
Contributor

@PaulMaddox PaulMaddox left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started messaging you back on Slack, but figured the feedback was probably better suited to discussion here.

  1. All this change in a single commit is pretty hard to grok.
  • Tests & Documentation for this are required

  • Agree with your comments on Slack that using an interface will be nicer

  • Can we rename StringIntrinsic to StringReference - intrinsic could mean anything from Fn::Join etc, where as we are specifically dealing with References here.

  • Rename cloudformation.NewStringIntrinsic(string) to cloudformation.NewStringReference(name), and I also think we should create a cloudformation.Ref(name) convenience method (to be used in documentation) as 99% of use cases will just be for a string.

errordeveloper added a commit to eksctl-io/eksctl that referenced this pull request Aug 8, 2018
errordeveloper added a commit to eksctl-io/eksctl that referenced this pull request Aug 9, 2018
errordeveloper added a commit to eksctl-io/eksctl that referenced this pull request Aug 10, 2018
errordeveloper added a commit to eksctl-io/eksctl that referenced this pull request Aug 10, 2018
@errordeveloper
Copy link
Author

@PaulMaddox I decided to rework this because my use-case already requires Fn::GetAtt, Fn::ImportValue, Fn::Join, Fn::Split and Fn::Sub. So I'll rework it to use an interface and make type naming more sensible. I'm happy to add docs and tests, but only after we agree on weather the direction is overall plausible.

@errordeveloper errordeveloper changed the title Add replace primitive types with <type>Intrinsic Define Value interface Aug 13, 2018
@errordeveloper errordeveloper changed the title Define Value interface WIP: Define Value interface Aug 13, 2018
@errordeveloper
Copy link
Author

@PaulMaddox I've re-written this, please take a look at c0c0166.

@PaulMaddox
Copy link
Contributor

This is a lot cleaner - I like the approach.

Do you have any thoughts about what the API would look like for setting Value values? Obviously we can't just use strings now :(

Something like the aws.String("") method in the aws sdk maybe? cloudformation.String("") ?

@errordeveloper
Copy link
Author

errordeveloper commented Aug 14, 2018

Yes, it will be cloudformation.String(""). Here is an edited example from eksctl code:

func addResources(globalCIDR *net.IPNet, subnets map[string]*net.IPNet) {
	t.Resource["VPC"] = &cloudformation.AWSEC2VPC{
		CidrBlock:          cloudformation.String(globalCIDR.String()),
		EnableDnsSupport:   cloudformation.True,
		EnableDnsHostnames: cloudformation.True,
	}
        refVPC := cloudformation.MakeRef("VPC")

        t.Resource["InternetGateway"] = &cloudformation.AWSEC2InternetGateway{})
        refIG := cloudformation.MakeRef("InternetGateway")
	t.Resource["VPCGatewayAttachment"] = &cloudformation.AWSEC2VPCGatewayAttachment{
		InternetGatewayId: refIG,
		VpcId:             refVPC,
	}

	t.Resources["RouteTable"] = &cloudformation.AWSEC2RouteTable{
		VpcId: refVPC,
	}
        refRT := cloudformation.MakeRef("RouteTable")

	t.Resources["PublicSubnetRoute"] = &cloudformation.AWSEC2Route{
		RouteTableId:         refRT,
		DestinationCidrBlock: cloudformation.String("0.0.0.0/0"),
		GatewayId:            refIG,
	}

        subnetRefs := []cloudformation.Value{}
	for az, subnet := range subnets {
		alias := strings.ToUpper(strings.Join(strings.Split(az, "-"), ""))
		t.Resources["Subnet"+alias] = &cloudformation.AWSEC2Subnet{
			AvailabilityZone: cloudformation.String(az),
			CidrBlock:        cloudformation.String(subnet.String()),
			VpcId:            refVPC,
		}
                refSubnet := cloudformation.MakeRef("Subnet"+alias)
		t.Resources["RouteTableAssociation"+alias] = &cloudformation.AWSEC2SubnetRouteTableAssociation{
			SubnetId:     refSubnet,
			RouteTableId: refRT,
		}
		subnetRefs = append(subnetRefs, refSubnet)
	}

	t.Resources["ControlPlaneSecurityGroup"] = &cloudformation.AWSEC2SecurityGroup{
		GroupDescription: cloudformation.String("Communication between the control plane and worker node groups"),
		VpcId:            refVPC,
	})
       
	t.Resources["ControlPlane"] = & cloudformation.AWSEKSCluster{
		Name:    cloudformation.String(c.spec.ClusterName),
		RoleArn: cloudformation.MakeFnGetAtt("ServiceRole.Arn"),
		Version: cloudformation.String(version),
		ResourcesVpcConfig: & cloudformation.AWSEKSCluster_ResourcesVpcConfig{
			SubnetIds:        subnetRefs,
			SecurityGroupIds:  []cloudformation.Value{cloudformation.MakeRef("ControlPlaneSecurityGroup")},
		},
	}
}

However, in eksctl has some helpers, e.g.

func (r *resourceSet) newResource(name string, properties interface{}) cloudformation.Value

This function adds the resource with t.Resources[name] = properties and returns cloudformation.MakeRef(name) which you can capture whenever you need it.

so this

	t.Resource["VPC"] = &cloudformation.AWSEC2VPC{
		CidrBlock:          cloudformation.String(globalCIDR.String()),
		EnableDnsSupport:   cloudformation.True,
		EnableDnsHostnames: cloudformation.True,
	}
        refVPC := cloudformation.MakeRef("VPC")

becomes

	refVPC := r.newResource("VPC", &cloudformation.AWSEC2VPC{
		CidrBlock:          cloudformation.String(globalCIDR.String()),
		EnableDnsSupport:   cloudformation.True,
		EnableDnsHostnames: cloudformation.True,
	}

If you are intertested, I'm happy to add this here. We have other syntactic sugar, but is a bit more specific to eksctl, and I wouldn't hurry to suggest it here.

@errordeveloper
Copy link
Author

errordeveloper commented Aug 14, 2018

I'll go ahead and try to fix the tests, then see what new tests can be added also.

errordeveloper added a commit to eksctl-io/eksctl that referenced this pull request Sep 4, 2018
@errordeveloper
Copy link
Author

@PaulMaddox please review commits separately, not checking generated code doesn't show that tests pass, so I had to do that.

@PaulMaddox
Copy link
Contributor

I have #114 in a good working state now, so am closing this PR in favour of that one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants