

这是新的《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::GetStackOutput`
<a name="intrinsic-function-reference-getstackoutput"></a>

内置函数 `Fn::GetStackOutput` 返回由另一个堆栈输出的值。与 `Fn::ImportValue` 不同，此函数不需要被引用堆栈显式导出输出值。它还支持跨账户和跨区域引用。

当您需要跨 AWS 账户或区域引用堆栈输出，或者希望在不管理显式导出的情况下引用输出时，请使用此函数。

**注意**  
`Fn::GetStackOutput` 创建的是弱引用。被引用的值在堆栈创建或更新时解析。如果被引用的堆栈或输出随后被删除或修改，使用该引用的堆栈不会自动更新或收到通知。为确保一致性，请保护被引用的堆栈和输出免受意外更改。

**注意**  
`Fn::GetStackOutput` 不支持跨分区引用。

## 声明
<a name="w2aac24c43c11"></a>

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

```
{
  "Fn::GetStackOutput": {
    "StackName": "{{stack-name}}",
    "OutputName": "{{output-name}}",
    "Region": "{{region}}",
    "RoleArn": "{{role-arn}}"
  }
}
```

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

您可以使用完整的函数名称：

```
Fn::GetStackOutput:
  StackName: {{stack-name}}
  OutputName: {{output-name}}
  Region: {{region}}
  RoleArn: {{role-arn}}
```

或者，您也可以使用短格式：

```
!GetStackOutput
  StackName: {{stack-name}}
  OutputName: {{output-name}}
  Region: {{region}}
  RoleArn: {{role-arn}}
```

**重要**  
当 `!GetStackOutput` 的短格式中包含其他短格式函数（如 `!Sub` 或 `!Ref` ）作为参数值时，不能使用短格式。在这种情况下，请使用完整函数名：  

```
# Do not use
!GetStackOutput
  StackName: !Ref MyStackNameParam
  OutputName: VpcId

# Use this instead
Fn::GetStackOutput:
  StackName: !Ref MyStackNameParam
  OutputName: VpcId
```

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

StackName  
包含您要引用的输出的堆栈名称。  
*是否必需*：是

OutputName  
要引用的输出的逻辑 ID。这是在引用堆栈模板的输出部分中定义的键。  
*是否必需*：是

区域  
被引用堆栈所在区域的 AWS 区域。默认为正在创建或更新的堆栈所在区域。  
*必需*：否

RoleArn  
对被引用堆栈具有 `cloudformation:DescribeStacks` 权限的 IAM 角色的 ARN。该角色必须可以被正在创建或更新的堆栈的执行角色代入。默认为当前堆栈的执行角色。在跨不同 AWS 账户引用堆栈时使用此参数。  
*必需*：否

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

被引用堆栈中指定输出的值。

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

### 同一个账户，同一个区域
<a name="intrinsic-function-reference-getstackoutput-example-same-account-region"></a>

以下示例引用同一账户和区域中名为 `ProducerStack` 的堆栈的 `VpcId` 输出。由于未指定 `Region` 或 `RoleArn` ，CloudFormation 使用当前堆栈的区域和执行角色。

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

```
{
  "Fn::GetStackOutput": {
    "StackName": "ProducerStack",
    "OutputName": "VpcId"
  }
}
```

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

```
Fn::GetStackOutput:
  StackName: ProducerStack
  OutputName: VpcId
```

### 同一个账户，不同的区域
<a name="intrinsic-function-reference-getstackoutput-example-cross-region"></a>

以下示例引用 `ProducerStack` 部署在 `us-west-2` 中的 `VpcId` 输出，而使用该引用的堆栈位于不同的区域。`Region` 参数指示 CloudFormation 在 `us-west-2` 中查找被引用的值。

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

```
{
  "Fn::GetStackOutput": {
    "StackName": "ProducerStack",
    "OutputName": "VpcId",
    "Region": "us-west-2"
  }
}
```

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

```
Fn::GetStackOutput:
  StackName: ProducerStack
  OutputName: VpcId
  Region: us-west-2
```

### 跨账户
<a name="intrinsic-function-reference-getstackoutput-example-cross-account"></a>

以下示例引用账户 `111111111111` 中 `ProducerStack` 的`VpcId` 输出。使用引用的堆栈位于账户 `222222222222` 中。`RoleArn` 参数指定了账户 `111111111111` 中具有 `cloudformation:DescribeStacks` 权限的角色，该角色必须可以被使用引用的堆栈的执行角色代入。

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

```
{
  "Fn::GetStackOutput": {
    "StackName": "ProducerStack",
    "OutputName": "VpcId",
    "RoleArn": "arn:aws:iam::111111111111:role/GetStackOutputRole"
  }
}
```

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

```
Fn::GetStackOutput:
  StackName: ProducerStack
  OutputName: VpcId
  RoleArn: arn:aws:iam::111111111111:role/GetStackOutputRole
```

### 跨账户和跨区域集群
<a name="intrinsic-function-reference-getstackoutput-example-cross-account-region"></a>

以下示例引用不同账户和不同区域中堆栈的输出。同时指定了参数 `RoleArn` 和 `Region`。

#### JSON
<a name="intrinsic-function-reference-getstackoutput-example-cross-account-region.json"></a>

```
{
  "Fn::GetStackOutput": {
    "StackName": "ProducerStack",
    "OutputName": "VpcId",
    "RoleArn": "arn:aws:iam::111111111111:role/GetStackOutputRole",
    "Region": "us-west-2"
  }
}
```

#### YAML
<a name="intrinsic-function-reference-getstackoutput-example-cross-account-region.yaml"></a>

```
Fn::GetStackOutput:
  StackName: ProducerStack
  OutputName: VpcId
  RoleArn: arn:aws:iam::111111111111:role/GetStackOutputRole
  Region: us-west-2
```

## IAM 角色配置
<a name="intrinsic-function-reference-getstackoutput-iam"></a>

在跨账户引用中使用 `RoleArn` 参数时，IAM 角色必须具有描述被引用堆栈所在账户中堆栈的权限：

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:DescribeStacks"
      ],
      "Resource": "*"
    }
  ]
}
```

**提示**  
对于更严格的策略，请将 `Resource` 的作用域限定为您要引用的特定堆栈 ARN。

该角色必须具有授予使用引用的堆栈执行角色以 `AssumeRole` 权限的信任策略：

```
{
  "Version": "2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::222222222222:role/CloudFormationExecutionRole"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

## 支持的函数
<a name="w2aac24c43c21"></a>

以下函数可以在 `Fn::GetStackOutput` 的参数值内部使用（例如，用于构造 `StackName` 或 `RoleArn`）。这些函数的值无法依赖资源。
+ `Fn::Base64`
+ `Fn::FindInMap`
+ `Fn::If`
+ `Fn::Join`
+ `Fn::Select`
+ `Fn::Sub`
+ `Ref`

`Fn::GetStackOutput`本身可以在以下模板位置中使用：
+ 直接资源属性值
+ 在 `Fn::Join` 内部
+ 在 `Fn::If` 内部
+ 在 `Fn::Select` 内部

有关尚不支持的位置，请参阅下方的 [已知限制条件](#intrinsic-function-reference-getstackoutput-limitations) 说明。

例如，您可以使用 `Ref` 将参数值作为堆栈名称传递：

```
Parameters:
  SourceStackName:
    Type: String

Resources:
  MyResource:
    Type: AWS::EC2::Instance
    Properties:
      SubnetId:
        Fn::GetStackOutput:
          StackName: !Ref SourceStackName
          OutputName: SubnetId
