Reference resource by its logical id/name

381 views
Skip to first unread message

Larry Liang

unread,
Dec 29, 2015, 11:42:08 PM12/29/15
to cloudtools-dev
Hi, 

I need to refer to a resource created in the same template by its logical name. For example the cloudformation "DependsOn" attribute takes a list of Strings (resource logical names). 

In native cloudformation template, you could just use the "logical name" of the resource such as below. Noted that the "DependsOn" attribute of "PublicSubnet" directly referring to VPC resource by its logical name.

"VPC" : {
"Type" : "AWS::EC2::VPC",
"Properties" : {
"CidrBlock" : { "Fn::FindInMap" : [ "SubnetConfig", "VPC", "CIDR" ]},


},
"PublicSubnet" : {
"DependsOn" : ["VPC"],
"Type" : "AWS::EC2::Subnet",
"Properties" : {
"VpcId" : { "Ref" : "VPC" },
"CidrBlock" : { "Fn::FindInMap" : [ "SubnetConfig", "Public", "CIDR" ]},
"Tags" : [
{ "Key" : "Application", "Value" : { "Ref" : "AWS::StackName" } },
{ "Key" : "Network", "Value" : "Public" },
{ "Key" : "Name", "Value" : "Public Subnet" }
]
}
},

I can not really do this with troposphere by either using the python object or using the Ref function with the python object, which generates something like { "Ref": "$VPC_Name"}

There is a way to get this done by using the ".title" attribute on the troposphere python AWSBaseObject class. But I feel it relies on an internal implementation (which may change in the new version).

Can someone point me in the right direction if I'm missed something obvious here?

Cheers,

Larry



Mark Peek

unread,
Dec 30, 2015, 1:09:26 AM12/30/15
to Larry Liang, cloudtools-dev
Good question. For now go ahead and use .title. I might see about adding an access method in the future. But yes, you should be able to get the name from the VPC object itself rather than duplicating the name in other ways.

Mark
--
You received this message because you are subscribed to the Google Groups "cloudtools-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cloudtools-de...@googlegroups.com.
To post to this group, send email to cloudto...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cloudtools-dev/c108e812-5c4e-412d-8a0f-6902e8c028af%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Larry Liang

unread,
Dec 30, 2015, 9:55:10 PM12/30/15
to cloudtools-dev, ptole...@gmail.com
Thanks for the response Mark.

For now, I'm encapsulating the logic of accessing .title attribute inside a utility function "get_logical_name(obj)", in order to minimize future refactoring work.

I'd definitely propose this as a quite important enhancement as "being able to refer to resources by name" make the code looks much cleaner and easier to read.

Is there a way that I can track the progress on this request, say a jira ticket or something?

Thx again for your help,

Larry

Markus Juenemann

unread,
Mar 12, 2016, 12:32:14 AM3/12/16
to cloudtools-dev, ptole...@gmail.com
I know this thread is old but I have just been investigating this. First the disclaimer: I am pretty familiar with Python but very new to CouldFormation and Troposphere so I may have missed something very important regarding "Ref".

My ad-hoc approach to this was to add a few lines to troposphere/__init__.py that extract the .title attribute if it exists and is a string.

--- a/troposphere/__init__.py
+++ b/troposphere/__init__.py
@@ -92,6 +92,11 @@ class BaseAWSObject(object):
             # Check the type of the object and compare against what we were
             # expecting.
             expected_type = self.props[name][0]
+           
+            # Auto-deduce Ref
+            #
+            if hasattr(value, 'title') and isinstance(value.title, str):
+                return self.properties.__setitem__(name, value.title)
 
             # If the value is a AWSHelperFn we can't do much validation
             # we'll have to leave that to Amazon.  Maybe there's another way

As an example, line 32 in examples/EC2InstanceSample.py could be changed as shown below, skipping the Ref() encapsulation. The generated output would remain the same.

    #KeyName=Ref(keyname_param),
    KeyName=keyname_param,


There should probably some more checks as in the get_data() method of the AWSHelperFn class.

Markus

Markus Juenemann

unread,
Mar 12, 2016, 1:08:22 AM3/12/16
to cloudtools-dev, ptole...@gmail.com
Replying to my own post here ;-)

"Auto-dereferencing" as suggested by myself above won't work for AWS Resources where Ref(...) returns other information than the name/title. For example Ref(AWS::EC2::EIP) returns the public IP address.

I am going to try whether it is possible to "auto-insert" Ref() instead.

Markus Juenemann

unread,
Mar 12, 2016, 6:24:11 AM3/12/16
to cloudtools-dev, ptole...@gmail.com
I put a little research into this. Auto-inserting Ref() may be possible as long as the Resource or Parameter has been previously added to the Template.

It doesn't work at all with the Openstack code and it is currently not easily possible to identify Openstack classes as they are also based on AWSObject and AWSProperty.

Markus
Reply all
Reply to author
Forward
0 new messages