Heat Orchestration Template (HOT) 规范

HOT 是一种旨在随着时间推移取代 Heat CloudFormation 兼容格式 (CFN) 作为 Heat 原生格式的模板格式。本规范详细解释了 HOT 模板格式的所有元素。有关编写 HOT 模板的示例驱动指南,请参阅 Heat Orchestration Template (HOT) 指南

状态

自 2014 年 4 月的 Icehouse 版本起,HOT 被认为可靠、受支持且标准化。Heat 核心团队可能会改进标准,这些改进很可能向后兼容。模板格式也支持版本控制。自 Juno 版本以来,Heat 支持 HOT 规范的多个不同版本。

模板结构

HOT 模板使用 YAML 定义,并遵循下文概述的结构。

heat_template_version: 2016-10-14

description:
  # a description of the template

parameter_groups:
  # a declaration of input parameter groups and order

parameters:
  # declaration of input parameters

resources:
  # declaration of template resources

outputs:
  # declaration of output parameters

conditions:
  # declaration of conditions
heat_template_version

此键的值为 2013-05-23(或更晚的日期)表示 YAML 文档是指定版本的 HOT 模板。

description

此可选键允许为模板或使用模板可部署的工作负载提供描述。

parameter_groups

此部分允许指定输入参数应如何分组以及提供参数的顺序。此部分是可选的,必要时可以省略。

parameters

此部分允许指定实例化模板时必须提供的输入参数。此部分是可选的,当不需要输入时可以省略。

resources

此部分包含模板单个资源的声明。任何 HOT 模板都应定义此部分(至少一个资源),否则模板在实例化时将无法执行任何操作。

outputs

此部分允许指定模板实例化后可供用户使用的输出参数。此部分是可选的,当不需要输出值时可以省略。

conditions

此可选部分包含语句,可用于限制何时创建资源或何时定义属性。它们可以与 resources 部分中的资源和资源属性相关联,也可以与模板的 outputs 部分中的输出相关联。

注意:此部分的支持已在 Newton 版本中添加。

Heat 模板版本

heat_template_version 的值不仅告知 Heat 模板的格式,还告知 Heat 将验证和支持的功能。从 Newton 版本开始,版本可以是 Heat 发布的日期或 Heat 发布的代号。Heat 目前支持 heat_template_version 键的以下值:

2013-05-23

键值为 2013-05-23 表示 YAML 文档是 HOT 模板,并且可能包含截至 Icehouse 版本实现的功能。此版本支持以下函数(其中一些已向后移植到此版本):

get_attr
get_file
get_param
get_resource
list_join
resource_facade
str_replace
Fn::Base64
Fn::GetAZs
Fn::Join
Fn::MemberListToMap
Fn::Replace
Fn::ResourceFacade
Fn::Select
Fn::Split
Ref

2014-10-16

键值为 2014-10-16 表示 YAML 文档是 HOT 模板,并且可能包含截至 Juno 版本添加和/或删除的功能。此版本删除了 Icehouse 版本(即 2013-05-23 版本)支持的大多数 CFN 函数。因此,现在支持的函数是:

get_attr
get_file
get_param
get_resource
list_join
resource_facade
str_replace
Fn::Select

2015-04-30

键值为 2015-04-30 表示 YAML 文档是 HOT 模板,并且可能包含截至 Kilo 版本添加和/或删除的功能。此版本添加了 repeat 函数。因此,支持的函数完整列表是:

get_attr
get_file
get_param
get_resource
list_join
repeat
digest
resource_facade
str_replace
Fn::Select

2015-10-15

键值为 2015-10-15 表示 YAML 文档是 HOT 模板,并且可能包含截至 Liberty 版本添加和/或删除的功能。此版本删除了 _Fn::Select_ 函数,应使用基于路径的 get_attr/get_param 引用。此外,从该版本开始,get_attr 在未指定 < <attribute name> 时,返回给定资源的所有属性的字典,不包括 _show_ 属性,例如 { get_attr: [<resource name>]}。此版本还添加了 str_split 函数,并支持将多个列表传递给现有的 list_join 函数。支持的函数完整列表是:

get_attr
get_file
get_param
get_resource
list_join
repeat
digest
resource_facade
str_replace
str_split

2016-04-08

键值为 2016-04-08 表示 YAML 文档是 HOT 模板,并且可能包含截至 Mitaka 版本添加和/或删除的功能。此版本还添加了 map_merge 函数,可用于合并映射的内容。支持的函数完整列表是:

digest
get_attr
get_file
get_param
get_resource
list_join
map_merge
repeat
resource_facade
str_replace
str_split

2016-10-14 | newton

键值为 2016-10-14newton 表示 YAML 文档是 HOT 模板,并且可能包含截至 Newton 版本添加和/或删除的功能。此版本添加了 yaql 函数,可用于评估复杂表达式;map_replace 函数,可对映射执行键/值替换;以及 if 函数,可根据条件评估返回相应的值。支持的函数完整列表是:

digest
get_attr
get_file
get_param
get_resource
list_join
map_merge
map_replace
repeat
resource_facade
str_replace
str_split
yaql
if

此版本添加了 equals 条件函数,用于比较两个值是否相等;not 条件函数,用作 NOT 运算符;and 条件函数,用作 AND 运算符来评估所有指定的条件;or 条件函数,用作 OR 运算符来评估所有指定的条件。支持的条件函数完整列表是:

equals
get_param
not
and
or

2017-02-24 | ocata

键值为 2017-02-24ocata 表示 YAML 文档是 HOT 模板,并且可能包含截至 Ocata 版本添加和/或删除的功能。此版本添加了 str_replace_strict 函数,该函数会为丢失的参数引发错误;以及 filter 函数,用于从列表中过滤掉值。支持的函数完整列表是:

digest
filter
get_attr
get_file
get_param
get_resource
list_join
map_merge
map_replace
repeat
resource_facade
str_replace
str_replace_strict
str_split
yaql
if

支持的条件函数完整列表是:

equals
get_param
not
and
or

2017-09-01 | pike

