Jump to: navigation, search

Difference between revisions of "Heat/YAMLTemplates"

(Test Cases)
 
(One intermediate revision by one other user not shown)
Line 1: Line 1:
__NOTOC__
+
 
 
* '''Launchpad Entry''': [[HeatSpec]]:yaml-templates
 
* '''Launchpad Entry''': [[HeatSpec]]:yaml-templates
 
* '''Created''': 29 Nov 2012
 
* '''Created''': 29 Nov 2012
Line 157: Line 157:
  
 
= Test Cases =
 
= Test Cases =
The templates [https://raw.github.com/openstack/heat/master/templates/WordPress_Single_Instance.template WordPress_Single_Instance.template] and [https://raw.github.com/openstack/heat/master/templates/WordPress_Single_Instance.yaml WordPress_Single_Instance.yaml] are validated in a unit test as parsing to an equivalent Heat stack.
+
The templates [https://raw.github.com/openstack/heat/master/heat/tests/templates/WordPress_Single_Instance.template WordPress_Single_Instance.template] and [https://raw.github.com/openstack/heat/master/heat/tests/templates/WordPress_Single_Instance.yaml WordPress_Single_Instance.yaml] are validated in a unit test as parsing to an equivalent Heat stack.
  
 
Other tests include using the conversion utility to convert existing JSON templates to YAML, then parsing both and validating that they result in the same python dict structure.
 
Other tests include using the conversion utility to convert existing JSON templates to YAML, then parsing both and validating that they result in the same python dict structure.

Latest revision as of 21:28, 12 May 2013

Scope

The CloudFormation template syntax is based on JSON. This has shortcomings for templates maintained by hand, most notably:

  • lack of support for block (multi-line) strings
  • lack of commenting syntax (useful for documenting templates, and commenting out disabled sections).

So that Heat is not held back by this design decision, a new template format is proposed which will be supported alongside the existing CloudFormation format.

This format will be a YAML based syntax. The initial version of this new format will be a YAML document which parses to the same document structure as the current CloudFormation format. Future format changes will most likely focus on making it easier to write templates by hand.

User Stories

Alice evaluated Heat for her orchestration requirements, and decided not to use it because she didn't want to maintain her templates in JSON.

Bob wanted to make many comments in his template to document the approach he had taken.

Carlos had to debug a problem in a template so he wanted to temporarily comment out some resources.

Implementation Overview

When Heat parses a template, it assumes that the format is JSON if the first character is {, otherwise it attempts to parse as YAML. A template can explicitly state that it complies to the initial YAML syntax by including this top-level attribute:

#!highlight yaml
HeatTemplateFormatVersion: '2012-12-12'


If HeatTemplateFormatVersion is omitted from the template, parsing will assume that the template complies with the most recent format known to that Heat instance.

Dependencies

PyYAML is required for parsing.

Usage Example

Here are some examples of the new format.

This is an empty file:

#!highlight yaml


Which is equivalent to this skeleton template:

#!highlight yaml
HeatTemplateFormatVersion: '2012-12-12'
Parameters: {}
Mappings: {}
Resources: {}
Outputs: {}


Here is a JSON Parameters snippet

#!highlight js
  "Parameters" : {

    "KeyName" : {
      "Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
      "Type" : "String"
    },

    "InstanceType" : {
      "Description" : "WebServer EC2 instance type",
      "Type" : "String",
      "Default" : "m1.large",
      "AllowedValues" : [ "t1.micro", "m1.small", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge" ],
      "ConstraintDescription" : "must be a valid EC2 instance type."
    }


Along with an equivalent representation in the YAML syntax, including an inline comment:

#!highlight yaml
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instances
    Type: String
  InstanceType:
    Description: WebServer EC2 instance type
    Type: String
    Default: m1.large
# there is an assumption that the Nova instance supports the following instance types
    AllowedValues: [t1.micro, m1.small, m1.large, m1.xlarge, m2.xlarge,
      m2.2xlarge, m2.4xlarge, c1.medium, c1.xlarge, cc1.4xlarge]
    ConstraintDescription: must be a valid EC2 instance type.


It is common to use Fn::Join as a workaround for the lack of multi-line blocks, so the following

#!highlight js
        "UserData"       : { "Fn::Base64" : { "Fn::Join" : ["", [
          "#!/bin/bash -v\n",
          "/opt/aws/bin/cfn-init\n",
          "# Setup MySQL root password and create a user\n",
          "mysqladmin -u root password '", { "Ref" : "DBRootPassword" }, "'\n",
          "cat << EOF | mysql -u root --password='", { "Ref" : "DBRootPassword" }, "'\n",
          "CREATE DATABASE ", { "Ref" : "DBName" }, ";\n",
          "GRANT ALL PRIVILEGES ON ", { "Ref" : "DBName" }, ".* TO \"", { "Ref" : "DBUsername" }, "\"@\"localhost\"\n",
          "IDENTIFIED BY \"", { "Ref" : "DBPassword" }, "\";\n",
          "FLUSH PRIVILEGES;\n",
          "EXIT\n",
          "EOF\n",
          "sed --in-place --e s/database_name_here/", { "Ref" : "DBName" }, "/ --e s/username_here/", { "Ref" : "DBUsername" }, "/ --e s/password_here/", { "Ref" : "DBPassword" }, "/ /usr/share/wordpress/wp-config.php\n"
        ]]}}

Could be recomposed using any of YAML's block or quoted scalar styles, such as:

#!highlight yaml
      UserData:
        Fn::Base64:
          Fn::Join:
          - ''
          - - |-
                #!/bin/bash -v
                /opt/aws/bin/cfn-init
                # Setup MySQL root password and create a user
                mysqladmin -u root password '
            - {Ref: DBRootPassword}
            - |-
                '
                cat << EOF | mysql -u root --password='
            - {Ref: DBRootPassword}
            - |-
                '
                CREATE DATABASE 
            - {Ref: DBName}
            - |-
                ;
                GRANT ALL PRIVILEGES ON 
            - {Ref: DBName}
            - .* TO "
            - {Ref: DBUsername}
            - |-
                "@"localhost"
                IDENTIFIED BY "
            - {Ref: DBPassword}
            - |-
                ";
                FLUSH PRIVILEGES;
                EXIT
                EOF
                sed --in-place --e s/database_name_here/
            - {Ref: DBName}
            - / --e s/username_here/
            - {Ref: DBUsername}
            - / --e s/password_here/
            - {Ref: DBPassword}
            - |
                / /usr/share/wordpress/wp-config.php


Test Cases

The templates WordPress_Single_Instance.template and WordPress_Single_Instance.yaml are validated in a unit test as parsing to an equivalent Heat stack.

Other tests include using the conversion utility to convert existing JSON templates to YAML, then parsing both and validating that they result in the same python dict structure.