Trying to use Fn::Join within Fn::FindInMap, as below:
"SubnetId": {
"Fn::FindInMap": [
{
"Ref": "OrganizationName"
},
"AZ",
{
"Fn::Join": [
"",
[
{
"Ref": "Environment"
},
{
"Ref": "Member1AZ"
}
]
]
}
]
}
The OrganizationName, Environment and Member1AZ are all parameters. Essentially it should hook up to my mappings and produce, for example :
"SubnetId" : { "Fn::FindInMap" : [ "Organization2", "AZ", "prod1c" ]}
However, it does not seem to be taking the output from the Fn::Join as a single entity on the Fn::FindInMap, it validates correctly if I hardcode that section of the template.
A client error (ValidationError) occurred when calling the ValidateTemplate operation: Template error: every Fn::FindInMap object requires three parameters, the map name, map key and the attribute for return value
My Mappings are as follows:
Mappings" : {
"OrganizationDefaults" : {
"AZ" : {
"prod1a" : "subnet-foobar1",
"qa1a" : "subnet-foobar2",
"prod1c" : "subnet-foobar3",
"qa1c" : "subnet-foobar4"
}
},
"OrganizationTwo" : {
"AZ" : {
"prod1a" : "subnet-foobar5",
"qa1a" : "subnet-foobar6",
"prod1c" : "subnet-foobar7",
"qa1c" : "subnet-foobar8"
}
},
},
Can anyone help on this, or had to do something similar before? I need to use the same template for any organizations listed, so Mappings should solve this for me, if I can get it right.
You can use the Fn::Sub function to substitute supported functions or to substitute as a string for other functions. In your AWS CloudFormation template, you can use Fn::Sub to substitute other supported functions, such as Fn::FindInMap. If you're using a JSON template, substitute Var1Name and Var2Name with a Var1Value and Var2Value. For example:
In your AWS CloudFormation template, you can use Fn::Sub to substitute other supported functions, such as Fn::FindInMap. If you're using a JSON template, substitute Var1Name and Var2Name with a Var1Value and Var2Value.
CloudFormation supports a number of intrinsic functions and Fn::Join (or !Join) is often used to construct parameterised names and paths. The Serverless framework, for instance, uses it extensively.
Check out the serverless-cloudformation-sub-variables plugin which lets you use Fn::Sub in the serverless.yml. You just need to use # {VariableName} instead of $ {VariableName}. CloudFormation supports a number of intrinsic functions and Fn::Join (or !Join) is often used to construct parameterised names and paths.
Although I agree with @Jason that in your case a refactor of your map layout is the best solution for you, there are cases where the 2D limitations of the maps in CloudFormation can be limiting, so I will post a possible solution here.
As of the date of this post, the Fn::FindInMap
intrinsic function only supports the following nested functions:
Fn::FindInMap
Ref
Using a Join
will give you the slightly cryptic error you post above. However, because you can nest FindInMap
calls, you can achieve a "3rd dimention" for the map by creating another lookup map:
Mappings" : {
"OrganizationDefaults" : {
"AZ" : {
"prod1a" : "subnet-foobar1",
"qa1a" : "subnet-foobar2",
"prod1c" : "subnet-foobar3",
"qa1c" : "subnet-foobar4"
}
},
"OrganizationTwo" : {
"AZ" : {
"prod1a" : "subnet-foobar5",
"qa1a" : "subnet-foobar6",
"prod1c" : "subnet-foobar7",
"qa1c" : "subnet-foobar8"
}
},
"EnvMemberMap" : {
"prod": {
"1a" : "prod1a",
"1c" : "prod1c",
},
"qa": {
"1a" : "qa1a",
"1c" : "qa1c",
}
}
},
And then perform the map retrieval like this:
"SubnetId": {
"Fn::FindInMap": [
{
"Ref": "OrganizationName"
},
"AZ",
{
"Fn::FindInMap": [
"EnvMemberMap",
{
"Ref": "Environment"
},
{
"Ref": "Member1AZ"
}
]
}
]
}
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