键值为 2017-09-01pike 表示 YAML 文档是 HOT 模板,并且可能包含截至 Pike 版本添加和/或删除的功能。此版本添加了用于组合 URL 的 make_url 函数;用于组合多个列表的 list_concat 函数;用于组合多个列表而不重复项的 list_concat_unique 函数;用于为丢失和空的参数引发错误的 string_replace_vstrict 函数;以及用于检查特定值是否在序列中的 contains 函数。支持的函数完整列表是:

digest
filter
get_attr
get_file
get_param
get_resource
list_join
make_url
list_concat
list_concat_unique
contains
map_merge
map_replace
repeat
resource_facade
str_replace
str_replace_strict
str_replace_vstrict
str_split
yaql
if

在此版本中,我们支持“yaql”和“contains”作为条件函数。支持的条件函数完整列表是:

equals
get_param
not
and
or
yaql
contains

2018-03-02 | queens

键值为 2018-03-02queens 表示 YAML 文档是 HOT 模板,并且可能包含截至 Queens 版本添加和/或删除的功能。支持的函数完整列表是:

digest
filter
get_attr
get_file
get_param
get_resource
list_join
make_url
list_concat
list_concat_unique
contains
map_merge
map_replace
repeat
resource_facade
str_replace
str_replace_strict
str_replace_vstrict
str_split
yaql
if

支持的条件函数完整列表是:

equals
get_param
not
and
or
yaql
contains

2018-08-31 | rocky

键值为 2018-08-31rocky 表示 YAML 文档是 HOT 模板,并且可能包含截至 Rocky 版本添加和/或删除的功能。支持的函数完整列表是:

digest
filter
get_attr
get_file
get_param
get_resource
list_join
make_url
list_concat
list_concat_unique
contains
map_merge
map_replace
repeat
resource_facade
str_replace
str_replace_strict
str_replace_vstrict
str_split
yaql
if

支持的条件函数完整列表是:

equals
get_param
not
and
or
yaql
contains

2021-04-16 | wallaby

键值为 2021-04-16wallaby 表示 YAML 文档是 HOT 模板,并且可能包含截至 Wallaby 版本添加和/或删除的功能。

此版本添加了 if 函数的 2 参数变体。当条件为 false 且未提供第三个参数时,整个封闭项(可能是列表项、字典中的键值对或属性值)将被省略。这允许例如有条件地定义属性,同时在条件为 false 时保留默认值。

支持的函数完整列表是:

digest
filter
get_attr
get_file
get_param
get_resource
list_join
make_url
list_concat
list_concat_unique
contains
map_merge
map_replace
repeat
resource_facade
str_replace
str_replace_strict
str_replace_vstrict
str_split
yaql
if

支持的条件函数完整列表是:

equals
get_param
not
and
or
yaql
contains

参数组部分

parameter_groups 部分允许指定输入参数应如何分组以及提供参数的顺序。这些组通常用于描述下游用户界面的预期行为。

这些组在列表中指定,每个组包含一个关联参数列表。列表用于表示参数的预期顺序。每个参数应仅一次与特定组相关联,使用参数名将其绑定到 parameters 部分中定义的参数。

parameter_groups:
- label: <human-readable label of parameter group>
  description: <description of the parameter group>
  parameters:
  - <param name>
  - <param name>
标签

定义关联参数组的可读标签。

description

此属性允许为参数组提供可读的描述。

parameters

与此参数组关联的参数列表。

param name

parameters 部分中定义的参数名称。

参数部分

parameters 部分允许指定实例化模板时必须提供的输入参数。这些参数通常用于自定义每次部署(例如,通过设置自定义用户名或密码)或绑定到环境特定项(如某些镜像)。

每个参数都在一个单独的嵌套块中指定,第一个行定义参数名,其他属性(如类型或默认值)作为嵌套元素定义。

parameters:
  <param name>:
    type: <string | number | json | comma_delimited_list | boolean>
    label: <human-readable name of the parameter>
    description: <description of the parameter>
    default: <default value for parameter>
    hidden: <true | false>
    constraints:
      <parameter constraints>
    immutable: <true | false>
    tags: <list of parameter categories>
param name

参数的名称。

type

参数的类型。支持的类型为 stringnumbercomma_delimited_listjsonboolean。此属性是必需的。

标签

参数的可读名称。此属性是可选的。

description

参数的可读描述。此属性是可选的。

default

参数的默认值。如果用户在部署期间未指定自己的值,则使用此值。此属性是可选的。

hidden

定义在用户请求有关从模板创建的堆栈的信息时是否应隐藏参数。此属性可用于隐藏作为参数指定的密码。

此属性是可选的,默认为 false

constraints

要应用的约束列表。在用户部署堆栈时,编排引擎会验证这些约束。如果参数值不符合约束,则堆栈创建失败。此属性是可选的。

immutable

定义参数是否可更新。如果此参数设置为 true 且参数值已更改,则堆栈更新失败。此属性是可选的,默认为 false

tags

指定参数类别的字符串列表。此值用于对参数进行分类,以便用户可以分组参数。此属性是可选的。

下表描述了所有当前支持的类型及其示例:

类型

描述

示例

字符串

字面字符串。

“String param”

数字

整数或浮点数。

“2”;“0.2”

comma_delimited_list

由逗号分隔的字面字符串数组。字符串总数应比逗号总数多一个。

[“one”, “two”];“one, two”;注意:“one, two”返回 [“one”, “ two”]

json

JSON 格式的映射或列表。

{“key”: “value”}

布尔值

布尔类型值,“t”、“true”、“on”、“y”、“yes”或“1”表示 true,而“f”、“false”、“off”、“n”、“no”或“0”表示 false。

“on”;“n”

以下示例显示了两个参数的极简定义:

parameters:
  user_name:
    type: string
    label: User Name
    description: User name to be configured for the application
  port_number:
    type: number
    label: Port Number
    description: Port number to be configured for the web server

注意

描述和标签是可选的,但定义这些属性是为用户提供参数角色的有用信息的最佳实践。

参数约束

参数定义中的 constraints 块定义了应用于参数值的附加验证约束。用户提供的参数值在实例化时会根据约束进行验证。约束定义为一个列表,其语法如下:

constraints:
  - <constraint type>: <constraint definition>
    description: <constraint description>
constraint type

要应用的约束类型。目前支持的约束集如下所示。

