{"id":4862,"date":"2014-05-02T13:27:58","date_gmt":"2014-05-02T11:27:58","guid":{"rendered":"http:\/\/blog.zhaw.ch\/icclab\/?p=4862"},"modified":"2014-05-07T14:01:52","modified_gmt":"2014-05-07T12:01:52","slug":"manage-instance-startup-order-in-openstack-heat-templates","status":"publish","type":"post","link":"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/","title":{"rendered":"Manage instance startup order in OpenStack Heat Templates"},"content":{"rendered":"<p>In many applications it is necessary to create virtual resources in a certain order. As an orchestration engine, Heat is able to support such a requirement, but how it is actually done\u00a0in a template can be tricky. Recently I had to write such a Heat template, which seemed pretty easy as there is a number of examples on the <a title=\"OpenStack\/heat-templates\" href=\"https:\/\/github.com\/openstack\/heat-templates\">OpenStack\/heat-templates<\/a> github. My requirements and the relative lack of explanation on how the templates are written made this a bit more difficult than expected, but after finding information dispersed over several websites I solved my issues: This post is a summary of my findings. My application was made of three servers which had to be started and configured in a specific order, each server needing to be ready before the next one can be started as it automatically connects to the previously started servers. This was really the main concern\u00a0of the application. In the following examples I will use the names service1, service2 and service3, with startup order being service1 &gt; service2 &gt; service3. I had three requirements:<\/p>\n<ol>\n<li>I wanted to follow the <a title=\"Heat Orchestration Template (HOT) format\" href=\"http:\/\/docs.openstack.org\/developer\/heat\/template_guide\/hot_guide.html\">Heat Orchestration Template (HOT) format<\/a>, which is the latest template format meant to replace Heat CloudFormation-compatible format (CFN) as the native format supported by Heat over time, so my template is still usable in the next Heat versions.<\/li>\n<li>To support my startup order I needed to use <a href=\"http:\/\/docs.openstack.org\/developer\/heat\/template_guide\/cfn.html#AWS::CloudFormation::WaitCondition\">WaitConditions<\/a>, which are directly issued from the CFN format but normally HOT still supports the usage of CFN resources, in the new format.<\/li>\n<li>My image did not have the cfn tools installed and thus I could not use cfn calls directly from inside the machine during the post-boot phase. This is an issue as from the templates which can be found on github, they all use these tools when WaitConditions are used.<\/li>\n<\/ol>\n<p>The idea of WaitConditions is that they have to be declared and linked to one resource, and when this resource is configured and ready it sends a signal back to Heat. Another resource depending on this signal can then be started. The template which met my requirements can be found on <a href=\"https:\/\/github.com\/fzhaw\/blog\/blob\/master\/wait_tpl.yml\">github<\/a>, I will explain the relevant parts here:<\/p>\n<pre><code>\r\n  service1: \r\n    type: \"OS::Nova::Server\"\r\n    properties: \r\n      flavor: m1.medium\r\n      image: ubuntu_cloud\r\n      key_name: \r\n        get_param: key_name\r\n      user_data: \r\n        str_replace: \r\n          template: |\r\n              #!\/bin\/bash\r\n              curl -X PUT -H 'Content-Type:application\/json' \\\r\n                   -d '{\"Status\" : \"SUCCESS\",\"Reason\" : \"Configuration OK\",\"UniqueId\" : \"SERVICE1\",\"Data\" : \"Service1 Configured.\"}' \\\r\n                   \"$wait_handle$\"\r\n          params: \r\n            $wait_handle$: \r\n              get_resource: service1_wait_handle\r\n\r\n  service1_wait: \r\n    type: \"AWS::CloudFormation::WaitCondition\"\r\n    depends_on: service1\r\n    properties: \r\n      Handle: \r\n        get_resource: service1_wait_handle\r\n      Timeout: 1000\r\n\r\n  service1_wait_handle: \r\n    type: \"AWS::CloudFormation::WaitConditionHandle\"\r\n<\/code><\/pre>\n<p>A first resource &#8220;service1&#8221; is declared, with the WaitCondition and WaitConditionHandle declared as separate resources linked together with a dependence on service1 in the case of the WaitCondition. The interesting part is in the post-boot script of service1: user-data. Here you can a curl with a specific JSON data blob (details on <a href=\"http:\/\/docs.aws.amazon.com\/AWSCloudFormation\/latest\/UserGuide\/quickref-waitcondition.html\">CloudFormation&#8217;s website<\/a>) sent through a PUT on an address retrieved from the WaitConditionHandle designed as service1_wait_handle. This is what signals the success to the wait condition. Now how is it possible to specify that the next virtual instance has to wait for this success signal before being started?<\/p>\n<pre><code>\r\n  service2: \r\n    type: \"OS::Nova::Server\"\r\n    depends_on: service1_wait\r\n    properties: \r\n      flavor: \r\n        get_param: instance_type\r\n      image: ubuntu_cloud\r\n      key_name: \r\n        get_param: key_name\r\n      user_data: \r\n        str_replace: \r\n          template: |\r\n              #!\/bin\/bash\r\n              curl -X PUT -H 'Content-Type:application\/json' \\\r\n                -d '{\"Status\" : \"SUCCESS\",\"Reason\" : \"Configuration OK\",\"UniqueId\" : \"SERVICE2\",\"Data\" : \"Service2 Configured.\"}' \\\r\n                \"$wait_handle$\"\r\n          params: \r\n            $data$: \r\n              get_attr: \r\n                - service1_wait\r\n                - Data\r\n            $wait_handle$: \r\n              get_resource: service2_wait_handle\r\n\t\t\r\n  service2_wait: \r\n    type: \"AWS::CloudFormation::WaitCondition\"\r\n    depends_on: service2\r\n    properties: \r\n      Handle: \r\n        get_resource: service2_wait_handle\r\n      Timeout: 1000\r\n\r\n  service2_wait_handle: \r\n    type: \"AWS::CloudFormation::WaitConditionHandle\"\r\n<\/code><\/pre>\n<p>Here you can see a structure similar to the one shown on the previous code snippet, with a new WaitCondition and Handle. This is because this server will in turn need to be configured before the final server can be started. The service2 resource differs on two points:<\/p>\n<pre><code>depends_on: service1_wait<\/code><\/pre>\n<p>This specifies that this resource depends on the completion of the service1_wait WaitCondition. Intuitively this should be enough as one might think that this will only happen when the success signal previously described is sent. Unfortunately it is not sufficient, at least in the Havana Release where this template was tested the resource did not wait at all and was started as soon as the template was created. A work-around to this problem is implemented in this code snippet:<\/p>\n<pre><code>\r\n  params: \r\n    $data$: \r\n      get_attr: \r\n        - service1_wait\r\n        - Data\r\n<\/code><\/pre>\n<p>This specifically tells Heat that service2 needs to retrieve the data (in our case, a string) sent through the curl call in the service1 post-boot script. This requirement is what actually makes service2 wait for service1 to be ready, even if in the actual post-boot script of service2, there is no reference to this data at all: it is sufficient to retrieve it in the params sections of str_replace and not use it at all in the actual script. With this template, you can now start and configure you instances in whatever order fits your application&#8217;s requirements, and even combine wait conditions so that instance C waits for instance B which in turn waits for instance A. It is also possible to actually use the data sent through the success signal in other templates if this actually makes sense if your application configuration scheme.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In many applications it is necessary to create virtual resources in a certain order. As an orchestration engine, Heat is able to support such a requirement, but how it is actually done\u00a0in a template can be tricky. Recently I had to write such a Heat template, which seemed pretty easy as there is a number [&hellip;]<\/p>\n","protected":false},"author":94,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[5,15,21],"tags":[],"features":[],"class_list":["post-4862","post","type-post","status-publish","format-standard","hentry","category-articles","category-howtos","category-openstack-2"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Manage instance startup order in OpenStack Heat Templates - Service Engineering (ICCLab &amp; SPLab)<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Manage instance startup order in OpenStack Heat Templates\" \/>\n<meta property=\"og:description\" content=\"In many applications it is necessary to create virtual resources in a certain order. As an orchestration engine, Heat is able to support such a requirement, but how it is actually done\u00a0in a template can be tricky. Recently I had to write such a Heat template, which seemed pretty easy as there is a number [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/\" \/>\n<meta property=\"og:site_name\" content=\"Service Engineering (ICCLab &amp; SPLab)\" \/>\n<meta property=\"article:published_time\" content=\"2014-05-02T11:27:58+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2014-05-07T12:01:52+00:00\" \/>\n<meta name=\"author\" content=\"dudo\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"dudo\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/\"},\"author\":{\"name\":\"dudo\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/aba82692aa266eab256d8df5ea04b06a\"},\"headline\":\"Manage instance startup order in OpenStack Heat Templates\",\"datePublished\":\"2014-05-02T11:27:58+00:00\",\"dateModified\":\"2014-05-07T12:01:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/\"},\"wordCount\":748,\"commentCount\":2,\"articleSection\":[\"Articles\",\"HowTos\",\"OpenStack\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/\",\"name\":\"Manage instance startup order in OpenStack Heat Templates - Service Engineering (ICCLab &amp; SPLab)\",\"isPartOf\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#website\"},\"datePublished\":\"2014-05-02T11:27:58+00:00\",\"dateModified\":\"2014-05-07T12:01:52+00:00\",\"author\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/aba82692aa266eab256d8df5ea04b06a\"},\"breadcrumb\":{\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Startseite\",\"item\":\"https:\/\/blog.zhaw.ch\/icclab\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Manage instance startup order in OpenStack Heat Templates\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#website\",\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/\",\"name\":\"Service Engineering (ICCLab &amp; SPLab)\",\"description\":\"A Blog of the ZHAW Zurich University of Applied Sciences\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.zhaw.ch\/icclab\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/aba82692aa266eab256d8df5ea04b06a\",\"name\":\"dudo\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/0df0ad477b78c3b2ef455cd33a99c552c77c6b80c18289b27b7036a0c7cff025?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/0df0ad477b78c3b2ef455cd33a99c552c77c6b80c18289b27b7036a0c7cff025?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/0df0ad477b78c3b2ef455cd33a99c552c77c6b80c18289b27b7036a0c7cff025?s=96&d=mm&r=g\",\"caption\":\"dudo\"},\"url\":\"https:\/\/blog.zhaw.ch\/icclab\/author\/dudo\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Manage instance startup order in OpenStack Heat Templates - Service Engineering (ICCLab &amp; SPLab)","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/","og_locale":"en_US","og_type":"article","og_title":"Manage instance startup order in OpenStack Heat Templates","og_description":"In many applications it is necessary to create virtual resources in a certain order. As an orchestration engine, Heat is able to support such a requirement, but how it is actually done\u00a0in a template can be tricky. Recently I had to write such a Heat template, which seemed pretty easy as there is a number [&hellip;]","og_url":"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/","og_site_name":"Service Engineering (ICCLab &amp; SPLab)","article_published_time":"2014-05-02T11:27:58+00:00","article_modified_time":"2014-05-07T12:01:52+00:00","author":"dudo","twitter_card":"summary_large_image","twitter_misc":{"Written by":"dudo","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/#article","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/"},"author":{"name":"dudo","@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/aba82692aa266eab256d8df5ea04b06a"},"headline":"Manage instance startup order in OpenStack Heat Templates","datePublished":"2014-05-02T11:27:58+00:00","dateModified":"2014-05-07T12:01:52+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/"},"wordCount":748,"commentCount":2,"articleSection":["Articles","HowTos","OpenStack"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/","url":"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/","name":"Manage instance startup order in OpenStack Heat Templates - Service Engineering (ICCLab &amp; SPLab)","isPartOf":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/#website"},"datePublished":"2014-05-02T11:27:58+00:00","dateModified":"2014-05-07T12:01:52+00:00","author":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/aba82692aa266eab256d8df5ea04b06a"},"breadcrumb":{"@id":"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.zhaw.ch\/icclab\/manage-instance-startup-order-in-openstack-heat-templates\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Startseite","item":"https:\/\/blog.zhaw.ch\/icclab\/"},{"@type":"ListItem","position":2,"name":"Manage instance startup order in OpenStack Heat Templates"}]},{"@type":"WebSite","@id":"https:\/\/blog.zhaw.ch\/icclab\/#website","url":"https:\/\/blog.zhaw.ch\/icclab\/","name":"Service Engineering (ICCLab &amp; SPLab)","description":"A Blog of the ZHAW Zurich University of Applied Sciences","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.zhaw.ch\/icclab\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blog.zhaw.ch\/icclab\/#\/schema\/person\/aba82692aa266eab256d8df5ea04b06a","name":"dudo","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/0df0ad477b78c3b2ef455cd33a99c552c77c6b80c18289b27b7036a0c7cff025?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/0df0ad477b78c3b2ef455cd33a99c552c77c6b80c18289b27b7036a0c7cff025?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/0df0ad477b78c3b2ef455cd33a99c552c77c6b80c18289b27b7036a0c7cff025?s=96&d=mm&r=g","caption":"dudo"},"url":"https:\/\/blog.zhaw.ch\/icclab\/author\/dudo\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/4862","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/users\/94"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/comments?post=4862"}],"version-history":[{"count":24,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/4862\/revisions"}],"predecessor-version":[{"id":4936,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/posts\/4862\/revisions\/4936"}],"wp:attachment":[{"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/media?parent=4862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/categories?post=4862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/tags?post=4862"},{"taxonomy":"features","embeddable":true,"href":"https:\/\/blog.zhaw.ch\/icclab\/wp-json\/wp\/v2\/features?post=4862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}