1 .. Licensed under a Creative Commons Attribution 4.0 International License.
2 .. http://creativecommons.org/licenses/by/4.0
3 .. Copyright 2017 AT&T Intellectual Property. All rights reserved.
5 .. _ONAP Heat Heat Template Constructs:
7 ONAP Heat Heat Template Constructs
8 --------------------------------------
10 .. _Nested Heat Templates:
13 ^^^^^^^^^^^^^^^^^^^^^^^^^
15 ONAP supports nested Heat templates per the OpenStack specifications.
16 Nested templates may be suitable for larger VNFs that contain many
17 repeated instances of the same VM type(s). A common usage pattern is to
18 create a nested template for each {vm-type} along with its supporting
19 resources. The VNF module may then reference these component templates
20 either statically by repeated definition or dynamically by using the
21 resource OS::Heat::ResourceGroup.
23 Nested Heat Template Requirements
24 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 ONAP supports nested Heat Orchestration Templates.
28 As stated in Requirements :need:`R-36582`, :need:`R-56721`, and
29 :need:`R-30395`, a Base Module, Incremental Module, and Cinder Volume
30 Module may use nested heat.
37 A VNF's Heat Orchestration Template **MAY**
38 reference the nested heat statically by repeated definition.
46 A VNF's Heat Orchestration Template **MAY**
47 reference the nested heat dynamically using the resource
48 ``OS::Heat::ResourceGroup``.
54 :validation_mode: static
57 A VNF's Heat Orchestration Template **MUST** have no more than
58 two levels of nesting.
64 :validation_mode: static
65 :introduced: casablanca
67 A VNF's Heat Orchestration Template **MUST** reference a Nested YAML
68 file by name. The use of ``resource_registry`` in the VNF's Heat
69 Orchestration Templates Environment File **MUST NOT** be used.
71 Two levels of nesting is defined as follows: A base module, incremental
72 module, or cinder volume module references a nested heat file either
73 statically or by using the resource ``OS::Heat::ResourceGroup``.
74 The referenced YAML heat file is the first level of nested heat.
75 If first level nested YAML file references a nested heat file, that file is
76 the second level of nested heat.
78 As stated in requirement :need:`R-99646`, a VNF's YAML files
79 (i.e, Heat Orchestration Template files and Nested files) **MUST**
80 have a unique name in the scope of the VNF.
86 :validation_mode: static
89 A VNF's Heat Orchestration Template's Nested YAML file
90 **MUST** be in the same directory hierarchy as the VNF's Heat
91 Orchestration Templates.
98 A VNF's Nested YAML file **MAY** be invoked more than
99 once by a VNF's Heat Orchestration Template.
106 A VNF's Nested YAML file **MAY** be invoked by more than one of
107 a VNF's Heat Orchestration Templates (when the VNF is composed of two
108 or more Heat Orchestration Templates).
110 Note that as stated in requirement :need:`R-00011`, a VNF's Heat Orchestration
111 Template's Nested YAML file's parameter's **MUST NOT** have a parameter
118 :validation_mode: static
121 All parameters defined in a VNFs Nested YAML file
122 **MUST** be passed in as properties of the resource calling
123 the nested yaml file.
127 As stated in Requirement :need:`R-44491`, if a VNF's Heat Orchestration
128 Template's ``OS::Nova::Server`` Resource ``metadata`` map value parameter
129 ``vnf_id`` is passed into a Nested YAML file, the parameter name
130 ``vnf_id`` **MUST NOT** change.
132 As stated in Requirement :need:`R-86237`, if a VNF's Heat Orchestration
133 Template's ``OS::Nova::Server`` Resource ``metadata`` map value parameter
134 ``vf_module_id`` is passed into a Nested YAML file, the parameter name
135 ``vf_module_id`` **MUST NOT** change.
137 As stated in Requirement :need:`R-16576`, if a VNF's Heat Orchestration
138 Template's ``OS::Nova::Server`` Resource ``metadata`` map value parameter
139 ``vnf_name`` is passed into a Nested YAML file, the parameter name
140 ``vnf_name`` **MUST NOT** change.
142 As stated in Requirement :need:`R-49177`, if a VNF's Heat Orchestration
143 Template's ``OS::Nova::Server`` Resource ``metadata`` map value parameter
144 ``vf_module_name`` is passed into a Nested YAML file, the parameter name
145 ``vf_module_name`` **MUST NOT** change.
147 As stated in Requirement :need:`R-70757`, if a VNF's Heat Orchestration
148 Template's ``OS::Nova::Server`` Resource ``metadata`` map value parameter
149 ``vm_role`` is passed into a Nested YAML file, the parameter name
150 ``vm_role`` **MUST NOT** change.
152 As stated in Requirement :need:`R-22441`, if a VNF's Heat Orchestration
153 Template's ``OS::Nova::Server`` Resource ``metadata`` map value parameter
154 ``vf_module_index`` is passed into a Nested YAML file, the parameter
155 name ``vf_module_index`` **MUST NOT** change.
157 As stated in Requirement :need:`R-75202`, if a VNF's Heat Orchestration
158 Template's ``OS::Nova::Server`` Resource ``metadata`` map value parameter
159 ``workload_context`` is passed into a Nested YAML file, the parameter
160 name ``workload_context`` **MUST NOT** change.
162 As stated in Requirement :need:`R-62954`, if a VNF's Heat Orchestration
163 Template's ``OS::Nova::Server`` Resource ``metadata`` map value parameter
164 ``environment_context`` is passed into a Nested YAML file, the parameter
165 name ``environment_context`` **MUST NOT** change.
167 With nested templates, outputs are required to expose any resource
168 properties of the child templates to the parent template. Those would
169 not explicitly be declared as parameters but simply referenced as
170 ``get_attribute`` targets against the "parent" resource.
172 A parameter declared in the outputs: section of a nested template can
173 be accessed from the parent template as an attribute (i.e., via
174 ``get_attr``) of the "pseudo resource" whose type is in the nested
175 template. In the case of a ``OS::Heat::ResourceGroup``, an output will be
176 an attribute of the ``OS::Heat::ResourceGroup`` itself, and will be an
177 array from the perspective of the parent template.
183 :validation_mode: static
186 A VNF's Heat Orchestration Template's first level Nested YAML file
187 **MUST NOT** contain more than one ``OS::Nova::Server`` resource.
188 A VNF's Heat Orchestration Template's second level Nested YAML file
189 **MUST NOT** contain an ``OS::Nova::Server`` resource.
191 Nested Heat Template Example: Static
192 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
202 dns_image_name: { get_param: dns_image_name }
203 dns_flavor_name: { get_param: dns_flavor_name }
204 availability_zone: { get_param: availability_zone_0 }
205 security_group: { get_param: DNS_shared_sec_grp_id }
206 oam_net_id: { get_param: oam_protected_net_id }
207 dns_oam_ip: { get_param: dns_oam_ip_0 }
208 dns_name: { get_param: dns_name_0 }
209 vnf_name: { get_param: vnf_name }
210 vnf_id: { get_param: vnf_id }
211 vf_module_id: {get_param: vf_module_id}
216 dns_image_name: { get_param: dns_image_name }
217 dns_flavor_name: { get_param: dns_flavor_name }
218 availability_zone: { get_param: availability_zone_1 }
219 security_group: { get_param: DNS_shared_sec_grp_id }
220 oam_net_id: { get_param: oam_protected_net_id }
221 dns_oam_ip: { get_param: dns_oam_ip_1 }
222 dns_name: { get_param: dns_name_1 }
223 vnf_name: { get_param: vnf_name }
224 vnf_id: { get_param: vnf_id }
225 vf_module_id: {get_param: vf_module_id}
232 type: OS::Neutron::Port
236 template: VNF_NAME_dns_oam_port
238 VNF_NAME: {get_param: vnf_name}
239 network: { get_param: oam_net_id }
240 fixed_ips: [{ "ip_address": { get_param: dns_oam_ip }}]
241 security_groups: [{ get_param: security_group }]
244 type: OS::Nova::Server
246 name: { get_param: dns_names }
247 image: { get_param: dns_image_name }
248 flavor: { get_param: dns_flavor_name }
249 availability_zone: { get_param: availability_zone }
251 - port: { get_resource: dns_oam_0_port }
253 vnf_id: { get_param: vnf_id }
254 vf_module_id: { get_param: vf_module_id }
255 vnf_name {get_param: vnf_name }
257 Use of Heat ResourceGroup
258 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
260 The OS::Heat::ResourceGroup is a useful Heat element for creating
261 multiple instances of a given resource or collection of resources.
262 Typically, it is used with a nested Heat template to create, for
263 example, a set of identical OS::Nova::Server resources plus their
264 related OS::Neutron::Port resources via a single resource in a master
267 OS::Heat::ResourceGroup may be used to simplify the structure of a Heat
268 template that creates multiple instances of the same VM type.
270 However, there are important caveats to be aware of:
272 OS::Heat::ResourceGroup does not deal with structured parameters
273 (comma-delimited-list and json) as one might typically expect. In
274 particular, when using a list-based parameter, where each list element
275 corresponds to one instance of the ResourceGroup, it is not possible to
276 use the intrinsic "loop variable" %index% in the OS::Heat::ResourceGroup
279 For instance, the following is **not** valid Heat for
280 OS::Heat::ResourceGroup:
284 type: OS::Heat::ResourceGroup
288 type: my_nested_vm_template.yaml
290 name: {get_param: [vm_name_list, "%index%"]}
292 Although this appears to use the nth entry of the vm_name_list list for
293 the nth element of the OS::Heat::ResourceGroup, it will in fact result
294 in a Heat exception. When parameters are provided as a list (one for
295 each element of a OS::Heat::ResourceGroup), you must pass the complete
296 parameter to the nested template along with the current index as
299 Below is an example of an **acceptable** Heat Syntax for a
304 type: OS::Heat::ResourceGroup
308 type: my_nested_vm_template.yaml
310 names: {get_param: vm_name_list}
313 You can then reference within the nested template as:
315 { get_param: [names, {get_param: index} ] }
317 OS::Heat::ResourceGroup Property count
318 ++++++++++++++++++++++++++++++++++++++++
325 :validation_mode: static
328 A VNF's Heat Orchestration Template's ``OS::Heat::ResourceGroup``
329 property ``count`` **MUST** be enumerated in the VNF's
330 Heat Orchestration Template's Environment File and **MUST** be
333 This is required for ONAP to build the TOSCA model for the VNF.
337 type: OS::Heat::ResourceGroup
339 count: { get_param: count }
342 type: my_nested_vm_template.yaml
344 names: {get_param: vm_name_list}
347 Availability Zone and ResourceGroups
348 ++++++++++++++++++++++++++++++++++++++++
350 The resource OS::Heat::ResourceGroup and the property availability_zone
351 has been an "issue" with a few VNFs since ONAP only supports
352 availability_zone as a string parameter and not as a
353 comma_delimited_list. This makes it difficult to use a
354 OS::Heat::ResourceGroup to create Virtual Machines in more than one
357 There are numerous solutions to this issue. Below are two suggested
360 **Option 1:** create a CDL in the OS::Heat::ResourceGroup. In the
361 resource type: OS::Heat::ResourceGroup, create a comma_delimited_list
362 availability_zones by using the intrinsic function list_join.
367 type: OS::Heat::ResourceGroup
369 count: { get_param: node_count }
375 availability_zones: { list_join: [',', [ { get_param: availability_zone_0 }, { get_param: availability_zone_1 } ] ] }
383 type: comma_delimited_list
388 type: OS::Nova::Server
390 name: { get_param: [ dns_names, get_param: index ] }
391 image: { get_param: dns_image_name }
392 flavor: { get_param: dns_flavor_name }
393 availability_zone: { get_param: [ availability_zones, get_param: index ] }
395 **Option 2:** Create a CDL by passing the availability zone parameter
396 into a nested heat template. An example is provided below.
402 availability_zone_list:
403 type: az_list_generate.yaml
405 availability_zone_0: { get_param: availability_zone_0 }
406 availability_zone_1: { get_param: availability_zone_1 }
408 create_virtual_machines:
409 type: OS::Heat::ResourceGroup
411 count: { get_param: count }
417 availability_zone_0 : { get_attr: [availability_zone_list, general_zones ] }
420 az_list_generate.yaml
427 description: availability zone 0
431 description: availability zone 1
437 { get_param: availability_zone_0 },
438 { get_param: availability_zone_1 },
439 { get_param: availability_zone_0 },
440 { get_param: availability_zone_1 },
441 { get_param: availability_zone_0 },
442 { get_param: availability_zone_1 },
446 Nested Heat Template Example: OS::Heat::ResourceGroup
447 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
449 In this example, ocgapp_volume.yml creates volumes using a
450 OS::Heat::ResourceGroup that uses nested heat by calling
451 ocgapp_nested_volume.yml. ocgapp_volume.yml has an outputs: parameter
452 ocgapp_volume_ids which is declared a input parameter of type: json in
456 This is an example of requirement :need:`R-07443`, where
457 a VNF's Heat Orchestration Templates' Cinder Volume Module Output
458 Parameter's name and type **MUST** match the input parameter name and type
459 in the corresponding Base Module or Incremental Module unless the Output
460 Parameter is of the type ``comma_delimited_list``, then the corresponding
461 input parameter **MUST** be declared as type ``json``.
467 heat_template_version: 2014-10-16
469 description: Template for the volumes
475 description: OCG VNF Name
476 ocgapp_volume_size_0:
478 label: Cinder volume 1 size
479 description: the size of the Cinder volume
481 - range: { min: 100, max: 400 }
482 ocgapp_volume_type_0:
484 label: app vm 1 volume type
485 description: the name of the target volume backend for the first OCG APP
489 description: number of volumes needed
492 ocgapp_volume_resource_group:
493 type: OS::Heat::ResourceGroup
495 count: {get_param: volume_count}
498 type: ocgapp_nested_volume.yml
501 size: {get_param: ocgapp_volume_size_0}
502 volume_type: {get_param: ocgapp_volume_type_0}
503 vnf_name: {get_param: vnf_name}
507 description: ocgapp volume ids
508 value: {get_attr: [ocgapp_volume_resource_group, ocgapp_volume_id_0]}
510 ocgapp_nested_volume.yml
514 heat_template_version: 2014-10-16
516 description: nested heat
522 description: number of volumes to spin up
526 description: size of the cinder volumes
530 description: type of cinder volumes
534 description: vnf name
538 type: OS::Cinder::Volume
540 size: {get_param: size}
541 volume_type: {get_param: volume_type}
544 template: VF_NAME_STACK_NAME_INDEX
546 VF_NAME: { get_param: vnf_name }
547 STACK_NAME: { get_param: 'OS::stack_name' }
548 INDEX: {get_param: index}
552 description: the ocgapp volume uuid
553 value: {get_resource: ocgapp_volume_0}
555 Below is a screen shot of parameter ocgapp_volume_ids from the OpenStack
556 Horizon GUI showing the output.
558 .. image:: ../../heat_picture3.png
563 The heat template below is a partial heat template,
569 heat_template_version: 2014-10-16
572 description: OCG Apps template
577 description: Unique IDs for volumes
581 type: OS::Nova::Server
585 type: OS::Nova::Server
588 ocgapp_volume_attachment_0:
589 type: OS::Cinder::VolumeAttachment
591 volume_id: {get_param: [ocgapp_volume_ids, 0]}
592 instance_uuid: {get_resource: ocgapp_server_0}
593 ocgapp_volume_attachment_1:
594 type: OS::Cinder::VolumeAttachment
596 volume_id: {get_param: [ocgapp_volume_ids, 1]}
597 instance_uuid: {get_resource: ocgapp_server_1}
600 ^^^^^^^^^^^^^^^^^^^^^^
602 Heat templates *must not* reference any HTTP-based resource
603 definitions, any HTTP-based nested configurations, or any HTTP-based
606 - During orchestration, ONAP *must not* retrieve any such resources
607 from external/untrusted/unknown sources.
609 - VNF images must not contain external references in user-data or other
610 configuration/operational scripts that are specified via Heat or
611 encoded into the VNF image itself.
613 *Note: HTTP-based references are acceptable if the HTTP-based reference
614 is accessing information utilizing the VM private/internal network.*
616 Note that Namespaces in XML (defined at
617 http://www.w3.org/TR/2009/REC-xml-names-20091208/) are allowed if the
618 Heat Orchestration Template is describing and storing software
619 configuration information. An XML namespace is identified by a URI
620 reference. A Uniform Resource Identifier (URI) is a string of characters
621 which identifies an Internet Resource. The most common URI is the
622 Uniform Resource Locator (URL) which identifies an Internet domain
623 address. Another, not so common type of URI is the Universal Resource
624 Name (URN). The namespace URI is not used by XML the parser to look up
625 information. The purpose of using an URI is to give the namespace a
628 Heat Files Support (get_file)
629 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
631 Heat Templates may contain the inclusion of text files into Heat
632 templates via the Heat get_file directive. This may be used, for
633 example, to define a common "user-data" script, or to inject files into
634 a VM on startup via the "personality" property.
636 Support for Heat Files is subject to the following limitations:
643 :validation_mode: static
646 If a VNF's Heat Orchestration Template uses the intrinsic function
647 ``get_file``, the ``get_file`` target **MUST** be referenced in
648 the Heat Orchestration Template by file name.
650 The ``get_file`` target files are on-boarded to SDC in the same package
651 that contains the VNF's complete Heat Orchestration Template.
658 :validation_mode: static
661 A VNF's Heat Orchestration Template intrinsic function
662 ``get_file`` **MUST NOT** utilize URL-based file retrieval.
668 :validation_mode: static
671 When using the intrinsic function get_file, ONAP does not support
672 a directory hierarchy for included files. All files must be in a
673 single, flat directory per VNF. A VNF's Heat Orchestration
674 Template's ``get_file`` target files **MUST** be in the same
675 directory hierarchy as the VNF's Heat Orchestration Templates.
677 ONAP does not support a hierarchical structure. A VNF's YAML files
678 must be in a single, flat directory.
686 A VNF's Heat Orchestration Templates intrinsic function
687 ``get_file`` <content key> **MAY** be used:
689 * more than once in a VNF's Heat Orchestration Template
690 * in two or more of a VNF's Heat Orchestration Templates
691 * in a VNF's Heat Orchestration Templates nested YAML file
696 When Nova Servers are created via Heat templates, they may be passed a
697 "keypair" which provides an ssh key to the 'root' login on the newly
698 created VM. This is often done so that an initial root key/password does
699 not need to be hard-coded into the image.
701 Key pairs are unusual in OpenStack, because they are the one resource
702 that is owned by an OpenStack User as opposed to being owned by an
703 OpenStack Tenant. As a result, they are usable only by the User that
704 created the keypair. This causes a problem when a Heat template attempts
705 to reference a keypair by name, because it assumes that the keypair was
706 previously created by a specific ONAP user ID.
708 When a keypair is assigned to a server, the SSH public-key is
709 provisioned on the VMs at instantiation time. They keypair itself is not
710 referenced further by the VM (i.e. if the keypair is updated with a new
711 public key, it would only apply to subsequent VMs created with that
714 Due to this behavior, the recommended usage of keypairs is in a more
715 generic manner which does not require the pre-requisite creation of a
716 keypair. The Heat should be structured in such a way as to:
718 - Pass a public key as a parameter value instead of a keypair name
720 - Create a new keypair within the VNF Heat templates (in the base module)
721 based on an existing public key for use within that VNF
723 By following this approach, the end result is the same as pre-creating
724 the keypair using the public key – i.e., that public key will be
725 provisioned in the new VM. However, this recommended approach also makes
726 sure that a known public key is supplied (instead of having OpenStack
727 generate a public/private pair to be saved and tracked outside of ONAP).
728 It also removes any access/ownership issues over the created keypair.
730 The public keys may be enumerated as a VNF Orchestration Constant in the
731 environment file (since it is public, it is not a secret key), or passed
732 at run-time as instance-specific parameters. ONAP will never
733 automatically assign a public/private key pair.
735 *Example (create keypair with an existing ssh public-key for {vm-type}
736 of lb (for load balancer)):*
748 type: OS::Nova::Keypair
752 template: VNF_NAME_key_pair
754 VNF_NAME: { get_param: vnf_name }
755 public_key: {get_param: lb_ssh_public_key}
756 save_private_key: false
761 OpenStack allows a tenant to create Security groups and define rules
762 within the security groups.
764 Security groups, with their rules, may either be created in the Heat
765 Orchestration Template or they can be pre-created in OpenStack and
766 referenced within the Heat template via parameter(s). There can be a
767 different approach for security groups assigned to ports on internal
768 (intra-VNF) networks or external networks (inter-VNF). Furthermore,
769 there can be a common security group across all VMs for a specific
770 network or it can vary by VM (i.e., {vm-type}) and network type (i.e.,
773 Anti-Affinity and Affinity Rules
774 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
776 Anti-affinity or affinity rules are supported using normal OpenStack
777 OS::Nova::ServerGroup resources. Separate ServerGroups are typically
778 created for each VM type to prevent them from residing on the same host,
779 but they can be applied to multiple VM types to extend the
780 affinity/anti-affinity across related VM types as well.
784 In this example, the {network-role} has been defined as oam to represent
785 an oam network and the {vm-type} have been defined as lb for load
786 balancer and db for database.
792 type: OS::Nova::ServerGroup
797 $vnf_name: {get_param: vnf_name}
798 template: $vnf_name-server_group1
802 type: OS::Nova::ServerGroup
807 $vnf_name: {get_param: vnf_name}
808 template: $vnf_name-server_group2
812 type: OS::Nova::Server
816 group: {get_resource: db_server_group}
818 type: OS::Nova::Server
822 group: {get_resource: db_server_group}
824 type: OS::Nova::Server
828 group: {get_resource: lb_server_group}
830 Resource Data Synchronization
831 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
833 For cases where synchronization is required in the orchestration of Heat
834 resources, two approaches are recommended:
836 - Standard Heat depends_on property for resources
838 - Assures that one resource completes before the dependent resource
841 - Definition of completeness to OpenStack may not be sufficient
842 (e.g., a VM is considered complete by OpenStack when it is ready
843 to be booted, not when the application is up and running).
845 - Use of Heat Notifications
847 - Create OS::Heat::WaitCondition and OS::Heat::WaitConditionHandle
850 - Pre-requisite resources issue *wc_notify* commands in user_data.
852 - Dependent resource define depends_on in the
853 OS::Heat::WaitCondition resource.
855 *Example: "depends_on" case*
857 In this example, the {network-role} has been defined as oam to represent
858 an oam network and the {vm-type} has been defined as oam to represent an
865 type: OS::Nova::Server
867 name: {get_param: [oam_names, 0]}
868 image: {get_param: oam_image_name}
869 flavor: {get_param: oam_flavor_name}
870 availability_zone: {get_param: availability_zone_0}
872 - port: {get_resource: oam01_port_0}
873 - port: {get_resource: oam01_port_1}
875 scheduler_hints: {group: {get_resource: oam_servergroup}}
876 user_data_format: RAW
878 type: OS::Neutron::Port
880 network: {get_resource: oam_net_name}
881 fixed_ips: [{"ip_address": {get_param: [oam_oam_net_ips, 1]}}]
882 security_groups: [{get_resource: oam_security_group}]
884 type: OS::Neutron::Port
886 network: {get_param: oam_net_name}
887 fixed_ips: [{"ip_address": {get_param: [oam_oam_net_ips, 2]}}]
888 security_groups: [{get_resource: oam_security_group}]
889 oam_volume_attachment_0:
890 type: OS::Cinder::VolumeAttachment
891 depends_on: oam_server_01
893 volume_id: {get_param: oam_vol_1}
895 instance_uuid: {get_resource: oam_server_01}