constraint definition

实际约束,取决于约束类型。每种约束类型的具体语法如下所示。

description

约束的描述。当用户定义的值违反约束时,将向用户显示此文本。如果省略,将向用户显示默认验证消息。此属性是可选的。

以下示例显示了一个带有两个约束的字符串参数的定义。请注意,虽然每个约束的描述都是可选的,但提供具体的描述以在部署时向用户显示有用的消息是最佳实践。

parameters:
  user_name:
    type: string
    label: User Name
    description: User name to be configured for the application
    constraints:
      - length: { min: 6, max: 8 }
        description: User name must be between 6 and 8 characters
      - allowed_pattern: "[A-Z]+[a-zA-Z0-9]*"
        description: User name must start with an uppercase character

注意

虽然每个约束的描述都是可选的,但提供具体的描述以在部署时向用户显示有用的消息是最佳实践。

以下各节列出了支持的参数约束类型以及每种类型的具体语法。

length

length 约束适用于 stringcomma_delimited_listjson 类型的参数。

它定义了字符串值或列表/映射集合长度的下限和上限。

length 约束的语法是:

length: { min: <lower limit>, max: <upper limit> }

可以仅定义下限或上限的长度约束。但是,必须指定 minmax 中的至少一个。

range

range 约束适用于 number 类型的参数。它定义了参数数值的下限和上限。

range 约束的语法是:

range: { min: <lower limit>, max: <upper limit> }

可以仅定义下限或上限的范围约束。但是,必须指定 minmax 中的至少一个。

范围包括最小值和最大值。例如,以下范围约束允许所有介于 0 和 10 之间的数字值:

range: { min: 0, max: 10 }

modulo

modulo 约束适用于 number 类型的参数。当值为 offset 起始的 step 的倍数时,该值有效。

modulo 约束的语法是:

modulo: { step: <step>, offset: <offset> }

必须同时指定 stepoffset

例如,以下模约束将仅允许奇数:

modulo: { step: 2, offset: 1 }

allowed_values

allowed_values 约束适用于 stringnumber 类型的参数。它指定了参数的可能值集合。在部署时,用户提供的相应参数值必须与列表中的元素之一匹配。

allowed_values 约束的语法是:

allowed_values: [ <value>, <value>, ... ]

或者,可以使用以下 YAML 列表表示法:

allowed_values:
  - <value>
  - <value>
  - ...

例如

parameters:
  instance_type:
    type: string
    label: Instance Type
    description: Instance type for compute instances
    constraints:
      - allowed_values:
        - m1.small
        - m1.medium
        - m1.large

allowed_pattern

allowed_pattern 约束适用于 string 类型的参数。它指定了一个正则表达式,用户提供的参数值在部署时必须匹配该正则表达式。

allowed_pattern 约束的语法是:

allowed_pattern: <regular expression>

例如

parameters:
  user_name:
    type: string
    label: User Name
    description: User name to be configured for the application
    constraints:
      - allowed_pattern: "[A-Z]+[a-zA-Z0-9]*"
        description: User name must start with an uppercase character

custom_constraint

custom_constraint 约束添加了一个额外的验证步骤,通常用于检查资源是否存在于后端。自定义约束通过插件实现,并可提供任何高级约束验证逻辑。

custom_constraint 约束的语法是:

custom_constraint: <name>

name 属性指定了自定义约束的具体类型。它对应于验证插件在编排引擎中注册的名称。

例如

parameters:
  key_name
    type: string
    description: SSH key pair
    constraints:
      - custom_constraint: nova.keypair

以下部分列出了自定义约束和支持它们的插件。

名称

Plug-in

barbican.container

heat.engine.clients.os.barbican:ContainerConstraint

barbican.secret

heat.engine.clients.os.barbican:SecretConstraint

blazar.reservation

heat.engine.clients.os.blazar:ReservationConstraint

cinder.backup

heat.engine.clients.os.cinder:VolumeBackupConstraint

cinder.qos_specs

heat.engine.clients.os.cinder:QoSSpecsConstraint

cinder.snapshot

heat.engine.clients.os.cinder:VolumeSnapshotConstraint

cinder.volume

heat.engine.clients.os.cinder:VolumeConstraint

cinder.vtype

heat.engine.clients.os.cinder:VolumeTypeConstraint

cron_expression

heat.engine.constraint.common_constraints:CRONExpressionConstraint

designate.zone

heat.engine.clients.os.designate:DesignateZoneConstraint

dns_domain

heat.engine.constraint.common_constraints:DNSDomainConstraint

dns_name

heat.engine.constraint.common_constraints:DNSNameConstraint

expiration

heat.engine.constraint.common_constraints:ExpirationConstraint

glance.image

heat.engine.clients.os.glance:ImageConstraint

ip_addr

heat.engine.constraint.common_constraints:IPConstraint

ip_or_cidr

heat.engine.constraint.common_constraints:IPCIDRConstraint

ironic.node

heat.engine.clients.os.ironic:NodeConstraint

ironic.portgroup

heat.engine.clients.os.ironic:PortGroupConstraint

iso_8601

heat.engine.constraint.common_constraints:ISO8601Constraint

json_string

heat.engine.constraint.common_constraints:JsonStringConstraint

keystone.domain

heat.engine.clients.os.keystone.keystone_constraints:KeystoneDomainConstraint

keystone.group

heat.engine.clients.os.keystone.keystone_constraints:KeystoneGroupConstraint

keystone.project

heat.engine.clients.os.keystone.keystone_constraints:KeystoneProjectConstraint

keystone.region

heat.engine.clients.os.keystone.keystone_constraints:KeystoneRegionConstraint

keystone.role

heat.engine.clients.os.keystone.keystone_constraints:KeystoneRoleConstraint

keystone.service

heat.engine.clients.os.keystone.keystone_constraints:KeystoneServiceConstraint

keystone.user

heat.engine.clients.os.keystone.keystone_constraints:KeystoneUserConstraint

mac_addr

heat.engine.constraint.common_constraints:MACConstraint

magnum.cluster_template

heat.engine.clients.os.magnum:ClusterTemplateConstraint

manila.share_network

heat.engine.clients.os.manila:ManilaShareNetworkConstraint

