I want to use the Fn::Sub intrinsic function in AWS CloudFormation with Fn::FindInMap, Fn::ImportValue, or other supported functions.
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.
To substitute the value from supported functions, you must use variable map with the name and value as shown below:
JSON:
{ "Fn::Sub" : [ String, { Var1Name: Var1Value, Var2Name: Var2Value } ] }
YAML:
!Sub
- String
- Var1Name: Var1Value
Var2Name: Var2Value
Resolution
Usage of Fn::Sub with Ref function
The following example uses a mapping to substitute the Domain variable with the resulting value from the Ref function.
JSON:
{
"Parameters": {
"RootDomainName": {
"Type": "String",
"Default": "example123.com"
}
},
"Resources": {
"DNS": {
"Type": "AWS::Route53::HostedZone",
"Properties": {
"Name": {
"Fn::Sub": [
"www.${Domain}",
{
"Domain": {
"Ref": "RootDomainName"
}
}
]
}
}
}
}
}
YAML:
Parameters:
RootDomainName:
Type: String
Default: example123.com
Resources:
DNS:
Type: 'AWS::Route53::HostedZone'
Properties:
Name: !Sub
- 'www.${Domain}'
- Domain: !Ref RootDomainName
Usage of Fn::Sub with Fn::FindInMap function
The following example uses a mapping to substitute the log_group_name variable with the resulting value from the Fn::FindInMap function.
JSON:
{
"Mappings": {
"LogGroupMapping": {
"Test": {
"Name": "test_log_group"
},
"Prod": {
"Name": "prod_log_group"
}
}
},
"Resources": {
"myLogGroup": {
"Type": "AWS::Logs::LogGroup",
"Properties": {
"LogGroupName": {
"Fn::Sub": [
"cloud_watch_${log_group_name}",
{
"log_group_name": {
"Fn::FindInMap": [
"LogGroupMapping",
"Test",
"Name"
]
}
}
]
}
}
}
}
}
YAML:
Mappings:
LogGroupMapping:
Test:
Name: test_log_group
Prod:
Name: prod_log_group
Resources:
myLogGroup:
Type: 'AWS::Logs::LogGroup'
Properties:
LogGroupName: !Sub
- 'cloud_watch_${log_group_name}'
- log_group_name: !FindInMap
- LogGroupMapping
- Test
- Name
Usage of Fn::Sub with Fn::ImportValue function
The following example uses a mapping to substitute the Domain variable with the resulting value from the Fn::ImportValue function.
Note: DomainName is the name of the Output exported by another CloudFormation stack.
JSON:
{
"Resources": {
"DNS": {
"Type": "AWS::Route53::HostedZone",
"Properties": {
"Name": {
"Fn::Sub": [
"www.${Domain}",
{
"Domain": {
"Fn::ImportValue": "DomainName"
}
}
]
}
}
}
}
}
YAML:
Resources:
DNS:
Type: 'AWS::Route53::HostedZone'
Properties:
Name: !Sub
- 'www.${Domain}'
- Domain: !ImportValue DomainName