We all like to make our lives easier in technology with tooling (well most of us do), be that CI/CD/monitoring/scans/git repos, however, how can we deploy these functions in a way that makes our lives easier? If you ask this same question to a group of architects/engineer you will get a long list of answers, my answer is…Bosh!
The reason for Bosh is covered in this blog post.
At this stage I do not want to be prescriptive of which tools are needed, just that I need something to make my deployment of these tools easier. OK, thats a bit miss-leading, I ultimately need to stand up Concourse for some CI/CD pipeline fun and already know that Bosh is a good fit due to a previous role :-)
Where do I start? Based on experience, I know that many options exist for this. Things like bosh-init, Bosh Bootloader (BBL), BUCC all exist to help with this. They each have their pros and cons, however, my preferred method at the moment is bosh-deployment
which will allow me to use any IaaS, it has useful options for things like no Internet/or proxy access to the Internet and is also pretty generic rather than focussing on deploying a specific tool (like concourse).
vSphere Deployment
To start off with I want to work in an on-prem environment using vSphere. So my first step would be to get a jumpbox (in my case I picked an Ubuntu image) up and running with the following things installed;
I will also assume that the vSphere environment is up and running and you have the required topology, credentials, firewalls already defined.
Now I can just follow the bosh-deployment
instructions and if it no longer quite works, refer to the official docs.
Firstly create a working directory for the bosh
deployment
$ mkdir o-bosh && cd o-bosh
Then pull down the bosh-deployment
repo
$ git clone https://github.com/cloudfoundry/bosh-deployment
The repo contains a good baseline manifest/template on how to get bosh up and running and will just need to pass a few parameters. Remember what I said about making my life easier? I am a firm believer of not always reinventing the wheel and I look to reuse things where applicable.
The create-env
option is used. It will take the manifest we have and implement the desired configuration. A key file is created that bosh create-env
needs to keep track of resources created for future alterations. We also need to use something called a manifest operation to tell bosh to use the vSphere CPI and also define what variables need to be passed in. What does this look like? The -h
flag can guide us;
$ bosh create-env -h
Usage:
bosh [OPTIONS] create-env [create-env-OPTIONS] PATH
Application Options:
-v, --version Show CLI version
--config= Config file path (default: ~/.bosh/config) [$BOSH_CONFIG]
-e, --environment= Director environment name or URL [$BOSH_ENVIRONMENT]
--ca-cert= Director CA certificate path or value [$BOSH_CA_CERT]
--sha2 Use sha256 checksums. Requires recent director and stemcells.
--client= Override username or UAA client [$BOSH_CLIENT]
--client-secret= Override password or UAA client secret [$BOSH_CLIENT_SECRET]
-d, --deployment= Deployment name [$BOSH_DEPLOYMENT]
--json Output as JSON
--tty Force TTY-like output
--no-color Toggle colorized output
-n, --non-interactive Don't ask for user input
Help Options:
-h, --help Show this help message
[create-env command options]
-v, --var=VAR=VALUE Set variable
--var-file=VAR=PATH Set variable to file contents
-l, --vars-file=PATH Load variables from a YAML file
--vars-env=PREFIX Load variables from environment variables (e.g.: 'MY' to load MY_var=value)
--vars-store=PATH Load/save variables from/to a YAML file
-o, --ops-file=PATH Load manifest operations from a YAML file
--state=PATH State file path
[create-env command arguments]
PATH: Path to a manifest file
Succeeded
Now we have the background, lets just get something running (the below is an example and you should reflect the settings for your own environment);
bosh create-env bosh-deployment/bosh.yml \
--state state.json \
--vars-store ./creds.yml \
-o ~/bosh-deployment/vsphere/cpi.yml \
-v director_name=o-bosh \
-v internal_cidr=10.193.177.0/24 \
-v internal_gw=10.193.177.1 \
-v internal_ip=10.193.177.201 \
-v network_name="VM Network" \
-v vcenter_dc=Datacenter \
-v vcenter_ds=LUN01 \
-v vcenter_ip=10.193.177.11 \
-v vcenter_user="administrator@vsphere.local" \
-v vcenter_password=GkTzepNWtbtw! \
-v vcenter_templates=o-bosh-templates \
-v vcenter_vms=o-bosh-vms \
-v vcenter_disks=o-bosh-disks \
-v vcenter_cluster=Cluster \
-v vcenter_rp=RP01
Commit the state thats created and the manifest files to git (or some other safe location that multiple people can access).
What happens if I want to see what the deployment manifest will look like without making the deployment? Well, bosh int
is your best friend.
bosh int ~/bosh-deployment/bosh.yml \ ................
Logging in
After the deployment has finished you should be able to login to your director;
bosh alias-env o-bosh -e 10.193.177.201 --ca-cert <(bosh int creds.yml --path /director_ssl/ca)
$ bosh -e o-bosh env
Alternatively you can set export BOSH_ENVIRONMENT=o-bosh once instead of using –environment flag for each command. You could always make use of direnv.
Internet Restrictions
In the majority of enterprise customers I have deployed bosh direct, Internet access has been a bit of an issue. This means a couple of things;
- Default DNS servers are Google
- Bosh ‘stuff’ is on the Internet
To get around the Google DNS issue you can simply use an operation file to alter the default settings
-o ~/bosh-deployment/misc/dns.yml -v internal_dns=[10.193.177.2]
The default mainfest trys to pull files (stellcells, releases etc.) from the Internet. The bosh release location can be found in bosh.yml
;
releases:
- name: bosh
version: "264.7.0"
url: https://s3.amazonaws.com/bosh-compiled-release-tarballs/bosh-264.7.0-ubuntu-trusty-3468.21-20180125-031202-579399892-20180125031207.tgz?versionId=gnR.RVKDRH_Vk63jxsGBOhcHOZ9p8qCJ
sha1: 3850c68124bf5bce3cfb1433cce52e2d67741d94
To solve this I have created a few operations files (PR) to overide these settings here.
To make use of these you need to include the opertions files in your deployment and also specify the lcations of the files.
-o ~/bosh-deployment/misc/no-internet-access/vsphere-cpi.yml \
-o ~/bosh-deployment/misc/no-internet-access/stemcell.yml \
-o ~/bosh-deployment/local-bosh-release.yml \
-v local_bosh_release="~/bosh/bosh-264.6.0.tgz" \
-v local_vsphere_cpi="~/bosh/bosh-vsphere-cpi" \
-v local_stemcell="~/bosh/bosh-stemcell-3468.13-vsphere-esxi-ubuntu-trusty-go_agent.tgz" \
Other operation options
If you browse the GitHub repo you will find a number of operations files that can be used to add UAA/Credhub/Syslog etc. functionality. They are mostly in the /
, /misc
or /experimental
directories.
The operations file concept is pretty cool because it means that you can use a base line deployment template and then add/remplace functionality as required.
Tidier way to Deploy
I have found that to make deployments more reusable, the above command can be seperated into two discrete components;
- Deployment Script
- Variable file
This means that you can use the same deployment script for all deployments and just point to the variables file for the specific environment you are working on.
Deployement Script
#!/bin/bash
if [ -z "$1" ]
then
echo "Please supply an enviroment"
echo "example is deploy-bosh.sh development"
exit 2
fi
WORKDIR=/pcf/workspace/deployments/${1}
BOSHDIR=/pcf/workspace/bosh-deployment
PATCHDIR=/pcf/workspace/deployments/patches
bosh create-env ${BOSHDIR}/bosh.yml \
--state ${WORKDIR}/bosh-state.json \
--vars-file=${WORKDIR}/params-bosh.yml \
--vars-store=${WORKDIR}/bosh-creds.yml \
-o ${BOSHDIR}/misc/dns.yml \
-o ${BOSHDIR}/vsphere/cpi.yml \
-o ${BOSHDIR}/local-bosh-release-tarball.yml \
-o ${BOSHDIR}/misc/no-internet-access/vsphere-cpi.yml \
-o ${BOSHDIR}/misc/no-internet-access/stemcell.yml
Variables file
The variables file is just plain old Yaml.
director_name: o-bosh
internal_cidr: 10.193.177.0/24
internal_gw: 10.193.177.1
internal_ip: 10.193.177.201
network_name: "VM Network"
vcenter_dc: Datacenter
vcenter_ds: LUN01
vcenter_ip: 10.193.177.11
vcenter_user: "administrator@vsphere.local"
vcenter_password: GkTzepNWtbtw!
vcenter_templates: o-bosh-templates
vcenter_vms: o-bosh-vms
vcenter_disks: o-bosh-disks
vcenter_cluster: Cluster
vcenter_rp: RP01
Each environment should have its own file and these should be stored in a git repo or backed up file system (you may want to use git-crypt if using a git repo).
Next
You now have a great place to deploy other services to make your life easy, once you upload a cloud-config
that is.