manila.share_snapshot

heat.engine.clients.os.manila:ManilaShareSnapshotConstraint

manila.share_type

heat.engine.clients.os.manila:ManilaShareTypeConstraint

mistral.workflow

heat.engine.clients.os.mistral:WorkflowConstraint

net_cidr

heat.engine.constraint.common_constraints:CIDRConstraint

neutron.address_scope

heat.engine.clients.os.neutron.neutron_constraints:AddressScopeConstraint

neutron.flow_classifier

heat.engine.clients.os.neutron.neutron_constraints:FlowClassifierConstraint

neutron.lbaas.listener

heat.engine.clients.os.neutron.lbaas_constraints:ListenerConstraint

neutron.lbaas.loadbalancer

heat.engine.clients.os.neutron.lbaas_constraints:LoadbalancerConstraint

neutron.lbaas.pool

heat.engine.clients.os.neutron.lbaas_constraints:PoolConstraint

neutron.lbaas.provider

heat.engine.clients.os.neutron.lbaas_constraints:LBaasV2ProviderConstraint

neutron.network

heat.engine.clients.os.neutron.neutron_constraints:NetworkConstraint

neutron.port

heat.engine.clients.os.neutron.neutron_constraints:PortConstraint

neutron.port_pair

heat.engine.clients.os.neutron.neutron_constraints:PortPairConstraint

neutron.port_pair_group

heat.engine.clients.os.neutron.neutron_constraints:PortPairGroupConstraint

neutron.qos_policy

heat.engine.clients.os.neutron.neutron_constraints:QoSPolicyConstraint

neutron.router

heat.engine.clients.os.neutron.neutron_constraints:RouterConstraint

neutron.security_group

heat.engine.clients.os.neutron.neutron_constraints:SecurityGroupConstraint

neutron.segment

heat.engine.clients.os.openstacksdk:SegmentConstraint

neutron.subnet

heat.engine.clients.os.neutron.neutron_constraints:SubnetConstraint

neutron.subnetpool

heat.engine.clients.os.neutron.neutron_constraints:SubnetPoolConstraint

neutron.taas.tap_flow

heat.engine.clients.os.neutron.taas_constraints:TapFlowConstraint

neutron.taas.tap_service

heat.engine.clients.os.neutron.taas_constraints:TapServiceConstraint

nova.flavor

heat.engine.clients.os.nova:FlavorConstraint

nova.host

heat.engine.clients.os.nova:HostConstraint

nova.keypair

heat.engine.clients.os.nova:KeypairConstraint

nova.network

heat.engine.constraint.common_constraints:TestConstraintDelay

nova.server

heat.engine.clients.os.nova:ServerConstraint

octavia.availabilityzone

heat.engine.clients.os.octavia:AvailabilityZoneConstraint

octavia.availabilityzoneprofile

heat.engine.clients.os.octavia:AvailabilityZoneProfileConstraint

octavia.flavor

heat.engine.clients.os.octavia:FlavorConstraint

octavia.flavorprofile

heat.engine.clients.os.octavia:FlavorProfileConstraint

octavia.l7policy

heat.engine.clients.os.octavia:L7PolicyConstraint

octavia.listener

heat.engine.clients.os.octavia:ListenerConstraint

octavia.loadbalancer

heat.engine.clients.os.octavia:LoadbalancerConstraint

octavia.pool

heat.engine.clients.os.octavia:PoolConstraint

rel_dns_name

heat.engine.constraint.common_constraints:RelativeDNSNameConstraint

test_constr

heat.engine.constraint.common_constraints:TestConstraintDelay

timezone

heat.engine.constraint.common_constraints:TimezoneConstraint

trove.flavor

heat.engine.clients.os.trove:FlavorConstraint

zaqar.queue

heat.engine.clients.os.zaqar:QueueConstraint

伪参数

除了模板作者定义的参数外,Heat 还为每个堆栈创建了三个参数,允许引用堆栈的名称、堆栈的标识符和项目的标识符。这些参数分别命名为 OS::stack_name(堆栈名称)、OS::stack_id(堆栈标识符)和 OS::project_id(项目标识符)。这些值可以通过 get_param 内在函数访问,与用户定义的参数一样。

注意

OS::project_id 自 2015.1 (Kilo) 版本起可用。

资源部分

resources 部分定义了构成从 HOT 模板部署的堆栈的实际资源(例如,计算实例、网络、存储卷)。

每个资源在 resources 部分中定义为一个单独的块,语法如下:

resources:
  <resource ID>:
    type: <resource type>
    properties:
      <property name>: <property value>
    metadata:
      <resource specific metadata>
    depends_on: <resource ID or list of ID>
    update_policy: <update policy>
    deletion_policy: <deletion policy>
    external_id: <external resource ID>
    condition: <condition name or expression or boolean>
resource ID

模板的 resources 部分中必须唯一的资源 ID。

type

资源类型,例如 OS::Nova::ServerOS::Neutron::Port。此属性是必需的。

properties

资源特定属性的列表。属性值可以内联提供,或通过函数提供(请参阅 内在函数)。此部分是可选的。

metadata

资源特定元数据。此部分是可选的。

depends_on

资源的对模板的一个或多个资源具有依赖关系。有关详细信息,请参阅 资源依赖项。此属性是可选的。

update_policy

资源的更新策略,形式为嵌套字典。更新策略是否受支持以及确切的语义取决于当前资源的类型。此属性是可选的。

deletion_policy

资源的删除策略。允许的删除策略是 DeleteRetainSnapshot。从 heat_template_version 2016-10-14 开始,小写等效项 deleteretainsnapshot 也被允许。此属性是可选的;默认策略是在删除堆栈中的资源时删除物理资源。

external_id

允许为现有的外部(堆栈外部)资源的 resource_id 指定。外部资源不能依赖于其他资源,但允许其他资源依赖于外部资源。此属性是可选的。注意:当指定此属性时,不会使用属性来构建资源,并且资源不由 Heat 管理。此属性无法更新。此外,当删除堆栈时,Heat 也不会删除资源。

condition

资源的条件。决定是否创建该资源。此属性是可选的。

注意:Newton 版本添加了对资源 condition 的支持。

根据资源类型,资源块可能包含更多特定于资源的 Pdata。

CFN 模板中可用的所有资源类型也可用于 HOT 模板,并根据上述 YAML 结构进行调整。

以下示例演示了具有固定属性值的简单计算资源的定义:

resources:
  my_instance:
    type: OS::Nova::Server
    properties:
      flavor: m1.small
      image: F18-x86_64-cfntools

资源依赖项

资源的 depends_on 属性定义了该资源与一个或多个其他资源之间的依赖关系。

如果一个资源仅依赖于另一个资源,则另一个资源的 ID 作为 depends_on 属性的字符串指定,如下例所示:

resources:
  server1:
    type: OS::Nova::Server
    depends_on: server2

  server2:
    type: OS::Nova::Server

如果一个资源依赖于多个其他资源,则 depends_on 属性的值指定为资源 ID 列表,如下例所示:

resources:
  server1:
    type: OS::Nova::Server
    depends_on: [ server2, server3 ]

  server2:
    type: OS::Nova::Server

  server3:
    type: OS::Nova::Server

输出部分

outputs 部分定义了在堆栈创建后应提供给用户的输出参数。例如,这些参数可以是已部署实例的 IP 地址,或作为堆栈一部分部署的 Web 应用程序的 URL。

每个输出参数都在 outputs 部分中定义为一个单独的块,根据以下语法:

outputs:
  <parameter name>:
    description: <description>
    value: <parameter value>
    condition: <condition name or expression or boolean>
parameter name

输出参数的名称,该名称在模板的 outputs 部分中必须唯一。

description

输出参数的简短描述。此属性是可选的。

parameter value

输出参数的值。此值通常通过函数解析。有关函数的详细信息,请参阅 内在函数。此属性是必需的。

condition

有条件地定义输出值。如果条件为 False,则不显示任何值。此属性是可选的。

注意:Newton 版本添加了对输出 condition 的支持。

以下示例演示了如何将计算资源的 IP 地址定义为输出参数:

outputs:
  instance_ip:
    description: IP address of the deployed compute instance
    value: { get_attr: [my_instance, first_address] }

条件部分

conditions 部分定义了一个或多个条件,这些条件根据用户创建或更新堆栈时提供的输入参数值进行评估。条件可以与资源、资源属性和输出相关联。例如,根据条件的结果,用户可以有条件地创建资源,有条件地设置不同的属性值,以及有条件地提供堆栈的输出。

conditions 部分的定义语法如下:

conditions:
  <condition name1>: {expression1}
  <condition name2>: {expression2}
  ...
condition name

条件名称,该名称在模板的 conditions 部分中必须唯一。

expression

预期返回 True 或 False 的表达式。通常,条件函数可用作表达式来定义条件。

equals
get_param
not
and
or
yaql

注意:在条件函数中,您可以引用输入参数的值,但不能引用资源或其属性。我们支持引用其他条件(按条件名称)在条件函数中。我们支持 Pike 版本中的“yaql”作为条件函数。

条件部分定义的示例:

conditions:
  cd1: True
  cd2:
    get_param: param1
  cd3:
    equals:
    - get_param: param2
    - yes
  cd4:
    not:
      equals:
      - get_param: param3
      - yes
  cd5:
    and:
    - equals:
      - get_param: env_type
      - prod
    - not:
        equals:
        - get_param: zone
        - beijing
  cd6:
    or:
    - equals:
      - get_param: zone
      - shanghai
    - equals:
      - get_param: zone
      - beijing
  cd7:
    not: cd4
  cd8:
    and:
    - cd1
    - cd2
  cd9:
    yaql:
      expression: $.data.services.contains('heat')
      data:
        services:
          get_param: ServiceNames
  cd10:
    contains:
    - 'neutron'
    - get_param: ServiceNames

以下示例展示了如何将条件与资源相关联:

parameters:
  env_type:
    default: test
    type: string
conditions:
  create_prod_res: {equals : [{get_param: env_type}, "prod"]}
resources:
  volume:
    type: OS::Cinder::Volume
    condition: create_prod_res
    properties:
      size: 1

如果“env_type”参数等于“prod”,则“create_prod_res”条件求值为 true。在上面的示例模板中,“volume”资源与“create_prod_res”条件相关联。因此,“volume”资源仅在“env_type”等于“prod”时创建。

以下示例展示了如何有条件地定义输出:

outputs:
  vol_size:
    value: {get_attr: [my_volume, size]}
    condition: create_prod_res

在上面的示例模板中,“vol_size”输出与“create_prod_res”条件相关联。因此,“vol_size”输出仅在“env_type”等于“prod”时才提供相应的值,否则输出的值为 None。

内在函数

HOT 提供了一组内在函数,这些函数可以在模板中使用以执行特定任务,例如在运行时获取资源属性的值。以下部分描述了内在函数的作用和语法。

注意:这些函数只能在每个资源的“properties”部分或 outputs 部分中使用。

get_attr

get_attr 函数引用资源的属性。属性值在运行时使用从相应资源定义创建的资源实例进行解析。

使用键或索引的基于路径的属性引用需要 heat_template_version 2014-10-16 或更高版本。

get_attr 函数的语法是:

get_attr:
  - <resource name>
  - <attribute name>
  - <key/index 1> (optional)
  - <key/index 2> (optional)
  - ...
resource name

需要解析属性的资源名称。

资源名称必须存在于模板的 resources 部分。

attribute name

需要解析的属性名称。如果属性返回复杂的数据结构(如列表或映射),则可以指定后续的键或索引。这些附加参数用于导航数据结构以返回所需的值。

以下示例演示了如何使用 get_attr 函数:

resources:
  my_instance:
    type: OS::Nova::Server
    # ...

outputs:
  instance_ip:
    description: IP address of the deployed compute instance
    value: { get_attr: [my_instance, first_address] }
  instance_private_ip:
    description: Private IP address of the deployed compute instance
    value: { get_attr: [my_instance, networks, private, 0] }

在此示例中,如果 networks 属性包含以下数据:

{"public": ["2001:0db8:0000:0000:0000:ff00:0042:8329", "1.2.3.4"],
 "private": ["10.0.0.1"]}

那么 get_attr 函数的值将解析为 10.0.0.1networks 映射中 private 条目的第一个项)。

