【发布时间】:2020-10-07 23:44:43
【问题描述】:
在 CloudFormation 中,我们能够从模板输出一些值,以便其他进程、堆栈等可以检索它们。这通常是某物的名称,可能是 URL 或在堆栈创建(部署)期间生成的某物等。
我们还可以从模板“导出”。将值作为“输出”返回与“导出”有什么区别?
【问题讨论】:
标签: amazon-web-services amazon-cloudformation
在 CloudFormation 中,我们能够从模板输出一些值,以便其他进程、堆栈等可以检索它们。这通常是某物的名称,可能是 URL 或在堆栈创建(部署)期间生成的某物等。
我们还可以从模板“导出”。将值作为“输出”返回与“导出”有什么区别?
【问题讨论】:
标签: amazon-web-services amazon-cloudformation
常规输出值不能被其他堆栈引用。当您链接或嵌套您的堆栈并且它们的范围/可见性是本地的时,它们会很有用。导出的输出在帐户和区域内全局可见,并且可供您将来要部署的任何堆栈使用。
链接
当您链接堆栈时,您部署一个堆栈,将其作为输出,并将其用作您要部署的第二个堆栈的输入参数。
例如,假设您有两个名为 instance.yaml 和 eip.yaml 的模板。 instance.yaml 输出其实例 ID(不导出),而 eip.yaml 将实例 ID 作为输入参数。
要同时部署它们,您必须将它们链接起来:
instance.yaml 并等待其完成。eip.yaml 并将instance-id 作为其输入参数。嵌套
当您嵌套堆栈时,您将拥有一个父模板和一个子模板。子堆栈将从父堆栈内部创建。在这种情况下,子堆栈将产生一些输出(而不是导出)供父堆栈使用。
例如,让我们再次使用instance.yaml 和eip.yaml。但是这次eip.yaml 将是父级,instance.yaml 将是子级。同样eip.yaml 不接受任何输入参数,但instance.yaml 输出其instance-id(不导出)
在这种情况下,要部署它们,请执行以下操作:
eip.yaml)到s3eip.yaml 中,使用AWS::CloudFormation::Stack 和步骤1 中的s3 url 创建子实例堆栈。这样eip.yaml 将能够使用GetAtt 从嵌套堆栈的输出中访问实例ID。
交叉引用
当您交叉引用堆栈时,您有一个堆栈可以导出它的输出,以便同一区域和帐户中的任何其他堆栈都可以使用它们。
例如,让我们再次使用instance.yaml 和eip.yaml。 instance.yaml 将导出其输出(instance-id)。要使用实例 ID eip.yaml,必须在其模板中使用 ImportValue,而无需任何输入参数或嵌套堆栈。
在这种情况下,要部署它们,请执行以下操作:
instance.yaml 并等待它完成。eip.yaml,它将导入instance-id。虽然交叉引用看起来很有用,但它有一个主要问题,那就是很难更新或删除交叉引用的stacks:
在另一个堆栈导入输出值后,您无法删除正在导出输出值的堆栈或修改导出的输出值。必须先删除所有导入,然后才能删除导出堆栈或修改输出值。
如果您刚开始设计并且您的模板可能经常更改,这将是非常有问题的。
什么时候使用?
当您有一些 全局资源 将在给定区域和帐户中的许多堆栈之间共享时,请使用交叉引用(导出值)。此外,它们不应该经常更改,因为它们很难修改。常见示例有:用于集中记录位置的全局存储桶、VPC。
当您有一些您经常部署的通用组件时使用嵌套堆栈(不是导出的输出),但每次它们可能会有所不同。例如:ALB、堡垒主机实例、vpc 接口端点。
最后,链式堆栈(不是导出的输出)对于设计松散耦合模板很有用,您可以在其中根据新要求混合和匹配模板。
【讨论】:
eip.yaml 上传到 S3,但下一项说要使用 eip.yml 中的 S3 url。这不是循环引用吗?您的意思是说要将子 instance.yml 上传到 S3 吗?
here 的简短回答,在堆栈之间使用export,并在嵌套堆栈中使用output。
要在堆栈之间共享信息,请导出堆栈的输出值。 同一 AWS 账户和区域中的其他堆栈可以导入 导出的值。
使用嵌套堆栈,您可以从一个单一的部署和管理所有资源 堆。您可以将嵌套堆栈组中一个堆栈的输出用作 组中另一个堆栈的输入。这与导出不同 价值观。
【讨论】: