Remove HOT Guide from User Guide
The HOT Guide is being moved to the developer heat repository as per Bug-1461720. This patch removes the HOT Guide content and adds a link to its new home in the dev docs. Change-Id: I3503627fa6adb8f3edeb2b2e3fc37be87862880f Closes-Bug: #1461720
This commit is contained in:
parent
6a9f926c60
commit
094e76eb37
@ -1,17 +0,0 @@
|
|||||||
=========
|
|
||||||
HOT Guide
|
|
||||||
=========
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
hot_hello_world.rst
|
|
||||||
hot_spec.rst
|
|
||||||
hot_basic_resources.rst
|
|
||||||
hot_software_deployment.rst
|
|
||||||
hot_environment.rst
|
|
||||||
hot_composition.rst
|
|
||||||
|
|
||||||
.. hot_existing_templates.rst
|
|
||||||
.. hot_advanced_topics.rst
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
|||||||
:orphan:
|
|
||||||
|
|
||||||
.. _hot_advanced_topics:
|
|
||||||
|
|
||||||
===============
|
|
||||||
Advanced topics
|
|
||||||
===============
|
|
||||||
|
|
||||||
Networking
|
|
||||||
~~~~~~~~~~
|
|
||||||
|
|
||||||
Load balancer
|
|
||||||
-------------
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
Firewall
|
|
||||||
--------
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
VPN
|
|
||||||
---
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
Auto scaling
|
|
||||||
~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Alarming
|
|
||||||
--------
|
|
||||||
|
|
||||||
TODO
|
|
||||||
|
|
||||||
Up scaling and down scaling
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
TODO
|
|
@ -1,500 +0,0 @@
|
|||||||
.. highlight: yaml
|
|
||||||
:linenothreshold: 5
|
|
||||||
|
|
||||||
.. _hot_basic_resources:
|
|
||||||
|
|
||||||
=========
|
|
||||||
Instances
|
|
||||||
=========
|
|
||||||
|
|
||||||
.. For consistency let's define a few values to use in the samples:
|
|
||||||
* image name: ubuntu-trusty-x86_64
|
|
||||||
* shared/provider network name: "public"
|
|
||||||
* tenant network and subnet names: "private" and "private-subnet"
|
|
||||||
|
|
||||||
Manage instances
|
|
||||||
~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Create an instance
|
|
||||||
------------------
|
|
||||||
Use the :hotref:`OS::Nova::Server` resource to create a Compute instance. The
|
|
||||||
``flavor`` property is the only mandatory one, but you need to define a boot
|
|
||||||
source using one of the ``image`` or ``block_device_mapping`` properties.
|
|
||||||
|
|
||||||
You also need to define the ``networks`` property to indicate to which networks
|
|
||||||
your instance must connect if multiple networks are available in your tenant.
|
|
||||||
|
|
||||||
The following example creates a simple instance, booted from an image, and
|
|
||||||
connecting to the ``private`` network:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
networks:
|
|
||||||
- network: private
|
|
||||||
|
|
||||||
|
|
||||||
Connect an instance to a network
|
|
||||||
--------------------------------
|
|
||||||
Use the ``networks`` property of an :hotref:`OS::Nova::Server` resource to
|
|
||||||
define which networks an instance should connect to. Define each network as a
|
|
||||||
YAML map, containing one of the following keys:
|
|
||||||
|
|
||||||
``port``
|
|
||||||
The ID of an existing Networking port. You usually create this port in the
|
|
||||||
same template using an :hotref:`OS::Neutron::Port` resource. You will be
|
|
||||||
able to associate a floating IP to this port, and the port to your Compute
|
|
||||||
instance.
|
|
||||||
|
|
||||||
``network``
|
|
||||||
The name or ID of an existing network. You don't need to create an
|
|
||||||
:hotref:`OS::Neutron::Port` resource if you use this property, but you will
|
|
||||||
not be able to associate a floating IP with the instance interface in the
|
|
||||||
template.
|
|
||||||
|
|
||||||
The following example demonstrates the use of the ``port`` and ``network``
|
|
||||||
properties:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
instance_port:
|
|
||||||
type: OS::Neutron::Port
|
|
||||||
properties:
|
|
||||||
network: private
|
|
||||||
fixed_ips:
|
|
||||||
- subnet_id: "private-subnet"
|
|
||||||
|
|
||||||
instance1:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
networks:
|
|
||||||
- port: { get_resource: instance_port }
|
|
||||||
|
|
||||||
instance2:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
networks:
|
|
||||||
- network: private
|
|
||||||
|
|
||||||
|
|
||||||
Create and associate security groups to an instance
|
|
||||||
---------------------------------------------------
|
|
||||||
Use the :hotref:`OS::Neutron::SecurityGroup` resource to create security
|
|
||||||
groups.
|
|
||||||
|
|
||||||
Define the ``security_groups`` property of the :hotref:`OS::Neutron::Port`
|
|
||||||
resource to associate security groups to a port, then associate the port to an
|
|
||||||
instance.
|
|
||||||
|
|
||||||
The following example creates a security group allowing inbound connections on
|
|
||||||
ports 80 and 443 (web server) and associates this security group to an instance
|
|
||||||
port:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
web_secgroup:
|
|
||||||
type: OS::Neutron::SecurityGroup
|
|
||||||
properties:
|
|
||||||
rules:
|
|
||||||
- protocol: tcp
|
|
||||||
remote_ip_prefix: 0.0.0.0/0
|
|
||||||
port_range_min: 80
|
|
||||||
port_range_max: 80
|
|
||||||
- protocol: tcp
|
|
||||||
remote_ip_prefix: 0.0.0.0/0
|
|
||||||
port_range_min: 443
|
|
||||||
port_range_max: 443
|
|
||||||
|
|
||||||
instance_port:
|
|
||||||
type: OS::Neutron::Port
|
|
||||||
properties:
|
|
||||||
network: private
|
|
||||||
security_groups:
|
|
||||||
- default
|
|
||||||
- { get_resource: web_secgroup }
|
|
||||||
fixed_ips:
|
|
||||||
- subnet_id: private-subnet
|
|
||||||
|
|
||||||
instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
networks:
|
|
||||||
- port: { get_resource: instance_port }
|
|
||||||
|
|
||||||
|
|
||||||
Create and associate a floating IP to an instance
|
|
||||||
-------------------------------------------------
|
|
||||||
You can use two sets of resources to create and associate floating IPs to
|
|
||||||
instances.
|
|
||||||
|
|
||||||
OS::Nova resources
|
|
||||||
++++++++++++++++++
|
|
||||||
Use the :hotref:`OS::Nova::FloatingIP` resource to create a floating IP, and
|
|
||||||
the :hotref:`OS::Nova::FloatingIPAssociation` resource to associate the
|
|
||||||
floating IP to an instance.
|
|
||||||
|
|
||||||
The following example creates an instance and a floating IP, and associate the
|
|
||||||
floating IP to the instance:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
floating_ip:
|
|
||||||
type: OS::Nova::FloatingIP
|
|
||||||
properties:
|
|
||||||
pool: public
|
|
||||||
|
|
||||||
inst1:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
networks:
|
|
||||||
- network: private
|
|
||||||
|
|
||||||
association:
|
|
||||||
type: OS::Nova::FloatingIPAssociation
|
|
||||||
properties:
|
|
||||||
floating_ip: { get_resource: floating_ip }
|
|
||||||
server_id: { get_resource: instance }
|
|
||||||
|
|
||||||
OS::Neutron resources
|
|
||||||
+++++++++++++++++++++
|
|
||||||
.. note::
|
|
||||||
The Networking service (neutron) must be enabled on your OpenStack
|
|
||||||
deployment to use these resources.
|
|
||||||
|
|
||||||
Use the :hotref:`OS::Neutron::FloatingIP` resource to create a floating IP, and
|
|
||||||
the :hotref:`OS::Neutron::FloatingIPAssociation` resource to associate the
|
|
||||||
floating IP to a port:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
net:
|
|
||||||
description: name of network used to launch instance.
|
|
||||||
type: string
|
|
||||||
default: private
|
|
||||||
|
|
||||||
resources:
|
|
||||||
inst1:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
networks:
|
|
||||||
- network: {get_param: net}
|
|
||||||
|
|
||||||
floating_ip:
|
|
||||||
type: OS::Neutron::FloatingIP
|
|
||||||
properties:
|
|
||||||
floating_network: public
|
|
||||||
|
|
||||||
association:
|
|
||||||
type: OS::Neutron::FloatingIPAssociation
|
|
||||||
properties:
|
|
||||||
floatingip_id: { get_resource: floating_ip }
|
|
||||||
port_id: {get_attr: [inst1, addresses, {get_param: net}, 0, port]}
|
|
||||||
|
|
||||||
You can also create an OS::Neutron::Port and associate that with the server and
|
|
||||||
the floating IP. However the approach mentioned above will work better
|
|
||||||
with stack updates.
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
instance_port:
|
|
||||||
type: OS::Neutron::Port
|
|
||||||
properties:
|
|
||||||
network: private
|
|
||||||
fixed_ips:
|
|
||||||
- subnet_id: "private-subnet"
|
|
||||||
|
|
||||||
floating_ip:
|
|
||||||
type: OS::Neutron::FloatingIP
|
|
||||||
properties:
|
|
||||||
floating_network: public
|
|
||||||
|
|
||||||
association:
|
|
||||||
type: OS::Neutron::FloatingIPAssociation
|
|
||||||
properties:
|
|
||||||
floatingip_id: { get_resource: floating_ip }
|
|
||||||
port_id: { get_resource: instance_port }
|
|
||||||
|
|
||||||
Enable remote access to an instance
|
|
||||||
-----------------------------------
|
|
||||||
The ``key_name`` attribute of the :hotref:`OS::Nova::Server` resource defines
|
|
||||||
the key pair to use to enable SSH remote access:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
key_name: my_key
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
For more information about key pairs, see the :doc:`../cli_nova_configure_access_security_for_instances`.
|
|
||||||
|
|
||||||
Create a key pair
|
|
||||||
-----------------
|
|
||||||
You can create new key pairs with the :hotref:`OS::Nova::KeyPair` resource. Key
|
|
||||||
pairs can be imported or created during the stack creation.
|
|
||||||
|
|
||||||
If the ``public_key`` property is not specified, the Orchestration module
|
|
||||||
creates a new key pair. If the ``save_private_key`` property is set to
|
|
||||||
``true``, the ``private_key`` attribute of the resource holds the private key.
|
|
||||||
|
|
||||||
The following example creates a new key pair and uses it as authentication key
|
|
||||||
for an instance:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_key:
|
|
||||||
type: OS::Nova::KeyPair
|
|
||||||
properties:
|
|
||||||
save_private_key: true
|
|
||||||
|
|
||||||
my_instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
key_name: { get_resource: my_key }
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
private_key:
|
|
||||||
description: Private key
|
|
||||||
value: { get_attr: [ my_key, private_key ] }
|
|
||||||
|
|
||||||
Manage networks
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
Create a network and a subnet
|
|
||||||
-----------------------------
|
|
||||||
.. note::
|
|
||||||
The Networking service (neutron) must be enabled on your OpenStack
|
|
||||||
deployment to create and manage networks and subnets. Networks and subnets
|
|
||||||
cannot be created if your deployment uses legacy networking (nova-network).
|
|
||||||
|
|
||||||
Use the :hotref:`OS::Neutron::Net` resource to create a network, and the
|
|
||||||
:hotref:`OS::Neutron::Subnet` resource to provide a subnet for this network:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
new_net:
|
|
||||||
type: OS::Neutron::Net
|
|
||||||
|
|
||||||
new_subnet:
|
|
||||||
type: OS::Neutron::Subnet
|
|
||||||
properties:
|
|
||||||
network_id: { get_resource: new_net }
|
|
||||||
cidr: "10.8.1.0/24"
|
|
||||||
dns_nameservers: [ "8.8.8.8", "8.8.4.4" ]
|
|
||||||
ip_version: 4
|
|
||||||
|
|
||||||
|
|
||||||
Create and manage a router
|
|
||||||
--------------------------
|
|
||||||
Use the :hotref:`OS::Neutron::Router` resource to create a router. You can
|
|
||||||
define its gateway with the ``external_gateway_info`` property:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
router1:
|
|
||||||
type: OS::Neutron::Router
|
|
||||||
properties:
|
|
||||||
external_gateway_info: { network: public }
|
|
||||||
|
|
||||||
You can connect subnets to routers with the
|
|
||||||
:hotref:`OS::Neutron::RouterInterface` resource:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
subnet1_interface:
|
|
||||||
type: OS::Neutron::RouterInterface
|
|
||||||
properties:
|
|
||||||
router_id: { get_resource: router1 }
|
|
||||||
subnet: private-subnet
|
|
||||||
|
|
||||||
|
|
||||||
Complete network example
|
|
||||||
------------------------
|
|
||||||
The following example creates a network stack:
|
|
||||||
|
|
||||||
* A network and an associated subnet.
|
|
||||||
* A router with an external gateway.
|
|
||||||
* An interface to the new subnet for the new router.
|
|
||||||
|
|
||||||
In this example, the ``public`` network is an existing shared network:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
internal_net:
|
|
||||||
type: OS::Neutron::Net
|
|
||||||
|
|
||||||
internal_subnet:
|
|
||||||
type: OS::Neutron::Subnet
|
|
||||||
properties:
|
|
||||||
network_id: { get_resource: internal_net }
|
|
||||||
cidr: "10.8.1.0/24"
|
|
||||||
dns_nameservers: [ "8.8.8.8", "8.8.4.4" ]
|
|
||||||
ip_version: 4
|
|
||||||
|
|
||||||
internal_router:
|
|
||||||
type: OS::Neutron::Router
|
|
||||||
properties:
|
|
||||||
external_gateway_info: { network: public }
|
|
||||||
|
|
||||||
internal_interface:
|
|
||||||
type: OS::Neutron::RouterInterface
|
|
||||||
properties:
|
|
||||||
router_id: { get_resource: internal_router }
|
|
||||||
subnet: { get_resource: internal_subnet }
|
|
||||||
|
|
||||||
|
|
||||||
Manage volumes
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
Create a volume
|
|
||||||
---------------
|
|
||||||
Use the :hotref:`OS::Cinder::Volume` resource to create a new Block Storage
|
|
||||||
volume.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_new_volume:
|
|
||||||
type: OS::Cinder::Volume
|
|
||||||
properties:
|
|
||||||
size: 10
|
|
||||||
|
|
||||||
The volumes that you create are empty by default. Use the ``image`` property to
|
|
||||||
create a bootable volume from an existing image:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_new_bootable_volume:
|
|
||||||
type: OS::Cinder::Volume
|
|
||||||
properties:
|
|
||||||
size: 10
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
|
|
||||||
|
|
||||||
You can also create new volumes from another volume, a volume snapshot, or a
|
|
||||||
volume backup. Use the ``source_volid``, ``snapshot_id`` or ``backup_id``
|
|
||||||
properties to create a new volume from an existing source.
|
|
||||||
|
|
||||||
For example, to create a new volume from a backup:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
another_volume:
|
|
||||||
type: OS::Cinder::Volume
|
|
||||||
properties:
|
|
||||||
backup_id: 2fff50ab-1a9c-4d45-ae60-1d054d6bc868
|
|
||||||
|
|
||||||
In this example the ``size`` property is not defined because the Block Storage
|
|
||||||
service uses the size of the backup to define the size of the new volume.
|
|
||||||
|
|
||||||
Attach a volume to an instance
|
|
||||||
------------------------------
|
|
||||||
Use the :hotref:`OS::Cinder::VolumeAttachment` resource to attach a volume to
|
|
||||||
an instance.
|
|
||||||
|
|
||||||
The following example creates a volume and an instance, and attaches the volume
|
|
||||||
to the instance:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
new_volume:
|
|
||||||
type: OS::Cinder::Volume
|
|
||||||
properties:
|
|
||||||
size: 1
|
|
||||||
|
|
||||||
new_instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
|
|
||||||
volume_attachment:
|
|
||||||
type: OS::Cinder::VolumeAttachment
|
|
||||||
properties:
|
|
||||||
volume_id: { get_resource: new_volume }
|
|
||||||
instance_uuid: { get_resource: new_instance }
|
|
||||||
|
|
||||||
Boot an instance from a volume
|
|
||||||
------------------------------
|
|
||||||
Use the ``block_device_mapping`` property of the :hotref:`OS::Nova::Server`
|
|
||||||
resource to define a volume used to boot the instance. This property is a list
|
|
||||||
of volumes to attach to the instance before its boot.
|
|
||||||
|
|
||||||
The following example creates a bootable volume from an image, and uses it to
|
|
||||||
boot an instance:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
bootable_volume:
|
|
||||||
type: OS::Cinder::Volume
|
|
||||||
properties:
|
|
||||||
size: 10
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
|
|
||||||
instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
networks:
|
|
||||||
- network: private
|
|
||||||
block_device_mapping:
|
|
||||||
- device_name: vda
|
|
||||||
volume_id: { get_resource: bootable_volume }
|
|
||||||
delete_on_termination: false
|
|
||||||
|
|
||||||
.. TODO
|
|
||||||
A few elements that probably belong here:
|
|
||||||
- OS::Swift::Container
|
|
||||||
- OS::Trove::Instance
|
|
@ -1,168 +0,0 @@
|
|||||||
.. highlight: yaml
|
|
||||||
:linenothreshold: 5
|
|
||||||
|
|
||||||
.. _composition:
|
|
||||||
|
|
||||||
====================
|
|
||||||
Template composition
|
|
||||||
====================
|
|
||||||
|
|
||||||
When writing complex templates you are encouraged to break up your
|
|
||||||
template into separate smaller templates. These can then be brought
|
|
||||||
together using template resources. This is a mechanism to define a resource
|
|
||||||
using a template, thus composing one logical stack with multiple templates.
|
|
||||||
|
|
||||||
Template resources provide a feature similar to the
|
|
||||||
:hotref:`AWS::CloudFormation::Stack` resource, but also provide a way to:
|
|
||||||
|
|
||||||
* Define new resource types and build your own resource library.
|
|
||||||
* Override the default behaviour of existing resource types.
|
|
||||||
|
|
||||||
To achieve this:
|
|
||||||
|
|
||||||
* The Orchestration client gets the associated template files and passes them
|
|
||||||
along in the ``files`` section of the ``POST stacks/`` API request.
|
|
||||||
* The environment in the Orchestration engine manages the mapping of resource
|
|
||||||
type to template creation.
|
|
||||||
* The Orchestration engine translates template parameters into resource
|
|
||||||
properties.
|
|
||||||
|
|
||||||
The following examples illustrate how you can use a custom template to define
|
|
||||||
new types of resources. These examples use a custom template stored in a
|
|
||||||
:file:`my_nova.yml` file:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
heat_template_version: 2014-10-16
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
key_name:
|
|
||||||
type: string
|
|
||||||
description: Name of a KeyPair
|
|
||||||
|
|
||||||
resources:
|
|
||||||
server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
key_name: {get_param: key_name}
|
|
||||||
flavor: m1.small
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
|
|
||||||
Use the template filename as type
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The following template defines the :file:`my_nova.yaml` file as value for the
|
|
||||||
``type`` property of a resource:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
heat_template_version: 2014-10-16
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_server:
|
|
||||||
type: my_nova.yaml
|
|
||||||
properties:
|
|
||||||
key_name: my_key
|
|
||||||
|
|
||||||
The :code:`key_name` argument of the ``my_nova.yaml`` template gets
|
|
||||||
its value from the :code:`key_name` property of the new template.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
The above reference to ``my_nova.yaml`` assumes it is in the same directory.
|
|
||||||
You can use any of the following forms:
|
|
||||||
|
|
||||||
* Relative path (:file:`my_nova.yaml`)
|
|
||||||
* Absolute path (:file:`file:///home/user/templates/my_nova.yaml`)
|
|
||||||
* Http URL (:file:`http://example.com/templates/my_nova.yaml`)
|
|
||||||
* Https URL (:file:`https://example.com/templates/my_nova.yaml`)
|
|
||||||
|
|
||||||
To create the stack run:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ heat stack-create -f main.yaml stack1
|
|
||||||
|
|
||||||
|
|
||||||
Define a new resource type
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
You can associate a name to the :file:`my_nova.yaml` template in an environment
|
|
||||||
file. If the name is already known by the Orchestration module then your new
|
|
||||||
resource will override the default one.
|
|
||||||
|
|
||||||
In the following example a new ``OS::Nova::Server`` resource overrides the
|
|
||||||
default resource of the same name.
|
|
||||||
|
|
||||||
An :file:`env.yaml` environment file holds the definition of the new resource:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
resource_registry:
|
|
||||||
"OS::Nova::Server": my_nova.yaml
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
See :ref:`environments` for more detail about environment files.
|
|
||||||
|
|
||||||
You can now use the new ``OS::Nova::Server`` in your new template:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
heat_template_version: 2014-10-16
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
key_name: my_key
|
|
||||||
|
|
||||||
To create the stack run:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ heat stack-create -f main.yaml -e env.yaml example-two
|
|
||||||
|
|
||||||
|
|
||||||
Get access to nested attributes
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
There are implicit attributes of a template resource. These are
|
|
||||||
accessible as follows:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
heat_template_version: 2014-10-16
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_server:
|
|
||||||
type: my_nova.yaml
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
test_out:
|
|
||||||
value: {get_attr: my_server, resource.server, first_address}
|
|
||||||
|
|
||||||
|
|
||||||
Making your template resource more "transparent"
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
If you wish to be able to return the ID of one of the inner resources
|
|
||||||
instead of the nested stack's identifier, you can add the special reserved
|
|
||||||
output ``OS::stack_id`` to your template resource.
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
heat_template_version: 2014-10-16
|
|
||||||
|
|
||||||
resources:
|
|
||||||
server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
OS::stack_id:
|
|
||||||
value: {get_resource: server}
|
|
||||||
|
|
||||||
Now when you use :code:`get_resource` from the outer template heat
|
|
||||||
will use the nova server id and not the template resource identifier.
|
|
@ -1,128 +0,0 @@
|
|||||||
.. highlight: yaml
|
|
||||||
:linenothreshold: 5
|
|
||||||
|
|
||||||
.. _environments:
|
|
||||||
|
|
||||||
============
|
|
||||||
Environments
|
|
||||||
============
|
|
||||||
|
|
||||||
The environment affects the runtime behaviour of a template. It provides a way
|
|
||||||
to override the resource implementations and a mechanism to place parameters
|
|
||||||
that the service needs.
|
|
||||||
|
|
||||||
To fully understand the runtime behavior you have to consider what plug-ins are
|
|
||||||
installed on the cloud you're using.
|
|
||||||
|
|
||||||
Environment file format
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The environment is a yaml text file that contains two main sections:
|
|
||||||
|
|
||||||
``parameters``
|
|
||||||
A list of key/value pairs.
|
|
||||||
|
|
||||||
``resource_registry``
|
|
||||||
Definition of custom resources.
|
|
||||||
|
|
||||||
Use the :option:`-e` option of the :command:`heat stack-create` command to
|
|
||||||
create a stack using with the environment defined in such a file.
|
|
||||||
|
|
||||||
You can also provide environment parameters as a list of key/value pairs using
|
|
||||||
the :option:`-P` option of the :command:`heat stack-create` command.
|
|
||||||
|
|
||||||
In the following example the environment is read from the :file:`my_env.yaml`
|
|
||||||
file and an extra parameter is provided using the :option:`-P` option::
|
|
||||||
|
|
||||||
$ heat stack-create my_stack -e my_env.yaml -P "param1=val1;param2=val2" -f my_tmpl.yaml
|
|
||||||
|
|
||||||
|
|
||||||
Global and effective environments
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The environment used for a stack is the combination of the environment you
|
|
||||||
use with the template for the stack, and a global environment that is
|
|
||||||
determined by your cloud operator. An entry in the user environment takes
|
|
||||||
precedence over the global environment. OpenStack includes a default global
|
|
||||||
environment, but you cloud operator can add additional environment entries.
|
|
||||||
|
|
||||||
.. TODO:
|
|
||||||
move this to a heat section in the admin-guide-cloud
|
|
||||||
|
|
||||||
The cloud operator can add to the global environment
|
|
||||||
by putting environment files in a configurable directory wherever
|
|
||||||
the Orchestration engine runs. The configuration variable is named
|
|
||||||
"environment_dir" is found in the "[DEFAULT]" section
|
|
||||||
of "/etc/heat/heat.conf". The default for that directory is
|
|
||||||
"/etc/heat/environment.d". Its contents are combined in whatever
|
|
||||||
order the shell delivers them when the service starts up,
|
|
||||||
which is the time when these files are read.
|
|
||||||
|
|
||||||
If the "my_env.yaml" file from the example above had been put in the
|
|
||||||
"environment_dir" then the user's command line could be this::
|
|
||||||
|
|
||||||
heat stack-create my_stack -P "some_parm=bla" -f my_tmpl.yaml
|
|
||||||
|
|
||||||
Define values for a template arguments
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can define values for the template arguments in the ``parameters`` section
|
|
||||||
of an environment file:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
KeyName: my_keypair
|
|
||||||
InstanceType: m1.tiny
|
|
||||||
ImageId: F18-x86_64-cfntools
|
|
||||||
|
|
||||||
Create and override resources
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
You can create or override resources in the ``resource_registry`` section of an
|
|
||||||
environment file. The resource you provide in this manner must have an
|
|
||||||
identifier, and references either other resources IDs or the URL of an existing
|
|
||||||
template file.
|
|
||||||
|
|
||||||
The following example maps the new ``OS::Networking::FloatingIP``
|
|
||||||
resource to the existing :hotref:`OS::Nova::FloatingIP` resource:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
resource_registry:
|
|
||||||
"OS::Networking::FloatingIP": "OS::Nova::FloatingIP"
|
|
||||||
|
|
||||||
You can use wildcards to map multiple resources:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
resource_registry:
|
|
||||||
"OS::Network*": "OS::Neutron*"
|
|
||||||
|
|
||||||
To create or override a resource with a custom resource, create a template file
|
|
||||||
to define this resource, and provide the URL to the template file in the
|
|
||||||
environment file:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
resource_registry:
|
|
||||||
"AWS::EC2::Instance": file:///path/to/my_instance.yaml
|
|
||||||
|
|
||||||
The supported URL scheme are ``file``, ``http`` and ``https``.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
The template file extension must be ``.yaml`` or ``.template``, or it will
|
|
||||||
not be treated as a custom template resource.
|
|
||||||
|
|
||||||
You can limit the usage of a custom resource to a specific resource of the
|
|
||||||
template:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resource_registry:
|
|
||||||
resources:
|
|
||||||
my_db_server:
|
|
||||||
"OS::DBInstance": file:///home/mine/all_my_cool_templates/db.yaml
|
|
@ -1,28 +0,0 @@
|
|||||||
:orphan:
|
|
||||||
|
|
||||||
.. _existing_templates:
|
|
||||||
|
|
||||||
================================
|
|
||||||
Where to find existing templates
|
|
||||||
================================
|
|
||||||
|
|
||||||
There are several repositories where you can find existing HOT templates.
|
|
||||||
|
|
||||||
The `OpenStack Heat Templates repository`_ is a collection of example
|
|
||||||
templates which demonstrates core Heat functionality, related image-building
|
|
||||||
templates, template-related scripts and conversion tools.
|
|
||||||
|
|
||||||
.. _OpenStack Heat Templates Repository: https://git.openstack.org/cgit/openstack/heat-templates/tree/
|
|
||||||
|
|
||||||
The `OpenStack TripleO Heat Templates repository`_ contains a variety of
|
|
||||||
heat templates that are included in the tripleo-heat-templates codebase.
|
|
||||||
|
|
||||||
.. _OpenStack TripleO Heat Templates repository: https://git.openstack.org/cgit/openstack/tripleo-heat-templates/tree/
|
|
||||||
|
|
||||||
Rackspace has provided a set of Heat templates at the `RCB Ops repository`_
|
|
||||||
that can be used by cloud operators to launch applications, templates for
|
|
||||||
building a multi-node OpenStack cluster, as well as templates for CI
|
|
||||||
development. Heat templates for deployment of Magento, Hadoop, MongoDB,
|
|
||||||
ELK, Drupal and more can be found here.
|
|
||||||
|
|
||||||
.. _RCB Ops repository: https://github.com/rcbops/
|
|
@ -1,233 +0,0 @@
|
|||||||
.. highlight: yaml
|
|
||||||
:linenothreshold: 5
|
|
||||||
|
|
||||||
..
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
not use this file except in compliance with the License. You may obtain
|
|
||||||
a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
License for the specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
.. _hello_world:
|
|
||||||
|
|
||||||
==================================
|
|
||||||
Writing a hello world HOT template
|
|
||||||
==================================
|
|
||||||
|
|
||||||
HOT is a new template format meant to replace the CloudFormation-compatible
|
|
||||||
format (CFN) as the native format supported by the Orchestration module over
|
|
||||||
time.
|
|
||||||
This guide is targeted towards template authors and explains how to write
|
|
||||||
HOT templates based on examples. A detailed specification of HOT can be found
|
|
||||||
at :ref:`hot_spec`.
|
|
||||||
|
|
||||||
|
|
||||||
This section gives an introduction on how to write HOT templates, starting from
|
|
||||||
very basic steps and then going into more and more detail by means of examples.
|
|
||||||
|
|
||||||
A most basic template
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
The most basic template you can think of contains only a single resource
|
|
||||||
definition using only predefined properties. For example, the template below
|
|
||||||
could be used to deploy a single compute instance:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
heat_template_version: 2013-05-23
|
|
||||||
|
|
||||||
description: Simple template to deploy a single compute instance
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
key_name: my_key
|
|
||||||
image: ubuntu-trusty-x86_64
|
|
||||||
flavor: m1.small
|
|
||||||
|
|
||||||
Each HOT template must include the ``heat_template_version`` key with
|
|
||||||
the HOT version value, for example, ``2013-05-23``. A list of HOT template
|
|
||||||
versions can be found at `Heat Template Version
|
|
||||||
file <http://docs.openstack.org/developer/heat/template_guide/hot_spec.html#heat-template-version>`__
|
|
||||||
|
|
||||||
The ``description`` key is optional, however it is good practice to include
|
|
||||||
some useful text that describes what users can do with the template.
|
|
||||||
In case you want to provide a longer description that does not fit on
|
|
||||||
a single line, you can provide multi-line text in YAML, for example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
description: >
|
|
||||||
This is how you can provide a longer description
|
|
||||||
of your template that goes over several lines.
|
|
||||||
|
|
||||||
The ``resources`` section is required and must contain at least one resource
|
|
||||||
definition. In the above example, a compute instance is defined with fixed
|
|
||||||
values for the ``key_name``, ``image`` and ``flavor`` properties.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
All the defined elements (key pair, image, flavor) have to exist in the
|
|
||||||
OpenStack environment where the template is used.
|
|
||||||
|
|
||||||
Input parameters
|
|
||||||
~~~~~~~~~~~~~~~~
|
|
||||||
Input parameters defined in the ``parameters`` section of a template
|
|
||||||
allow users to customize a template during deployment. For example, this allows
|
|
||||||
for providing custom key pair names or image IDs to be used for a deployment.
|
|
||||||
From a template author's perspective, this helps to make a template more easily
|
|
||||||
reusable by avoiding hardcoded assumptions.
|
|
||||||
|
|
||||||
The following example extends the previous template to provide parameters for
|
|
||||||
the key pair, image and flavor properties of the resource:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
heat_template_version: 2013-05-23
|
|
||||||
|
|
||||||
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
|
|
||||||
flavor:
|
|
||||||
type: string
|
|
||||||
label: Instance Type
|
|
||||||
description: Type of instance (flavor) to be used
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
key_name: { get_param: key_name }
|
|
||||||
image: { get_param: image_id }
|
|
||||||
flavor: { get_param: flavor }
|
|
||||||
|
|
||||||
|
|
||||||
Values for the three parameters must be defined by the template user during the
|
|
||||||
deployment of a stack. The ``get_param`` intrinsic function retrieves a
|
|
||||||
user-specified value for a given parameter and uses this value for the
|
|
||||||
associated resource property.
|
|
||||||
|
|
||||||
For more information about intrinsic functions, see
|
|
||||||
:ref:`hot_spec_intrinsic_functions`.
|
|
||||||
|
|
||||||
Providing default values
|
|
||||||
------------------------
|
|
||||||
You can provide default values for parameters. If a user doesn't define a value
|
|
||||||
for a parameter, the default value is used during the stack deployment. The
|
|
||||||
following example defines a default value ``m1.small`` for the
|
|
||||||
``flavor`` property:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
flavor:
|
|
||||||
type: string
|
|
||||||
label: Instance Type
|
|
||||||
description: Flavor to be used
|
|
||||||
default: m1.small
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
If a template doesn't define a default value for a parameter, then the user
|
|
||||||
must define the value, otherwise the stack creation will fail.
|
|
||||||
|
|
||||||
Hiding parameters values
|
|
||||||
------------------------
|
|
||||||
The values that a user provides when deploying a stack are available in the
|
|
||||||
stack details and can be accessed by any user in the same tenant. To hide the
|
|
||||||
value of a parameter, use the ``hidden`` boolean attribute of the parameter:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
database_password:
|
|
||||||
type: string
|
|
||||||
label: Database Password
|
|
||||||
description: Password to be used for database
|
|
||||||
hidden: true
|
|
||||||
|
|
||||||
Restricting user input
|
|
||||||
----------------------
|
|
||||||
You can restrict the values of an input parameter to make sure that the user
|
|
||||||
defines valid data for this parameter. The ``constraints`` property of an input
|
|
||||||
parameter defines a list of constraints to apply for the parameter.
|
|
||||||
The following example restricts the ``flavor`` parameter to a list of three
|
|
||||||
possible values:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
flavor:
|
|
||||||
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.
|
|
||||||
|
|
||||||
The following example defines multiple constraints for a password definition:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
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.
|
|
||||||
|
|
||||||
The list of supported constraints is available in the
|
|
||||||
:ref:`hot_spec_parameters_constraints` section.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
You can define multiple constraints of the same type. Especially in the
|
|
||||||
case of allowed patterns this not only allows for keeping regular
|
|
||||||
expressions simple and maintainable, but also for keeping error messages to
|
|
||||||
be presented to users precise.
|
|
||||||
|
|
||||||
|
|
||||||
Template outputs
|
|
||||||
~~~~~~~~~~~~~~~~
|
|
||||||
In addition to template customization through input parameters, you can
|
|
||||||
provide information about the resources created during the stack deployment to
|
|
||||||
the users in the ``outputs`` section of a template. In the following example
|
|
||||||
the output section provides the IP address of the ``my_instance`` resource:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
instance_ip:
|
|
||||||
description: The IP address of the deployed instance
|
|
||||||
value: { get_attr: [my_instance, first_address] }
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
Output values are typically resolved using intrinsic function such as
|
|
||||||
the ``get_attr``. See :ref:`hot_spec_intrinsic_functions` for more information
|
|
||||||
about intrinsic functions..
|
|
||||||
|
|
||||||
See :ref:`hot_spec_outputs` for more information about the ``outputs`` section.
|
|
@ -1,804 +0,0 @@
|
|||||||
.. highlight: yaml
|
|
||||||
:linenothreshold: 5
|
|
||||||
|
|
||||||
.. _hot_software_deployment:
|
|
||||||
|
|
||||||
======================
|
|
||||||
Software configuration
|
|
||||||
======================
|
|
||||||
|
|
||||||
There are a variety of options to configure the software which runs on the
|
|
||||||
servers in your stack. These can be broadly divided into the following:
|
|
||||||
|
|
||||||
* Custom image building
|
|
||||||
|
|
||||||
* User-data boot scripts and cloud-init
|
|
||||||
|
|
||||||
* Software deployment resources
|
|
||||||
|
|
||||||
This section will describe each of these options and provide examples for
|
|
||||||
using them together in your stacks.
|
|
||||||
|
|
||||||
Image building
|
|
||||||
~~~~~~~~~~~~~~
|
|
||||||
The first opportunity to influence what software is configured on your servers
|
|
||||||
is by booting them with a custom-built image. There are a number of reasons
|
|
||||||
you might want to do this, including:
|
|
||||||
|
|
||||||
* **Boot speed** - since the required software is already on the image there
|
|
||||||
is no need to download and install anything at boot time.
|
|
||||||
|
|
||||||
* **Boot reliability** - software downloads can fail for a number of reasons
|
|
||||||
including transient network failures and inconsistent software repositories.
|
|
||||||
|
|
||||||
* **Test verification** - custom built images can be verified in test
|
|
||||||
environments before being promoted to production.
|
|
||||||
|
|
||||||
* **Configuration dependencies** - post-boot configuration may depend on
|
|
||||||
agents already being installed and enabled
|
|
||||||
|
|
||||||
A number of tools are available for building custom images, including:
|
|
||||||
|
|
||||||
* diskimage-builder_ image building tools for OpenStack
|
|
||||||
|
|
||||||
* imagefactory_ builds images for a variety of operating system/cloud
|
|
||||||
combinations
|
|
||||||
|
|
||||||
Examples in this guide which require custom images will use diskimage-builder_.
|
|
||||||
|
|
||||||
User-data boot scripts and cloud-init
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
When booting a server it is possible to specify the contents of the user-data
|
|
||||||
to be passed to that server. This user-data is made available either from
|
|
||||||
configured config-drive or from the `Metadata service`_.
|
|
||||||
|
|
||||||
How this user-data is consumed depends on the image being booted, but the most
|
|
||||||
commonly used tool for default cloud images is Cloud-init_.
|
|
||||||
|
|
||||||
Whether the image is using Cloud-init_ or not, it should be possible to
|
|
||||||
specify a shell script in the ``user_data`` property and have it be executed by
|
|
||||||
the server during boot:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
|
|
||||||
the_server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
# flavor, image etc
|
|
||||||
user_data: |
|
|
||||||
#!/bin/bash
|
|
||||||
echo "Running boot script"
|
|
||||||
# ...
|
|
||||||
|
|
||||||
.. note:: Debugging these scripts it is often useful to view the boot
|
|
||||||
log using :code:`nova console-log <server-id>` to view the progress of boot
|
|
||||||
script execution.
|
|
||||||
|
|
||||||
Often there is a need to set variable values based on parameters or resources
|
|
||||||
in the stack. This can be done with the :code:`str_replace` intrinsic function:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
foo:
|
|
||||||
default: bar
|
|
||||||
|
|
||||||
resources:
|
|
||||||
|
|
||||||
the_server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
# flavor, image etc
|
|
||||||
user_data:
|
|
||||||
str_replace:
|
|
||||||
template: |
|
|
||||||
#!/bin/bash
|
|
||||||
echo "Running boot script with $FOO"
|
|
||||||
# ...
|
|
||||||
params:
|
|
||||||
$FOO: {get_param: foo}
|
|
||||||
|
|
||||||
.. warning:: If a stack-update is performed and there are any changes
|
|
||||||
at all to the content of user_data then the server will be replaced
|
|
||||||
(deleted and recreated) so that the modified boot configuration can be
|
|
||||||
run on a new server.
|
|
||||||
|
|
||||||
When these scripts grow it can become difficult to maintain them inside the
|
|
||||||
template, so the ``get_file`` intrinsic function can be used to maintain the
|
|
||||||
script in a separate file:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
foo:
|
|
||||||
default: bar
|
|
||||||
|
|
||||||
resources:
|
|
||||||
|
|
||||||
the_server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
# flavor, image etc
|
|
||||||
user_data:
|
|
||||||
str_replace:
|
|
||||||
template: {get_file: the_server_boot.sh}
|
|
||||||
params:
|
|
||||||
$FOO: {get_param: foo}
|
|
||||||
|
|
||||||
.. note:: ``str_replace`` can replace any strings, not just strings
|
|
||||||
starting with ``$``. However doing this for the above example is useful
|
|
||||||
because the script file can be executed for testing by passing in
|
|
||||||
environment variables.
|
|
||||||
|
|
||||||
Choosing the user_data_format
|
|
||||||
-----------------------------
|
|
||||||
The :hotref:`OS::Nova::Server` ``user_data_format`` property determines how the
|
|
||||||
``user_data`` should be formatted for the server. For the default value
|
|
||||||
``HEAT_CFNTOOLS``, the ``user_data`` is bundled as part of the heat-cfntools
|
|
||||||
cloud-init boot configuration data. While ``HEAT_CFNTOOLS`` is the default
|
|
||||||
for ``user_data_format``, it is considered legacy and ``RAW`` or
|
|
||||||
``SOFTWARE_CONFIG`` will generally be more appropriate.
|
|
||||||
|
|
||||||
For ``RAW`` the user_data is passed to Nova unmodified. For a Cloud-init_
|
|
||||||
enabled image, the following are both valid ``RAW`` user-data:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
|
|
||||||
server_with_boot_script:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
# flavor, image etc
|
|
||||||
user_data_format: RAW
|
|
||||||
user_data: |
|
|
||||||
#!/bin/bash
|
|
||||||
echo "Running boot script"
|
|
||||||
# ...
|
|
||||||
|
|
||||||
server_with_cloud_config:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
# flavor, image etc
|
|
||||||
user_data_format: RAW
|
|
||||||
user_data: |
|
|
||||||
#cloud-config
|
|
||||||
final_message: "The system is finally up, after $UPTIME seconds"
|
|
||||||
|
|
||||||
For ``SOFTWARE_CONFIG`` ``user_data`` is bundled as part of the software config
|
|
||||||
data, and metadata is derived from any associated
|
|
||||||
`Software deployment resources`_.
|
|
||||||
|
|
||||||
Signals and wait conditions
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
Often it is necessary to pause further creation of stack resources
|
|
||||||
until the boot configuration script has notified that it has reached a
|
|
||||||
certain state. This is usually either to notify that a service is now
|
|
||||||
active, or to pass out some generated data which is needed by another
|
|
||||||
resource. The resources :hotref:`OS::Heat::WaitCondition` and
|
|
||||||
:hotref:`OS::Heat::SwiftSignal` both perform this function using
|
|
||||||
different techniques and tradeoffs.
|
|
||||||
|
|
||||||
:hotref:`OS::Heat::WaitCondition` is implemented as a call to the
|
|
||||||
`Orchestration API`_ resource signal. The token is created using credentials
|
|
||||||
for a user account which is scoped only to the wait condition handle
|
|
||||||
resource. This user is created when the handle is created, and is associated
|
|
||||||
to a project which belongs to the stack, in an identity domain which is
|
|
||||||
dedicated to the orchestration service.
|
|
||||||
|
|
||||||
Sending the signal is a simple HTTP request, as with this example using curl_:
|
|
||||||
|
|
||||||
.. code-block:: sh
|
|
||||||
|
|
||||||
curl -i -X POST -H 'X-Auth-Token: <token>' \
|
|
||||||
-H 'Content-Type: application/json' -H 'Accept: application/json' \
|
|
||||||
'<wait condition URL>' --data-binary '<json containing signal data>'
|
|
||||||
|
|
||||||
The JSON containing the signal data is expected to be of the following format:
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"status": "SUCCESS",
|
|
||||||
"reason": "The reason which will appear in the 'heat event-list' output",
|
|
||||||
"data": "Data to be used elsewhere in the template via get_attr",
|
|
||||||
"id": "Optional unique ID of signal"
|
|
||||||
}
|
|
||||||
|
|
||||||
All of these values are optional, and if not specified will be set to the
|
|
||||||
following defaults:
|
|
||||||
|
|
||||||
.. code-block:: json
|
|
||||||
|
|
||||||
{
|
|
||||||
"status": "SUCCESS",
|
|
||||||
"reason": "Signal <id> received",
|
|
||||||
"data": null,
|
|
||||||
"id": "<sequential number starting from 1 for each signal received>"
|
|
||||||
}
|
|
||||||
|
|
||||||
If ``status`` is set to ``FAILURE`` then the resource (and the stack) will go
|
|
||||||
into a ``FAILED`` state using the ``reason`` as failure reason.
|
|
||||||
|
|
||||||
The following template example uses the convenience attribute ``curl_cli``
|
|
||||||
which builds a curl command with a valid token:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
wait_condition:
|
|
||||||
type: OS::Heat::WaitCondition
|
|
||||||
properties:
|
|
||||||
handle: {get_resource: wait_handle}
|
|
||||||
# Note, count of 5 vs 6 is due to duplicate signal ID 5 sent below
|
|
||||||
count: 5
|
|
||||||
timeout: 300
|
|
||||||
|
|
||||||
wait_handle:
|
|
||||||
type: OS::Heat::WaitConditionHandle
|
|
||||||
|
|
||||||
the_server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
# flavor, image etc
|
|
||||||
user_data_format: RAW
|
|
||||||
user_data:
|
|
||||||
str_replace:
|
|
||||||
template: |
|
|
||||||
#!/bin/sh
|
|
||||||
# Below are some examples of the various ways signals
|
|
||||||
# can be sent to the Handle resource
|
|
||||||
|
|
||||||
# Simple success signal
|
|
||||||
wc_notify --data-binary '{"status": "SUCCESS"}'
|
|
||||||
|
|
||||||
# Or you optionally can specify any of the additional fields
|
|
||||||
wc_notify --data-binary '{"status": "SUCCESS", "reason": "signal2"}'
|
|
||||||
wc_notify --data-binary '{"status": "SUCCESS", "reason": "signal3", "data": "data3"}'
|
|
||||||
wc_notify --data-binary '{"status": "SUCCESS", "reason": "signal4", "data": "data4"}'
|
|
||||||
|
|
||||||
# If you require control of the ID, you can pass it.
|
|
||||||
# The ID should be unique, unless you intend for duplicate
|
|
||||||
# signals to overwrite each other. The following two calls
|
|
||||||
# do the exact same thing, and will be treated as one signal
|
|
||||||
# (You can prove this by changing count above to 7)
|
|
||||||
wc_notify --data-binary '{"status": "SUCCESS", "id": "5"}'
|
|
||||||
wc_notify --data-binary '{"status": "SUCCESS", "id": "5"}'
|
|
||||||
|
|
||||||
# Example of sending a failure signal, optionally
|
|
||||||
# reason, id, and data can be specified as above
|
|
||||||
# wc_notify --data-binary '{"status": "FAILURE"}'
|
|
||||||
params:
|
|
||||||
wc_notify: { get_attr: [wait_handle, curl_cli] }
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
wc_data:
|
|
||||||
value: { get_attr: [wait_condition, data] }
|
|
||||||
# this would return the following json
|
|
||||||
# {"1": null, "2": null, "3": "data3", "4": "data4", "5": null}
|
|
||||||
|
|
||||||
wc_data_4:
|
|
||||||
value: { get_attr: [wait_condition, data, '4'] }
|
|
||||||
# this would return "data4"
|
|
||||||
|
|
||||||
..
|
|
||||||
|
|
||||||
:hotref:`OS::Heat::SwiftSignal` is implemented by creating an Object Storage
|
|
||||||
API temporary URL which is populated with signal data with an HTTP PUT. The
|
|
||||||
orchestration service will poll this object until the signal data is available.
|
|
||||||
Object versioning is used to store multiple signals.
|
|
||||||
|
|
||||||
Sending the signal is a simple HTTP request, as with this example using curl_:
|
|
||||||
|
|
||||||
.. code-block:: sh
|
|
||||||
|
|
||||||
curl -i -X PUT '<object URL>' --data-binary '<json containing signal data>'
|
|
||||||
|
|
||||||
The above template example only needs to have the ``type`` changed to the
|
|
||||||
swift signal resources:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
signal:
|
|
||||||
type: OS::Heat::SwiftSignal
|
|
||||||
properties:
|
|
||||||
handle: {get_resource: wait_handle}
|
|
||||||
timeout: 300
|
|
||||||
|
|
||||||
signal_handle:
|
|
||||||
type: OS::Heat::SwiftSignalHandle
|
|
||||||
# ...
|
|
||||||
|
|
||||||
The decision to use :hotref:`OS::Heat::WaitCondition` or
|
|
||||||
:hotref:`OS::Heat::SwiftSignal` will depend on a few factors:
|
|
||||||
|
|
||||||
* :hotref:`OS::Heat::SwiftSignal` depends on the availability of an Object
|
|
||||||
Storage API
|
|
||||||
|
|
||||||
* :hotref:`OS::Heat::WaitCondition` depends on whether the orchestration
|
|
||||||
service has been configured with a dedicated stack domain (which may depend
|
|
||||||
on the availability of an Identity V3 API).
|
|
||||||
|
|
||||||
* The preference to protect signal URLs with token authentication or a
|
|
||||||
secret webhook URL.
|
|
||||||
|
|
||||||
|
|
||||||
Software config resources
|
|
||||||
-------------------------
|
|
||||||
Boot configuration scripts can also be managed as their own resources. This
|
|
||||||
allows configuration to be defined once and run on multiple server resources.
|
|
||||||
These software-config resources are stored and retrieved via dedicated calls
|
|
||||||
to the `Orchestration API`_. It is not possible to modify the contents of an
|
|
||||||
existing software-config resource, so a stack-update which changes any
|
|
||||||
existing software-config resource will result in API calls to create a new
|
|
||||||
config and delete the old one.
|
|
||||||
|
|
||||||
The resource :hotref:`OS::Heat::SoftwareConfig` is used for storing configs
|
|
||||||
represented by text scripts, for example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
boot_script:
|
|
||||||
type: OS::Heat::SoftwareConfig
|
|
||||||
properties:
|
|
||||||
group: ungrouped
|
|
||||||
config: |
|
|
||||||
#!/bin/bash
|
|
||||||
echo "Running boot script"
|
|
||||||
# ...
|
|
||||||
|
|
||||||
server_with_boot_script:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
# flavor, image etc
|
|
||||||
user_data_format: RAW
|
|
||||||
user_data: {get_resource: boot_script}
|
|
||||||
|
|
||||||
The resource :hotref:`OS::Heat::CloudConfig` allows Cloud-init_ cloud-config to
|
|
||||||
be represented as template YAML rather than a block string. This allows
|
|
||||||
intrinsic functions to be included when building the cloud-config. This also
|
|
||||||
ensures that the cloud-config is valid YAML, although no further checks for
|
|
||||||
valid cloud-config are done.
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
file_content:
|
|
||||||
type: string
|
|
||||||
description: The contents of the file /tmp/file
|
|
||||||
|
|
||||||
resources:
|
|
||||||
boot_config:
|
|
||||||
type: OS::Heat::CloudConfig
|
|
||||||
properties:
|
|
||||||
cloud_config:
|
|
||||||
write_files:
|
|
||||||
- path: /tmp/file
|
|
||||||
content: {get_param: file_content}
|
|
||||||
|
|
||||||
server_with_cloud_config:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
# flavor, image etc
|
|
||||||
user_data_format: RAW
|
|
||||||
user_data: {get_resource: boot_config}
|
|
||||||
|
|
||||||
The resource :hotref:`OS::Heat::MultipartMime` allows multiple
|
|
||||||
:hotref:`OS::Heat::SoftwareConfig` and :hotref:`OS::Heat::CloudConfig`
|
|
||||||
resources to be combined into a single Cloud-init_ multi-part message:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
file_content:
|
|
||||||
type: string
|
|
||||||
description: The contents of the file /tmp/file
|
|
||||||
|
|
||||||
other_config:
|
|
||||||
type: string
|
|
||||||
description: The ID of a software-config resource created elsewhere
|
|
||||||
|
|
||||||
resources:
|
|
||||||
boot_config:
|
|
||||||
type: OS::Heat::CloudConfig
|
|
||||||
properties:
|
|
||||||
cloud_config:
|
|
||||||
write_files:
|
|
||||||
- path: /tmp/file
|
|
||||||
content: {get_param: file_content}
|
|
||||||
|
|
||||||
boot_script:
|
|
||||||
type: OS::Heat::SoftwareConfig
|
|
||||||
properties:
|
|
||||||
group: ungrouped
|
|
||||||
config: |
|
|
||||||
#!/bin/bash
|
|
||||||
echo "Running boot script"
|
|
||||||
# ...
|
|
||||||
|
|
||||||
server_init:
|
|
||||||
type: OS::Heat::MultipartMime
|
|
||||||
properties:
|
|
||||||
parts:
|
|
||||||
- config: {get_resource: boot_config}
|
|
||||||
- config: {get_resource: boot_script}
|
|
||||||
- config: {get_resource: other_config}
|
|
||||||
|
|
||||||
server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
# flavor, image etc
|
|
||||||
user_data_format: RAW
|
|
||||||
user_data: {get_resource: server_init}
|
|
||||||
|
|
||||||
|
|
||||||
Software deployment resources
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
There are many situations where it is not desirable to replace the server
|
|
||||||
whenever there is a configuration change. The
|
|
||||||
:hotref:`OS::Heat::SoftwareDeployment` resource allows any number of software
|
|
||||||
configurations to be added or removed from a server throughout its life-cycle.
|
|
||||||
|
|
||||||
Building custom image for software deployments
|
|
||||||
----------------------------------------------
|
|
||||||
:hotref:`OS::Heat::SoftwareConfig` resources are used to store software
|
|
||||||
configuration, and a :hotref:`OS::Heat::SoftwareDeployment` resource is used
|
|
||||||
to associate a config resource with one server. The ``group`` attribute on
|
|
||||||
:hotref:`OS::Heat::SoftwareConfig` specifies what tool will consume the
|
|
||||||
config content.
|
|
||||||
|
|
||||||
:hotref:`OS::Heat::SoftwareConfig` has the ability to define a schema of
|
|
||||||
``inputs`` and which the configuration script supports. Inputs are mapped to
|
|
||||||
whatever concept the configuration tool has for assigning
|
|
||||||
variables/parameters.
|
|
||||||
|
|
||||||
Likewise, ``outputs`` are mapped to the tool's capability to export structured
|
|
||||||
data after configuration execution. For tools which do not support this,
|
|
||||||
outputs can always be written to a known file path for the hook to read.
|
|
||||||
|
|
||||||
The :hotref:`OS::Heat::SoftwareDeployment` resource allows values to be
|
|
||||||
assigned to the config inputs, and the resource remains in an ``IN_PROGRESS``
|
|
||||||
state until the server signals to heat what (if any) output values were
|
|
||||||
generated by the config script.
|
|
||||||
|
|
||||||
Custom image script
|
|
||||||
-------------------
|
|
||||||
Each of the following examples requires that the servers be booted with a
|
|
||||||
custom image. The following script uses diskimage-builder to create an image
|
|
||||||
required in later examples:
|
|
||||||
|
|
||||||
.. code-block:: sh
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
# Clone the required repositories. Some of these are also available
|
|
||||||
# via pypi or as distro packages.
|
|
||||||
git clone https://git.openstack.org/openstack/diskimage-builder.git
|
|
||||||
git clone https://git.openstack.org/openstack/tripleo-image-elements.git
|
|
||||||
git clone https://git.openstack.org/openstack/heat-templates.git
|
|
||||||
|
|
||||||
# Required by diskimage-builder to discover element collections
|
|
||||||
export ELEMENTS_PATH=tripleo-image-elements/elements:heat-templates/hot/software-config/elements
|
|
||||||
|
|
||||||
# The base operating system element(s) provided by the diskimage-builder
|
|
||||||
# elements collection. Other values which may work include:
|
|
||||||
# centos7, debian, opensuse, rhel, rhel7, or ubuntu
|
|
||||||
export BASE_ELEMENTS="fedora selinux-permissive"
|
|
||||||
# Install and configure the os-collect-config agent to poll the heat service
|
|
||||||
# for configuration changes to execute
|
|
||||||
export AGENT_ELEMENTS="os-collect-config os-refresh-config os-apply-config"
|
|
||||||
|
|
||||||
|
|
||||||
# heat-config installs an os-refresh-config script which will invoke the
|
|
||||||
# appropriate hook to perform configuration. The element heat-config-script
|
|
||||||
# installs a hook to perform configuration with shell scripts
|
|
||||||
export DEPLOYMENT_BASE_ELEMENTS="heat-config heat-config-script"
|
|
||||||
|
|
||||||
# Install a hook for any other chosen configuration tool(s).
|
|
||||||
# Elements which install hooks include:
|
|
||||||
# heat-config-cfn-init, heat-config-puppet, or heat-config-salt
|
|
||||||
export DEPLOYMENT_TOOL=""
|
|
||||||
|
|
||||||
# The name of the qcow2 image to create, and the name of the image
|
|
||||||
# uploaded to the OpenStack image registry.
|
|
||||||
export IMAGE_NAME=fedora-software-config
|
|
||||||
|
|
||||||
# Create the image
|
|
||||||
diskimage-builder/bin/disk-image-create vm $BASE_ELEMENTS $AGENT_ELEMENTS \
|
|
||||||
$DEPLOYMENT_BASE_ELEMENTS $DEPLOYMENT_TOOL -o $IMAGE_NAME.qcow2
|
|
||||||
|
|
||||||
# Upload the image, assuming valid credentials are already sourced
|
|
||||||
glance image-create --disk-format qcow2 --container-format bare \
|
|
||||||
--name $IMAGE_NAME < $IMAGE_NAME.qcow2
|
|
||||||
|
|
||||||
|
|
||||||
Configuring with scripts
|
|
||||||
------------------------
|
|
||||||
The `Custom image script`_ already includes the ``heat-config-script`` element
|
|
||||||
so the built image will already have the ability to configure using shell
|
|
||||||
scripts.
|
|
||||||
|
|
||||||
Config inputs are mapped to shell environment variables. The script
|
|
||||||
can communicate outputs to heat by writing to the
|
|
||||||
:file:`$heat_outputs_path.{output name}` file. See the following
|
|
||||||
example for a script which expects inputs ``foo``, ``bar`` and
|
|
||||||
generates an output ``result``.
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
config:
|
|
||||||
type: OS::Heat::SoftwareConfig
|
|
||||||
properties:
|
|
||||||
group: script
|
|
||||||
inputs:
|
|
||||||
- name: foo
|
|
||||||
- name: bar
|
|
||||||
outputs:
|
|
||||||
- name: result
|
|
||||||
config: |
|
|
||||||
#!/bin/sh -x
|
|
||||||
echo "Writing to /tmp/$bar"
|
|
||||||
echo $foo > /tmp/$bar
|
|
||||||
echo -n "The file /tmp/$bar contains `cat /tmp/$bar` for server $deploy_server_id during $deploy_action" > $heat_outputs_path.result
|
|
||||||
echo "Written to /tmp/$bar"
|
|
||||||
echo "Output to stderr" 1>&2
|
|
||||||
|
|
||||||
deployment:
|
|
||||||
type: OS::Heat::SoftwareDeployment
|
|
||||||
properties:
|
|
||||||
config:
|
|
||||||
get_resource: config
|
|
||||||
server:
|
|
||||||
get_resource: server
|
|
||||||
input_values:
|
|
||||||
foo: fooooo
|
|
||||||
bar: baaaaa
|
|
||||||
|
|
||||||
server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
# flavor, image etc
|
|
||||||
user_data_format: SOFTWARE_CONFIG
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
result:
|
|
||||||
value:
|
|
||||||
get_attr: [deployment, result]
|
|
||||||
stdout:
|
|
||||||
value:
|
|
||||||
get_attr: [deployment, deploy_stdout]
|
|
||||||
stderr:
|
|
||||||
value:
|
|
||||||
get_attr: [deployment, deploy_stderr]
|
|
||||||
status_code:
|
|
||||||
value:
|
|
||||||
get_attr: [deployment, deploy_status_code]
|
|
||||||
|
|
||||||
.. note:: A config resource can be associated with multiple deployment
|
|
||||||
resources, and each deployment can specify the same or different values
|
|
||||||
for the ``server`` and ``input_values`` properties.
|
|
||||||
|
|
||||||
As can be seen in the ``outputs`` section of the above template, the
|
|
||||||
``result`` config output value is available as an attribute on the
|
|
||||||
``deployment`` resource. Likewise the captured stdout, stderr and status_code
|
|
||||||
are also available as attributes.
|
|
||||||
|
|
||||||
Configuring with os-apply-config
|
|
||||||
--------------------------------
|
|
||||||
The agent toolchain of ``os-collect-config``, ``os-refresh-config`` and
|
|
||||||
``os-apply-config`` can actually be used on their own to inject heat stack
|
|
||||||
configuration data into a server running a custom image.
|
|
||||||
|
|
||||||
The custom image needs to have the following to use this approach:
|
|
||||||
|
|
||||||
* All software dependencies installed
|
|
||||||
|
|
||||||
* os-refresh-config_ scripts to be executed on configuration changes
|
|
||||||
|
|
||||||
* os-apply-config_ templates to transform the heat-provided config data into
|
|
||||||
service configuration files
|
|
||||||
|
|
||||||
The projects tripleo-image-elements_ and tripleo-heat-templates_ demonstrate
|
|
||||||
this approach.
|
|
||||||
|
|
||||||
Configuring with cfn-init
|
|
||||||
-------------------------
|
|
||||||
Likely the only reason to use the ``cfn-init`` hook is to migrate templates
|
|
||||||
which contain `AWS::CloudFormation::Init`_ metadata without needing a
|
|
||||||
complete rewrite of the config metadata. It is included here as it introduces
|
|
||||||
a number of new concepts.
|
|
||||||
|
|
||||||
To use the ``cfn-init`` tool the ``heat-config-cfn-init`` element is required
|
|
||||||
to be on the built image, so `Custom image script`_ needs to be modified with
|
|
||||||
the following:
|
|
||||||
|
|
||||||
.. code-block:: sh
|
|
||||||
|
|
||||||
export DEPLOYMENT_TOOL="heat-config-cfn-init"
|
|
||||||
|
|
||||||
Configuration data which used to be included in the
|
|
||||||
``AWS::CloudFormation::Init`` section of resource metadata is instead moved
|
|
||||||
to the ``config`` property of the config resource, as in the following
|
|
||||||
example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
|
|
||||||
config:
|
|
||||||
type: OS::Heat::StructuredConfig
|
|
||||||
properties:
|
|
||||||
group: cfn-init
|
|
||||||
inputs:
|
|
||||||
- name: bar
|
|
||||||
config:
|
|
||||||
config:
|
|
||||||
files:
|
|
||||||
/tmp/foo:
|
|
||||||
content:
|
|
||||||
get_input: bar
|
|
||||||
mode: '000644'
|
|
||||||
|
|
||||||
deployment:
|
|
||||||
type: OS::Heat::StructuredDeployment
|
|
||||||
properties:
|
|
||||||
name: 10_deployment
|
|
||||||
signal_transport: NO_SIGNAL
|
|
||||||
config:
|
|
||||||
get_resource: config
|
|
||||||
server:
|
|
||||||
get_resource: server
|
|
||||||
input_values:
|
|
||||||
bar: baaaaa
|
|
||||||
|
|
||||||
other_deployment:
|
|
||||||
type: OS::Heat::StructuredDeployment
|
|
||||||
properties:
|
|
||||||
name: 20_other_deployment
|
|
||||||
signal_transport: NO_SIGNAL
|
|
||||||
config:
|
|
||||||
get_resource: config
|
|
||||||
server:
|
|
||||||
get_resource: server
|
|
||||||
input_values:
|
|
||||||
bar: barmy
|
|
||||||
|
|
||||||
server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
image: {get_param: image}
|
|
||||||
flavor: {get_param: flavor}
|
|
||||||
key_name: {get_param: key_name}
|
|
||||||
user_data_format: SOFTWARE_CONFIG
|
|
||||||
|
|
||||||
There are a number of things to note about this template example:
|
|
||||||
|
|
||||||
* :hotref:`OS::Heat::StructuredConfig` is like
|
|
||||||
:hotref:`OS::Heat::SoftwareConfig` except that the ``config`` property
|
|
||||||
contains structured YAML instead of text script. This is useful for a
|
|
||||||
number of other configuration tools including ansible, salt and
|
|
||||||
os-apply-config.
|
|
||||||
|
|
||||||
* ``cfn-init`` has no concept of inputs, so ``{get_input: bar}`` acts as a
|
|
||||||
placeholder which gets replaced with the
|
|
||||||
:hotref:`OS::Heat::StructuredDeployment` ``input_values`` value when the
|
|
||||||
deployment resource is created.
|
|
||||||
|
|
||||||
* ``cfn-init`` has no concept of outputs, so specifying
|
|
||||||
``signal_transport: NO_SIGNAL`` will mean that the deployment resource will
|
|
||||||
immediately go into the ``CREATED`` state instead of waiting for a
|
|
||||||
completed signal from the server.
|
|
||||||
|
|
||||||
* The template has 2 deployment resources deploying the same config with
|
|
||||||
different ``input_values``. The order these are deployed in on the server
|
|
||||||
is determined by sorting the values of the ``name`` property for each
|
|
||||||
resource (10_deployment, 20_other_deployment)
|
|
||||||
|
|
||||||
Configuring with puppet
|
|
||||||
-----------------------
|
|
||||||
The puppet_ hook makes it possible to write configuration as puppet manifests
|
|
||||||
which are deployed and run in a masterless environment.
|
|
||||||
|
|
||||||
To specify configuration as puppet manifests the ``heat-config-puppet``
|
|
||||||
element is required to be on the built image, so `Custom image script`_ needs
|
|
||||||
to be modified with the following:
|
|
||||||
|
|
||||||
|
|
||||||
.. code-block:: sh
|
|
||||||
|
|
||||||
export DEPLOYMENT_TOOL="heat-config-puppet"
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
|
|
||||||
config:
|
|
||||||
type: OS::Heat::SoftwareConfig
|
|
||||||
properties:
|
|
||||||
group: puppet
|
|
||||||
inputs:
|
|
||||||
- name: foo
|
|
||||||
- name: bar
|
|
||||||
outputs:
|
|
||||||
- name: result
|
|
||||||
config:
|
|
||||||
get_file: example-puppet-manifest.pp
|
|
||||||
|
|
||||||
deployment:
|
|
||||||
type: OS::Heat::SoftwareDeployment
|
|
||||||
properties:
|
|
||||||
config:
|
|
||||||
get_resource: config
|
|
||||||
server:
|
|
||||||
get_resource: server
|
|
||||||
input_values:
|
|
||||||
foo: fooooo
|
|
||||||
bar: baaaaa
|
|
||||||
|
|
||||||
server:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
image: {get_param: image}
|
|
||||||
flavor: {get_param: flavor}
|
|
||||||
key_name: {get_param: key_name}
|
|
||||||
user_data_format: SOFTWARE_CONFIG
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
result:
|
|
||||||
value:
|
|
||||||
get_attr: [deployment, result]
|
|
||||||
stdout:
|
|
||||||
value:
|
|
||||||
get_attr: [deployment, deploy_stdout]
|
|
||||||
|
|
||||||
This demonstrates the use of the ``get_file`` function, which will attach the
|
|
||||||
contents of the file ``example-puppet-manifest.pp``, containing:
|
|
||||||
|
|
||||||
.. code-block:: puppet
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
file { 'barfile':
|
|
||||||
ensure => file,
|
|
||||||
mode => '0644',
|
|
||||||
path => '/tmp/$::bar',
|
|
||||||
content => '$::foo',
|
|
||||||
}
|
|
||||||
|
|
||||||
file { 'output_result':
|
|
||||||
ensure => file,
|
|
||||||
path => '$::heat_outputs_path.result',
|
|
||||||
mode => '0644',
|
|
||||||
content => 'The file /tmp/$::bar contains $::foo',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _`AWS::CloudFormation::Init`: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html
|
|
||||||
.. _diskimage-builder: https://github.com/openstack/diskimage-builder
|
|
||||||
.. _imagefactory: http://imgfac.org/
|
|
||||||
.. _`Metadata service`: http://docs.openstack.org/admin-guide-cloud/content/section_metadata-service.html
|
|
||||||
.. _Cloud-init: http://cloudinit.readthedocs.org/en/latest/
|
|
||||||
.. _curl: http://curl.haxx.se/
|
|
||||||
.. _`Orchestration API`: http://developer.openstack.org/api-ref-orchestration-v1.html
|
|
||||||
.. _os-refresh-config: https://github.com/openstack/os-refresh-config
|
|
||||||
.. _os-apply-config: https://github.com/openstack/os-apply-config
|
|
||||||
.. _tripleo-heat-templates: https://github.com/openstack/tripleo-heat-templates
|
|
||||||
.. _tripleo-image-elements: https://github.com/openstack/tripleo-image-elements
|
|
||||||
.. _puppet: https://puppetlabs.com/
|
|
@ -1,878 +0,0 @@
|
|||||||
.. highlight: yaml
|
|
||||||
:linenothreshold: 5
|
|
||||||
|
|
||||||
..
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
||||||
not use this file except in compliance with the License. You may obtain
|
|
||||||
a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
License for the specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
.. _hot_spec:
|
|
||||||
|
|
||||||
===============================================
|
|
||||||
Heat Orchestration Template (HOT) specification
|
|
||||||
===============================================
|
|
||||||
|
|
||||||
Template structure
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
HOT templates are defined in YAML and use the following structure:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
heat_template_version: 2013-05-23
|
|
||||||
|
|
||||||
description:
|
|
||||||
# description of the template
|
|
||||||
|
|
||||||
parameter_groups:
|
|
||||||
# declaration of input parameter groups and order
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
# declaration of input parameters
|
|
||||||
|
|
||||||
resources:
|
|
||||||
# declaration of template resources
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
# declaration of output parameters
|
|
||||||
|
|
||||||
heat_template_version
|
|
||||||
This key with value ``2013-05-23`` (or a later date) indicates that the
|
|
||||||
YAML document is a HOT template of the specified version.
|
|
||||||
|
|
||||||
description
|
|
||||||
This optional key gives a description of the template, or
|
|
||||||
the workload that can be deployed using the template.
|
|
||||||
|
|
||||||
parameter_groups
|
|
||||||
This section specifies how the input parameters should be
|
|
||||||
grouped and the order to provide the parameters in.
|
|
||||||
This section is optional.
|
|
||||||
|
|
||||||
parameters
|
|
||||||
This section specifies input parameters that have to
|
|
||||||
be provided when instantiating the template.
|
|
||||||
This section is optional.
|
|
||||||
|
|
||||||
resources
|
|
||||||
This section contains the declaration of the resources of the template.
|
|
||||||
This section with at least one resource must be defined in any HOT
|
|
||||||
template, or the template would not really do anything when being
|
|
||||||
instantiated.
|
|
||||||
|
|
||||||
outputs
|
|
||||||
This section specifies output parameters available to users once the
|
|
||||||
template has been instantiated.
|
|
||||||
This section is optional.
|
|
||||||
|
|
||||||
.. _hot_spec_parameter_groups:
|
|
||||||
|
|
||||||
Parameter groups section
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
The ``parameter_groups`` section specifies how the input parameters should be
|
|
||||||
grouped and the order to provide the parameters in. These groups are typically
|
|
||||||
used to describe expected behavior for downstream user interfaces.
|
|
||||||
|
|
||||||
These groups are specified in a list with each group containing a list of
|
|
||||||
associated parameters. The lists are used to denote the expected order of the
|
|
||||||
parameters. A parameter can only be included in one group. Use the name of the
|
|
||||||
parameter to add it to a group. The parameters details are defined in
|
|
||||||
the ``parameters`` section.
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameter_groups:
|
|
||||||
- label: <human-readable label of parameter group>
|
|
||||||
description: <description of the parameter group>
|
|
||||||
parameters:
|
|
||||||
- <param name>
|
|
||||||
- <param name>
|
|
||||||
|
|
||||||
label
|
|
||||||
A human-readable label that defines the associated group of parameters.
|
|
||||||
|
|
||||||
description
|
|
||||||
A human-readable description of the parameter group.
|
|
||||||
|
|
||||||
parameters
|
|
||||||
A list of parameters that belong with this parameter group.
|
|
||||||
|
|
||||||
param name
|
|
||||||
The name of a parameter defined in the ``parameters`` section.
|
|
||||||
|
|
||||||
|
|
||||||
.. _hot_spec_parameters:
|
|
||||||
|
|
||||||
Parameters section
|
|
||||||
~~~~~~~~~~~~~~~~~~
|
|
||||||
The ``parameters`` section defines input parameters that have to be
|
|
||||||
provided when instantiating the template. Such parameters are typically used to
|
|
||||||
customize each deployment, or for binding to environment specifics like certain
|
|
||||||
images.
|
|
||||||
|
|
||||||
Each parameter is specified in a separated nested block with the name of the
|
|
||||||
parameter defined in the first line and additional attributes such as a type or
|
|
||||||
a default value defined as nested elements:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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>
|
|
||||||
|
|
||||||
param name
|
|
||||||
The name of the parameter.
|
|
||||||
|
|
||||||
type
|
|
||||||
The type of the parameter. Supported types
|
|
||||||
are ``string``, ``number``, ``comma_delimited_list``, ``json`` and
|
|
||||||
``boolean``.
|
|
||||||
This attribute is required.
|
|
||||||
|
|
||||||
label
|
|
||||||
A human readable name for the parameter.
|
|
||||||
This attribute is optional.
|
|
||||||
|
|
||||||
description
|
|
||||||
A human readable description for the parameter.
|
|
||||||
This attribute is optional.
|
|
||||||
|
|
||||||
default
|
|
||||||
A default value for the parameter. This value is used if the user doesn't
|
|
||||||
specify his own value during deployment.
|
|
||||||
This attribute is optional.
|
|
||||||
|
|
||||||
hidden
|
|
||||||
Defines whether the parameters should be hidden when a user requests
|
|
||||||
information about a stack created from the template. This attribute can be
|
|
||||||
used to hide passwords specified as parameters.
|
|
||||||
|
|
||||||
This attribute is optional and defaults to ``false``.
|
|
||||||
|
|
||||||
constraints
|
|
||||||
A list of constraints to apply. The constraints are validated by the
|
|
||||||
Orchestration engine when a user deploys a stack. The stack creation fails
|
|
||||||
if the parameter value doesn't comply to the constraints.
|
|
||||||
This attribute is optional.
|
|
||||||
|
|
||||||
The following example shows a minimalistic definition of two parameters:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
The description and the label are optional, but defining these attributes
|
|
||||||
is good practice to provide useful information about the role of the
|
|
||||||
parameter to the user.
|
|
||||||
|
|
||||||
.. _hot_spec_parameters_constraints:
|
|
||||||
|
|
||||||
Parameter constraints
|
|
||||||
---------------------
|
|
||||||
The ``constraints`` block of a parameter definition defines
|
|
||||||
additional validation constraints that apply to the value of the
|
|
||||||
parameter. The parameter values provided by a user are validated against the
|
|
||||||
constraints at instantiation time. The constraints are defined as a list with
|
|
||||||
the following syntax:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
constraints:
|
|
||||||
- <constraint type>: <constraint definition>
|
|
||||||
description: <constraint description>
|
|
||||||
|
|
||||||
constraint type
|
|
||||||
Type of constraint to apply. The set of currently supported constraints is
|
|
||||||
given below.
|
|
||||||
|
|
||||||
constraint definition
|
|
||||||
The actual constraint, depending on the constraint type. The
|
|
||||||
concrete syntax for each constraint type is given below.
|
|
||||||
|
|
||||||
description
|
|
||||||
A description of the constraint. The text
|
|
||||||
is presented to the user when the value he defines violates the constraint.
|
|
||||||
If omitted, a default validation message is presented to the user.
|
|
||||||
This attribute is optional.
|
|
||||||
|
|
||||||
The following example shows the definition of a string parameter with two
|
|
||||||
constraints. Note that while the descriptions for each constraint are optional,
|
|
||||||
it is good practice to provide concrete descriptions to present useful messages
|
|
||||||
to the user at deployment time.
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
While the descriptions for each constraint are optional, it is good practice
|
|
||||||
to provide concrete descriptions so useful messages can be presented to the
|
|
||||||
user at deployment time.
|
|
||||||
|
|
||||||
The following sections list the supported types of parameter constraints, along
|
|
||||||
with the syntax for each type.
|
|
||||||
|
|
||||||
length
|
|
||||||
++++++
|
|
||||||
|
|
||||||
The :code:`length` constraint applies to parameters of type
|
|
||||||
``string``. It defines a lower and upper limit for the length of the
|
|
||||||
string value.
|
|
||||||
|
|
||||||
The syntax of the :code:`length` constraint is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
length: { min: <lower limit>, max: <upper limit> }
|
|
||||||
|
|
||||||
It is possible to define a length constraint with only a lower limit or an
|
|
||||||
upper limit. However, at least one of ``min`` or ``max`` must be specified.
|
|
||||||
|
|
||||||
range
|
|
||||||
+++++
|
|
||||||
|
|
||||||
The :code:`range` constraint applies to parameters of type ``number``.
|
|
||||||
It defines a lower and upper limit for the numeric value of the
|
|
||||||
parameter.
|
|
||||||
|
|
||||||
The syntax of the :code:`range` constraint is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
range: { min: <lower limit>, max: <upper limit> }
|
|
||||||
|
|
||||||
It is possible to define a range constraint with only a lower limit or an
|
|
||||||
upper limit. However, at least one of ``min`` or ``max`` must be specified.
|
|
||||||
|
|
||||||
The minimum and maximum boundaries are included in the range. For example, the
|
|
||||||
following range constraint would allow for all numeric values between 0 and 10:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
range: { min: 0, max: 10 }
|
|
||||||
|
|
||||||
allowed_values
|
|
||||||
++++++++++++++
|
|
||||||
|
|
||||||
The :code:`allowed_values` constraint applies to parameters of type
|
|
||||||
``string`` or ``number``. It specifies a set of possible values for a
|
|
||||||
parameter. At deployment time, the user-provided value for the
|
|
||||||
respective parameter must match one of the elements of the list.
|
|
||||||
|
|
||||||
The syntax of the :code:`allowed_values` constraint is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
allowed_values: [ <value>, <value>, ... ]
|
|
||||||
|
|
||||||
Alternatively, the following YAML list notation can be used:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
allowed_values:
|
|
||||||
- <value>
|
|
||||||
- <value>
|
|
||||||
- ...
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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
|
|
||||||
+++++++++++++++
|
|
||||||
|
|
||||||
The :code:`allowed_pattern` constraint applies to parameters of type
|
|
||||||
``string``. It specifies a regular expression against which a
|
|
||||||
user-provided parameter value must evaluate at deployment.
|
|
||||||
|
|
||||||
The syntax of the :code:`allowed_pattern` constraint is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
allowed_pattern: <regular expression>
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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
|
|
||||||
+++++++++++++++++
|
|
||||||
The :code:`custom_constraint`` constraint adds an extra step of validation,
|
|
||||||
generally to check that the specified resource exists in the backend. Custom
|
|
||||||
constraints get implemented by plug-ins and can provide any kind of advanced
|
|
||||||
constraint validation logic.
|
|
||||||
|
|
||||||
The syntax of the :code:`custom_constraint` constraint is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
custom_constraint: <name>
|
|
||||||
|
|
||||||
The ``name`` attribute specifies the concrete type of custom constraint. It
|
|
||||||
corresponds to the name under which the respective validation plugin has been
|
|
||||||
registered in the Orchestration engine.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
parameters:
|
|
||||||
key_name
|
|
||||||
type: string
|
|
||||||
description: SSH key pair
|
|
||||||
constraints:
|
|
||||||
- custom_constraint: nova.keypair
|
|
||||||
|
|
||||||
.. _hot_spec_pseudo_parameters:
|
|
||||||
|
|
||||||
Pseudo Parameters
|
|
||||||
-----------------
|
|
||||||
In addition to parameters defined by a template author, the Orchestration
|
|
||||||
module also creates two parameters for every stack that allow referential
|
|
||||||
access to the stack's name and identifier. These parameters are named
|
|
||||||
``OS::stack_name`` for the stack name and ``OS::stack_id`` for the stack
|
|
||||||
identifier. These values are accessible via the :code:`get_param` intrinsic
|
|
||||||
function, just like user-defined parameters.
|
|
||||||
|
|
||||||
.. _hot_spec_resources:
|
|
||||||
|
|
||||||
Resources section
|
|
||||||
~~~~~~~~~~~~~~~~~
|
|
||||||
The ``resources`` section defines actual resources that make up a stack
|
|
||||||
deployed from the HOT template (for instance compute instances, networks,
|
|
||||||
storage volumes).
|
|
||||||
|
|
||||||
Each resource is defined as a separate block in the ``resources`` section with
|
|
||||||
the following syntax:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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>
|
|
||||||
|
|
||||||
resource ID
|
|
||||||
A resource ID which must be unique within the ``resources`` section of the
|
|
||||||
template.
|
|
||||||
|
|
||||||
type
|
|
||||||
The resource type, such as ``OS::Nova::Server`` or ``OS::Neutron::Port``.
|
|
||||||
This attribute is required.
|
|
||||||
|
|
||||||
properties
|
|
||||||
A list of resource-specific properties. The property value can be provided
|
|
||||||
in place, or via a function (see :ref:`hot_spec_intrinsic_functions`).
|
|
||||||
This section is optional.
|
|
||||||
|
|
||||||
metadata
|
|
||||||
Resource-specific metadata.
|
|
||||||
This section is optional.
|
|
||||||
|
|
||||||
depends_on
|
|
||||||
Dependencies of the resource on one or more resources of the template.
|
|
||||||
See :ref:`hot_spec_resources_dependencies` for details.
|
|
||||||
This attribute is optional.
|
|
||||||
|
|
||||||
update_policy
|
|
||||||
Update policy for the resource, in the form of a nested dictionary. Whether
|
|
||||||
update policies are supported and what the exact semantics are depends on
|
|
||||||
the type of the current resource.
|
|
||||||
This attribute is optional.
|
|
||||||
|
|
||||||
deletion_policy
|
|
||||||
Deletion policy for the resource. Which type of deletion policy is
|
|
||||||
supported depends on the type of the current resource.
|
|
||||||
This attribute is optional.
|
|
||||||
|
|
||||||
Depending on the type of resource, the resource block might include more
|
|
||||||
resource specific data.
|
|
||||||
|
|
||||||
All resource types that can be used in CFN templates can also be used in HOT
|
|
||||||
templates, adapted to the YAML structure as outlined above.
|
|
||||||
|
|
||||||
The following example demonstrates the definition of a simple compute resource
|
|
||||||
with some fixed property values:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
my_instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
flavor: m1.small
|
|
||||||
image: F18-x86_64-cfntools
|
|
||||||
|
|
||||||
.. _hot_spec_resources_dependencies:
|
|
||||||
|
|
||||||
Resource dependencies
|
|
||||||
---------------------
|
|
||||||
The ``depends_on`` attribute of a resource defines a dependency between this
|
|
||||||
resource and one or more other resources.
|
|
||||||
|
|
||||||
If a resource depends on just one other resource, the ID of the other resource
|
|
||||||
is specified as string of the ``depends_on`` attribute, as shown in the
|
|
||||||
following example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
server1:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
depends_on: server2
|
|
||||||
|
|
||||||
server2:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
|
|
||||||
If a resource depends on more than one other resources, the value of the
|
|
||||||
``depends_on`` attribute is specified as a list of resource IDs, as shown in
|
|
||||||
the following example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
server1:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
depends_on: [ server2, server3 ]
|
|
||||||
|
|
||||||
server2:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
|
|
||||||
server3:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
|
|
||||||
|
|
||||||
.. _hot_spec_outputs:
|
|
||||||
|
|
||||||
Outputs section
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
The ``outputs`` section defines output parameters that should be available to
|
|
||||||
the user once a stack has been created. This would be, for example, parameters
|
|
||||||
such as IP addresses of deployed instances, or URLs of web applications
|
|
||||||
deployed as part of a stack.
|
|
||||||
|
|
||||||
Each output parameter is defined as a separate block within the outputs section
|
|
||||||
according to the following syntax:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
<parameter name>:
|
|
||||||
description: <description>
|
|
||||||
value: <parameter value>
|
|
||||||
|
|
||||||
parameter name
|
|
||||||
The output parameter name, which must be unique within the ``outputs``
|
|
||||||
section of a template.
|
|
||||||
|
|
||||||
description
|
|
||||||
A short description of the output parameter.
|
|
||||||
This attribute is optional.
|
|
||||||
|
|
||||||
parameter value
|
|
||||||
The value of the output parameter. This value is usually resolved by means
|
|
||||||
of a function. See :ref:`hot_spec_intrinsic_functions` for details about
|
|
||||||
the functions.
|
|
||||||
This attribute is required.
|
|
||||||
|
|
||||||
The example below shows how the IP address of a compute resource can
|
|
||||||
be defined as an output parameter:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
instance_ip:
|
|
||||||
description: IP address of the deployed compute instance
|
|
||||||
value: { get_attr: [my_instance, first_address] }
|
|
||||||
|
|
||||||
|
|
||||||
.. _hot_spec_intrinsic_functions:
|
|
||||||
|
|
||||||
Intrinsic functions
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
HOT provides a set of intrinsic functions that can be used inside templates
|
|
||||||
to perform specific tasks, such as getting the value of a resource attribute at
|
|
||||||
runtime. The following section describes the role and syntax of the intrinsic
|
|
||||||
functions.
|
|
||||||
|
|
||||||
get_attr
|
|
||||||
--------
|
|
||||||
The :code:`get_attr` function references an attribute of a
|
|
||||||
resource. The attribute value is resolved at runtime using the resource
|
|
||||||
instance created from the respective resource definition.
|
|
||||||
|
|
||||||
The syntax of the :code:`get_attr` function is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
get_attr:
|
|
||||||
- <resource ID>
|
|
||||||
- <attribute name>
|
|
||||||
- <key/index 1> (optional)
|
|
||||||
- <key/index 2> (optional)
|
|
||||||
- ...
|
|
||||||
|
|
||||||
resource ID
|
|
||||||
The resource ID for which the attribute needs to be resolved.
|
|
||||||
|
|
||||||
The resource ID must exist in the ``resources`` section of the template.
|
|
||||||
|
|
||||||
attribute name
|
|
||||||
The attribute name to be resolved. If the attribute returns a complex data
|
|
||||||
structure such as a list or a map, then subsequent keys or indexes can be
|
|
||||||
specified. These additional parameters are used to navigate the data
|
|
||||||
structure to return the desired value.
|
|
||||||
|
|
||||||
The following example demonstrates how to use the :code:`get_param` function:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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] }
|
|
||||||
|
|
||||||
In this example, if the networks attribute contained the following data:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
{"public": ["2001:0db8:0000:0000:0000:ff00:0042:8329", "1.2.3.4"],
|
|
||||||
"private": ["10.0.0.1"]}
|
|
||||||
|
|
||||||
then the value of :code:`the get_attr` function would resolve to ``10.0.0.1``
|
|
||||||
(first item of the ``private`` entry in the ``networks`` map).
|
|
||||||
|
|
||||||
get_file
|
|
||||||
--------
|
|
||||||
The :code:`get_file` function returns the content of a file into the template.
|
|
||||||
It is generally used as a file inclusion mechanism for files
|
|
||||||
containing scripts or configuration files.
|
|
||||||
|
|
||||||
The syntax of :code:`the get_file` function is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
get_file: <content key>
|
|
||||||
|
|
||||||
The ``content key`` is used to look up the ``files`` dictionary that is
|
|
||||||
provided in the REST API call. The Orchestration client command
|
|
||||||
(:command:`heat`) is :code:`get_file` aware and will populate the ``files``
|
|
||||||
dictionary with the actual content of fetched paths and URLs. The
|
|
||||||
Orchestration client command supports relative paths and will transform these
|
|
||||||
to the absolute URLs required by the Orchestration API.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
The :code:`get_file` argument must be a static path or URL and not rely on
|
|
||||||
intrinsic functions like :code:`get_param`. the Orchestration client does not
|
|
||||||
process intrinsic functions (they are only processed by the Orchestration
|
|
||||||
engine).
|
|
||||||
|
|
||||||
The example below demonstrates the :code:`get_file` function usage with both
|
|
||||||
relative and absolute URLs:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
The ``files`` dictionary generated by the Orchestration client during
|
|
||||||
instantiation of the stack would contain the following keys:
|
|
||||||
|
|
||||||
* :file:`file:///path/to/my_instance_user_data.sh`
|
|
||||||
* :file:`http://example.com/my_other_instance_user_data.sh`
|
|
||||||
|
|
||||||
get_param
|
|
||||||
---------
|
|
||||||
The :code:`get_param` function references an input parameter of a template. It
|
|
||||||
resolves to the value provided for this input parameter at runtime.
|
|
||||||
|
|
||||||
The syntax of the :code:`get_param` function is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
get_param:
|
|
||||||
- <parameter name>
|
|
||||||
- <key/index 1> (optional)
|
|
||||||
- <key/index 2> (optional)
|
|
||||||
- ...
|
|
||||||
|
|
||||||
parameter name
|
|
||||||
The parameter name to be resolved. If the parameters returns a complex data
|
|
||||||
structure such as a list or a map, then subsequent keys or indexes can be
|
|
||||||
specified. These additional parameters are used to navigate the data
|
|
||||||
structure to return the desired value.
|
|
||||||
|
|
||||||
The following example demonstrates the use of the :code:`get_param` function:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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 ] }
|
|
||||||
|
|
||||||
In this example, if the ``instance_type`` and ``server_data`` parameters
|
|
||||||
contained the following data:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
{"instance_type": "m1.tiny",
|
|
||||||
{"server_data": {"metadata": {"foo": "bar"},
|
|
||||||
"keys": ["a_key","other_key"]}}}
|
|
||||||
|
|
||||||
then the value of the property ``flavor`` would resolve to ``m1.tiny``,
|
|
||||||
``metadata`` would resolve to ``{"foo": "bar"}`` and ``key_name`` would resolve
|
|
||||||
to ``a_key``.
|
|
||||||
|
|
||||||
get_resource
|
|
||||||
------------
|
|
||||||
The ``get_resource`` function references another resource within the
|
|
||||||
same template. At runtime, it is resolved to reference the ID of the referenced
|
|
||||||
resource, which is resource type specific. For example, a reference to a
|
|
||||||
floating IP resource returns the respective IP address at runtime. The syntax
|
|
||||||
of the ``get_resource`` function is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
get_resource: <resource ID>
|
|
||||||
|
|
||||||
The resource ID of the referenced resource is given as single parameter to the
|
|
||||||
get_resource function.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
resources:
|
|
||||||
instance_port:
|
|
||||||
type: OS::Neutron::Port
|
|
||||||
properties: ...
|
|
||||||
|
|
||||||
instance:
|
|
||||||
type: OS::Nova::Server
|
|
||||||
properties:
|
|
||||||
...
|
|
||||||
networks:
|
|
||||||
port: { get_resource: instance_port }
|
|
||||||
|
|
||||||
|
|
||||||
list_join
|
|
||||||
---------
|
|
||||||
|
|
||||||
The :code:`list_join` function joins a list of strings with the given
|
|
||||||
delimiter.
|
|
||||||
|
|
||||||
The syntax of the :code:`list_join` function is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
list_join:
|
|
||||||
- <delimiter>
|
|
||||||
- <list to join>
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
list_join: [', ', ['one', 'two', 'and three']]
|
|
||||||
|
|
||||||
This resolve to the string ``one, two, and three``.
|
|
||||||
|
|
||||||
resource_facade
|
|
||||||
---------------
|
|
||||||
|
|
||||||
The :code:`resource_facade` function retrieves data in a parent
|
|
||||||
provider template.
|
|
||||||
|
|
||||||
A provider template provides a custom definition of a resource, called its
|
|
||||||
facade. For more information about custom templates, see :ref:`composition`.
|
|
||||||
The syntax of the :code:`resource_facade` function is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
resource_facade: <data type>
|
|
||||||
|
|
||||||
``data type`` can be one of ``metadata``, ``deletion_policy`` or
|
|
||||||
``update_policy``.
|
|
||||||
|
|
||||||
|
|
||||||
str_replace
|
|
||||||
-----------
|
|
||||||
The :code:`str_replace` function dynamically constructs strings by
|
|
||||||
providing a template string with placeholders and a list of mappings to assign
|
|
||||||
values to those placeholders at runtime. The placeholders are replaced with
|
|
||||||
mapping values wherever a mapping key exactly matches a placeholder.
|
|
||||||
|
|
||||||
The syntax of the :code:`str_replace` function is:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
|
|
||||||
str_replace:
|
|
||||||
template: <template string>
|
|
||||||
params: <parameter mappings>
|
|
||||||
|
|
||||||
template
|
|
||||||
Defines the template string that contains placeholders which will be
|
|
||||||
substituted at runtime.
|
|
||||||
|
|
||||||
params
|
|
||||||
Provides parameter mappings in the form of dictionary. Each key refers to a
|
|
||||||
placeholder used in the ``template`` attribute.
|
|
||||||
|
|
||||||
The following example shows a simple use of the ``str_replace`` function in the
|
|
||||||
outputs section of a template to build a URL for logging into a deployed
|
|
||||||
application:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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 ] }
|
|
||||||
|
|
||||||
The following examples show the use of the :code:`str_replace`
|
|
||||||
function to build an instance initialization script:
|
|
||||||
|
|
||||||
.. code-block:: yaml
|
|
||||||
:linenos:
|
|
||||||
|
|
||||||
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 }
|
|
7
doc/user-guide/source/hot.rst
Normal file
7
doc/user-guide/source/hot.rst
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
=========
|
||||||
|
HOT Guide
|
||||||
|
=========
|
||||||
|
|
||||||
|
The HOT Guide is now maintained as part of the Heat repository and is available
|
||||||
|
on the OpenStack developer documentation website: `Heat Template Guide
|
||||||
|
<http://docs.openstack.org/developer/heat/template_guide/index.html>`__
|
@ -24,7 +24,7 @@ Contents
|
|||||||
dashboard.rst
|
dashboard.rst
|
||||||
cli.rst
|
cli.rst
|
||||||
sdk.rst
|
sdk.rst
|
||||||
hot-guide/hot.rst
|
hot.rst
|
||||||
cli_cheat_sheet.rst
|
cli_cheat_sheet.rst
|
||||||
|
|
||||||
common/app_support.rst
|
common/app_support.rst
|
||||||
|
Loading…
Reference in New Issue
Block a user