

这是新的《CloudFormation 模板参考指南》**。请更新您的书签和链接。有关开始使用 CloudFormation 的帮助，请参阅《AWS CloudFormation 用户指南》[https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)。

# `Fn::Sub`
<a name="intrinsic-function-reference-sub"></a>

内部函数 `Fn::Sub` 将输入字符串中的变量替换为您指定的值。在您的模板中，可以使用此函数构建命令或输出，其中包含在创建或更新堆栈之前不可用的值。

## 声明
<a name="intrinsic-function-reference-sub-declaration"></a>

以下部分显示函数的语法。

### JSON
<a name="intrinsic-function-reference-sub-syntax.json"></a>

```
{ "Fn::Sub" : [ String, { Var1Name: Var1Value, Var2Name: Var2Value } ] }
```

如果您仅替换 `String` 参数中的模板参数、资源逻辑 ID 或资源属性，则不要指定变量映射。

```
{ "Fn::Sub" : String }
```

### YAML
<a name="intrinsic-function-reference-sub-syntax.yaml"></a>

完整函数名称的语法：

```
Fn::Sub:
  - String
  - Var1Name: Var1Value
    Var2Name: Var2Value
```

短格式的语法：

```
!Sub
  - String
  - Var1Name: Var1Value
    Var2Name: Var2Value
```

如果您仅替换 `String` 参数中的模板参数、资源逻辑 ID 或资源属性，则不要指定变量映射。

完整函数名称的语法：

```
Fn::Sub: String
```

短格式的语法：

```
!Sub String
```

## 参数
<a name="w2aac24c66b7"></a>

`String`  
一个带变量的字符串，CloudFormation 在运行时会将这些变量替换为其关联的值。以 `${MyVarName}` 形式编写变量。变量可以是模板参数名、资源逻辑 ID、资源属性或键值映射中的变量。如果您仅指定模板参数名、资源逻辑 ID 和资源属性，则不要指定键值映射。  
如果您指定模板参数名或资源逻辑 ID（例如 `${InstanceTypeParameter}`），则 CloudFormation 返回的值与您使用 `Ref` 内部函数时返回的值相同。如果您指定资源属性（例如 `${MyInstance.PublicIp}`），则 CloudFormation 返回的值与您使用 `Fn::GetAtt` 内部函数时返回的值相同。  
要按字面书写美元符号和大括号（`${}`），请在左大括号后面添加感叹号（`!`），如 `${!Literal}`。CloudFormation 将该文本解析为 `${Literal}`。  
如果您使用的是启动模板，请在美元符号（如 `\${!Literal}`）前添加反斜杠 `\`，否则字面解析结果将为空字符串。

`VarName`  
`String` 参数中包含的变量的名称。

`VarValue`  
CloudFormation 在运行时要将关联的变量名称替换为的值。

## 返回值
<a name="w2aac24c66b9"></a>

CloudFormation 返回原始字符串，并替换所有变量的值。

## 示例
<a name="w2aac24c66c11"></a>

以下示例说明如何使用 `Fn::Sub` 函数。

### 使用不带键值映射的 `Fn::Sub`
<a name="w2aac24c66c11b5"></a>

在这一简单示例中，`InstanceSecurityGroup` 资源描述使用 `AWS::StackName` 伪参数动态创建。例如，如果堆栈名称为“VPC-EC2-ALB-Stack”，则生成的描述为“SSH security group for VPC-EC2-ALB-Stack”。

#### JSON
<a name="intrinsic-function-reference-sub-example-1.json"></a>

```
"InstanceSecurityGroup" : {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
        "GroupDescription" : {"Fn::Sub": "SSH security group for ${AWS::StackName}"}
}}
```

#### YAML
<a name="intrinsic-function-reference-sub-example-1.yaml"></a>

```
InstanceSecurityGroup:
  Type: AWS::EC2::SecurityGroup
  Properties:
    GroupDescription: !Sub "SSH security group for ${AWS::StackName}"
