You can now deploy/scale/upgrade a single server using any of dozens of community BOSH releases WITHOUT needing BOSH server running.

What do you get? A single VM. A single persistent disk - attached and mounted. And either can be scaled/resized over time. And you can upgrade between BOSH releases over time.

At the time of writing there are 33 community releases at https://bosh.io/releases. Many are suitable candidates for deploying to a single server.

release

Why don't we need a running BOSH server? There is a new CLI coming soon called bosh-init - it can deploy a single server into any BOSH-supporting infrastructure (e.g. AWS, OpenStack, vSphere, vCloud...), install and run one or more BOSH releases' job templates.

bosh-init can do more than that - it will attach a persistent disk; it can resize the disk later; and it can even resize the entire server - change to any instance type over time.

It can deploy into AWS EC2 and attach an elastic IP. It can deploy into AWS VPC into any public or private subnet. It can deploy into any AWS region. Or private OpenStack or private vSphere, etc.

This blog post will show how to deploy three different services:

That is, the last service will be a single server running a full BOSH. It is the future "Micro BOSH" and will replace the bosh micro deploy CLI commands.

What does bosh-init do?

bosh-init can deploy a single server, attach a persistent disk, install software and start processes. It can also scale up/down that single server - all whilst maintaining the same persistent disk. Or it can scale up/down that persistent disk at the same time. It's pretty incredible.

For reference, here is the bosh-lite flow diagram for how it does all this (from docs).

flow

See "Scaling and upgrades" section below for the full flow diagram

Getting prepared

For this walk thru you will need the following items from your trusty cloud toolbox:

  • AWS API key & secret
  • Elastic IP for each deployment (or reuse one) - 23.23.23.23 in examples below
  • Keypair (assumed to be called bosh-init and saved at ~/.ssh/bosh-init)
  • Security group for each deploy (ports discussed below)

We will be deploying into AWS us-east-1 region - for magical reasons outside the scope of the article this means we can do the deployments from our laptops; rather than another AWS VM.

Fetching dependencies

To deploy our bosh-init servers to AWS we need some system dependencies. Except I don't know what they are anymore for my OS X machine. If you are missing anything you will get errors - install the dependencies and re-deploy.

On Ubuntu, the following packages are required in order for the AWS CPI (Cloud Provider Interface) to compile Ruby successfully (the OpenStack and AWS CPIs are currently written in Ruby; but hopefully someone rewrites them into Go):

sudo apt-get install -y build-essential zlibc zlib1g-dev \  
  openssl libxslt-dev libxml2-dev libssl-dev \
  libreadline6 libreadline6-dev libyaml-dev libsqlite3-dev sqlite3

Deploying Redis

I'll describe the sequence for deploying a Redis server in more depth; as much of it is the same for Concourse and BOSH deployments below.

BOSH assets

To deploy Redis via bosh-init we will need:

  • bosh-init CLI
  • the BOSH release describing how to run Redis [source] [releases]
  • the BOSH release describing how bosh-init talks to AWS API (called a CPI, or Cloud Provider Interface) [source] [releases]
  • the light BOSH stemcell that references an existing base AMI in us-east-1 (see http://bosh.io/stemcells for available stemcells)
  • YAML manifest file describing what to put on the VM

For Redis, Concourse and BOSH I have created helpful tutorial repos.

Redis tutorial

To get started and fetch all the assets above:

git clone https://github.com/cloudfoundry-community/bosh-init-redis  
cd bosh-init-redis  
./bin/fetch_assets.sh

Next, create the YAML manifest:

EIP=23.23.23.23 \  
ACCESS_KEY_ID=XXXX \  
SECRET_ACCESS_KEY=YYY \  
KEY_NAME=keypair-name-in-aws \  
PRIVATE_KEY_PATH=~/.ssh/keypair-name-in-aws.pem  \  
SECURITY_GROUP=redis \  
./bin/make_manifest.sh

The security group used for any bosh-init deployment currently must include ports:

  • 22
  • 6868

Plus whatever ports are required for the BOSH release being deployed (port 6379 for redis).

The make_manifest.sh command above will create a redis.yml manifest file (YAML format).

It describes that we will be deploying into AWS EC2 networking (we know this as one of the networks is type: dynamic; rather than type: manual and doesn't specify a subnet_id for VPC).

It specifies that the server VM will include one BOSH job template from one BOSH release:

templates:  
- {name: redis, release: redis}

It also says that the VM will have a persistent disk of 10G (persistent_disk: 10240). It is where Redis database will be stored.

This disk will survive any resizing/configuration changes from subsequent bosh-init deploy commands.

This disk can be resized by changing 10240 to a larger number and redeploying.

The ability for BOSH and its server-less version bosh-init to detact, reattach and resize persistent disks is one of its very special orchestration abilities.

Finally, deploying the AWS server with Redis running on it:

./bin/deploy.sh

This shell wrapper runs the bosh-init deploy command with the BOSH assets required. For example:

bosh-init deploy redis.yml \  
  assets/light-bosh-stemcell-2830-aws-xen-ubuntu-trusty-go_agent.tgz \
  assets/bosh-aws-cpi-release-5.tgz \
  assets/redis-9.tgz

The output will look something like:

Deployment manifest: '/Users/drnic/Projects/bosh-deployments/experiments/bosh-init-redis/redis.yml'  
Deployment state: 'deployment.json'

Started validating  
  Validating stemcell... Finished (00:00:00)
  Validating releases... Finished (00:00:00)
  Validating deployment manifest... Finished (00:00:00)
  Validating cpi release... Finished (00:00:00)
Finished validating (00:00:00)

Started installing CPI  
  Compiling package 'ruby_aws_cpi/052a28b8976e6d9ad14d3eaec6d3dd237973d800'... Finished (00:01:22)
  Compiling package 'bosh_aws_cpi/deabbf731a4fedc9285324d85af6456cfa74c10c'... Finished (00:00:34)
  Rendering job templates... Finished (00:00:00)
  Installing packages... Finished (00:00:03)
  Installing job 'cpi'... Finished (00:00:00)
Finished installing CPI (00:02:01)

Starting registry... Finished (00:00:00)  
Uploading stemcell 'bosh-aws-xen-ubuntu-trusty-go_agent/2830'... Finished (00:00:09)

Started deploying  
  Creating VM for instance 'redis/0' from stemcell 'ami-94c187fc light'... Finished (00:00:47)
  Waiting for the agent on VM 'i-3d7ffec0' to be ready... Finished (00:01:17)
  Rendering job templates... Finished (00:00:09)
  Compiling package 'redis-server/b53d5357ab95a74c9489cd98a024e6ef6047aba0'... Finished (00:03:36)
  Updating instance 'redis/0'... Finished (00:00:06)
  Waiting for instance 'redis/0' to be running... Finished (00:00:00)
Finished deploying (00:05:58)  

To test your Redis server use your local redis-cli:

redis-cli -h 23.23.23.23  

Delete Redis

There is a helper script to delete your Redis server and its attached disk:

./bin/delete.sh
cd ..  

Concourse tutorial

As above, clone a helpful tutorial and run the same commands:

git clone https://github.com/cloudfoundry-community/bosh-init-concourse  
cd bosh-init-concourse  
./bin/fetch_assets.sh

EIP=107.22.193.126 \  
ACCESS_KEY_ID=XXXX \  
SECRET_ACCESS_KEY=YYY \  
KEY_NAME=keypair-name-in-aws \  
PRIVATE_KEY_PATH=~/.ssh/keypair-name-in-aws.pem  \  
SECURITY_GROUP=concourse \  
./bin/make_manifest.sh

./bin/deploy.sh

The concourse security group needs ports 22 and 6868 for bosh-init, plus 8080 for the Concourse ATC API.

Open http://23.23.23.23:8080 in the browser to see your Concoure CI.

Read the following for information on Concourse:

Concourse includes a Postgresql database and it is stored on the persistent, scalable EBS volume that is managed by each bosh-init deploy (or ./bin/deploy.sh) deploy.

Again, to delete you can run ./bin/delete.sh.

BOSH tutorial

The killer use case for bosh-init is to replace the bosh micro deploy tool for creating Micro BOSH. Clone the helpful tutorial as above:

git clone https://github.com/cloudfoundry-community/bosh-init-bosh  
cd bosh-init-concourse  
./bin/fetch_assets.sh

EIP=23.23.23.23 \  
ACCESS_KEY_ID=XXXX \  
SECRET_ACCESS_KEY=YYY \  
KEY_NAME=keypair-name-in-aws \  
PRIVATE_KEY_PATH=~/.ssh/keypair-name-in-aws.pem  \  
SECURITY_GROUP=bosh \  
./bin/make_manifest.sh

./bin/deploy.sh

The bosh security group needs ports 22 and 686 for bosh-init as well as 25555 for BOSH CLI to access the Director API.

To check that your BOSH server is running:

gem install bosh_cli  
bosh target 23.23.23.23  

You should be prompted for credentials. The username and password are admin.

bosh status  

Again, to delete you can run ./bin/delete.sh.

Scaling and upgrades

One of bosh-init special tricks (like a BOSH server) is that it can:

  • scale the VM
  • resize the persistent disk
  • reconfigure the workload, or
  • upgrade the version of workloads.

Re-deploy the Redis server above. Put some data in it:

$ redis-cli -h 23.23.23.23
23.23.23.23:6379> set foo 123  
OK  
(0.79s)
23.23.23.23:6379> get foo  
"123"
(0.78s)

Now let's resize the server, its disk and change the port that Redis listens on (from the default of 6379):

In the redis.yml change the m3.medium to m3.large under resource_pools:

resource_pools:  
- name: default
  network: default
  cloud_properties:
    instance_type: m3.large

In the same redis.yml file also change the persistent_disk under jobs from 10G to 20G:

jobs:  
- name: redis
  instances: 1
  persistent_disk: 20480

Finally, to change the port that Redis listens on (further under jobs):

jobs:  
...
  properties:
    redis:
      port: 6379

Now re-deploy:

./bin/deploy

The upgrade process for these three changes follows this path through the flow diagram:

change-flow

The interesting section of the output that matches the the flow diagram is:

Started deploying  
  Waiting for the agent on VM 'i-8b6ae276'... Finished (00:00:00)
  Stopping jobs on instance 'unknown/0'... Finished (00:00:00)
  Unmounting disk 'vol-c682f6d0'... Finished (00:00:00)
  Deleting VM 'i-8b6ae276'... Finished (00:00:41)
  Creating VM for instance 'redis/0' from stemcell 'ami-94c187fc light'... Finished (00:00:44)
  Waiting for the agent on VM 'i-cd6fe730' to be ready... Finished (00:02:00)
  Attaching disk 'vol-c682f6d0' to VM 'i-cd6fe730'... Finished (00:00:16)
  Creating disk... Finished (00:00:15)
  Attaching disk 'vol-e88df9fe' to VM 'i-cd6fe730'... Finished (00:00:23)
  Migrating disk content from 'vol-c682f6d0' to 'vol-e88df9fe'... Finished (00:00:01)
  Detaching disk 'vol-c682f6d0'... Finished (00:00:24)
  Deleting disk 'vol-c682f6d0'... Finished (00:00:10)
  Rendering job templates... Finished (00:00:01)
  Compiling package 'redis-server/b53d5357ab95a74c9489cd98a024e6ef6047aba0'... Finished (00:00:43)
  Updating instance 'redis/0'... Finished (00:00:06)
  Waiting for instance 'redis/0' to be running... Finished (00:00:00)
Finished deploying (00:06:00)  

The Redis server is no longer on port 6379, so the following fails:

$ redis-cli -h 23.23.23.23
Could not connect to Redis at 23.23.23.23:6379: Connection refused  

Instead redis-cli -h 23.23.23.23 -p 6400 would connect to the Redis server and the data is intact (once the security group allows port 6400):

$ redis-cli -h 107.22.193.126 -p 6400
107.22.193.126:6400> get foo  
"123"

Summary

You now have a choice - nearly every BOSH release (or combination of releases) can be deployed into a single server without a running BOSH server using bosh-init.

Or you can use bosh-init to deploy a BOSH server and use it to deployed small and large clusters of systems.