heat_template_version:‘2015-10-15’ <attribute_name> 是可选的,如果未指定 <attribute_name>,get_attr 将返回给定资源的所有属性的字典,不包括 _show_ 属性。在这种情况下,语法将是:

get_attr:
  - <resource_name>

get_file

get_file 函数将文件内容返回到模板中。它通常用作包含脚本或配置文件文件的包含机制。

get_file 函数的语法是:

get_file: <content key>

content key 用于查找在 REST API 调用中提供的 files 字典。heat 编排客户端命令支持 get_file,并使用实际获取的路径内容和 URL 填充 files 字典。编排客户端命令支持相对路径,并将其转换为编排 API 所需的绝对 URL。

注意

get_file 参数必须是静态路径或 URL,并且不能依赖于 get_param 等内在函数。编排客户端不处理内在函数(仅由编排引擎处理)。

以下示例演示了 get_file 函数在相对和绝对 URL 上的用法:

resources:
  my_instance:
    type: OS::Nova::Server
    properties:
      # general properties ...
      user_data:
        get_file: my_instance_user_data.sh
  my_other_instance:
    type: OS::Nova::Server
    properties:
      # general properties ...
      user_data:
        get_file: http://example.com/my_other_instance_user_data.sh

编排客户端在实例化堆栈期间生成的 files 字典将包含以下键:

  • file:///path/to/my_instance_user_data.sh

  • http://example.com/my_other_instance_user_data.sh

get_param

get_param 函数引用模板的输入参数。它在运行时解析为为此输入参数提供的值。

get_param 函数的语法是:

get_param:
 - <parameter name>
 - <key/index 1> (optional)
 - <key/index 2> (optional)
 - ...
parameter name

需要解析的参数名称。如果参数返回复杂数据结构(如列表或映射),则可以指定后续的键或索引。这些附加参数用于导航数据结构以返回所需的值。

以下示例演示了 get_param 函数的用法:

parameters:
  instance_type:
    type: string
    label: Instance Type
    description: Instance type to be used.
  server_data:
    type: json

resources:
  my_instance:
    type: OS::Nova::Server
    properties:
      flavor: { get_param: instance_type}
      metadata: { get_param: [ server_data, metadata ] }
      key_name: { get_param: [ server_data, keys, 0 ] }

在此示例中,如果 instance_typeserver_data 参数包含以下数据:

{"instance_type": "m1.tiny",
{"server_data": {"metadata": {"foo": "bar"},
                 "keys": ["a_key","other_key"]}}}

那么属性 flavor 的值将解析为 m1.tinymetadata 将解析为 {"foo": "bar"}key_name 将解析为 a_key

get_resource

get_resource 函数引用同一模板中的另一个资源。在运行时,它会被解析为引用所引用资源的 ID,该 ID 特定于资源类型。例如,对浮动 IP 资源的引用在运行时返回相应的 IP 地址。 get_resource 函数的语法是:

get_resource: <resource ID>

get_resource 函数将引用资源的资源 ID 作为单个参数给出。

例如

resources:
  instance_port:
    type: OS::Neutron::Port
    properties: ...

  instance:
    type: OS::Nova::Server
    properties:
      ...
      networks:
        port: { get_resource: instance_port }

list_join

list_join 函数使用给定的分隔符连接字符串列表。

list_join 函数的语法是:

list_join:
- <delimiter>
- <list to join>

例如

list_join: [', ', ['one', 'two', 'and three']]

这将解析为字符串 one, two, and three

从 HOT 版本 2015-10-15 开始,您还可以选择性地传递其他列表,这些列表将被附加到前面的列表进行连接。

例如

list_join: [', ', ['one', 'two'], ['three', 'four']]

这将解析为字符串 one, two, three, four

从 HOT 版本 2015-10-15 开始,您还可以选择性地传递非字符串列表项(例如 json/map/list 参数或属性),它们将在连接前被序列化为 json。

digest

digest 函数允许对给定值执行摘要操作。此函数在 Kilo 版本中引入,可用于晚于 2015-04-30 的 HOT 版本。

digest 函数的语法是:

digest:
  - <algorithm>
  - <value>
algorithm

摘要算法。有效算法是 hashlib(md5、sha1、sha224、sha256、sha384 和 sha512)或 OpenSSL 提供的任何算法。

value

要摘要的值。此函数将解析为该值的相应哈希。

例如

# from a user supplied parameter
pwd_hash: { digest: ['sha512', { get_param: raw_password }] }

digest 函数的值将解析为 raw_password 值的相应哈希。

repeat

repeat 函数允许通过迭代一个或多个源列表的内容并将列表元素替换到模板中来动态转换列表。此函数的结果是一个新列表,其中元素设置为在每个列表项上渲染的模板。

repeat 函数的语法是:

repeat:
  template:
    <template>
  for_each:
    <var>: <list>
template

template 参数定义为每个迭代生成的内容,其中包含需要在运行时替换的占位符。此参数可以是任何支持的类型。

for_each

for_each 参数是一个字典,用于定义如何生成模板的重复以及执行替换。在此字典中,键是模板中将要替换的占位符名称,值是要迭代的列表。在每次迭代中,函数将通过使用给定列表中的元素进行替换来渲染模板。如果在此参数中给出了单个键/值对,则模板将为列表中的每个元素渲染一次。当给出多个键/值对时,迭代将在给定列表之间的值的所有排列上进行。此字典中的值可以作为函数(如 get_attrget_param)提供。

以下示例展示了如何定义安全组资源以包含参数中提供的端口列表:

parameters:
  ports:
    type: comma_delimited_list
    label: ports
    default: "80,443,8080"

resources:
  security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: web_server_security_group
      rules:
        repeat:
          for_each:
            <%port%>: { get_param: ports }
          template:
            protocol: tcp
            port_range_min: <%port%>
            port_range_max: <%port%>

以下示例演示了如何使用多个列表来包含参数化的协议:

parameters:
  ports:
    type: comma_delimited_list
    label: ports
    default: "80,443,8080"
  protocols:
    type: comma_delimited_list
    label: protocols
    default: "tcp,udp"