```

### 使用带键值映射的 `Fn::Sub`
<a name="w2aac24c66c11b7"></a>

在此示例中，`WWWBucket` 资源名称使用键值映射动态创建。`Fn::Sub` 函数将输入字符串 `www.${Domain}` 中的 `${Domain}` 替换为引用在同一堆栈模板中定义的 `RootDomainName` 参数的 `Ref` 函数值。例如，如果根域名称为“mydomain.com”，则该资源生成的名称为“www.mydomain.com”。

#### JSON
<a name="intrinsic-function-reference-sub-example-2.json"></a>

```
"WWWBucket":{
  "Type":"AWS::S3::Bucket",
  "Properties":{
    "BucketName":{
      "Fn::Sub":[
        "www.${Domain}",
        {
          "Domain":{
            "Ref":"RootDomainName"
          }
        }
      ]
    }
  }
}
```

#### YAML
<a name="intrinsic-function-reference-sub-example-2.yaml"></a>

```
  WWWBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub
        - 'www.${Domain}'
        - Domain: !Ref RootDomainName
```

### 使用多个变量构造 ARN
<a name="w2aac24c66c11b9"></a>

以下示例使用 `Fn::Sub`、`AWS::Region` 和 `AWS::AccountId` 伪参数以及 `vpc` 资源逻辑 ID，为 VPC 创建 Amazon 资源名称（ARN）。

#### JSON
<a name="intrinsic-function-reference-sub-example-3.json"></a>

```
{ "Fn::Sub": "arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}" }
```

#### YAML
<a name="intrinsic-function-reference-sub-example-3.yaml"></a>

```
!Sub 'arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:vpc/${vpc}'
```

### 在用户数据脚本中传递参数值
<a name="w2aac24c66c11c11"></a>

以下示例使用 `Fn::Sub` 在运行时将 `AWS::StackName` 和 `AWS::Region` 伪参数替换为实际堆栈名称和区域。

#### JSON
<a name="intrinsic-function-reference-sub-example.json"></a>

为了便于阅读，JSON 示例使用 `Fn::Join` 函数来分隔每条命令，而不是在单个字符串值中指定整个用户数据脚本。

```
"UserData": { "Fn::Base64": { "Fn::Join": ["\n", [
  "#!/bin/bash -xe",
  "yum update -y aws-cfn-bootstrap",
  { "Fn::Sub": "/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfig --configsets wordpress_install --region ${AWS::Region}" },
  { "Fn::Sub": "/opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerGroup --region ${AWS::Region}" }]]
}}
```

#### YAML
<a name="intrinsic-function-reference-sub-example.yaml"></a>

YAML 示例使用文字块指定用户数据脚本。

```
UserData:
  Fn::Base64:
    !Sub |
      #!/bin/bash -xe
      yum update -y aws-cfn-bootstrap
      /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfig --configsets wordpress_install --region ${AWS::Region}
      /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource WebServerGroup --region ${AWS::Region}
```

### 使用映射指定条件值
<a name="w2aac24c66c11c13"></a>

在此示例中，`myLogGroup` 资源的名称是通过将 `log_group_name` 变量替换为 `Fn::FindInMap` 函数的结果值来动态创建的。

#### JSON
<a name="intrinsic-function-reference-sub-example-5.json"></a>

```
{
  "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
<a name="intrinsic-function-reference-sub-example-5.yaml"></a>

```
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
```

## 支持的函数
<a name="intrinsic-function-reference-sub-supported-functions"></a>

对于 `String` 参数，您无法使用任何函数。您必须指定字符串值。

对于 `VarName` 和 `VarValue` 参数，您可以使用以下函数：
+ [`Fn::Base64`](intrinsic-function-reference-base64.md)
+ [`Fn::FindInMap`](intrinsic-function-reference-findinmap.md)
+ [`Fn::GetAtt`](intrinsic-function-reference-getatt.md)
+ [`Fn::GetAZs`](intrinsic-function-reference-getavailabilityzones.md)
+ [`Fn::If`](intrinsic-function-reference-conditions.md#intrinsic-function-reference-conditions-if)
+ [`Fn::ImportValue`](intrinsic-function-reference-importvalue.md)
+ [`Fn::Join`](intrinsic-function-reference-join.md)
+ [`Fn::Select`](intrinsic-function-reference-select.md)
+ [`Fn::Sub`](#intrinsic-function-reference-sub)
+ [`Ref`](intrinsic-function-reference-ref.md)