openstack heat 编排模板(HOT)指南

openstack heat 编排模板指南

    • openstack 版本
    • HOT hello world
    • HOT 指南
      • 模板结构
      • Parameter groups section
      • Parameters section
        • 内置的参数
      • Resources section
        • Resource dependencies
      • Outputs section
      • Conditions section
      • 函数
        • get_attr
        • get_file
        • get_param
        • get_resource
        • list_join
        • digest
        • repeat
        • str_replace
        • str_replace_strict
        • str_replace_vstrict
        • str_split
        • map_merge
        • map_repalce
        • equals
        • if
        • not
        • and
        • or
        • filter
        • make_url
        • list_concat
        • list_concat_unique
        • contains
      • 云主机管理
        • 管理实例
        • 管理网络
        • 管理云盘
        • boot script
        • Signals and wait conditions
      • template 组合
        • 使用文件名作为资源类型
        • 定义资源类型
      • resource type
        • OS::Heat::ResourceGroup
        • OS::Heat::SoftwareConfig
        • OS::Heat::SoftwareDeployment
    • 参考

opentack heat orchestration template (HOT) 可以类比 k8syaml 文件,k8s 通过 yaml 文件实现编排, heat 通过 HOT yaml 文件实现 openstack 上的编排

openstack 版本

train

HOT hello world

heat_template_version: 2015-04-30

description: Simple template to deploy a single compute instance # 可选

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

有效的 HOT 版本参考:Heat template version

resources 段是必须的,并且至少包含一个资源定义,上面就是定义了一个名为my_instance的资源

上面的例子会创建一个镜像为 F18-x86_64-cfntools, 大小为 m1.small, ssh key 指定为 my_key 的一个云主机

通常为了使模板更通用,会使用变量,而不是像上面的例子那样硬编码

heat_template_version: 2015-04-30

description: Simple template to deploy a single compute instance

parameters:
  key_name:
    type: string
    label: Key Name
    description: Name of key-pair to be used for compute instance
  image_id:
    type: string
    label: Image ID
    description: Image to be used for compute instance
  instance_type:
    type: string
    label: Instance Type
    description: Type of instance (flavor) to be used
    default: m1.small # 指定默认值

resources:
  my_instance:
    type: OS::Nova::Server
    properties:
      key_name: { get_param: key_name }
      image: { get_param: image_id }
      flavor: { get_param: instance_type }

这次,定了三个变量,并且my_instance里面使用变量,而不是硬编码, 并且变量可以指定默认值,这些变量通过 horizon 页面或者 openstack 命令行传进来

变量除了设置默认值,还可以设置 hidden 属性,这样用户在 heat stack 页面看不到该属性的值,通常用来保护一些私密信息

parameters:
  database_password:
    type: string
    label: Database Password
    description: Password to be used for database
    hidden: true

allowed_valuesallowed_pattern 属性可以限制一个变量的取值

parameters:
  instance_type:
    type: string
    label: Instance Type
    description: Type of instance (flavor) to be used
    constraints:
      - allowed_values: [ m1.medium, m1.large, m1.xlarge ]
        description: Value must be one of m1.medium, m1.large or m1.xlarge.
  database_password:
    type: string
    label: Database Password
    description: Password to be used for database
    hidden: true
    constraints:
      - length: { min: 6, max: 8 }
        description: Password length must be between 6 and 8 characters.
      - allowed_pattern: "[a-zA-Z0-9]+"
        description: Password must consist of characters and numbers only.
      - allowed_pattern: "[A-Z]+[a-zA-Z0-9]*"
        description: Password must start with an uppercase character.

除了自定义用户的输入参数外,还可以配置输出变量

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

HOT 指南

模板结构

heat_template_version: 2016-10-14
# heat_template_version: rocky

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 : 必须,指定模板语法的版本,除了可以指定日期的格式,还可以直接指定 openstack 的版本, 如 rocky

description : 可选,描述信息

parameter_groups : 可选,指明输入参数该如何分组以及参数传入的顺序

parameters : 可选, 定义输入参数

resources : 必须,定义模板资源

outputs : 可选,定义输出参数

conditions : 可选,用来控制一个资源什么情况下可以被创建,或者资源某一属性什么情况下可以被定义

Parameter groups section

parameter_groups:
- label: -readable label of parameter group>
  description: >
  parameters:
  - >
  - >

Parameters section

parameters:
  >:
    type: | number | json | comma_delimited_list | boolean>
    label: -readable name of the parameter>
    description: >
    default: >
    hidden: | false>
    constraints:
      >
    immutable: | false>
    tags: >

type 示例 :

Type Description Examples
string A literal string. “String param”
number An integer or float. “2”; “0.2”
comma_delimited_list An array of literal strings that are separated by commas. The total number of strings should be one more than the total number of commas. [“one”, “two”]; “one, two”; Note: “one, two” returns [“one”, “two”]
json A JSON-formatted map or list. {“key”: “value”}
boolean Boolean type value, which can be equal “t”, “true”, “on”, “y”, “yes”, or “1” for true value and “f”, “false”, “off”, “n”, “no”, or “0” for false value. “on”; “n”

定义一个输入参数,至少包含 type

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

labeldescription 是可选的,但是一般为了更好的描述都加上了这两个属性

内置的参数

heat 会为每个 stack 内置三个参数

  1. OS::stack_name : stack 名称
  2. OS::stack_id : stack id
  3. OS::project_id : 项目 id

这三个参数都可以通过 get_param 参数获取

Resources section

resources:
  >:
    type: >
    properties:
      >: >
    metadata:
      >
    depends_on: >
    update_policy: >
    deletion_policy: >
    external_id: >
    condition: >

Resource dependencies

depends_on 属性定义资源之间的依赖关系

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

  server2:
    type: OS::Nova::Server
    depends_on: server3

  server3:
    type: OS::Nova::Server

Outputs section

outputs:
  >:
    description: >
    value: >
    condition: >

Conditions section

conditions:
  >: {expression1}
  >: {expression2}
  ...

示例

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

conditionresource 关联

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

conditionoutput 关联

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

函数

get_attr

获取某一资源的某属性

get_attr:
  - >
  - >
  - > (optional)
  - > (optional)
  - ...

示例

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] }

get_file

从网络或者本地文件系统获取文件

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

get_file 支持两类 url

file:///path/to/my_instance_user_data.sh
http://example.com/my_other_instance_user_data.sh

get_param

获取输入参数的值

get_param:
 - >
 - > (optional)
 - > (optional)
 - ...

示例

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.tiny

metadata 将被解析为 {"foo": "bar"}

get_resource

引用其他资源,通常会返回该资源对应的 ID

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

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

该例子中,port 值最终会被解析为 instance_port 资源对应的 id

list_join

以指定分隔符连接一些列字符串

list_join:
- >
- >
- >
- ...

示例

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

最终返回的值为 "one, two, three, four"

digest

根据指定摘要算法获取给定值的摘要

digest:
  - >
  - >

示例

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

repeat

相当于 for 循环

repeat:
  template:
    >
  for_each:
    : >
  permutations: >

permutations 指明是否对所给的 list 进行排序之后再循环

示例

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

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%>
          permutations: false

str_replace

字符串替换

str_replace:
  template: