{"id":352,"date":"2013-02-22T07:06:23","date_gmt":"2013-02-22T07:06:23","guid":{"rendered":"http:\/\/corneliadavis.com\/blog\/?p=352"},"modified":"2013-02-22T07:06:23","modified_gmt":"2013-02-22T07:06:23","slug":"deploying-a-service-to-cloud-foundry-via-bosh","status":"publish","type":"post","link":"https:\/\/corneliadavis.com\/blog\/2013\/02\/22\/deploying-a-service-to-cloud-foundry-via-bosh\/","title":{"rendered":"Deploying a service to cloud foundry via BOSH"},"content":{"rendered":"<p>In this last of a three part series on learning how to add services to a Cloud Foundry cloud we\u2019ll deploy the echo service into a BOSH-based deployment.\u00a0 In <a href=\"http:\/\/corneliadavis.com\/blog\/2013\/01\/29\/the-anatomy-of-a-cloud-foundry-system-service-implementation\/\">part II<\/a> you\u2019ll find a more detailed description of the parts of a system service implementation, and also a description of and link to an updated version (updated from <a href=\"http:\/\/support.cloudfoundry.com\/entries\/20485171-how-to-add-a-system-service-to-oss-cloud-foundry-step-by-step-guide\">here<\/a>) of the echo server itself.\u00a0 If I\u2019m doing my job right, with this post you should have an \u201cah ha\u201d moment or two \u2013 as I already mentioned, I went through the exercise of learning about cloud foundry services in exactly the order mirrored with this series of blog posts, and a lot of things came together for me in this last step. So, let\u2019s get started.<\/p>\n<p>I\u2019m going to roughly follow the instructions posted <a href=\"https:\/\/github.com\/cloudfoundry\/vcap-services-sample-release\">here<\/a> \u2013 a BOSH release for the Echo Service. As I went through this exercise I was working off of an older version of this repository, with an <a href=\"https:\/\/github.com\/cloudfoundry\/vcap-services-sample-release\/tree\/c05e5956b09765d69b0d5537acb40ffaa7a9218f\">older version of the documentation<\/a>, where after cloning the repository you copy things from this directory into your cloud foundry release.\u00a0 The latest instructions point out that BOSH now supports having multiple releases for a single deployment, a way to modularize a deployment, so you no longer have to copy things into a single directory structure for the cloud foundry deployment.\u00a0 There is, however, something to be learned by copying things, so I\u2019ve decided to keep this post in the older style to allow me to sprinkle the process with some explanation \u2013 I\u2019ll refer to the steps as described in the <a href=\"https:\/\/github.com\/cloudfoundry\/vcap-services-sample-release\/tree\/c05e5956b09765d69b0d5537acb40ffaa7a9218f\">older version of the docs<\/a>.<\/p>\n<p><strong>Step 1<\/strong>: We already had a BOSH-based deployment of cloud foundry running in our lab.\u00a0 We started with the <a href=\"https:\/\/github.com\/cloudfoundry\/cf-release\">cf-release posted here<\/a> and modified it so that it consumed a few less resources (you would think as EMC that we would have all the vBlocks we need, but then you would be wrong ;-)) ; before adding the echo service we were running 34 vms.<\/p>\n<p>Step 2: Clone the repository (<a href=\"https:\/\/github.com\/cloudfoundry\/vcap-services-sample-release\">https:\/\/github.com\/cloudfoundry\/vcap-services-sample-release<\/a>).<\/p>\n<p>Step 3: Copy the job and package directories into your cloud foundry release.<\/p>\n<pre>cp -r vcap-services-sample-release\/jobs\/* cf-release\/jobs\/\ncp -r vcap-services-sample-release\/packages\/* cf-release\/packages\/<\/pre>\n<p>If you haven\u2019t already dug into the primary portions of a bosh release, here\u2019s a brief explanation:<\/p>\n<ul>\n<li>Packages describe all of the bits that will make their way onto the VMs that will run the service.\u00a0 Every service I have looked at or built myself has had at least a spec file and a packaging file.\n<ul>\n<li>The spec describes what is required for that service component \u2013 dependencies on other cloud foundry packages (like ruby or sqlite) or files that are a part of the cloud foundry release. This tells bosh during deployment to copy these artifacts onto the VM that will run this component.<\/li>\n<li>The packaging file is a script that runs after all of those bits have been delivered to the newly provisioned VM.\u00a0 It usually will involve things like untarring a file and moving the resultant bits into the appropriate location on the VM.<\/li>\n<li>Some packages will also have a prepackaging script that is run during the compiling of a package, before the VM is even provisioned.<\/li>\n<\/ul>\n<\/li>\n<li> Jobs represent the things that will be run on a VM and the files are generally start scripts and configuration files.\u00a0 What is really interesting here is that those start scripts and config files are found in a subdirectory of the jobs directory called \u201ctemplates.\u201d The fact that these are templates allows you to instantiate them with values at <strong>run time<\/strong>, allowing you to do things like supply IP addresses of running machines at the point where that IP address is actually known.<\/li>\n<\/ul>\n<p>There are two <span style=\"text-decoration: underline;\">other<\/span> major pieces of a BOSH release: 1) the blobs (which I\u2019ll get to in a moment) and 2) the source tree containing code bits that make up the pieces of a package (mentioned in the package \u201cspec\u201d above).\u00a0 I won\u2019t say much about the latter in this post except that for the echo service, and all the base cloud foundry services, those bits get into your cloud foundry release via some git magic \u2013 it\u2019s all in the .\/update command that you do after cloning the <a href=\"https:\/\/github.com\/cloudfoundry\/cf-release\">cf-release repository<\/a>. This draws the pieces for those services, the node and gateway implementations, from the <a href=\"https:\/\/github.com\/cloudfoundry\/vcap-services\">vcap-services repository<\/a>.<\/p>\n<p>Step 4: In this step you are asked to put metadata for the echo server blob into the \u2026\/cf-release\/config\/blobs.yml file. This step isn\u2019t needed at the moment, and in fact, the latest version of the docs for this sample release does not include it.<\/p>\n<p>Step 5: Add echo to the list of built in services by modifying the cloud_controller.yml.erb file adding \u2018echo\u2019 to the <a href=\"https:\/\/github.com\/cloudfoundry\/cf-release\/blob\/master\/jobs\/cloud_controller\/templates\/cloud_controller.yml.erb#L168\">line that starts with &#8220;services =&#8221;<\/a>.<\/p>\n<p>At this point the instructions tell you that you can do a bosh create release and a bosh upload release but there is one critical step missing \u2013 what about the actual EchoServer-0.1.0.jar? How do we get it running on one of the BOSH managed VMs?<\/p>\n<p>I mentioned above that in addition to the packages and jobs portions of a cloud foundry release, there are also blobs.\u00a0 For cloud foundry services these are generally the tar\/zip files that contain the actual servers that will provide the service capabilities; the postgresql-9.0-x86_64.tar.gz file or the redis-2.2.15.tar.gz, for example. For our sample service this is the <a href=\"https:\/\/github.com\/cdavisafc\/cloudfoundry-misc\/blob\/master\/EchoServer\/EchoServer_0.1.0.jar\">EchoServer-0.1.0.jar file<\/a>. There are a number of ways that you can structure your cf-release leveraging git to make this perhaps a bit more elegant, but for now we\u2019ll just do the brute force:<\/p>\n<ol>\n<li>Create the echoserver directory in the \u2026\/cf-release\/blobs directory.<\/li>\n<li>Drop the EchoServer-0.1.0.jar file from <a href=\"http:\/\/corneliadavis.com\/blog\/2013\/01\/29\/the-anatomy-of-a-cloud-foundry-system-service-implementation\/\">part II<\/a> in this series into that new echoserver directory.<\/li>\n<\/ol>\n<p>(Looking into several of the echo service files that were copied over into the cf-release you can find reference to that jar file in places like \u2026\/cf-release\/packages\/echoserver\/spec, \u2026\/cf-release\/packages\/echoserver\/packaging and \u2026\/cf-release\/jobs\/echo_node\/templates\/echoserver_ctl.)<\/p>\n<p>During the bosh create release this jar will then get included in the tar ball that is subsequently uploaded to and deployed into the cloud.<\/p>\n<p>Okay, so now for the good stuff. In <a href=\"http:\/\/corneliadavis.com\/blog\/2013\/01\/29\/the-anatomy-of-a-cloud-foundry-system-service-implementation\/\">part II<\/a> of my series I promised you that some of the ugliness around coordinating the command line arguments for running the Echo Server with values in the echo_node.yml file would get better with BOSH.\u00a0 You see, BOSH is now responsible for running both the Echo Server (starting it with a java command) and the echo_node, so there must be a way that we can coordinate these two things.\u00a0 There is.<\/p>\n<p>The single place that we will put values that will then be used by the Echo Server and the echo_node is in the deployment manifest.\u00a0 Under the properties: section you need to include the following:<\/p>\n<pre>  echo_gateway:\n    token: changeme\n    ip_route: ***.***.***.***\n  echoserver:\n    port: 5555<\/pre>\n<p>Then you have to see to it that the Echo Server and the echo_node pick up the port value appropriately.<\/p>\n<h3>Echo Server<\/h3>\n<p>In the \u2026\/cf-release\/jobs\/echo_node\/templates\/echoserver_ctl file you will find the java command that runs the echo server:<\/p>\n<pre>exec java \n    -jar EchoServer-0.1.0.jar \n    -port &lt;%= properties.echoserver &amp;&amp; properties.echoserver.port || 8080 %&gt; \n    &gt;&gt;$LOG_DIR\/echoserver.stdout.log \n    2&gt;&gt;$LOG_DIR\/echoserver.stderr.log<\/pre>\n<p>Enclosed in the &lt;%= %&gt; is a template expression (using ruby\u2019s erb feature) that pulls values from the deployment manifest.\u00a0 But our Echo Server also takes in an IP address so we need to update this execution to the following:<\/p>\n<pre>exec java \n    -jar EchoServer-0.1.0.jar \n    -ipaddress &lt;%= spec.networks.default.ip %&gt; \n    -port &lt;%= properties.echoserver &amp;&amp; properties.echoserver.port || 8080 %&gt; \n    &gt;&gt;$LOG_DIR\/echoserver.stdout.log \n    2&gt;&gt;$LOG_DIR\/echoserver.stderr.log<\/pre>\n<h3>echo_node<\/h3>\n<p>In the \u2026\/ cf-release\/jobs\/echo_node\/templates\/echo_node.yml.erb file you will find the port for the echo server specified; recall from Part II that the echo_node oversimplified so as to just return the port number that is specified in the _node.yml file.<\/p>\n<pre>port: &lt;%= properties.echoserver &amp;&amp; properties.echoserver.port || 8080 %&gt;<\/pre>\n<p>Of course, now you can see that the port in this config file is drawn from the same source as the port supplied to the Echo Server when it is started.\u00a0 Something you had to coordinate manually is now handled by BOSH.\u00a0 Coolness.<\/p>\n<p>Step 6: NOW you can do the bosh create and upload.\u00a0 Because we were updating an already deployed release we need to do:<\/p>\n<pre>bosh create release \u2013force<\/pre>\n<p>Followed by<\/p>\n<pre>bosh upload release<\/pre>\n<p>Step 7: And while we have already updated the deployment manifest with the properties for the node and gateway, you also have to update it to include the two jobs that will be part of our cloud foundry deployment. Note that each VM gets a single job, but that the echo_node job launches two processes, the echo_node implementation and the actual Echo Server. The following are roughly those parts taken from our deployment manifest; your mileage will vary depending on how you configured your cf-release deployment. Under the jobs: section:<\/p>\n<pre>- name: echo_node\n   template: echo_node\n   instances: 1\n   resource_pool: infrastructure1\n   persistent_disk: 128\n   networks:\n   - name: default\n     static_ips:\n     - ***.***.***.***\n\n - name: echo_gateway\n   template: echo_gateway\n   instances: 1\n   resource_pool: infrastructure1\n   networks:\n   - name: default\n     static_ips:\n     - ***.***.***.***<\/pre>\n<p>Oh, and we increased the size of our \u201cinfrastructure1\u201d resource pool by 2.\u00a0 Of course, you\u2019ll have to update the ***.***.***.*** IP addresses appropriately.<\/p>\n<p>Now do Step 8:<\/p>\n<pre>bosh deploy<\/pre>\n<p>You should now be able to push the same echo app as posted in <a href=\"http:\/\/corneliadavis.com\/blog\/2013\/01\/29\/the-anatomy-of-a-cloud-foundry-system-service-implementation\/\">Part II <\/a>of the series.<\/p>\n<p>Have fun!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this last of a three part series on learning how to add services to a Cloud Foundry cloud we\u2019ll deploy the echo service into a BOSH-based deployment.\u00a0 In part II you\u2019ll find a more detailed description of the parts of a system service implementation, and also a description of and link to an updated [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[5,13,21],"tags":[53],"class_list":["post-352","post","type-post","status-publish","format-standard","hentry","category-cloud","category-howto","category-paas","tag-cloudfoundry"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts\/352","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/comments?post=352"}],"version-history":[{"count":0,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts\/352\/revisions"}],"wp:attachment":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/media?parent=352"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/categories?post=352"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/tags?post=352"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}