Merge "Merge HOT Guide files into Template Guide"

This commit is contained in:
Jenkins 2015-06-25 03:12:02 +00:00 committed by Gerrit Code Review
commit fd75324f44
9 changed files with 2222 additions and 676 deletions

View 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

View 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

View File

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

View File

@ -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}``.

View 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/

View 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

View File

@ -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

View 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/