Merge HOT Guide files into Template Guide
The HOT Guide was formerly located in the User Guide. This patch merges those files into the heat docs repository in the Template Guide directory. Change-Id: I559b1b3edb42b1de40013c37e5967d8898c8a916 Closes-Bug: #1461720
This commit is contained in:
38
doc/source/template_guide/advanced_topics.rst
Normal file
38
doc/source/template_guide/advanced_topics.rst
Normal file
@@ -0,0 +1,38 @@
|
||||
:orphan:
|
||||
|
||||
.. _advanced_topics:
|
||||
|
||||
===============
|
||||
Advanced topics
|
||||
===============
|
||||
|
||||
Networking
|
||||
~~~~~~~~~~
|
||||
|
||||
Load balancer
|
||||
-------------
|
||||
|
||||
TODO
|
||||
|
||||
Firewall
|
||||
--------
|
||||
|
||||
TODO
|
||||
|
||||
VPN
|
||||
---
|
||||
|
||||
TODO
|
||||
|
||||
Auto scaling
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Alarming
|
||||
--------
|
||||
|
||||
TODO
|
||||
|
||||
Up scaling and down scaling
|
||||
---------------------------
|
||||
|
||||
TODO
|
500
doc/source/template_guide/basic_resources.rst
Normal file
500
doc/source/template_guide/basic_resources.rst
Normal file
@@ -0,0 +1,500 @@
|
||||
.. highlight: yaml
|
||||
:linenothreshold: 5
|
||||
|
||||
.. _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,3 +1,6 @@
|
||||
.. 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
|
||||
@@ -39,9 +42,7 @@ To achieve this:
|
||||
|
||||
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.yaml` file:
|
||||
|
||||
.. code-block:: yaml
|
||||
:file:`my_nova.yaml` file::
|
||||
|
||||
heat_template_version: 2014-10-16
|
||||
|
||||
@@ -58,15 +59,10 @@ new types of resources. These examples use a custom template stored in a
|
||||
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
|
||||
``type`` property of a resource::
|
||||
|
||||
heat_template_version: 2014-10-16
|
||||
|
||||
@@ -81,34 +77,29 @@ the ``key_name`` property of the new template.
|
||||
|
||||
.. note::
|
||||
|
||||
The above reference to ``my_nova.yaml`` assumes it is in the same directory.
|
||||
The above reference to :file:`my_nova.yaml` assumes it is in the same directory.
|
||||
You can use any of the following forms:
|
||||
|
||||
* Relative path (``my_nova.yaml``)
|
||||
* Absolute path (``file:///home/user/templates/my_nova.yaml``)
|
||||
* Relative path (:file:`my_nova.yaml`)
|
||||
* Absolute path (:file:`file:///home/user/templates/my_nova.yaml`)
|
||||
* Http URL (``http://example.com/templates/my_nova.yaml``)
|
||||
* Https URL (``https://example.com/templates/my_nova.yaml``)
|
||||
|
||||
To create the stack run:
|
||||
|
||||
.. code-block:: console
|
||||
To create the stack run::
|
||||
|
||||
$ heat stack-create -f main.yaml stack1
|
||||
|
||||
|
||||
Define a new resource type
|
||||
==========================
|
||||
|
||||
You can associate a name to the ``my_nova.yaml`` template in an environment
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
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
|
||||
An :file:`env.yaml` environment file holds the definition of the new resource::
|
||||
|
||||
resource_registry:
|
||||
"OS::Nova::Server": my_nova.yaml
|
||||
@@ -117,9 +108,7 @@ An :file:`env.yaml` environment file holds the definition of the new resource:
|
||||
|
||||
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
|
||||
You can now use the new ``OS::Nova::Server`` in your new template::
|
||||
|
||||
heat_template_version: 2014-10-16
|
||||
|
||||
@@ -129,20 +118,15 @@ You can now use the new ``OS::Nova::Server`` in your new template:
|
||||
properties:
|
||||
key_name: my_key
|
||||
|
||||
To create the stack run:
|
||||
|
||||
.. code-block:: console
|
||||
To create the stack run::
|
||||
|
||||
$ heat stack-create -f main.yaml -e env.yaml example-two
|
||||
|
||||
|
||||
Get access to nested attributes
|
||||
===============================
|
||||
There are implicit attributes of a template resource. Accessing
|
||||
nested attributes require heat_template_version '2014-10-16' or
|
||||
higher and can be accessed as follows:
|
||||
|
||||
.. code-block:: yaml
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
There are implicit attributes of a template resource. Accessing nested
|
||||
attributes requires ``heat_template_version`` 2014-10-16 or higher. These are
|
||||
accessible as follows::
|
||||
|
||||
heat_template_version: 2014-10-16
|
||||
|
||||
@@ -154,18 +138,15 @@ higher and can be accessed as follows:
|
||||
test_out:
|
||||
value: {get_attr: my_server, resource.server, first_address}
|
||||
|
||||
|
||||
Making your template resource more "transparent"
|
||||
================================================
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
.. note::
|
||||
|
||||
Available since 2015.1 (Kilo).
|
||||
Available since 2015.1 (Kilo).
|
||||
|
||||
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
|
||||
output ``OS::stack_id`` to your template resource::
|
||||
|
||||
heat_template_version: 2014-10-16
|
||||
|
||||
@@ -177,5 +158,5 @@ output "OS::stack_id" to your template resource.
|
||||
OS::stack_id:
|
||||
value: {get_resource: server}
|
||||
|
||||
Now when you use "get_resource" from the outer template heat
|
||||
Now when you use ``get_resource`` from the outer template heat
|
||||
will use the nova server id and not the template resource identifier.
|
||||
|
@@ -1,3 +1,6 @@
|
||||
.. 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
|
||||
@@ -17,136 +20,135 @@
|
||||
Environments
|
||||
============
|
||||
|
||||
The environment is used to affect the runtime behavior of the
|
||||
template. It provides a way to override the resource
|
||||
implementations and provide a mechanism to place parameters
|
||||
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 also have to consider
|
||||
what plug-ins the cloud operator has installed.
|
||||
To fully understand the runtime behavior you have to consider what plug-ins are
|
||||
installed on the cloud you're using.
|
||||
|
||||
------
|
||||
Format
|
||||
------
|
||||
Environment file format
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
The environment is a yaml text file that contains two main sections:
|
||||
|
||||
It is a yaml text file with three main sections "resource_registry",
|
||||
"parameters" and "parameter_defaults".
|
||||
``parameters``
|
||||
A list of key/value pairs.
|
||||
|
||||
------------------
|
||||
Command line usage
|
||||
------------------
|
||||
::
|
||||
``resource_registry``
|
||||
Definition of custom resources.
|
||||
|
||||
Use the :option:`-e` option of the :command:`heat stack-create` command to
|
||||
create a stack using 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
|
||||
|
||||
heat stack-create my_stack -e my_env.yaml -P "some_parm=bla" -f my_tmpl.yaml
|
||||
|
||||
---------------------------------
|
||||
Global and effective environments
|
||||
---------------------------------
|
||||
|
||||
The environment used for a stack is the combination of (1) the
|
||||
environment given by the user with the template for the stack and (2)
|
||||
a global environment that is determined by the cloud operator.
|
||||
Combination is asymmetric: an entry in the user environment takes
|
||||
precedence over the global environment. The OpenStack software
|
||||
includes a default global environment, which supplies some resource
|
||||
types that are included in the standard documentation. The cloud
|
||||
operator can add additional environment entries.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
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 your cloud operator can add additional environment entries.
|
||||
|
||||
The cloud operator can add to the global environment
|
||||
by putting environment files in a configurable directory wherever
|
||||
the heat-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
|
||||
the Orchestration engine runs. The configuration variable is named
|
||||
``environment_dir`` and is found in the ``[DEFAULT]`` section
|
||||
of :file:`/etc/heat/heat.conf`. The default for that directory is
|
||||
:file:`/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 :file:`my_env.yaml` file from the example above had been put in the
|
||||
``environment_dir`` then the user's command line could be this::
|
||||
|
||||
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
|
||||
|
||||
::
|
||||
|
||||
heat stack-create my_stack -P "some_parm=bla" -f my_tmpl.yaml
|
||||
|
||||
--------------
|
||||
Usage examples
|
||||
--------------
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
1) Pass parameters into heat
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
::
|
||||
Define values for template arguments
|
||||
------------------------------------
|
||||
You can define values for the template arguments in the ``parameters`` section
|
||||
of an environment file::
|
||||
|
||||
parameters:
|
||||
KeyName: heat_key
|
||||
InstanceType: m1.micro
|
||||
ImageId: F18-x86_64-cfntools
|
||||
|
||||
2) Define defaults to parameters
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
This is especially useful when you have many template resources and
|
||||
you want the same value in each. Note: these defaults will get passed
|
||||
down into all template resources.
|
||||
::
|
||||
Define defaults to parameters
|
||||
--------------------------------
|
||||
You can define default values for all template arguments in the
|
||||
``parameter_defaults`` section of an environment file. These defaults are
|
||||
passed into all template resources::
|
||||
|
||||
parameter_defaults:
|
||||
KeyName: heat_key
|
||||
|
||||
Mapping resources
|
||||
-----------------
|
||||
You can map one resource to another in the ``resource_registry`` section
|
||||
of an evironment file. The resource you provide in this manner must have an
|
||||
identifier, and must reference either another resource's ID or the URL of an
|
||||
existing template file.
|
||||
|
||||
3) Deal with the mapping of Quantum to Neutron
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
::
|
||||
|
||||
resource_registry:
|
||||
"OS::Quantum*": "OS::Neutron*"
|
||||
|
||||
So all existing resources which can be matched with "OS::Neutron*"
|
||||
will be mapped to "OS::Quantum*" accordingly.
|
||||
|
||||
4) Override a resource type with a custom template resource
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
::
|
||||
|
||||
resource_registry:
|
||||
"AWS::EC2::Instance": file:///home/mine/my_instance_with_better_defaults.yaml
|
||||
|
||||
Please note that the template resource URL here must end with ".yaml"
|
||||
or ".template", or it will not be treated as a custom template
|
||||
resource. The supported URL types are "http, https and file".
|
||||
|
||||
5) Always map resource type X to Y
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
::
|
||||
The following example maps a new ``OS::Networking::FloatingIP``
|
||||
resource to an existing ``OS::Nova::FloatingIP`` resource::
|
||||
|
||||
resource_registry:
|
||||
"OS::Networking::FloatingIP": "OS::Nova::FloatingIP"
|
||||
|
||||
|
||||
6) Use default resources except one for a particular resource in the template
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
::
|
||||
You can use wildcards to map multiple resources, for example to map all
|
||||
``OS::Neutron`` resources to ``OS::Network``::
|
||||
|
||||
resource_registry:
|
||||
resources:
|
||||
my_db_server:
|
||||
"OS::DBInstance": file:///home/mine/all_my_cool_templates/db.yaml
|
||||
"OS::Network*": "OS::Neutron*"
|
||||
|
||||
|
||||
7) Pause stack creation/update on a given resource
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
If you want to debug your stack as it's being created or updated or if you want
|
||||
to run it in phases you can set `pre-create` and `pre-update` hooks in the
|
||||
`resources` section of `resource_registry`.
|
||||
|
||||
To set a hook, add either `hooks: pre-create` or `hooks: pre-update` to the
|
||||
resource's dictionary. You can also use the `[pre-create, pre-update]` to stop
|
||||
Override a resource with a custom resource
|
||||
------------------------------------------
|
||||
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::
|
||||
|
||||
resource_registry:
|
||||
"AWS::EC2::Instance": file:///path/to/my_instance.yaml
|
||||
|
||||
The supported URL schemes 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::
|
||||
|
||||
resource_registry:
|
||||
resources:
|
||||
my_db_server:
|
||||
"OS::DBInstance": file:///home/mine/all_my_cool_templates/db.yaml
|
||||
|
||||
Pause stack creation or update on a given resource
|
||||
--------------------------------------------------
|
||||
If you want to debug your stack as it's being created or updated, or if you want
|
||||
to run it in phases, you can set ``pre-create`` and ``pre-update`` hooks in the
|
||||
``resources`` section of ``resource_registry``.
|
||||
|
||||
To set a hook, add either ``hooks: pre-create`` or ``hooks: pre-update`` to the
|
||||
resource's dictionary. You can also use ``[pre-create, pre-update]`` to stop
|
||||
on both actions.
|
||||
|
||||
Hooks can be combined with other `resources` properties (e.g. provider
|
||||
templates or type mapping).
|
||||
|
||||
Example:
|
||||
|
||||
::
|
||||
You can combine hooks with other ``resources`` properties such as provider
|
||||
templates or type mapping::
|
||||
|
||||
resource_registry:
|
||||
resources:
|
||||
@@ -159,25 +161,19 @@ Example:
|
||||
another_resource:
|
||||
hooks: [pre-create, pre-update]
|
||||
|
||||
When heat encounters a resource that has a hook, it will pause the resource
|
||||
action until the hook is cleared. Any resources that depend on it will wait as
|
||||
well. Any resources that don't will be created in parallel (unless they have
|
||||
hooks, too).
|
||||
When heat encounters a resource that has a hook, it pauses the resource
|
||||
action until the hook clears. Any resources that depend on the paused action
|
||||
wait as well. Non-dependant resources are created in parallel unless they have
|
||||
their own hooks.
|
||||
|
||||
It is also possible to do a partial match by putting an asterisk (`*`) in the
|
||||
name.
|
||||
|
||||
This example:
|
||||
|
||||
::
|
||||
It is possible to perform a wild card match using an asterisk (`*`) in the
|
||||
resource name. For example, the following entry pauses while creating
|
||||
``app_server`` and ``database_server``, but not ``server`` or ``app_network``::
|
||||
|
||||
resource_registry:
|
||||
resources:
|
||||
"*_server":
|
||||
hooks: pre-create
|
||||
|
||||
will pause while creating `app_server` and `database_server` but not `server`
|
||||
or `app_network`.
|
||||
|
||||
Hook is cleared by signaling the resource with `{unset_hook: pre-create}` (or
|
||||
`pre-update`).
|
||||
Clear hooks by signaling the resource with ``{unset_hook: pre-create}``
|
||||
or ``{unset_hook: pre-update}``.
|
||||
|
28
doc/source/template_guide/existing_templates.rst
Normal file
28
doc/source/template_guide/existing_templates.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
:orphan:
|
||||
|
||||
.. _existing_templates:
|
||||
|
||||
================================
|
||||
Where to find existing templates
|
||||
================================
|
||||
|
||||
There are several repositories where you can find existing HOT templates.
|
||||
|
||||
The `OpenStack Heat Templates repository`_ contains example templates
|
||||
demonstrating core Heat functionality, related image-building templates,
|
||||
and 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: http://github.com/rcbops/
|
233
doc/source/template_guide/hello_world.rst
Normal file
233
doc/source/template_guide/hello_world.rst
Normal file
@@ -0,0 +1,233 @@
|
||||
.. 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.
|
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,10 @@ Template Guide
|
||||
:maxdepth: 2
|
||||
|
||||
hot_guide
|
||||
hello_world
|
||||
hot_spec
|
||||
basic_resources
|
||||
software_deployment
|
||||
environment
|
||||
composition
|
||||
openstack
|
||||
@@ -26,3 +29,6 @@ Template Guide
|
||||
unsupported
|
||||
contrib
|
||||
functions
|
||||
|
||||
.. existing_templates
|
||||
.. advanced_topics
|
801
doc/source/template_guide/software_deployment.rst
Normal file
801
doc/source/template_guide/software_deployment.rst
Normal file
@@ -0,0 +1,801 @@
|
||||
.. highlight: yaml
|
||||
:linenothreshold: 5
|
||||
|
||||
.. _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: http://puppetlabs.com/
|
Reference in New Issue
Block a user