resources:
  security_group:
    type: OS::Neutron::SecurityGroup
    properties:
      name: web_server_security_group
      rules:
        repeat:
          for_each:
            <%port%>: { get_param: ports }
            <%protocol%>: { get_param: protocols }
          template:
            protocol: <%protocol%>
            port_range_min: <%port%>

请注意,for_each 参数中的多个条目相当于大多数编程语言中的嵌套 for 循环。

从 HOT 版本 2016-10-14 开始,您还可以将映射作为 for_each 键的值传递,在这种情况下,将使用映射键的列表作为值。

从 HOT 版本 2017-09-01(或 pike)开始,您可以指定 permutations 参数来决定是否迭代嵌套到给定列表中的所有元素排列。如果未指定“permutations”,我们将其默认值设置为 true 以与之前的行为兼容。如果“permutations”为 False,则参数必须是列表而不是字典,因为字典中的键是无序的,并且列表参数必须具有相同的长度。

parameters:
  subnets:
    type: comma_delimited_list
    label: subnets
    default: "sub1, sub2"
  networks:
    type: comma_delimited_list
    label: networks
    default: "net1, net2"

resources:
  my_server:
    type: OS::Nova:Server
    properties:
      networks:
        repeat:
          for_each:
            <%sub%>: { get_param: subnets }
            <%net%>: { get_param: networks }
          template:
            subnet: <%sub%>
            network: <%net%>
          permutations: false

解析后,我们将获得服务器的网络,例如:[{subnet: sub1, network: net1}, {subnet: sub2, network: net2}]

resource_facade

resource_facade 函数检索父提供程序模板中的数据。

提供程序模板提供了资源的自定义定义,称为其外观。有关自定义模板的更多信息,请参阅 模板组合resource_facade 函数的语法是:

resource_facade: <data type>

data type 可以是 metadatadeletion_policyupdate_policy 之一。

str_replace

str_replace 函数通过提供带有占位符的模板字符串和在运行时为这些占位符分配值的映射列表来动态构建字符串。当映射键与占位符完全匹配时,占位符将被映射值替换。

str_replace 函数的语法是:

str_replace:
  template: <template string>
  params: <parameter mappings>
template

定义包含将在运行时进行替换的占位符的模板字符串。

params

以字典形式提供参数映射。每个键都引用 template 属性中使用的占位符。从 HOT 版本 2015-10-15 开始,您可以选择性地传递非字符串参数值(例如 json/map/list 参数或属性),它们将在替换前被序列化为 json,而早期的 heat/HOT 版本要求字符串值。

以下示例展示了在模板的 outputs 部分中使用 str_replace 函数来构建用于登录已部署应用程序的 URL:

resources:
  my_instance:
    type: OS::Nova::Server
    # general metadata and properties ...

outputs:
  Login_URL:
    description: The URL to log into the deployed application
    value:
      str_replace:
        template: http://host/MyApplication
        params:
          host: { get_attr: [ my_instance, first_address ] }

以下示例展示了 str_replace 函数在构建实例初始化脚本中的用法:

parameters:
  DBRootPassword:
    type: string
    label: Database Password
    description: Root password for MySQL
    hidden: true

resources:
  my_instance:
    type: OS::Nova::Server
    properties:
      # general properties ...
      user_data:
        str_replace:
          template: |
            #!/bin/bash
            echo "Hello world"
            echo "Setting MySQL root password"
            mysqladmin -u root password $db_rootpassword
            # do more things ...
          params:
            $db_rootpassword: { get_param: DBRootPassword }

在上面的示例中,可以想象 MySQL 正在计算实例上配置,并且 root 密码将基于用户提供的参数设置。用于此目的的脚本作为 userdata 提供给计算实例,利用了 str_replace 函数。

str_replace_strict

str_replace_strict 的行为与 str_replace 函数相同,只有当模板中任何参数不存在时才会引发错误。这有助于更早地捕获拼写错误或其他问题。

str_replace_vstrict

str_replace_vstrict 的行为与 str_replace_strict 函数相同,只有当任何参数为空时才会引发错误。这有助于更早地捕获问题(例如,防止资源使用无效值创建),如果已知所有参数都应为非空。

str_split

str_split 函数允许通过提供任意分隔符将字符串拆分为列表,与 list_join 相反。

str_split 函数的语法如下:

str_split:
  - ','
  - string,to,split

或者

str_split: [',', 'string,to,split']

其结果是:

['string', 'to', 'split']

可以选择提供一个索引来从生成的列表中选择特定条目,类似于 get_attr/get_param

str_split: [',', 'string,to,split', 0]

其结果是:

'string'

注意:索引从零开始,任何超出最大值(例如列表长度减一)的值都会导致错误。

map_merge

map_merge 函数将映射合并在一起。后一个映射中的值将覆盖前一个映射中的任何值。在将包含配置数据的映射组合成单个统一映射时非常有用。

map_merge 函数的语法是:

map_merge:
- <map 1>
- <map 2>
- ...

例如

map_merge: [{'k1': 'v1', 'k2': 'v2'}, {'k1': 'v2'}]

这将解析为包含 {'k1': 'v2', 'k2': 'v2'} 的映射。

不包含项目的映射将解析为 {}。

map_replace

map_replace 函数对现有映射执行键/值替换。通过迭代所有键/值来处理输入映射,并在可选的键/值映射中找到精确匹配时执行替换。

map_replace 函数的语法是:

map_replace:
- <input map>
- keys: <map of key replacements>
  values: <map of value replacements>

例如

map_replace:
- k1: v1
  k2: v2
- keys:
    k1: K1
  values:
    v2: V2

这将解析为包含 {'K1': 'v1', 'k2': 'V2'} 的映射。

键/值映射是可选的,可以指定一个或两个。

请注意,如果“keys”中定义的替换会导致与输入或输出映射中的现有键发生冲突,则会引发错误。

另请注意,虽然输入映射中不可哈希的值(例如列表)是有效的,但它们将被值替换忽略,因为在值映射中无法定义键来指定它们的替换。

yaql

yaql 用于评估给定数据上的 yaql 表达式。

yaql 函数的语法是:

yaql:
  expression: <expression>
  data: <data>

例如

parameters:
  list_param:
    type: comma_delimited_list
    default: [1, 2, 3]

