{"url":"https://api.github.com/gists/c2c0bd258610904514e7301474a2dc8f","forks_url":"https://api.github.com/gists/c2c0bd258610904514e7301474a2dc8f/forks","commits_url":"https://api.github.com/gists/c2c0bd258610904514e7301474a2dc8f/commits","id":"c2c0bd258610904514e7301474a2dc8f","node_id":"MDQ6R2lzdGMyYzBiZDI1ODYxMDkwNDUxNGU3MzAxNDc0YTJkYzhm","git_pull_url":"https://gist.github.com/c2c0bd258610904514e7301474a2dc8f.git","git_push_url":"https://gist.github.com/c2c0bd258610904514e7301474a2dc8f.git","html_url":"https://gist.github.com/michaellihs/c2c0bd258610904514e7301474a2dc8f","files":{"bucc-gcp.md":{"filename":"bucc-gcp.md","type":"text/markdown","language":"Markdown","raw_url":"https://gist.githubusercontent.com/michaellihs/c2c0bd258610904514e7301474a2dc8f/raw/655450657f46864840abce8ad8523768d419374f/bucc-gcp.md","size":9656,"truncated":false,"content":"Using BUCC on Google Cloud Platform (GCP)\n=============\n\n[BUCC](https://github.com/starkandwayne/bucc) is a command line tool from [Stark & Wayne](https://starkandwayne.com/) that let's you easily set up [**B**OSH](https://bosh.io/), [**U**AA](https://github.com/cloudfoundry/uaa), [**C**redhub](https://docs.cloudfoundry.org/credhub/) and [**C**oncourse](https://concourse-ci.org/) on multiple IaaS providers. In other words: what you get is a ready to use CI/CD infrastructure based on Concourse up and running within a few minutes. This blog post covers my setup on Google Cloud Platform (GCP).\n\n\nPreparations on GCP\n-------------------\n\nBefore we can start using BUCC, we have to prepare a few things on GCP. I assume that you have a project within GCP where you have admin permissions.\n\n\n### Creating a GCP Service Account\n\nIn order to use BUCC you need a GCP [Service Account](https://cloud.google.com/iam/docs/understanding-service-accounts) with the following permissions:\n\n* Project: owner\n* Compute Engine: admin\n\n> **Disclaimer:** I am not sure whether you really need to be owner and admin on those two roles. I tested it with these settings and for me it worked. If you figure out how to run it with less permissions, I will gladly update the post.\n\nMake sure to **create a private key for your service account** - you will later on need it for your BUCC setup.\n\n\n### Create a VPC and Subnet on GCP\n\nTo get a separate network for our BUCC setup, we create a dedicated VPC for it. You can either do this using the GCP console in the browser or use the commands below (which assume that you properly authenticated at GCP using `gcloud auth login` first and that your authenticated user has the necessary permissions to run the tasks).\n\n```bash\ngcloud compute networks create bucc-vpc \\\n    --description=\"VPC for BUCC\" \\\n    --subnet-mode=\"custom\"\n```\n\nAfterwards you have to create a subnet within this VPC\n\n```bash\ngcloud compute networks subnets create bucc-subnet \\\n    --network=bucc-vpc \\\n    --range='10.0.0.0/24' \\\n    --description=\"Subnet for BUCC\" \\\n    --region=europe-west3\n```\n\nAdd some firewall rules to allow traffic within the subnet, pings and ssh to our jumphost:\n\n```bash\ngcloud compute firewall-rules create bucc-allow-internal \\\n    --allow=all \\\n    --network=bucc-vpc \\\n    --priority=65534 \\\n    --source-ranges=10.0.0.0/24\n```\n\n```bash\ngcloud compute firewall-rules create bucc-allow-ssh \\\n    --allow=tcp:22 \\\n    --network=bucc-vpc \\\n    --priority=65534 \\\n    --source-ranges=0.0.0.0/0\n```\n\n```bash\ngcloud compute firewall-rules create bucc-allow-icmp \\\n    --allow=icmp \\\n    --network=bucc-vpc \\\n    --priority=65534 \\\n    --source-ranges=0.0.0.0/0\n```\n\n\nProvision a GCP VM as jumphost\n------------------------------\n\nFor managing our BUCC setup, we provision a VM in GCP that acts as a jumphost. It will be the only VM that allows SSH access from the internet and hence acts as a bastion host to connect to the other machines provisioned by BOSH later on.\n\nThe jumphost will have two IPs: one external IP (allowing access from the internet) and one internal IP for communicating with the other VMs in our VPC. Here's the `gcloud` command to provision the machine:\n\n```bash\ngcloud compute instances create bucc-jumphost \\\n    --machine-type=f1-micro \\\n    --network=bucc-vpc \\\n    --subnet=bucc-subnet \\\n    --zone=europe-west3-c \\\n    --service-account='bucc-648@bucc-233607.iam.gserviceaccount.com'\n```\n\nYou can add your ssh public key if you want. Therefore create a file with the following structure and save it as `ssh-keys.txt`:\n\n```\n<YOUR USERNAM>:ssh-rsa <YOUR PUBLIC SSH RSA KEY> <YOUR USERNAME>\n```\n\nnow run the following command to add this ssh key to your GCP VM:\n\n```bash\ngcloud compute instances add-metadata bucc-jumphost --metadata-from-file ssh-keys=ssh-keys.txt --zone=europe-west3-c\n```\n\nGet your public IP for the GCP VM via:\n\n```bash\ngcloud compute instances describe bucc-jumphost --zone=europe-west3-c | grep natIP\n```\n\nYou should now be able to ssh into your VM via\n\n```bash\nssh <YOUR USERNAME>@<NAT IP>\n```\n\nThe following packages need to be installed on the jumphost:\n\n```bash\nsudo apt-get install -y git direnv make ruby build-essential ruby-dev\nsudo gem install cf-uaac\n```\n\nSet up `direnv` via adding the following line to your user's `.bashrc`\n\n```bash\neval \"$(direnv hook bash)\"\n```\n\n\nInstall BUCC (BOSH, UAA, Credhub, Concourse)\n--------------------------------------------\n\nssh into your jumphost and clone the `bucc` repository:\n\n```bash\ngit clone https://github.com/starkandwayne/bucc.git\ncd bucc\n```\n\nassuming that you have `direnv` installed as described above, you should get an error message like\n\n```\ndirenv: error .envrc is blocked. Run `direnv allow` to approve its content.\n```\n\nrun `direnv allow` to allow the `.envrc` file in this directory to be sourced.\n\n\nRun `bucc up`\n-------------\n\nAfter all this preparation you should now be ready to finally `bucc up` your BOSH, UAA, Credhub and Concourse instances.\n\n```bash\nbucc up --cpi=gcp --debug\n```\n\nFirst of all this will download the BOSH cli for you and put it into a proper location (namely `bucc/bin/bosh`). Afterwards it will create a `vars.yml` file inside your `bucc` folder that you have to adapt to your needs. Before you can go on, you have to create an access key for your Service Account:\n\n```bash\n# run this command on your local workstation with gcloud set up\ngcloud iam service-accounts keys create ~/key.json \\\n  --iam-account [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com\n```\n\nthis will create a file `key.json` in your current directory. Copy the content of this file and replace the section `# paste service account's key JSON here` in the generated `vars.yml` file on your jumphost.\n\n`vars.yml` sample with all values generated above - make sure to replace the `project_id` and the `service_account` with your values:\n\n```yaml\ndirector_name: bosh-bucc\ngcp_credentials_json: |\n  # paste service account's key JSON here\n\ninternal_cidr: 10.0.0.0/24\ninternal_gw: 10.0.0.1\ninternal_ip: 10.0.0.6\nnetwork: bucc-vpc\nproject_id: <YOUR GCP PROJECT ID>\nsubnetwork: bucc-subnet\t\ntags: [internal]\nzone: europe-west3-c\n\n# flag: --service-account\nservice_account: [SA-NAME]@[PROJECT-ID].iam.gserviceaccount.com\n```\n\nWhen everything is set, run\n\n```bash\nbucc up --cpi=gcp --debug\n```\n\nAfter saving this file, you should be able to run\n\n```bash\nbuch up --cpi=gcp\n```\n\nand `bucc` provisions a VM with BOSH, UAA, Credhub and Concourse in it.\n\n\nUsing BUCC\n----------\n\nHere are some examples of how to use the BUCC setup.\n\n* Source the BUCC environment (not necessary if you use `direnv`):\n\n   ```bash\n   source <(bucc env)\n   ```\n\n* check BOSH connection:\n\n   ```bash\n   bosh alias-env bucc\n   ```\n\n*  set up UAA:\n\n   ```bash\n   bucc uaac\n   uaac client get admin\n   ```\n\n* get Concourse URL and credentials via:\n\n   ```bash\n   bucc info\n   ```\n\n* open Concourse UI in your browser\n\n   ```bash\n   # setup port forwarding from Concourse VM to your workstation (assuming Concourse runs on 10.0.0.6)\n   ssh -L 8443:10.0.0.6:443 michael.lihs@<EXTERNAL JUMPHOST IP>\n   ```\n\n   you can now open the Concourse UI in your browser via [https://localhost:8443/](https://localhost:8443/) (make sure to use `https`!)\n\n\nTroubleshooting BUCC on GCP\n---------------------------\n\nHere are some error messages that I came accross during testing the setup - maybe they are helpful for you as well.\n\n\n### `bucc up` on local workstation\n\nThe first deployment with upper `vars.yml` resulted in the following error:\n\n> ```\n> creating stemcell (bosh-google-kvm-ubuntu-xenial-go_agent 170.9):\n> CPI 'create_stemcell' method responded with error:\n>   CmdError{\"type\":\"Bosh::Clouds::CloudError\",\"message\":\"Creating stemcell: Creating Google Image from URL: Failed to create Google Image: Post https://www.googleapis.com/compute/v1/projects/bucc-233607/global/images?alt=json: Get http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token: dial tcp 169.254.169.254:80: connect: host is down\",\"ok_to_retry\":false}\n>\n> Exit code 1\n\n* moving from local workstation to a VM in GCP fixed the problem\n\n\n### `bucc up` on GCP VM - zone problem\n\n> ```\n> Deploying:\n> Creating instance 'bosh/0':\n>   Creating VM:\n>     Creating vm with stemcell cid 'stemcell-ee1c5f71-d5d4-41f9-4425-236afdfbb9b4':\n>       CPI 'create_vm' method responded with error: CmdError{\"type\":\"Bosh::Clouds::CloudError\",\"message\":\"Creating vm: Failed to find Google Machine Type 'n1-standard-1' in zone 'europe-west3': googleapi: Error 400: Invalid value for field 'zone': 'europe-west3'. Unknown zone., invalid\",\"ok_to_retry\":false}\n>\n> Exit code 1\n\n* changing `europe-west3` to `europe-west3-c` in the `vars.yml` fixed the problem\n\n\n### `bucc up` on GCP VM - network problem\n\n> ```\n> Deploying:\n>    Creating instance 'bosh/0':\n>      Creating VM:\n>        Creating vm with stemcell cid 'stemcell-ee1c5f71-d5d4-41f9-4425-236afdfbb9b4':\n>          CPI 'create_vm' method responded with error: CmdError{\"type\":\"Bosh::Clouds::VMCreationFailed\",\"message\":\"VM failed to create: googleapi: Error 400: Invalid value for field 'resource.networkInterfaces[0].networkIP': '10.0.0.6'. Requested internal IP is outside the subnetwork CIDR range., invalid\",\"ok_to_retry\":true}\n>\n> Exit code 1\n\n* fixed network and subnet configuration in `vars.yml`\n\n\n### `bucc up` errors with time out\n\n> ```\n> Deploying:\n>   Creating instance 'bosh/0':\n>     Waiting until instance is ready:\n>       Post https://mbus:<redacted>@10.0.0.6:6868/agent: dial tcp 10.0.0.6:6868: i/o timeout\n>  \n>  Exit code 1\n\n* adding `allow-all-internal` firewall rule for bucc network fixed the issue\n\n","encoding":"utf-8"}},"public":true,"created_at":"2019-03-05T14:18:06Z","updated_at":"2019-03-05T19:53:51Z","description":"BUCC on GCP","comments":0,"user":null,"comments_enabled":true,"comments_url":"https://api.github.com/gists/c2c0bd258610904514e7301474a2dc8f/comments","owner":{"login":"michaellihs","id":575011,"node_id":"MDQ6VXNlcjU3NTAxMQ==","avatar_url":"https://avatars.githubusercontent.com/u/575011?v=4","gravatar_id":"","url":"https://api.github.com/users/michaellihs","html_url":"https://github.com/michaellihs","followers_url":"https://api.github.com/users/michaellihs/followers","following_url":"https://api.github.com/users/michaellihs/following{/other_user}","gists_url":"https://api.github.com/users/michaellihs/gists{/gist_id}","starred_url":"https://api.github.com/users/michaellihs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/michaellihs/subscriptions","organizations_url":"https://api.github.com/users/michaellihs/orgs","repos_url":"https://api.github.com/users/michaellihs/repos","events_url":"https://api.github.com/users/michaellihs/events{/privacy}","received_events_url":"https://api.github.com/users/michaellihs/received_events","type":"User","user_view_type":"public","site_admin":false},"forks":[],"history":[{"user":{"login":"michaellihs","id":575011,"node_id":"MDQ6VXNlcjU3NTAxMQ==","avatar_url":"https://avatars.githubusercontent.com/u/575011?v=4","gravatar_id":"","url":"https://api.github.com/users/michaellihs","html_url":"https://github.com/michaellihs","followers_url":"https://api.github.com/users/michaellihs/followers","following_url":"https://api.github.com/users/michaellihs/following{/other_user}","gists_url":"https://api.github.com/users/michaellihs/gists{/gist_id}","starred_url":"https://api.github.com/users/michaellihs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/michaellihs/subscriptions","organizations_url":"https://api.github.com/users/michaellihs/orgs","repos_url":"https://api.github.com/users/michaellihs/repos","events_url":"https://api.github.com/users/michaellihs/events{/privacy}","received_events_url":"https://api.github.com/users/michaellihs/received_events","type":"User","user_view_type":"public","site_admin":false},"version":"77a686b6f8744c9f016ee7c31c4b752b1c87fe84","committed_at":"2019-03-05T19:53:50Z","change_status":{"total":2,"additions":1,"deletions":1},"url":"https://api.github.com/gists/c2c0bd258610904514e7301474a2dc8f/77a686b6f8744c9f016ee7c31c4b752b1c87fe84"},{"user":{"login":"michaellihs","id":575011,"node_id":"MDQ6VXNlcjU3NTAxMQ==","avatar_url":"https://avatars.githubusercontent.com/u/575011?v=4","gravatar_id":"","url":"https://api.github.com/users/michaellihs","html_url":"https://github.com/michaellihs","followers_url":"https://api.github.com/users/michaellihs/followers","following_url":"https://api.github.com/users/michaellihs/following{/other_user}","gists_url":"https://api.github.com/users/michaellihs/gists{/gist_id}","starred_url":"https://api.github.com/users/michaellihs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/michaellihs/subscriptions","organizations_url":"https://api.github.com/users/michaellihs/orgs","repos_url":"https://api.github.com/users/michaellihs/repos","events_url":"https://api.github.com/users/michaellihs/events{/privacy}","received_events_url":"https://api.github.com/users/michaellihs/received_events","type":"User","user_view_type":"public","site_admin":false},"version":"93e345c68e53471ec01e7530e15fc69193cc0cc4","committed_at":"2019-03-05T19:53:00Z","change_status":{"total":65,"additions":39,"deletions":26},"url":"https://api.github.com/gists/c2c0bd258610904514e7301474a2dc8f/93e345c68e53471ec01e7530e15fc69193cc0cc4"},{"user":{"login":"michaellihs","id":575011,"node_id":"MDQ6VXNlcjU3NTAxMQ==","avatar_url":"https://avatars.githubusercontent.com/u/575011?v=4","gravatar_id":"","url":"https://api.github.com/users/michaellihs","html_url":"https://github.com/michaellihs","followers_url":"https://api.github.com/users/michaellihs/followers","following_url":"https://api.github.com/users/michaellihs/following{/other_user}","gists_url":"https://api.github.com/users/michaellihs/gists{/gist_id}","starred_url":"https://api.github.com/users/michaellihs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/michaellihs/subscriptions","organizations_url":"https://api.github.com/users/michaellihs/orgs","repos_url":"https://api.github.com/users/michaellihs/repos","events_url":"https://api.github.com/users/michaellihs/events{/privacy}","received_events_url":"https://api.github.com/users/michaellihs/received_events","type":"User","user_view_type":"public","site_admin":false},"version":"838413b77abf7b3f528505fa8931144aa7ffa7d8","committed_at":"2019-03-05T19:42:00Z","change_status":{"total":94,"additions":56,"deletions":38},"url":"https://api.github.com/gists/c2c0bd258610904514e7301474a2dc8f/838413b77abf7b3f528505fa8931144aa7ffa7d8"},{"user":{"login":"michaellihs","id":575011,"node_id":"MDQ6VXNlcjU3NTAxMQ==","avatar_url":"https://avatars.githubusercontent.com/u/575011?v=4","gravatar_id":"","url":"https://api.github.com/users/michaellihs","html_url":"https://github.com/michaellihs","followers_url":"https://api.github.com/users/michaellihs/followers","following_url":"https://api.github.com/users/michaellihs/following{/other_user}","gists_url":"https://api.github.com/users/michaellihs/gists{/gist_id}","starred_url":"https://api.github.com/users/michaellihs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/michaellihs/subscriptions","organizations_url":"https://api.github.com/users/michaellihs/orgs","repos_url":"https://api.github.com/users/michaellihs/repos","events_url":"https://api.github.com/users/michaellihs/events{/privacy}","received_events_url":"https://api.github.com/users/michaellihs/received_events","type":"User","user_view_type":"public","site_admin":false},"version":"9bf690779929a6e208388e8a5096bdcb54b36214","committed_at":"2019-03-05T14:36:10Z","change_status":{"total":45,"additions":31,"deletions":14},"url":"https://api.github.com/gists/c2c0bd258610904514e7301474a2dc8f/9bf690779929a6e208388e8a5096bdcb54b36214"},{"user":{"login":"michaellihs","id":575011,"node_id":"MDQ6VXNlcjU3NTAxMQ==","avatar_url":"https://avatars.githubusercontent.com/u/575011?v=4","gravatar_id":"","url":"https://api.github.com/users/michaellihs","html_url":"https://github.com/michaellihs","followers_url":"https://api.github.com/users/michaellihs/followers","following_url":"https://api.github.com/users/michaellihs/following{/other_user}","gists_url":"https://api.github.com/users/michaellihs/gists{/gist_id}","starred_url":"https://api.github.com/users/michaellihs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/michaellihs/subscriptions","organizations_url":"https://api.github.com/users/michaellihs/orgs","repos_url":"https://api.github.com/users/michaellihs/repos","events_url":"https://api.github.com/users/michaellihs/events{/privacy}","received_events_url":"https://api.github.com/users/michaellihs/received_events","type":"User","user_view_type":"public","site_admin":false},"version":"cb2931a4c2b0888910330268f981888c552289a2","committed_at":"2019-03-05T14:18:06Z","change_status":{"total":250,"additions":250,"deletions":0},"url":"https://api.github.com/gists/c2c0bd258610904514e7301474a2dc8f/cb2931a4c2b0888910330268f981888c552289a2"}],"truncated":false}