You can find a sample repo for deploying to Google Cloud with Codeship Pro on Github here.
For authenticating with the Google Cloud Platform we’re going to create a Service account.
Go to the GCP console, select your project and go to APIs & auth → Credentials:
Now click Add credentials and add a Service account. Select the JSON download option when asked on the next page. You will download a json file that contains credentials for authentication later. This configuration file and other parameters need to be put into an encrypted environment file that can be used as part of the build.
We’re going to create an environment configuration file that sets the following keys:
GOOGLE_AUTH_JSON=... GOOGLE_AUTH_EMAIL=... GOOGLE_PROJECT_ID=...
Store the json file you received from the GCP console into a file named google_deployment.env in your repository. Make sure to remove all newlines from the file. On Linux and OSX you can use
tr '\n' ' ' < google_deployment.env to get the line and copy it back into the file. Then prepend the single line with
GOOGLE_AUTH_JSON=. You can find the
GOOGLE_AUTH_EMAIL on the credentials page in the Service accounts section. It has to be from the Service account we just created. The
GOOGLE_PROJECT_ID can be found on the Dashboard of your project in the Google developer console. Make sure to put the file into .gitignore so its never committed with
echo 'google_deployment.env' >> .gitignore
Now you can encrypt the env file into a file called
google_deployment.env.encrypted. Take a look at the encrypted environment files tutorial to encrypt the file properly.
Now we’re all set with the environment file and can set up our deployment script, codeship-services.yml and codeship-steps.yml.
Before calling any commands against the GCP API we need to authenticate with the gcloud tool. The authentication does not get persisted across steps, so we need to run the provided authentication command at the beginning of each step that wants to use the gcloud or kubectl tool.
codeship/google-cloud-deployment container provides a deployment command called
codeship_google authenticate. If you set up the environment variables as described above it will automatically read them and set the configuration up for you. The following example script runs the
codeship_google authenticate command first and then interacts with the
gcloud tool to deploy your application. You can use this script as a starting point to write your own deployment script and use it in the later stages.
#!/bin/bash # Authenticate with the Google Services codeship_google authenticate # Set the default zone to use gcloud config set compute/zone us-central1-a # Starting an Instance in Google Compute Engine gcloud compute instances create testmachine # Stopping an Instance in Google Compute Engine gcloud compute instances delete testmachine -q
We’re first authenticating, then setting the default zone to use and then starting an instance in the Google Compute Engine. Add any commands you need for your specific deployment integration with the Google Cloud Platform. You can also take a look at a longer example we use for integration testing our container.
Make sure to put it into your repository so we can later on use it inside the Docker container for deployment.
codeship-services.yml file uses the
codeship/google-cloud-deployment container, sets the encrypted environment file and adds the repository folder as a volume at
/deploy so we can use it as part of the build.
googleclouddeployment: image: codeship/google-cloud-deployment encrypted_env_file: test/google_deployment.env.encrypted # Add Docker if you want to interact with the Google Container Engine and Google Container Registry add_docker: true volumes: - ./:/deploy
In the steps we’re now calling the deployment script we created before in
scripts/deploy_to_gcp.sh in your repository. This will authenticate with GCP and then let you interact with any resources in the Google Cloud.
- service: googleclouddeployment command: /deploy/scripts/deploy_to_gcp.sh
Now you have a working integration with the Google Cloud that will automatically update with the latest
Our container also works with the Google Container Engine and Container Registry. At first we will set up a push step to push a container to the registry. Then a script will authenticate with Google and interact with kubectl to start the service.
First we define the dockercfg generator service container in the codeship-services.yml file which will create temporary credentials for us. You can check out the code behind the container in the codeship-library/gcr-dockercfg-generator repository. Make sure the environment variables mentioned above are set up in the encrypted_env_file.
gcr_dockercfg: image: codeship/gcr-dockercfg-generator add_docker: true encrypted_env_file: environment.encrypted
Now we can reference the service in the push step configuration and set up the deployment to the Google Container Registry.
- service: app type: push image_name: gcr.io/company_name/container_name registry: https://gcr.io dockercfg_service: gcr_dockercfg # Set up script that interacts with Gcloud after the container push - service: deployment command: /deploy/test/deploy_to_google.sh
Here is an example script you could use to interact with the Google Cloud registry.
#!/bin/bash set -e GOOGLE_CONTAINER_NAME=gcr.io/codeship-production/google-deployment-example KUBERNETES_APP_NAME=google-deployment DEFAULT_ZONE=us-central1-a codeship_google authenticate echo "Setting default timezone $DEFAULT_ZONE" gcloud config set compute/zone $DEFAULT_ZONE echo "Starting Cluster on GCE for $KUBERNETES_APP_NAME" gcloud container clusters create $KUBERNETES_APP_NAME \ --num-nodes 1 \ --machine-type g1-small echo "Deploying image on GCE" kubectl run $KUBERNETES_APP_NAME --image=$GOOGLE_CONTAINER_NAME --port=8080 echo "Exposing a port on GCE" kubectl expose rc $KUBERNETES_APP_NAME --create-external-load-balancer=true echo "Waiting for services to boot" echo "Listing services on GCE" kubectl get services $KUBERNETES_APP_NAME echo "Removing service $KUBERNETES_APP_NAME" kubectl delete services $KUBERNETES_APP_NAME echo "Waiting After Remove" echo "Stopping port forwarding for $KUBERNETES_APP_NAME" kubectl stop rc $KUBERNETES_APP_NAME echo "Stopping Container Cluster for $KUBERNETES_APP_NAME" gcloud container clusters delete $KUBERNETES_APP_NAME -q