Merge "Merge HOT Guide files into Template Guide"
This commit is contained in:
commit
fd75324f44
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/
|
Loading…
x
Reference in New Issue
Block a user