Run Cloud Foundry on your own Laptop
(*yes*, the whole enchilada)
You’ve probably read much recently about SAP adding Cloud Foundry in Cloud Platform. There’s a lot to like about Cloud Foundry as an application platform – its support for more languages and runtimes, its community open source approach – and, for SAP Cloud Platform, it runs as a true Platform as a Service.
I tend to learn things by tearing them apart. I was pleased to learn that Cloud Foundry has a capability to basically run the entire Cloud Foundry infrastructure on a single laptop.
Normally Cloud Foundry will run atop a full-blown IaaS infrastructure: AWS, Azure, GCP or OpenStack. There’s an abstraction layer call the Cloud Provider Interface (CPI) that drives that freedom of choice. The developer configuration of Cloud Foundry is known as BOSH-Lite and it, well, crams all the runtime components of CF into a single virtual machine.
Why bother when you could do this in the cloud in the first place? For me, it’s a learning choice. PaaS is great; I mean really, really great, but to truly grok something we often need to get a really deep look. Deploying CF on your own machine gives you a pathway to do that without a significant time investment or the cost of running multiple VMs in the cloud.
It’s worth saying that this installation is by no means a production configuration. A fully scalable and hardened Cloud Foundry installation takes a fair investment in time and hardware – that said, this is still a great way to get acquainted with CF components at a very deep level.
Lets get started
Cloud Foundry installation is highly scripted. You will find that you don’t have to do too many steps manually to get this running. You’ll only need a system with these resources:
- A Mac or Linux machine
- 16GB main memory (we’re going to build an 8GB VM)
- A live network connection (at least for general programming, you can’t run disconnected)
- VirtualBox 5.1.x or later (download from here)
- Roughly 40GB free disk space
The procedure to get this running has evolved over the past six months. The most recent (and accurate) blog I have encountered was this article, authored by Christopher Banck. There’s a few crucial spots where I deviate from the procedure he described, so I’ll list everything here.
Step 1. Verify your VirtualBox installation
you should see something like this::
Ensure your version is 5.1 or later. If not, you will need to upgrade.
Step 2. Download, install and verify the latest version of the BOSH2 CLI
Use the instructions at this web site: https://bosh.io/docs/cli-v2.html
Step 3. Download and install the cf command line
You can follow this guide.
Step 4. Clone BOSH Deployment and install BOSH Lite.
mkdir ~/workspace mkdir ~/deployments git clone https://github.com/cloudfoundry/bosh-deployment ~/workspace/bosh-deployment mkdir -p ~/deployments/vbox cd ~/deployments/vbox
In order to configure BOSH-lite to give you an 8GB VM, you will need to edit the file ~/workspace/bosh-deployment/virtualbox/cpi.yml ; change the 4096 MB memory specification to 8192:
- memory: 4096 + memory: 8192
You can now install the BOSH-lite Director into a VM
bosh create-env ~/workspace/bosh-deployment/bosh.yml \ --state ~/deployments/vbox/state.json \ -o ~/workspace/bosh-deployment/virtualbox/cpi.yml \ -o ~/workspace/bosh-deployment/virtualbox/outbound-network.yml \ -o ~/workspace/bosh-deployment/bosh-lite.yml \ -o ~/workspace/bosh-deployment/bosh-lite-runc.yml \ -o ~/workspace/bosh-deployment/jumpbox-user.yml \ --vars-store ~/deployments/vbox/creds.yml \ -v director_name="Bosh Lite Director" \ -v internal_ip=192.168.50.6 \ -v internal_gw=192.168.50.1 \ -v internal_cidr=192.168.50.0/24 \ -v outbound_network_name=NatNetwork
We then use BOSH to alias the environment we just created. We also save some environment variables for later use.
bosh -e 192.168.50.6 --ca-cert <(bosh int ~/deployments/vbox/creds.yml \ --path /director_ssl/ca) alias-env vbox
export BOSH_CA_CERT=$(bosh int ~/deployments/vbox/creds.yml --path /director_ssl/ca) export BOSH_CLIENT=admin export BOSH_CLIENT_SECRET=$(bosh int ~/deployments/vbox/creds.yml --path /admin_password) export BOSH_ENVIRONMENT=vbox
Step 4. Clone and Configure Cloud Foundry
git clone https://github.com/cloudfoundry/cf-deployment ~/workspace/cf-deployment cd ~/workspace/cf-deployment
upload the appropriate bosh stemcell:
export STEMCELL_VERSION=$(bosh int ~/workspace/cf-deployment/cf-deployment.yml \ --path /stemcells/alias=default/version) bosh upload-stemcell \ https://bosh.io/d/stemcells/bosh-warden-boshlite-ubuntu-trusty-go_agent?v=$STEMCELL_VERSION
Update the cloud configuration to reflect that we’ll be running in BOSH-lite:
bosh update-cloud-config ~/workspace/cf-deployment/iaas-support/bosh-lite/cloud-config.yml
Step 5. Install Cloud Foundry
The default cf deployment will have a baked-in OAuth2 problem with HTTPS. It turns out that the UAA authentication server – the authentication server that you’ll likely use to issue OAuth2 tickets – will not be trusted by any client application using HTTPS. That’s because the host certificate is self-signed. This issue is easy enough to fix. Download the specific patch script I created. We’ll use it in the actual deployment.
pushd operations/experimental/ wget https://raw.githubusercontent.com/rrainey/cf-local-tools/master/cf-deployment/operations/experimental/trust-route-ca.yml popd
Now execute the deployment; the reference to trust-route-ca.yml patches the deployment to install the Router CA certificate, thus allowing HTTPS client access to UAA to be trusted:
bosh -e vbox -d cf deploy cf-deployment.yml \ -o operations/bosh-lite.yml \ --vars-store deployment-vars.yml \ -v system_domain=bosh-lite.com \ -o operations/experimental/enable-instance-identity-credentials.yml \ -o operations/experimental/trust-route-ca.yml \ -o ~/workspace/cf-deployment/operations/use-compiled-releases.yml
Step 6. Verify that all the expected processes are running
bosh -e vbox -d cf instances
Step 7. Update network routing
You must now add a route to allow your machine to communicate with the BOSH-lite VM containers.
sudo route add -net 10.244.0.0/16 192.168.50.6
Step 8. Create an Organization and Space
We can now switch over to communicating via the cf command line. Note that the target domain, bosh-lite.com, actually resolves to an IP address inside your VirtualBox VM. Also note that the deployment scripts have auto-generated passwords for your use. The following commands grab those passwords as environment variables — depending on your inclination, you might consider deleting those environment variables when you are done using them here.
cd ~/workspace/cf-deployment cf api https://api.bosh-lite.com --skip-ssl-validation export CF_ADMIN_PASSWORD=$(bosh int ./deployment-vars.yml --path /cf_admin_password) cf auth admin $CF_ADMIN_PASSWORD export UAA_PASSWORD=$(bosh int ./deployment-vars.yml --path /uaa_admin_client_secret) cf create-org "mycloud" cf target -o "mycloud" cf create-space dev cf target -o "mycloud" -s "dev"
Step 9. Deploy and run a sample application
cd ~ git clone https://github.com/vchrisb/cf-helloworld ~/workspace/cf-helloworld cd ~/workspace/cf-helloworld cf push
Once the push operation completes, you will be able to access the application at the url http://cf-helloworld.bosh-lite.com/
Where to from here?
At this point you have a verified operational Cloud Foundry instance running on your machine. In the next article, I’ll show some examples of working with UAA, OAuth2, and Spring Boot in this environment. In the meantime, feel free to start your own experimenting.
An important postscript
If you are disconnecting your laptop from a network, I’ve found that it is generally a good idea to pause the BOSH-lite VM. You can do this either from the VirtualBox UI or from the command line:
vboxmanage controlvm $(bosh int ~/deployments/vbox/state.json –path /current_vm_cid) savestate
You can restart it once your reconnect to a new network using this command:
vboxmanage startvm $(bosh int ~/deployments/vbox/state.json --path /current_vm_cid) --type headless
In this article, we deployed the latest versions of both bosh-lite and cf. I point this out to say that what worked for me when I wrote this blog might potentially not work for you. These repositories use git tags to mark official releases. Although I didn’t reference tags, the ‘latest’ commits on master branches that I ended up deploying were:
bosh-deployment 5217f1a18461a4249fdac878b8a5a5efee8a7894 cf-deployment 77c48d298d9e7c8495cfe3464979d1a450ddfe62
In a future article, I’ll get into some specifics about how to match up the version you run with the version of Cloud Foundry we’re running in SAP Cloud Platform.
Thanks for this very interesting blog! Do you know if doing the same on a Windows machine is possible?
Windows is not yet supported unfortunately but it is in the works. I'm keeping tabs on it. If it changes, I'll post a follow-up when CF Deployment supports it.
i am very new to cloud foundry and was trying to deploy it on my laptop
i used the steps given above but when deploying i get an error when Updating instance api: api/f2f6b089-3ce9-430a-94ac-cbda7b8d5446 (0) (canary)
result: 1 of 7 pre-start scripts failed. Failed Jobs: cloud_controller_ng. Successful Jobs: cc_uploader, file_server, policy-server-internal, route_registrar, routing-api, consul_agent.
Could you help me out in this case
Since my instructions have you install of the latest code on the master branch, it's possible that there's a transient error that's crept into the code base. Two suggestions:
Thanks for such a crisp process. But i am getting the below error while running step 5.Googled a lot and cried for help here and there but In-vain .Any guidance is appreciated
Downloading remote release: Downloading remote release (00:00:40)
L Error: Downloading remote release failed. Check task debug log for details.
Task 17 | 17:27:03 | Error: Downloading remote release failed. Check task debug log for details.
Task 17 Started Fri Mar 30 17:26:23 UTC 2018
Task 17 Finished Fri Mar 30 17:27:03 UTC 2018
Task 17 Duration 00:00:40
Task 17 error
Task 16 | 17:27:03 | Downloading remote release: Downloading remote release (00:00:40)
L Error: Downloading remote release failed. Check task debug log for details.
Task 16 | 17:27:03 | Error: Downloading remote release failed. Check task debug log for details.
Task 16 Started Fri Mar 30 17:26:23 UTC 2018
Task 16 Finished Fri Mar 30 17:27:03 UTC 2018
Task 16 Duration 00:00:40
Task 16 error
Creating and uploading releases:
- Uploading release 'capi/1.52.0':
Uploading remote release 'https://storage.googleapis.com/cf-deployment-compiled-releases/capi-1.52.0-ubuntu-trusty-3541.10-20180327-184105-035528106.tgz':
Expected task '13' to succeed but state is 'error'
- Uploading release 'cf-mysql/36.11.0':
Uploading remote release 'https://storage.googleapis.com/cf-deployment-compiled-releases/cf-mysql-36.11.0-ubuntu-trusty-3541.10-20180327-190814-579497032.tgz':
Expected task '15' to succeed but state is 'error'
- Uploading release 'cf-networking/1.12.0':
Uploading remote release 'https://storage.googleapis.com/cf-deployment-compiled-releases/cf-networking-1.12.0-ubuntu-trusty-3541.10-20180327-183501-747828017.tgz':
Expected task '14' to succeed but state is 'error'
- Uploading release 'binary-buildpack/1.0.18':
Uploading remote release 'https://storage.googleapis.com/cf-deployment-compiled-releases/binary-buildpack-1.0.18-ubuntu-trusty-3541.10-20180327-183158-018354568.tgz':
Expected task '17' to succeed but state is 'error'
- Uploading release 'cf-smoke-tests/40.0.1':
Uploading remote release 'https://storage.googleapis.com/cf-deployment-compiled-releases/cf-smoke-tests-40.0.1-ubuntu-trusty-3541.10-20180327-183241-534645275.tgz':
Expected task '16' to succeed but state is 'error'
Exit code 1
I confess I have never tried this on Ubuntu. I'm unsure what differences might exist.
My instructions were specific to MacOS. One thing I could suggest: remove the final flag, "-o ~/workspace/cf-deployment/operations/use-compiled-releases.yml", from the cf deploy command. Executing it in this manner will take longer to run, but it makes fewer assumptions about the OS environment.