cloudformation-template-generator icon indicating copy to clipboard operation
cloudformation-template-generator copied to clipboard

Question - Using ParameterRef where Token[ResourceRef[`AWS::SOME::SERVICE`]] is expected

Open zodeus opened this issue 8 years ago • 7 comments

Hey, I really like the work you've done here. Not an expert in scala so I'm just wondering if there is a better way to do what I need.

Currently the RouteTableId parameter for AWS::EC2::Route is a Token[ResourceRef[AWS::EC2::RouteTable]]. However in my case the default route table is already created in aws and is passed in as a parameter.

So I need to do

AWS::EC2::Route`(
    name = "RouteToMainVpc",
    RouteTableId = ParameterRef(defaultVpcRouteTableIdParameter),
    DestinationCidrBlock = cidrBlock,
    connectionBobber = VPCPeeringRoute(vpcPeeringConnection)
  )

That doesn't work, but if I change the signature of that parameter to Token[String]. Then everything seems to be good. I imagine what I've done is remove the type safety, can you explain how you decide on using Token[String] vs Token[ResourceRef[some_aws_thing]].

Thanks

zodeus avatar Aug 25 '16 16:08 zodeus

So you've run into an issue we've recently identified ourselves when we tried to start doing more nested templates rather than one big monolith VPC template. I've got an issue open here for that: https://github.com/MonsantoCo/cloudformation-template-generator/issues/102

You're absolutely right, Token[String] removes a degree of type safety. However, clearly Token[ResourceRef[some_aws_thing]] is too type safe for the real world. I think the fix will be something along the lines of having a subtype of ResourceRef[T] that can be constructed with a reference to an existing some_aws_thing's ID, rather than require the thing itself. That's probably an over simplification of the actual fix though, as there's quite a bit of complexity in how all this works.

Right now our team is focused more on other efforts, so I don't know exactly when we'll be able to address this. We would certainly welcome PRs.

bkrodgers avatar Aug 25 '16 16:08 bkrodgers

I should add that what I describe is the ideal fix, that is, one that doesn't completely remove the type safety. We could also consider changing to Token[String] for now to meet this need, and re-introducing a more type safe solution later. @tj-corrigan, any thoughts?

bkrodgers avatar Aug 25 '16 16:08 bkrodgers

Right now we probably have a mix of a few different approaches. One is to just loosen the types and go with Token[String] as @bkrodgers mentioned. Another option we have played around with is building a custom parameter type to keep the safety (see example and corresponding test). From my recollection this works well as long as the type is a AWS-specific parameter types (have to scroll down the page to find it). Unfortunately your example doesn't fall in that category. I believe it still works out when you are passing in a string (see example), it just gets harder to specify a default value. I'm actually trying to work through the code today/tomorrow so I'll see if I can't get re-familiarize myself with how this all works and maybe get something implemented for you.

tjcorr avatar Aug 25 '16 16:08 tjcorr

That would be great guys, I'm just running through some prototyping using a few different things. Currently in-house we use cloudformation and sparkleformation but I'm not a fan of ruby...

Been playing with terrform/atlas as well however I'm struggling with their approach.

This library looks well implemented. If we end up using this to build out our new infrastructure we would be happy to help maintain this project.

zodeus avatar Aug 25 '16 17:08 zodeus

👍 We're beginning to run into this as well.

jfklingler avatar Mar 24 '17 13:03 jfklingler

I've run into this as well since I started modularizing my templates.

I think the fix will be something along the lines of having a subtype of ResourceRef[T] that can be constructed with a reference to an existing some_aws_thing's ID, rather than require the thing itself.

The above probably represents the best compromise; I recently ran into an issue where AWS::IAM::Group was expecting ResouceRefs for it's managed policies. It turned out that AWS::IAM::Role already had an ManagedPolicyARN type that it was using for the ManagedPolicyArns field. Changing the AWS::IAM::Group to do the same was trivial in my case. I am running into this issue with the vpc parameter for AWS::EC2::SecurityGroup etc., however I haven't taken the time to start adding an intermediate type..

@bkrodgers Have you guys made any progress regarding this?

elyzion avatar Jul 10 '17 04:07 elyzion

Another option would be to let Fn::ImportValue have a type param of the expected resource.

wngr avatar Sep 05 '17 15:09 wngr