outputs:
  max_elem:
    value:
      yaql:
        expression: $.data.list_param.select(int($)).max()
        data:
          list_param: {get_param: list_param}

max_elem 输出将求值为 3。

equals

equals 函数比较两个值是否相等。

equals 函数的语法是:

equals: [value_1, value_2]

值可以是您想比较的任何类型。如果两个值相等,此函数返回 true,否则返回 false。

例如

equals: [{get_param: env_type}, 'prod']

如果参数“env_type”等于“prod”,则此函数返回 true,否则返回 false。

if

if 函数根据条件评估的结果返回相应的值。

if 函数的语法是:

if: [condition_name, value_if_true, value_if_false]

例如

conditions:
  create_prod_res: {equals : [{get_param: env_type}, "prod"]}

resources:
  test_server:
    type: OS::Nova::Server
    properties:
      name: {if: ["create_prod_res", "s_prod", "s_test"]}

如果条件“create_prod_res”求值为 true(如果参数‘env_type’为‘prod’),则“name”属性设置为“s_prod”,如果条件“create_prod_res”求值为 false(如果参数‘env_type’不为‘prod’),则设置为‘s_test’。

注意:除 if 条件外,您在模板的 conditions 部分中定义所有条件。您可以在模板的 resources 部分和 outputs 部分的属性值中使用 if 条件。

wallaby 模板版本开始,第三个参数是可选的。如果只传递两个参数,则当条件为 false 时,整个封闭项将被删除。

例如

conditions:
  override_name: {not: {equals: [{get_param: server_name}, ""]}}

resources:
  test_server:
    type: OS::Nova::Server
    properties:
      name: {if: [override_name, {get_param: server_name}]}

在此示例中,当 server_name 参数值为空字符串时,将使用服务器的默认名称(由 Heat 在未指定属性值时生成)。

not

not 函数用作 NOT 运算符。

not 函数的语法是:

not: condition

注意:条件可以是求值为 true 或 false 的表达式(如 equalsorand),可以是布尔值,也可以是模板 conditions 部分中定义的其他条件名称。

如果条件评估为 false,则返回 true,或者如果条件评估为 true,则返回 false。

例如

not:
  equals:
  - get_param: env_type
  - prod

如果参数‘env_type’等于‘prod’,则此函数返回 false,否则返回 true。

布尔值定义的另一个示例:

not: True

此函数返回 false。

引用其他条件名称的另一个示例:

not: my_other_condition

如果 my_other_condition 求值为 true,则此函数返回 false,否则返回 true。

and

and 函数用作 AND 运算符来评估所有指定的条件。

and 函数的语法是:

and: [{condition_1}, {condition_2}, ... {condition_n}]

注意:条件可以是求值为 true 或 false 的表达式(如 equalsornot),可以是布尔值,也可以是模板 conditions 部分中定义的其他条件名称。

如果所有指定条件都求值为 true,则返回 true,如果任何一个条件求值为 false,则返回 false。

例如

and:
- equals:
  - get_param: env_type
  - prod
- not:
    equals:
    - get_param: zone
    - beijing

如果参数‘env_type’等于‘prod’,并且参数‘zone’不等于‘beijing’,则此函数返回 true,否则返回 false。

引用其他条件的另一个示例:

and:
- other_condition_1
- other_condition_2

如果 other_condition_1 和 other_condition_2 都求值为 true,则此函数返回 true,否则返回 false。

or

or 函数用作 OR 运算符来评估所有指定的条件。

or 函数的语法是:

or: [{condition_1}, {condition_2}, ... {condition_n}]

注意:条件可以是求值为 true 或 false 的表达式(如 equalsandnot),可以是布尔值,也可以是模板 conditions 部分中定义的其他条件名称。

如果任何一个指定条件求值为 true,则返回 true;如果所有条件都求值为 false,则返回 false。

例如

or:
- equals:
  - get_param: env_type
  - prod
- not:
    equals:
    - get_param: zone
    - beijing

如果参数‘env_type’等于‘prod’,或者参数‘zone’不等于‘beijing’,则此函数返回 true,否则返回 false。

引用其他条件的另一个示例:

or:
- other_condition_1
- other_condition_2

如果 other_condition_1 或 other_condition_2 中的任何一个求值为 true,则此函数返回 true,否则返回 false。

filter

filter 函数从列表中删除值。

filter 函数的语法是:

filter:
  - <values>
  - <list>

例如

parameters:
  list_param:
    type: comma_delimited_list
    default: [1, 2, 3]

outputs:
  output_list:
    value:
      filter:
        - [3]
        - {get_param: list_param}

output_list 将被求值为 [1, 2]。

make_url

make_url 函数构建 URL。

make_url 函数的语法是:

make_url:
  scheme: <protocol>
  username: <username>
  password: <password>
  host: <hostname or IP>
  port: <port>
  path: <path>
  query:
    <key1>: <value1>
    <key2>: <value2>
  fragment: <fragment>

所有参数都是可选的。

例如

outputs:
  server_url:
    value:
      make_url:
        scheme: http
        host: {get_attr: [server, networks, <network_name>, 0]}
        port: 8080
        path: /hello
        query:
          recipient: world
        fragment: greeting

server_url 将被求值为以下形式的 URL:

http://[<server IP>]:8080/hello?recipient=world#greeting

list_concat

list_concat 函数将列表连接在一起。

list_concat 函数的语法是:

list_concat:
  - <list #1>
  - <list #2>
  - ...

例如

list_concat: [['v1', 'v2'], ['v3', 'v4']]

将解析为列表 ['v1', 'v2', 'v3', 'v4']

Null 值将被忽略。

list_concat_unique

list_concat_unique 函数的行为与 list_concat 函数相同,只是它会删除列表中的重复项。

例如

list_concat_unique: [['v1', 'v2'], ['v2', 'v3']]

将解析为列表 ['v1', 'v2', 'v3']

contains

contains 函数检查特定值是否在序列中。

contains 函数的语法是:

contains: [<value>, <sequence>]

如果值在序列中,此函数返回 true,否则返回 false。

例如

contains: ['v1', ['v1', 'v2', 'v3']]

将解析为布尔值 true。