常规输出值不能被其他堆栈引用。当您chain or nest您的堆栈及其范围/可见性是本地的。导出的输出在帐户和区域内全局可见,并且可供您将来要部署的任何堆栈使用。
Chaining
当您链接堆栈时,您可以部署一个堆栈,获取其输出,并将其用作要部署的第二个堆栈的输入参数。
例如,假设您有两个名为instance.yaml
and eip.yaml
. The instance.yaml
输出其实例 ID(不导出),同时eip.yaml
将实例 id 作为输入参数。
要部署它们,您必须将它们链接起来:
- Deploy
instance.yaml
并等待其完成。
- 请注意,它输出值(即实例 ID)——通常以编程方式完成,而不是手动完成。
- Deploy
eip.yaml
并将实例 ID 作为其输入参数传递。
Nesting
当您嵌套堆栈时,您将拥有一个父模板和一个子模板。子堆栈将从父堆栈内部创建。在这种情况下,子堆栈将产生一些输出(而不是导出)供父堆栈使用。
例如,让我们再次使用instance.yaml
and eip.yaml
。但这一次eip.yaml
将成为父母并且instance.yaml
将是孩子。还eip.yaml
不接受任何输入参数,但是instance.yaml
输出其实例 ID(不导出)
在这种情况下,要部署它们,您需要执行以下操作:
- 上传子模板(
instance.yaml
) to s3
- In
eip.yaml
使用创建子实例堆栈AWS::CloudFormation::堆栈 https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html以及步骤 1 中的 s3 url。
这边走eip.yaml
将能够使用以下命令从嵌套堆栈的输出中访问实例 IDGetAtt
.
交叉引用
当您交叉引用堆栈时,您将拥有一个导出其输出的堆栈,以便同一区域和帐户中的任何其他堆栈都可以使用它们。
例如,让我们再次使用instance.yaml
and eip.yaml
. instance.yaml
将导出其输出(实例 ID)。使用实例 IDeip.yaml
将不得不使用进口值 https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html在其模板中,不需要任何输入参数或嵌套堆栈。
在这种情况下,要部署它们,您需要执行以下操作:
- Deploy
instance.yaml
并等待它完成。
- Deploy
eip.yaml
这将导入实例 ID。
Altough 交叉引用看起来很有用,但它有一个主要问题,那就是更新或删除交叉引用非常困难stacks https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html:
另一个堆栈导入输出值后,您无法删除正在导出输出值的堆栈或修改导出的输出值。必须先删除所有导入,然后才能删除导出堆栈或修改输出值。
如果您正在开始设计并且模板可能经常更改,那么这是非常有问题的。
什么时候用哪个?
当您有一些数据时,请使用交叉引用(导出的值)全球资源这些数据将在给定区域和帐户中的许多堆栈之间共享。此外,它们不应该经常更改,因为它们很难修改。常见的示例有:用于集中日志记录位置的全局存储桶、VPC。
当您有一些时,请使用嵌套堆栈(不导出输出)通用组件您经常部署,但每次它们可能会有所不同。示例包括:ALB、堡垒主机实例、vpc 接口端点。
最后,链式堆栈(不是导出的输出)对于设计很有用松耦合模板,您可以在其中根据新要求混合和匹配模板。