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.
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!" ]
Which produces this result.
[ "hello ", "!" ]
As you can see, the word "world" is gone from the result.
Let's do this again using "hello" instead:
!Split [ "hello", "hello world!" ]
[ "", " world!" ]
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!
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 ], "" ]]
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, "" ]]
Combining the empty string check and the
Fn::Split function gives us an implementation of
!And [ !Not [ !Equals [ VALUE, "" ]], !Equals [ !Select [ 0, !Split [ PREFIX, VALUE ]], "" ] ]
I hope you found this useful. If you know of other patterns to emulate missing functionality in CloudFormation, please leave a comment!