{"id":2155,"date":"2015-10-28T16:34:28","date_gmt":"2015-10-28T23:34:28","guid":{"rendered":"https:\/\/www.microsoft.com\/reallifecode\/index.php\/2015\/10\/28\/cloud-foundry-elastic-containerized-applications-on-azure\/"},"modified":"2020-03-18T19:38:06","modified_gmt":"2020-03-19T02:38:06","slug":"cloud-foundry-elastic-containerized-applications-on-azure","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/ise\/cloud-foundry-elastic-containerized-applications-on-azure\/","title":{"rendered":"Cloud Foundry: Elastic Containerized Applications on Azure"},"content":{"rendered":"<p><a href=\"https:\/\/www.cloudfoundry.org\/\">Cloud Foundry<\/a> is an open source application platform that deploys, runs, and scales applications as containers. It enables developers to deploy and scale applications in minutes, regardless of the cloud provider or the development framework in use.<\/p>\n<p>Cloud Foundry has a solid reputation in the enterprise space powering products such as <a href=\"http:\/\/www.ibm.com\/cloud-computing\/bluemix\/?cm_mmc=search-gsn-_-branded-Bluemix-general-_-ibm%20bluemix-_-usa-bm-mkt-oww\">IBM Bluemix<\/a> and the Chinese mega search engine <a href=\"https:\/\/www.baidu.com\/\">Baidu<\/a>. You may have heard of the recent announcement for <a href=\"https:\/\/azure.microsoft.com\/en-us\/blog\/general-availability-of-cloud-foundry-and-preview-access-of-pivotal-cloud-foundry\/\">General Availability of Cloud Foundry Support on Microsoft Azure<\/a>.<\/p>\n<h2 id=\"what-is-cloud-foundry\">What is Cloud Foundry?<\/h2>\n<p>Cloud Foundry is an extensible, open source platform as a service that allows developers to build, deploy, and scale applications on both public and private cloud models. Similar to Heroku, developers can deploy applications using a variety of buildpacks to package the framework and\/or runtime dependencies required for their application. Applications deployed to Cloud Foundry access external resources such as databases, messaging systems, files systems and so on, via Services. These features allow developers to develop applications with a loosely coupled services architecture.<\/p>\n<p>What does this mean for you? Well as a developer, now you own the operation of the code you write while operations team handles the platform. You now have the autonomy to choose from various frameworks in the form of <a href=\"https:\/\/docs.cloudfoundry.org\/buildpacks\/\">buildpacks<\/a> for your application. You can <a href=\"https:\/\/docs.cloudfoundry.org\/devguide\/deploy-apps\/manifest.html\">deploy and scale<\/a> your application to a variety of public and private cloud providers without bugging your operations team. You can even <a href=\"http:\/\/docs.cloudfoundry.org\/services\/\">publish your services<\/a> for other developers to consume or simply <a href=\"https:\/\/docs.cloudfoundry.org\/devguide\/services\/application-binding.html\">bind your application to services already in the marketplace<\/a>. In this post, you will learn how to provision your own Cloud Foundry cluster and how to deploy and scale your application to Cloud Foundry on Azure.<\/p>\n<h2 id=\"the-problem\">The Problem<\/h2>\n<p>Prior to our engagement, installing and pushing apps to Cloud Foundry (CF) on Azure was almost impossible, thus making hybrid CF deployments between on-premises and cloud workloads difficult when using Azure. Deploying Cloud Foundry involves interfacing with the underlying infrastructure using <a href=\"https:\/\/github.com\/cloudfoundry\/bosh\">BOSH<\/a>, an open source tool-chain for release engineering, deployment, and lifecycle management of large-scale distributed services. The benefit of having BOSH, like many other infrastructure-as-code solutions, is that the operations team can use it to author and maintain a single cloud-agnostic solution across all different cloud and on-premises infrastructures. BOSH provides the abstraction layer on top of each cloud provider\u2019s IaaS details. In order to deploy Cloud Foundry on Azure, we needed to implement a <a href=\"https:\/\/github.com\/cloudfoundry-incubator\/bosh-azure-cpi-release\">BOSH Cloud Provider Interface for Azure<\/a> that enables BOSH to install and update software packages on Azure VMs.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2020\/03\/2015-10-28-Cloud-Foundry-azure-login.png\" alt=\"Cloud Foundry Login\" \/><\/p>\n<h2 id=\"overview-of-the-solution\">Overview of the Solution<\/h2>\n<p>We partnered with Pivotal Labs, the maintainer of Cloud Foundry and BOSH, and the Azure Open Source Technology Center in Shanghai to enable Cloud Foundry deployments on Azure. As a result of our engagement, Microsoft recently announced the <a href=\"https:\/\/azure.microsoft.com\/en-us\/blog\/general-availability-of-cloud-foundry-and-preview-access-of-pivotal-cloud-foundry\/\">General Availability of Cloud Foundry Support on Microsoft Azure<\/a>.<\/p>\n<p>Deploying Cloud Foundry involves interfacing with the underlying infrastructure using BOSH. In order to deploy Cloud Foundry on Azure, we implemented an interface that enables BOSH to install and update software packages on Azure VMs. We then provided automation to provision the required storage, network, VM resources to deploy BOSH components on Azure. Once BOSH is deployed, we provide documentation for you to provision your own Cloud Foundry cluster on Azure using BOSH.<\/p>\n<p>In detail, to deploy and manage a Cloud Foundry cluster on Azure, we needed to do the following:<\/p>\n<ul>\n<li>Develop a <a href=\"https:\/\/github.com\/cloudfoundry-incubator\/bosh-azure-cpi-release\">BOSH Cloud Provider Interface for Azure<\/a> that enables BOSH to install and update software packages on Azure VMs<\/li>\n<li>Develop an <a href=\"https:\/\/github.com\/Azure\/azure-quickstart-templates\/tree\/master\/bosh-setup\">Azure Resource Manager (ARM) template<\/a> that can provision the following Azure resources required to deploy BOSH-managed infrastructure on Azure:\n<ul>\n<li>A storage account<\/li>\n<li>Two reserved public IP addresses<\/li>\n<li>Two subnets<\/li>\n<li>A virtual network<\/li>\n<li>A dev virtual machine with a public IP address on the same VNET as BOSH VM and Cloud Foundry VMs<\/li>\n<li>A resource group (if one does not already exist)<\/li>\n<\/ul>\n<\/li>\n<li>Create a <a href=\"https:\/\/github.com\/Azure\/azure-quickstart-templates\/blob\/master\/bosh-setup\/scripts\/setup_env.py\">script to install prerequisites on dev VM<\/a> to prep it for deploying BOSH director and Cloud Foundry. For a list of prerequisites this installs, you can view the following scripts:\n<ul>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-quickstart-templates\/blob\/master\/bosh-setup\/\">init.sh<\/a>: update package lists from repositories, update install prerequisites, updates Ruby, install gem prerequisites, and install <a href=\"https:\/\/bosh.io\/docs\/bosh-cli.html\">BOSH CLI<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/Azure\/azure-quickstart-templates\/blob\/master\/bosh-setup\/scripts\/setup_env.py\">setup_devbox.py<\/a>: copy scripts and configuration files, update parameters in definition file with current infrastructure value, create and copy cert and public key for SSH, and configure DNS<\/li>\n<\/ul>\n<\/li>\n<li>Document how to deploy a <a href=\"https:\/\/bosh.io\/docs\/bosh-components.html#director\">BOSH director<\/a>, the core orchestrating component in BOSH that controls VM creation and deployment, to manage infrastructure on Azure<\/li>\n<li>Document how to deploy Cloud Foundry through BOSH<\/li>\n<\/ul>\n<h2 id=\"deploying-cloud-foundry-on-azure---simplified\">Deploying Cloud Foundry on Azure &#8211; Simplified<\/h2>\n<p>Now that we have a <a href=\"https:\/\/github.com\/cloudfoundry-incubator\/bosh-azure-cpi-release\">BOSH Cloud Provider Interface for Azure<\/a> and an <a href=\"https:\/\/github.com\/Azure\/azure-quickstart-templates\/tree\/master\/bosh-setup\">Azure Resource Manager (ARM) template<\/a>, it\u2019s much easier to provision your own BOSH director and our very own Cloud Foundry cluster.<\/p>\n<h3 id=\"provision-with-azure-template\">Provision with Azure Template<\/h3>\n<p>First we need to create all the Azure resources required to provision a <a href=\"https:\/\/bosh.io\/docs\/bosh-components.html#director\">BOSH director<\/a>, which is required to deploy BOSH-managed infrastructure on Azure.<\/p>\n<p>Navigate to <a href=\"https:\/\/github.com\/Azure\/azure-quickstart-templates\/tree\/master\/bosh-setup\">Azure Resource Manager (ARM) template for BOSH<\/a>, click the blue <strong>Deploy to Azure<\/strong> button.<\/p>\n<p>You will be taken to the <a href=\"https:\/\/portal.azure.com\">Azure Portal<\/a> to provide values for the parameters to create all the necessary resources. Please be sure to provide unique names for your values. We recommend providing <code class=\"highlighter-rouge\">TENANT-ID<\/code>, <code class=\"highlighter-rouge\">CLIENT-ID<\/code>, <code class=\"highlighter-rouge\">CLIENTSECRET<\/code> as part of the ARM template deployment in the Azure portal. If you decide to leave them out, then you will need to update these three properties in ~\/bosh.yml on the dev VM. To create <code class=\"highlighter-rouge\">CLIENT-ID<\/code> and <code class=\"highlighter-rouge\">CLIENTSECRET<\/code>, follow these <a href=\"https:\/\/github.com\/cloudfoundry-incubator\/bosh-azure-cpi-release\/blob\/master\/docs\/get-started\/create-service-principal.md\">steps<\/a>. You should already have a <code class=\"highlighter-rouge\">TENANT-ID<\/code>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/cse\/wp-content\/uploads\/sites\/55\/2020\/03\/2015-10-28-Cloud-Foundry-azure-armtemplate.png\" alt=\"ARM Template\" \/><\/p>\n<h3 id=\"deploy-bosh-director\">Deploy BOSH Director<\/h3>\n<p>The previous step copied scripts, keys, and configuration files we need to deploy BOSH Director.<\/p>\n<p>Once the required resources are created from the previous step, SSH into the new dev VM. You can find the public IP of the VM in <a href=\"https:\/\/portal.azure.com\/\">Azure Portal<\/a>.<\/p>\n<p>Run the following command in your home directory to deploy BOSH Director. This <a href=\"https:\/\/github.com\/Azure\/azure-quickstart-templates\/blob\/master\/bosh-setup\/scripts\/deploy_bosh.sh\"><code class=\"highlighter-rouge\">deploy_bosh.sh<\/code><\/a> script uses <a href=\"https:\/\/bosh.io\/docs\/bosh-cli.html\">BOSH CLI<\/a> and the <a href=\"https:\/\/github.com\/Azure\/azure-quickstart-templates\/blob\/master\/bosh-setup\/manifests\/bosh.yml\"><code class=\"highlighter-rouge\">bosh.yml<\/code><\/a> configuration file that contains values from your previous Azure template deployment to deploy a new BOSH Director.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ .\/deploy_bosh.sh\r\n<\/code><\/pre>\n<\/div>\n<p>This step can take a bit of time to run since all the binaries need to be uploaded to Azure blob storage before the BOSH Director VM is created, and then bound to the private IP of <code class=\"highlighter-rouge\">10.0.0.4<\/code>. You can change these behaviors by modifying <code class=\"highlighter-rouge\">bosh.yml<\/code> in your home directory on the dev VM. You can also view verbose logs in <code class=\"highlighter-rouge\">~\/run.log<\/code>.<\/p>\n<p>Once we have successfully deployed BOSH Director, we can use it to deploy Cloud Foundry.<\/p>\n<p>Connect to BOSH Director for ongoing tasks<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ bosh target 10.0.0.4 # User name: admin; Password: admin\r\n<\/code><\/pre>\n<\/div>\n<p>Get UUID of your BOSH director<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ bosh status\r\n<\/code><\/pre>\n<\/div>\n<p>Get the value of UUID from the output that looks similar to the following and use it for next step<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>Director\r\n  Name       bosh\r\n  URL        https:\/\/10.0.0.4:25555\r\n  Version    1.0000.0 (00000000)\r\n  User       not logged in\r\n  UUID       71fc4763-a2b3-40d5-8d40-dea03602c0f5\r\n  CPI        cpi\r\n  dns        disabled\r\n  compiled_package_cache disabled\r\n  snapshots  enabled\r\n\r\nDeployment\r\n  not set\r\n<\/code><\/pre>\n<\/div>\n<h3 id=\"deploy-cloud-foundry\">Deploy Cloud Foundry<\/h3>\n<p>Now that we have a BOSH Director, we can use it to deploy Cloud Foundry. To deploy anything with BOSH, you are required to have a definition file that tells BOSH the OS to run, the binaries to install, the scripts to run, and the infrastructure resources to create.<\/p>\n<p>Use BOSH CLI to upload the latest <code class=\"highlighter-rouge\">stemcell<\/code>, a bare minimum OS image for Ubuntu with Azure specific configurations and agents. A <a href=\"https:\/\/bosh.io\/docs\/stemcell.html\">stemcell<\/a> is a versioned Operating System image wrapped with IaaS specific packaging. You can head over to <a href=\"https:\/\/bosh.io\/stemcells\">bosh.io\/stemcells<\/a> for full list of all stemcells for all OS and cloud providers. Replace <code class=\"highlighter-rouge\">STEMCELL-FOR-AZURE-URL<\/code> with the URL of the latest stemcell for Ubuntu on Azure.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ bosh upload stemcell STEMCELL-FOR-AZURE-URL\r\n<\/code><\/pre>\n<\/div>\n<p>Use BOSH CLI to upload the latest Cloud Foundry release. For example, if you want to use release version 212, you can upload that specific release.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ bosh upload release https:\/\/bosh.io\/d\/github.com\/cloudfoundry\/cf-release?v=212\r\n<\/code><\/pre>\n<\/div>\n<p>Update deployment file for your Cloud Foundry cluster with your current infrastructure values<\/p>\n<p>Use this sample Cloud Foundry deployment <a href=\"https:\/\/github.com\/cloudfoundry-incubator\/bosh-azure-cpi-release\/blob\/master\/docs\/stubs\/cf\/cf-stub.yml\">cf-stub.yml<\/a> file as a reference. You can update infrastructure values with your own, such as <code class=\"highlighter-rouge\">director_uuid<\/code>, <code class=\"highlighter-rouge\">virtual_network_name<\/code>, <code class=\"highlighter-rouge\">subnet_name<\/code>, <code class=\"highlighter-rouge\">static_ips<\/code>, <code class=\"highlighter-rouge\">ssl_pem<\/code>, and <code class=\"highlighter-rouge\">domain<\/code>.<\/p>\n<blockquote><p>Note this deployment is for CF release v212. For other CF release versions, you can refer to the official CF release <a href=\"https:\/\/github.com\/cloudfoundry\/cf-release\/tree\/master\/templates\">templates<\/a> to create your own cf.yml template for a specific cf release.<\/p><\/blockquote>\n<ul>\n<li>For <code class=\"highlighter-rouge\">director_uuid<\/code>, use the same UUID you got from <code class=\"highlighter-rouge\">$ bosh status<\/code> in the previous step.<\/li>\n<li>For <code class=\"highlighter-rouge\">virtual_network_name<\/code> and <code class=\"highlighter-rouge\">subnet_name<\/code>, use the same values you provided at the time of provisioning Azure resources using the Azure template.<\/li>\n<li>For <code class=\"highlighter-rouge\">static_ips<\/code>, use the public IP generated for Cloud Foundry in the previous resource provision step. From the Azure portal, under the resource group you have provisioned, use the public IP: XXXX_cf. Then look for the following in the cf.yml file and replace the IP with the public IP address created for Cloud Foundry.\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>static_ips: [public ip] # &lt;--- Replace with your reserved public IP address for Cloud Foundry\r\n<\/code><\/pre>\n<\/div>\n<\/li>\n<li>For <code class=\"highlighter-rouge\">ssl_pem<\/code>, you can concatenate the bosh certification in the bosh.yml file and the bosh private key on the dev VM and replace <code class=\"highlighter-rouge\">SSL-CERT-AND-KEY<\/code> in the cf.yml file.\n<ul>\n<li>To get the content of the bosh certificate, ssh into the dev VM, then run the following command and copy the entire content under <code class=\"highlighter-rouge\">ssh_certificate<\/code>: <code class=\"highlighter-rouge\">$ cat bosh.yml<\/code><\/li>\n<li>Then to get the content of the bosh private key, run the following command and copy the entire output. <code class=\"highlighter-rouge\">$ cat bosh<\/code><\/li>\n<li>After concatenating the two values, place the content under <code class=\"highlighter-rouge\">ssl_pem<\/code>. The end result should look similar to the following:<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>ssl_pem: |\r\n        -----BEGIN CERTIFICATE-----\r\n        [omit for brevity]\r\n        -----END CERTIFICATE-----\r\n        -----BEGIN RSA PRIVATE KEY-----\r\n        [omit for brevity]\r\n        -----END RSA PRIVATE KEY-----\r\n<\/code><\/pre>\n<\/div>\n<p>After you have updated all the necessary values in the cf_212.yml, <code class=\"highlighter-rouge\">scp<\/code> to copy the file from local machine to the dev VM. Then from the dev VM, enter the following command on the dev VM to let BOSH use this file for your next deployment.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ bosh deployment cf_212.yml\r\n<\/code><\/pre>\n<\/div>\n<p>Use BOSH to deploy your Cloud Foundry cluster<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ bosh deploy\r\n<\/code><\/pre>\n<\/div>\n<blockquote><p>This step will take some time as Azure provisions all the <a href=\"https:\/\/docs.cloudfoundry.org\/concepts\/architecture\/\">components for Cloud Foundry<\/a>.<\/p><\/blockquote>\n<p>Once this is completed successfully, we can now use CF CLI to communicate with our Cloud Foundry cluster to push apps and deploy services.<\/p>\n<h2 id=\"deploy-your-app-in-minutes\">Deploy Your App in Minutes<\/h2>\n<p>Now that you have your own Cloud Foundry instance, let\u2019s deploy a Java application.<\/p>\n<p>First, let\u2019s get the Cloud Foundry CLI on our dev machine<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ curl -L \"https:\/\/cli.run.pivotal.io\/stable?release=linux64-binary&amp;source=github\" | tar -zx\r\n<\/code><\/pre>\n<\/div>\n<p>Once the CF CLI is on the machine, add it to your environment path.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ export PATH=$HOME:$PATH\r\n<\/code><\/pre>\n<\/div>\n<p>or add the below line to your <code class=\"highlighter-rouge\">$ vi ~\/.bash_profile<\/code><\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>export PATH=[[home directory path]]:$PATH\r\n<\/code><\/pre>\n<\/div>\n<p>Check CF CLI version:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf --version\r\n<\/code><\/pre>\n<\/div>\n<p>Use CF CLI to connect to your new Cloud Foundry instance<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf api api.cf.azurelovecf.com --skip-ssl-validation\r\n<\/code><\/pre>\n<\/div>\n<p>Login with CF<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf login\r\n# If you used the reference configuration, login is Email: admin; Password: c1oudc0w\r\n<\/code><\/pre>\n<\/div>\n<p>The output should look similar to this:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>API endpoint:   https:\/\/api.cf.azurelovecf.com (API version: 2.29.0)   \r\nUser:           admin   \r\nOrg:            default_organization\r\n<\/code><\/pre>\n<\/div>\n<p>Cloud Foundry has concepts of <a href=\"http:\/\/docs.cloudfoundry.org\/concepts\/roles.html\">Orgs, Spaces, Roles, and Permissions<\/a>. It uses role-based access control (RBAC) to grant permission to resources in either an org or a space. At this point, there is only one organization and nothing else is created. In order to push an app, we need to have a space.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf create-space dev\r\n<\/code><\/pre>\n<\/div>\n<p>Let\u2019s clone a Java application from Cloud Foundry samples on github to our dev machine.<\/p>\n<blockquote><p>If the machine does not already have git installed, do the following:<\/p><\/blockquote>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ sudo apt-get install git\r\n<\/code><\/pre>\n<\/div>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ git clone https:\/\/github.com\/cloudfoundry-samples\/spring-music.git\r\n<\/code><\/pre>\n<\/div>\n<blockquote><p>To learn more about how to prepare your application for Cloud Foundry deployment, you can follow this <a href=\"https:\/\/github.com\/cloudfoundry-samples\/spring-music.git\">Java sample<\/a>.<\/p><\/blockquote>\n<p>Next let\u2019s build our Java app with Gradle. Change directory into the recently cloned Java project.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cd spring-music\/\r\n<\/code><\/pre>\n<\/div>\n<blockquote><p>If the machine does not already have Java installed, for example if you get: <code class=\"highlighter-rouge\">ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH<\/code>, do the following:<\/p><\/blockquote>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ sudo add-apt-repository ppa:webupd8team\/java -y\r\n$ sudo apt-get update\r\n$ sudo apt-get install oracle-java8-installer\r\n$ java -version         # Confirm your Java installation\r\n<\/code><\/pre>\n<\/div>\n<p>Build the Java app with Gradle<\/p>\n<blockquote><p>If the machine does not already have Gradle installed, do the following:<\/p><\/blockquote>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ sudo apt-get install gradle\r\n<\/code><\/pre>\n<\/div>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ .\/gradlew assemble\r\nDownloading https:\/\/services.gradle.org\/distributions\/gradle-2.3-all.zip\r\n......\r\nBUILD SUCCESSFUL\r\n<\/code><\/pre>\n<\/div>\n<p>We are ready to push the app!<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf push\r\nUsing manifest file \/home\/ritacfvmadmin\/spring-music\/manifest.yml\r\n\r\nCreating app spring-music in org default_organization \/ space dev as admin...\r\nOK\r\n\r\nCreating route spring-music-subnutritious-monolithism.cf.azurelovecf.com...\r\nOK\r\n\r\nBinding spring-music-subnutritious-monolithism.cf.azurelovecf.com to spring-music...\r\nOK\r\n\r\nUploading spring-music...\r\n...\r\n\r\n<\/code><\/pre>\n<\/div>\n<p>At the end of the output, you should see the app has been deployed and is now in the <code class=\"highlighter-rouge\">running<\/code> state. To confirm, you can always run the <code class=\"highlighter-rouge\">cf apps<\/code> command to view all apps or just <code class=\"highlighter-rouge\">cf app [your app name]<\/code> to view information about that specific app.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf apps\r\nGetting apps in org default_organization \/ space dev as admin...\r\nOK\r\n\r\nname           requested state   instances   memory   disk   urls   \r\nspring-music   started           1\/1         512M     1G     spring-music-subnutritious-monolithism.cf.azurelovecf.com\r\n\r\n<\/code><\/pre>\n<\/div>\n<h2 id=\"scale-your-app-with-one-command\">Scale Your App with One Command<\/h2>\n<p>Now that your app is running happily in Cloud Foundry, what if we want to scale it up to provide high-availability? All you need to do is run the following command.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf scale spring-music -i 2\r\n\r\nCheck app state\r\n$ cf app spring-music\r\nShowing health and status for app spring-music in org default_organization \/ space dev as admin...\r\nOK\r\n\r\nrequested state: started\r\ninstances: 2\/2\r\nusage: 512M x 2 instances\r\nurls: spring-music-subnutritious-monolithism.cf.azurelovecf.com\r\nlast uploaded: Thu Oct 29 21:24:47 UTC 2015\r\nstack: cflinuxfs2\r\nbuildpack: java-buildpack=v3.0-https:\/\/github.com\/cloudfoundry\/java-buildpack.git#3bd15e1 open-jdk-jre=1.8.0_65 spring-auto-reconfiguration=1.10.0_RELEASE tomcat-access-logging-support=2.4.0_RELEASE tomcat-instance=8.0.28 tomcat-lifecycle-support=2.4.0_RELEASE to...\r\n\r\n     state     since                    cpu    memory           disk           details   \r\n#0   running   2015-10-30 01:15:51 PM   0.1%   510.8M of 512M   153.6M of 1G      \r\n#1   running   2015-10-30 04:43:30 PM   0.2%   491.9M of 512M   153.6M of 1G      \r\n<\/code><\/pre>\n<\/div>\n<h2 id=\"register-a-publicly-accessible-domain\">Register a Publicly Accessible Domain<\/h2>\n<p>This is all great, but if users can\u2019t actually access the newly deployed app, it\u2019s pretty useless. Cloud Foundry allows us to register as many <a href=\"https:\/\/docs.cloudfoundry.org\/devguide\/deploy-apps\/domains-routes.html#assign-domains-hosts\">domains<\/a> as we want. Now let\u2019s leverage that public IP address that was created for Cloud Foundry at the beginning. With the goodness of <a href=\"http:\/\/xip.io\/\">xip.io<\/a>, you can use your public IP address as its own domain. We can now change your app domain from <code class=\"highlighter-rouge\">cf.azurelovecf.com<\/code> to <code class=\"highlighter-rouge\">[Cloud Foundry public ip].xip.io<\/code>.<\/p>\n<p>First we need to create a new domain with our public IP address<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf create-domain default_organization 137.116.77.xx.xip.io\r\nCreating domain 137.116.77.xxx.xip.io for org default_organization as admin...\r\nOK\r\n<\/code><\/pre>\n<\/div>\n<p>To verify that we now have a new domain<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf domains\r\nGetting domains in org default_organization as admin...\r\nname                    status   \r\ncf.azurelovecf.com      shared   \r\n137.116.77.xxx.xip.io   owned  \r\n<\/code><\/pre>\n<\/div>\n<p>To map existing apps to this new domain, we need to create a new route within our dev space<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf create-route dev 137.116.77.xxx.xip.io -n springapp\r\nCreating route springapp.137.116.77.xxx.xip.io for org default_organization \/ space dev as admin...\r\nOK\r\n<\/code><\/pre>\n<\/div>\n<p>Now, Let\u2019s map the new route to your app<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf map-route spring-music 137.116.77.xxx.xip.io -n springapp\r\nCreating route springapp.137.116.77.xxx.xip.io for org default_organization \/ space dev as admin...\r\nOK\r\nRoute springapp.137.116.77.xxx.xip.io already exists\r\nAdding route springapp.137.116.77.xxx.xip.io to app spring-music in org default_organization \/ space dev as admin...\r\nOK\r\n<\/code><\/pre>\n<\/div>\n<p>Now if you view your app, you will see two routes\/URLs mapped to it<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>$ cf apps\r\nGetting apps in org default_organization \/ space dev as admin...\r\nOK\r\n\r\nname           requested state   instances   memory   disk   urls  \r\nspring-music   started           2\/2         512M     1G     spring-music-subnutritious-monolithism.cf.azurelovecf.com, springapp.137.116.77.xxx.xip.io\r\n\r\n<\/code><\/pre>\n<\/div>\n<p>From your browser, you can now view and perform basic CRUD operations in the app by using <code class=\"highlighter-rouge\">http:\/\/springapp.137.116.77.xxx.xip.io<\/code>.<\/p>\n<h2 id=\"challenges\">Challenges<\/h2>\n<p>There were lots of challenges bringing the Cloud Foundry PaaS onto Azure. Most issues were around its own tooling and providing certain workarounds due to Azure specific behaviors. To enable Cloud Foundry on Azure, we had to first make BOSH work on Azure and then make <a href=\"http:\/\/concourse.ci\/\">Concourse CI<\/a> work to test each CPI (Cloud Provider Interface) release. To read more about how we enabled Concourse CI on Azure to perform end to end test of the Azure BOSH CPI (Cloud Provider Interface), head over to our post on <a href=\"\/developerblog\/2015\/08\/30\/containerized-ci-with-concourse-on-azure\/\">Containerized CI with Concourse on Azure<\/a>.<\/p>\n<p>Another issue we uncovered is the lack of client-side timeouts for the <a href=\"https:\/\/github.com\/ritazh\/azure-sdk-for-ruby\">Azure Ruby SDK<\/a> which impacted the upload of large blobs to Azure blob storage, which resulted in deployment failures. We were able to work with the Azure engineering team to identify the issue and provided a fix to the Azure Ruby SDK to provide <a href=\"https:\/\/github.com\/ritazh\/azure-sdk-for-ruby\/tree\/featclienttimeout\">client-side timeouts<\/a> for the rare instance when it\u2019s necessary.<\/p>\n<h2 id=\"opportunities-for-reuse\">Opportunities for Reuse<\/h2>\n<p>The BOSH Azure CPI (Cloud Provider Interface) will be used by all customers who will be deploying Cloud Foundry or BOSH on Azure. It will be used for all things that need to be deployed and managed using BOSH on Azure. We have already started to leverage the BOSH Azure CPI to deploy Concourse CI to Azure to test new releases of BOSH Azure CPI. We were able to unblock Cloud Foundry deployments for a couple of our enterprise customers. In addition, the Azure Resource Management template is a huge time saver for anyone wishing to run their own Cloud Foundry cluster.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This code story discusses how we enabled Cloud Foundry deployment on Azure by implementing an interface that enables BOSH to install and update software packages on Azure VMs. We also provide documentation for you to provision your own Cloud Foundry cluster on Azure using BOSH.<\/p>\n","protected":false},"author":21378,"featured_media":12807,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[16],"tags":[60,118],"class_list":["post-2155","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops","tag-azure","tag-cloud-foundry"],"acf":[],"blog_post_summary":"<p>This code story discusses how we enabled Cloud Foundry deployment on Azure by implementing an interface that enables BOSH to install and update software packages on Azure VMs. We also provide documentation for you to provision your own Cloud Foundry cluster on Azure using BOSH.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2155","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/users\/21378"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/comments?post=2155"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2155\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media\/12807"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media?parent=2155"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/categories?post=2155"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/tags?post=2155"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}