DEV Community

loading...
LambdaSharp

Emulating Fn::StartsWith in CloudFormation

Steve Bjorg
Founder/CTO MindTouch, AWS and .NET Core fan, Author of LambdaSharp, AWS Hero
Updated on ・2 min read

Overview

CloudFormation has a limited number of intrinsic functions that can be combined in some interesting ways.

One of the intrinsic functions I wish existed is Fn::StartsWith. As the name implies, the objective is to check if a string begins with another string. While this operation doesn't exist natively, it can be constructed using the existing intrinsic functions.

Part 1 - Fn::Split

Fn::Split is an intrinsic function used to split a string into an array using a delimiter string. It's most commonly used to split on a punctuation mark, such a comma (,). One of the side effects of applying this function, is that the resulting array does NOT contain the delimiter string, which we can leverage.

Consider the following example:

!Split [ "world", "hello world!" ]
Enter fullscreen mode Exit fullscreen mode

Which produces this result.

[ "hello ", "!" ]
Enter fullscreen mode Exit fullscreen mode

As you can see, the word "world" is gone from the result.

Let's do this again using "hello" instead:

!Split [ "hello", "hello world!" ]
Enter fullscreen mode Exit fullscreen mode

We get:

[ "", " world!" ]
Enter fullscreen mode Exit fullscreen mode

Now the lightbulb is turning on. Indeed, when the first string of a Fn::Split operation is empty, it means the split operation found an occurrence of the delimiter string at the beginning. Let's use this!

Part 2 - Fn::Select and Fn::Equals

Fortunately, Fn::Split always returns an array of at least one element. This makes it safe to always access the first item in the returned array. We can use that to compare the value to an empty string.

!Equals [ !Select [ 0, !Split [ PREFIX, VALUE ], "" ]]
Enter fullscreen mode Exit fullscreen mode

Part 3 - Beware of empty strings

An empty string, split on any delimiter string, always produces an array with a single empty string in it. This gives us a false positive if we don't check for it.

!Not [ !Equals [ VALUE, "" ]]
Enter fullscreen mode Exit fullscreen mode

Final - Putting it all together

Combining the empty string check and the Fn::Split function gives us an implementation of Fn::StartsWith.

!And [ 
    !Not [ !Equals [ VALUE, "" ]],
    !Equals [ !Select [ 0, !Split [ PREFIX, VALUE ]], "" ]
]
Enter fullscreen mode Exit fullscreen mode

I hope you found this useful. If you know of other patterns to emulate missing functionality in CloudFormation, please leave a comment!

Happy Hacking!

Discussion (2)

Collapse
nimbusscale profile image
Joe

I tried the above, but found there was an issue with the !Equals clause as one of the closing brackets was in the wrong spot. I was able to get it to work as the following:

!Equals [!Select [ 0, !Split [ PREFIX, VALUE ]], ""]

Collapse
bjorg profile image
Steve Bjorg Author

Thanks for letting me know. I corrected the article.