```

## 已知限制条件
<a name="intrinsic-function-reference-getstackoutput-limitations"></a>

以下使用模式在本版本中不受支持。均会返回 `InternalFailure` 错误。后续更新中将添加对这些模式的支持。
+ 在 `Fn::Sub` 变量映射值内部使用 `Fn::GetStackOutput`
+ 在 `Fn::Base64` 内部使用 `Fn::GetStackOutput`
+ 将`Fn::GetStackOutput` 直接用作 `Outputs` 节的值
+ 在 `Conditions` 节中的 `Fn::Equals` 内部使用 `Fn::GetStackOutput` 
+ 在 `Fn::ImportValue` 内部使用 `Fn::GetStackOutput` 

请直接将 `Fn::GetStackOutput` 用作资源属性值，或将其包裹在 `Fn::Join`、`Fn::If` 或 `Fn::Select` 内部。

## 错误处理
<a name="intrinsic-function-reference-getstackoutput-errors"></a>

CloudFormation 会在堆栈创建或更新操作期间验证 `Fn::GetStackOutput` 引用。以下是您可能遇到的常见错误：
+ *无法代入 IAM 角色* - 堆栈操作因访问被拒绝错误而失败。请验证该角色是否可以被使用引用的堆栈的执行角色代入。
+ *IAM 角色缺少 DescribeStacks 权限* - 堆栈操作失败并返回访问被拒绝错误。请验证角色的权限策略是否包含 `cloudformation:DescribeStacks`。
+ *被引用的堆栈不存在* - 堆栈操作失败，返回验证错误，指示未找到该堆栈。如果包含 `Region` 参数，请检查这是否是您要引用的堆栈的正确区域。
+ *被引用堆栈上的输出键不存在* - 堆栈操作失败，返回验证错误，指示未找到该输出。
+ *被引用堆栈所在区域未对目标账户启用* - 堆栈操作失败。请确保被引用堆栈所属账户中已启用目标区域。
+ *被引用的区域无效* - 堆栈操作失败并返回验证错误。

### us-east-1 与选择加入区域之间的引用
<a name="intrinsic-function-reference-getstackoutput-errors-optin"></a>

当您在 `us-east-1` 区域与选择加入区域之间实现引用时，可能会遇到错误。为避免此类错误，请遵循[本指南更新全局 STS 端点的令牌兼容性](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_enable-regions.html)。

## 将 Fn::GetStackOutput 与 AWS Cloud Development Kit (AWS CDK) 配合使用
<a name="intrinsic-function-reference-getstackoutput-cdk"></a>

AWS Cloud Development Kit (AWS CDK) (CDK) 通过 `Fn.getStackOutput()` 方法支持 `Fn::GetStackOutput`。当 CDK 堆栈之间存在跨区域或跨账户引用时，CDK 现在可以直接使用 `Fn::GetStackOutput`，而不再需要使用 SSM 参数生成自定义资源。这简化了合成后的模板，并消除了之前 `crossRegionReferences` 变通方法的需求。

有关更多信息，请参阅 [ CDK API 参考](https://docs.aws.amazon.com/cdk/api/v2/)。

## 与 Fn::ImportValue 的对比
<a name="intrinsic-function-reference-getstackoutput-comparison"></a>


| 能力 | `Fn::ImportValue` | `Fn::GetStackOutput` | 
| --- | --- | --- | 
| 同一个账户，同一个区域 | 支持 | 支持 | 
| 跨账户 | 不支持 | 支持 | 
| 跨区域 | 不支持 | 支持 | 
| 需要显式导出 | 是 | 否 | 
| 参考类型 | 强引用（阻止删除导出堆栈） | 弱引用（在部署时解析） | 
| 引用完整性 | 是 | 否 | 

当您需要在同一账户和区域内使用强引用完整性时，请使用 `Fn::ImportValue`。当您需要跨账户或跨区域引用，或希望避免管理显式导出时，请使用 `Fn::GetStackOutput`。

## 最佳实践
<a name="intrinsic-function-reference-getstackoutput-best-practices"></a>
+ *保护被引用的堆栈和输出。*由于 `Fn::GetStackOutput` 创建的是弱引用，删除被引用的堆栈不会阻止使用引用的堆栈被创建或更新。但是，后续需要重新解析引用的操作将失败。请使用堆栈策略、删除保护或 IAM 策略来防止意外删除被引用的堆栈。
+ *严格限定 IAM 角色的作用范围* 在配置跨账户访问的 `RoleArn` 时，请尽可能将 `DescribeStacks` 权限限定到特定的堆栈 ARN。
+ *注意解析时机。*被引用的值在堆栈创建或更新时解析。如果源值发生变化，使用引用的堆栈不会自动更新。要获取变更，请对使用引用的堆栈执行更新。