Currently I am converting CFT from JSON to Yaml. Everything works fine until Userdata section.I am having hard time to use any of functions like !Ref or !FindInMap in userdata section.
UserData:
Fn::Base64: !Sub |
#!/bin/bash -v
/command {Fn::FindInMap: [ "url", Ref: AWS::Region, Ref: EnvironmentType ] }
It would be very helpful, If anyone can share any snippet of code.
Short description. You can use the Fn::Sub intrinsic function to substitute supported functions or to substitute variables in an input string with values that you specify.
The intrinsic function Fn::FindInMap returns the value corresponding to keys in a two-level map that's declared in the Mappings section.
To create a stack you run the aws cloudformation create-stack command. You must provide the stack name, the location of a valid template, and any input parameters. Parameters are separated with a space and the key names are case sensitive.
The optional Mappings section matches a key to a corresponding set of named values. For example, if you want to set values based on a region, you can create a mapping that uses the region name as a key and contains the values you want to specify for each specific region.
I've been having fun and games with this as well. Although the documentation says that Fn::FindInMap
is supported in Fn::Sub
, there's no example of use and I've tried all sorts of combinations of quotes and colons without success, but I finally seem to have hit upon a functional solution using mappings. The following should work:
Fn::Base64: !Sub
- |+
#!/bin/bash -v
/command ${Url}
- Url:
Fn::FindInMap:
- UrlMap
- !Ref AWS::Region
- !Ref EnvironmentType
The pipe at the start of arg0 tells YAML to preserve newlines, and the plus tells it to keep a newline afterwards.
Arg1 tells it to substitute the result of the Fn::FindInMap
for the Url in arg0.
The following shorter version should also work:
Fn::Base64: !Sub
- |+
#!/bin/bash -v
/command ${Url}
- Url:
Fn::FindInMap: [UrlMap, Ref: "AWS::Region", Ref: EnvironmentType]
But you should test that. Note the commas, quotes, and reversion to Ref:
s rather than !Ref
s. This probably tells us something about how the files are being pre-processed, but I'm not sure what that is.
I'm sure that this solution is obvious to experienced YAMLers, but I was only just starting to get my head around JSON when all this YAMLy goodness was added to CloudFormation.
I had similar use case: Substitute value from map for corresponding parameter value. If parameter value doesn't match the mapping entry, use default value. Here's my working sample, hope this helps.
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
Env:
Type: String
Description: The environment.
Mappings:
envResourcesMap:
dev:
someHost: "hostVal_D"
staging:
someHost: "hostVal_S"
prod:
someHost: "hostVal_P"
other:
someHost: "hostValm_XXX"
Conditions:
IsDevEnv: !Equals
- !Ref Env
- dev
IsStagingEnv: !Equals
- !Ref Env
- staging
IsProdEnv: !Equals
- !Ref Env
- prod
IsStandardEnv:
Fn::Or:
- Condition: IsDevEnv
- Condition: IsStagingEnv
- Condition: IsProdEnv
Resources:
storeSSM:
Type: AWS::SSM::Parameter
Properties:
Description: !Sub "DESC for ${Env}"
Name: !Sub "/Global/ssmpath/someHost"
Type: String
Value: !Sub
- ${spiderman}
- spiderman: !If [
IsStandardEnv,
!FindInMap [ "envResourcesMap", !Ref Env, "someHost" ],
!FindInMap [ "envResourcesMap", "other", "someHost" ]]
This works fine for me
UserData :
Fn::Base64 : !Sub
- |
#!/bin/bash -v
export some_variable = ${url}
- url : !FindInMap [Mapping, !Ref AWS::Region, !Ref EnvironmentType]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With