#!/bin/bash -ev
# TravisCI Autodeploy to Kubernetes Script
# Ensure all required environment variables are present
if [ -z "$KUBERNETES_CLUSTER_CERTIFICATE" ] || \
[ -z "$KUBERNETES_SERVER" ] || \
[ -z "$KUBERNETES_SERVICE_ACC_TOKEN" ]; then
>&2 echo 'Required variable unset, docker build and deploy failed'
exit 1
fi
# Generate latest docker image name
container_version=$(git rev-parse --short=8 HEAD)
echo : "
Travis-CI autodeploy to kubernetes script
Repo: $TRAVIS_REPO_SLUG
Image Version: $container_version
"
# Update kube deployment files with new container version
find ./kube/ -type f -print0 | xargs sed -i "s/CONTAINER_VERSION/$container_version/g"
# Install kubernetes cli and add to path
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
# Create cerifiticate file
echo "$KUBERNETES_CLUSTER_CERTIFICATE" | base64 --decode > cert.crt
# Apply updated kubernetes application config
kubectl --kubeconfig=/dev/null \
--certificate-authority=cert.crt \
--server="$KUBERNETES_SERVER" \
--token="$KUBERNETES_SERVICE_ACC_TOKEN" \
apply -f ./kube/
Travis-CI Auto-Deploy to Kubernetes
Automatically apply updated Kubernetes config to control plane using Travis-CI
Add script to project in suitable scripts directory:
./scripts/travis-ci/travis-ci-autodeploy-kube.sh
Add the travis-ci-autodeploy-kube.sh script
as a script to the travis-ci deploy hook in travis.yml
:
deploy:
provider: script
script: bash ./scripts/travis-ci/travis-ci-autodeploy-kube.sh
on:
branch: master
In the Kubernetes deployment create and apply a ServiceAccount object and bind a role to it, allowing limited deploy access to the cluster. For example:
Account: cicd-service-account.yml
apiVersion: v1
kind: ServiceAccount
metadata:
name: cicd
namespace: default
Role: cicd-role.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cicd
rules:
- apiGroups: ["", "apps", "batch", "extensions", "storage.k8s.io"]
resources: ["deployments", "services", "replicasets", "pods", "jobs", "cronjobs", "storageclasses", "persistentvolumeclaims"]
verbs: ["*"]
Binding: cicd-role-binding.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cicd
subjects:
- kind: ServiceAccount
name: cicd
namespace: default
roleRef:
kind: ClusterRole
name: cicd
apiGroup: rbac.authorization.k8s.io
Ensure the required environment variables are set in the build. For secret credentials, add to build directly on travis-ci.com, or by using Travis secure values (see notes on max length of secure credentials).
- KUBERNETES_CLUSTER_CERTIFICATE - Can be found (base64 encoded) in the .kube/config file on the Kubernetes server, key:
cluster.certificate-authority-data
. - KUBERNETES_SERVER - Can also be found in the
.kube/config
file on the Kubernetes server. Note the IP address may need substituting for your domain name. - KUBERNETES_SERVICE_ACC_TOKEN - After the above service account has been created, run
kubectl get secret $(kubectl get secrets --namespace default | grep cicd-token | awk '{print $1}') -o jsonpath='{.data.token}' --namespace default | base64 --decode
on kubernetes server to get the service account access token.
Before deploying, the script will also search and replace and references of 'CONTAINER_VERSION' in config files contained in ./kube/
with the first characters of the git commit. This provides specific container deployment and identification, allowing for quick rollbacks if required.
Notes
The CI/CD role is based in the
default
Kubernetes namespace, you can change this to suit your app setup.The auto-deploy script assumes you have tagged your build image name with the first 8 characters of the git commit hash it was built from.
Max length of Travis-CI encrypted values seems to be around 128 bytes, therefore the KUBERNETES_CLUSTER_CERTIFICATE and KUBERNETES_SERVICE_ACC_TOKEN will have to be added directly to Travis-CI using either their web app or
travis set env
.- When adding environment variables as Travis-CI secure values they will only be available in pull requests created by trusted users. Therefore, if an outside user makes a pull request to your repository, they will not have access to your access token and the deployment will fail.
Depending on when your travis-ci account was made, secret may require encrypting with the
--com
flag. See this stackoverflow for more details.