Monday, 18 September 2017

Deploy Vault, the great credential management tool, by BOSH

Yes, We Need Credential Management Tool

Credential management is critical in microservices world.
You can imagine that within microservices architecture, there are a series of services/apps deployed into our environment. How to provide a service, let's use MySQL as an example, to identified applications, creation of credentials is mandatory.
Now how to handover the credential to these identified applications? How to make sure the credentials won't be leaked to developers/operators?

Yes, in short, we need credential management tools like Vault.

Since BOSH is a great platform for deploying and managing software clusters. It's a good idea to let Vault work with BOSH.

Preparation & Requisites

1. Prepare Infra

The process is based on Google Cloud Platform (GCP).
But, as BOSH is the great platform to abstract the IaaSes, changing to another IaaS, for example AWS or Azure, is just a trivial thing to handle.

What we need to prepare are:

  • VPC with subnet(s). In my example, my VPC is as below
    • VPC Network: bosh-sandbox
    • Subnet: bosh-releases
    • Region: us-central1
    • IP address range: 10.0.100.0/22
  • A Service Account with necessary Roles, for example:
    • App Engine Admin
    • Compute Instance Admin (v1)
    • Compute Network Admin
    • Compute Storage Admin
  • A Ubuntu Jumpbox (within the same VPC)

2. Create BOSH Director

$ git clone https://github.com/cloudfoundry/bosh-deployment
$ bosh create-env bosh-deployment/bosh.yml \
    --state=state.json \
    --vars-store=creds.yml \
    -o bosh-deployment/gcp/cpi.yml \
    -v director_name=bosh-gcp \
    -v internal_cidr=10.0.100.0/22 \
    -v internal_gw=10.0.100.1 \
    -v internal_ip=10.0.100.6 \
    --var-file gcp_credentials_json=<CREDENTIAL JSON FILE> \
    -v project_id=<PROJECT ID> \
    -v zone=us-central1-a \
    -v tags=[internal,bosh] \
    -v network=bosh-sandbox \
    -v subnetwork=bosh-releases

3. Alias BOSH Env

$ bosh alias-env sandbox -e 10.0.100.6 --ca-cert <(bosh int ./creds.yml --path /director_ssl/ca)

4. Export & Login to the Director

$ export BOSH_CLIENT=admin && export BOSH_CLIENT_SECRET=`bosh int ./creds.yml --path /admin_password`

5. Prepare & Update Cloud Config

$ bosh -e sandbox update-cloud-config cloud-config-gcp.yml

6. Upload Stemcells

$ bosh -e sandbox upload-stemcell stemcells/light-bosh-stemcell-3421.11-google-kvm-ubuntu-trusty-go_agent.tgz

Prepare Manifest File

$ vi vault.yml

With below content:
---
name: vault

instance_groups:
- instances: 1
  name: vault
  networks: [
    {
      name: ((VAULT_NW_NAME)), 
      static_ips: ((VAULT_STATIC_IP))
    }
  ]
  persistent_disk: 4096
  properties:
    vault:
      backend:
        use_file: true
      ha:
        redirect: null
  vm_type: ((VAULT_VM_TYPE))
  stemcell: trusty
  azs: [((VAULT_AZ_NAME))]
  jobs:
  - name: vault
    release: vault

releases:
- name: vault
  version: 0.6.2
  url: https://bosh.io/d/github.com/cloudfoundry-community/vault-boshrelease?v=0.6.2
  sha1: 36fd3294f756372ff9fbbd6dfac11fe6030d02f9

stemcells:
- alias: trusty
  os: ubuntu-trusty
  version: latest

update:
  canaries: 1
  canary_watch_time: 1000-30000
  max_in_flight: 50
  serial: false
  update_watch_time: 1000-30000

Deploy Vault

$ bosh -e sandbox -d vault deploy vault.yml \
    -v VAULT_NW_NAME=network-z1-only \
    -v VAULT_STATIC_IP=10.0.100.10 \
    -v VAULT_VM_TYPE=small \
    -v VAULT_AZ_NAME=z1

Once it's done, we can verify:
$ bosh -e sandbox -d vault vms
Using environment '10.0.100.6' as client 'admin'

Task 118. Done

Deployment 'vault'

Instance                                    Process State  AZ  IPs          VM CID                                   VM Type
vault/8753e1bb-e486-44a2-8bba-25fa4c2278b4  running        z1  10.0.100.10  vm-86c20491-ebdc-4948-631f-e0ac733d0690  small

1 vms

Succeeded

Post Actions

After deployment is done, enable it by following steps.

1. Prepare Tools

$ wget https://releases.hashicorp.com/vault/0.8.2/vault_0.8.2_linux_amd64.zip
$ unzip vault_0.8.2_linux_amd64.zip
$ chmod +x vault && sudo mv vault /usr/local/bin/
$ vault -v
    Vault v0.8.2 ('9afe7330e06e486ee326621624f2077d88bc9511')

2. Unseal Vault

$ export VAULT_ADDR=http://10.0.100.10:8200
    Unseal Key 1: xxx
    Unseal Key 2: xxx
    Unseal Key 3: xxx
    Unseal Key 4: xxx
    Unseal Key 5: xxx
    Initial Root Token: xxx

    Vault initialized with 5 keys and a key threshold of 3. Please
    securely distribute the above keys. When the vault is re-sealed,
    restarted, or stopped, you must provide at least 3 of these keys
    to unseal it again.

    Vault does not store the master key. Without at least 3 keys,
    your vault will remain permanently sealed.
$ vault unseal
    Key (will be hidden):
    Sealed: true
    Key Shares: 5
    Key Threshold: 3
    Unseal Progress: 1
    Unseal Nonce: 1ffc83e5-2e5f-1038-4e68-0223f1544746
$ vault unseal
    Key (will be hidden):
    Sealed: true
    Key Shares: 5
    Key Threshold: 3
    Unseal Progress: 2
    Unseal Nonce: 1ffc83e5-2e5f-1038-4e68-0223f1544746
$ vault unseal
    Key (will be hidden):
    Sealed: false
    Key Shares: 5
    Key Threshold: 3
    Unseal Progress: 0
    Unseal Nonce:
$ vault auth
    Token (will be hidden):
    Successfully authenticated! You are now logged in.
    token: 5e3f7eba-2e27-fc74-7c55-f6084bad4b00
    token_duration: 0
    token_policies: [root]

3. Try Putting Values

Now, you can put secrets in the vault, and read them back out. For example:

$ vault write secret/test mykey=myvalue
    Success! Data written to: secret/test
$ vault read secret/test
    Key              Value
    ---              -----
    refresh_interval 768h0m0s
    mykey            myvalue
$ vault delete secret/test
    Success! Deleted 'secret/test' if it existed.

Yeah! Vault, managed by BOSH, is ready to rock.

Note: this is just the basic setup, please refer to vault-boshrelease for more advanced topics like HA, zero-downtime upgrade etc.