Update the user guide with the latest HOT guide content

Change-Id: If71ad2579328d22430f56f81f3d35d220be734d5
This commit is contained in:
Gauvain Pocentek 2014-12-30 10:55:05 +01:00
parent a9d9dbec1c
commit a8f6cc1f09

View File

@ -51,8 +51,7 @@ agents already being installed and enabled</para>
combinations</para>
</listitem>
</itemizedlist>
<para>Examples in this guide which require custom images will use
<link xlink:href="https://github.com/openstack/diskimage-builder">diskimage-builder</link>.</para>
<para>Examples in this guide which require custom images will use <link xlink:href="https://github.com/openstack/diskimage-builder">diskimage-builder</link>.</para>
</section>
<section xml:id="user-data-boot-scripts-and-cloud-init">
<?dbhtml stop-chunking?>
@ -164,8 +163,8 @@ enabled image, the following are both valid <literal>RAW</literal> user-data:</p
#cloud-config
final_message: "The system is finally up, after $UPTIME seconds"</programlisting>
<para>For <literal>SOFTWARE_CONFIG</literal> user_data is bundled as part of the software config
data, and metadata is derived from any associated software deployment
resources.</para>
data, and metadata is derived from any associated
<link linkend="software-deployment-resources">Software deployment resources</link>.</para>
</section>
<section xml:id="signals-and-wait-conditions">
<title>Signals and wait conditions</title>
@ -396,4 +395,325 @@ resources:
<!---->
</section>
</section>
<section xml:id="software-deployment-resources">
<?dbhtml stop-chunking?>
<title>Software deployment resources</title>
<para>There are many situations where it is not desirable to replace the server
whenever there is a configuration change. The
<literal><link xlink:href="http://docs.openstack.org/hot-reference/content/OS__Heat__SoftwareDeployment.html">OS::Heat::SoftwareDeployment</link></literal> resource allows any number of software
configurations to be added or removed from a server throughout its life-cycle.</para>
<section xml:id="building-custom-image-for-software-deployments">
<title>Building custom image for software deployments</title>
<para><literal><link xlink:href="http://docs.openstack.org/hot-reference/content/OS__Heat__SoftwareConfig.html">OS::Heat::SoftwareConfig</link></literal> resources are used to store software
configuration, and a <literal><link xlink:href="http://docs.openstack.org/hot-reference/content/OS__Heat__SoftwareDeployment.html">OS::Heat::SoftwareDeployment</link></literal> resource is used
to associate a config resource with one server. The <literal>group</literal> attribute on
<literal><link xlink:href="http://docs.openstack.org/hot-reference/content/OS__Heat__SoftwareConfig.html">OS::Heat::SoftwareConfig</link></literal> specifies what tool will consume the
config content.</para>
<para><literal><link xlink:href="http://docs.openstack.org/hot-reference/content/OS__Heat__SoftwareConfig.html">OS::Heat::SoftwareConfig</link></literal> has the ability to define a schema of
<literal>inputs</literal> and which the configuration script supports. Inputs are mapped to
whatever concept the configuration tool has for assigning
variables/parameters.</para>
<para>Likewise, <literal>outputs</literal> 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.</para>
<para>The <literal><link xlink:href="http://docs.openstack.org/hot-reference/content/OS__Heat__SoftwareDeployment.html">OS::Heat::SoftwareDeployment</link></literal> resource allows values to be
assigned to the config inputs, and the resource remains in an <literal>IN_PROGRESS</literal>
state until the server signals to heat what (if any) output values were
generated by the config script.</para>
</section>
<section xml:id="custom-image-script">
<title>Custom image script</title>
<para>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:</para>
<programlisting language="sh"># 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 &lt; $IMAGE_NAME.qcow2</programlisting>
<!---->
</section>
<section xml:id="configuring-with-scripts">
<title>Configuring with scripts</title>
<para>The <link linkend="custom-image-script">Custom image script</link> already includes the <literal>heat-config-script</literal> element
so the built image will already have the ability to configure using shell
scripts.</para>
<para>Config inputs are mapped to shell environment variables. The script can
communicate outputs to heat by writing to the file
<literal>$heat_outputs_path.&lt;output name&gt;</literal>. See the following example for a script
which expects inputs <literal>foo</literal>, <literal>bar</literal> and generates an output <literal>result</literal>.</para>
<programlisting language="yaml">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 &gt; /tmp/$bar
echo -n "The file /tmp/$bar contains `cat /tmp/$bar` for server $deploy_server_id during $deploy_action" &gt; $heat_outputs_path.result
echo "Written to /tmp/$bar"
echo "Output to stderr" 1&gt;&amp;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]</programlisting>
<!---->
<blockquote>
<para><emphasis role="Tip"/>: A config resource can be associated with multiple deployment
resources, and each deployment can specify the same or different values
for the <literal>server</literal> and <literal>input_values</literal> properties.</para>
</blockquote>
<para>As can be seen in the <literal>outputs</literal> section of the above template, the
<literal>result</literal> config output value is available as an attribute on the
<literal>deployment</literal> resource. Likewise the captured stdout, stderr and status_code
are also available as attributes.</para>
</section>
<section xml:id="configuring-with-os-apply-config">
<title>Configuring with os-apply-config</title>
<para>The agent toolchain of <literal>os-collect-config</literal>, <literal>os-refresh-config</literal> and
<literal>os-apply-config</literal> can actually be used on their own to inject heat stack
configuration data into a server running a custom image.</para>
<para>The custom image needs to have the following to use this approach:</para>
<itemizedlist>
<listitem>
<para>All software dependencies installed</para>
</listitem>
<listitem>
<para><link xlink:href="https://github.com/openstack/os-refresh-config">os-refresh-config</link> scripts to be executed on configuration changes</para>
</listitem>
<listitem>
<para><link xlink:href="https://github.com/openstack/os-apply-config">os-apply-config</link> templates to transform the heat-provided config data into
service configuration files</para>
</listitem>
</itemizedlist>
<para>The projects <link xlink:href="https://github.com/openstack/tripleo-image-elements">tripleo-image-elements</link> and <link xlink:href="https://github.com/openstack/tripleo-heat-templates">tripleo-heat-templates</link> demonstrate
this approach.</para>
</section>
<section xml:id="configuring-with-cfn-init">
<title>Configuring with cfn-init</title>
<para>Likely the only reason to use the <literal>cfn-init</literal> hook is to migrate templates
which contain <link xlink:href="http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html">AWS::CloudFormation::Init</link> metadata without needing a
complete rewrite of the config metadata. It is included here as it introduces
a number of new concepts.</para>
<para>To use the <literal>cfn-init</literal> tool the <literal>heat-config-cfn-init</literal> element is required
to be on the built image, so <link linkend="custom-image-script">Custom image script</link> needs to be modified with
the following:</para>
<programlisting language="sh">export DEPLOYMENT_TOOL="heat-config-cfn-init"</programlisting>
<!---->
<para>Configuration data which used to be included in the
<literal>AWS::CloudFormation::Init</literal> section of resource metadata is instead moved
to the <literal>config</literal> property of the config resource, as in the following
example:</para>
<programlisting language="yaml">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</programlisting>
<!---->
<para>There are a number of things to note about this template example:</para>
<itemizedlist>
<listitem>
<para><literal><link xlink:href="http://docs.openstack.org/hot-reference/content/OS__Heat__StructuredConfig.html">OS::Heat::StructuredConfig</link></literal> is like
<literal><link xlink:href="http://docs.openstack.org/hot-reference/content/OS__Heat__SoftwareConfig.html">OS::Heat::SoftwareConfig</link></literal> except that the <literal>config</literal> 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.</para>
</listitem>
<listitem>
<para><literal>cfn-init</literal> has no concept of inputs, so <literal>{get_input: bar}</literal> acts as a
placeholder which gets replaced with the
<literal><link xlink:href="http://docs.openstack.org/hot-reference/content/OS__Heat__StructuredDeployment.html">OS::Heat::StructuredDeployment</link></literal><literal>input_values</literal> value when the
deployment resource is created.</para>
</listitem>
<listitem>
<para><literal>cfn-init</literal> has no concept of outputs, so specifying
<literal>signal_transport: NO_SIGNAL</literal> will mean that the deployment resource will
immediately go into the <literal>CREATED</literal> state instead of waiting for a
completed signal from the server.</para>
</listitem>
<listitem>
<para>The template has 2 deployment resources deploying the same config with
different <literal>input_values</literal>. The order these are deployed in on the server
is determined by sorting the values of the <literal>name</literal> property for each
resource (10_deployment, 20_other_deployment)</para>
</listitem>
</itemizedlist>
</section>
<section xml:id="configuring-with-puppet">
<title>Configuring with puppet</title>
<para>The <link xlink:href="http://puppetlabs.com/">puppet</link> hook makes it possible to write configuration as puppet manifests
which are deployed and run in a masterless environment.</para>
<para>To specify configuration as puppet manifests the <literal>heat-config-puppet</literal>
element is required to be on the built image, so <link linkend="custom-image-script">Custom image script</link> needs
to be modified with the following:</para>
<programlisting language="sh">export DEPLOYMENT_TOOL="heat-config-puppet"</programlisting>
<!---->
<programlisting language="yaml">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]</programlisting>
<!---->
<para>This demonstrates the use of the <literal>get_file</literal> function, which will attach the
contents of the file <literal>example-puppet-manifest.pp</literal>, containing:</para>
<programlisting language="puppet">file { 'barfile':
ensure =&gt; file,
mode =&gt; '0644',
path =&gt; '/tmp/$::bar',
content =&gt; '$::foo',
}
file { 'output_result':
ensure =&gt; file,
path =&gt; '$::heat_outputs_path.result',
mode =&gt; '0644',
content =&gt; 'The file /tmp/$::bar contains $::foo',
}</programlisting>
<!---->
</section>
</section>
</section>