cloudbuild.vm.yaml (127 lines of code) (raw):
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
steps:
# 1. terraform: make [self-destructing] VM [with microk8s]
# 2. terraform: retrieve VM's ephemeral IP (via terraform output ip) and write to file
# 3. bash: sed the IP into the kubeconfig
# 4. kubectl apply the application
# 5. run the test
# 6. destroy the VM
# (if any of steps 1-5 fail, #6 won't be reached, but self-destruct mechanism will kick in)
- id: 'init terraform'
name: 'gcr.io/$PROJECT_ID/terraform'
args: ['init']
waitFor: ['-']
- id: 'launch vm'
name: 'gcr.io/$PROJECT_ID/terraform'
args: [
'apply',
'-var=project-name=$PROJECT_ID',
'-var=instance-name=test-$BUILD_ID',
'-auto-approve'
]
waitFor: ['init terraform']
- id: 'patch k8s config'
name: 'gcr.io/cloud-builders/gcloud'
entrypoint: 'bash'
args: ['-c','find k8s -type f | xargs sed -i "s/PROJECT_ID/$PROJECT_ID/g"']
waitFor: ['-']
- id: 'patch kubeconfig'
name: 'gcr.io/$PROJECT_ID/terraform'
entrypoint: '/bin/bash'
args:
- '-c'
- |
echo $(terraform output ip) > _clusterip
sed -i.sed-bak "s/CLUSTER_IP/"$(< _clusterip)"/" kubeconfig.microk8s
cat kubeconfig.microk8s
# loop until connection works
# TODO: replace this with a looped kubectl connection
apt-get update && apt-get -y install curl
for i in $$(seq 0 59); do
status="$$(curl -sL -w "%{http_code}" -I "http://$$(< _clusterip):8080" -o /dev/null)" || status='000'
if [[ $status == '200' ]]
then
echo "connected to kubernetes api"
break
else
if [ $$i -gt 0 ]; then
echo "unable to connect. retrying in 5s..."
sleep 5
fi
fi
done
waitFor: ['launch vm']
- id: 'compile web app'
name: 'gcr.io/cloud-builders/npm'
dir: 'web'
args: ['install']
waitFor: ['-']
- id: 'web app unit tests'
name: 'gcr.io/cloud-builders/npm'
dir: 'web'
args: ['test']
waitFor: ['compile web app']
- id: 'build web'
name: 'gcr.io/cloud-builders/docker'
args: [
'build',
'--tag=web',
'--tag=gcr.io/$PROJECT_ID/web',
'--cache-from', 'gcr.io/$PROJECT_ID/web:latest',
'web/.',
]
waitFor: ['web app unit tests']
- id: 'build db'
name: 'gcr.io/cloud-builders/docker'
args: [
'build',
'--tag=mysql',
'--tag=gcr.io/$PROJECT_ID/mysql',
'--cache-from', 'gcr.io/$PROJECT_ID/mysql:latest',
'mysql/.',
]
env:
- "MYSQL_ROOT_PASSWORD=password"
waitFor: ['-']
- id: 'push web'
name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/web']
waitFor: ['build web']
- id: 'push db'
name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/mysql']
waitFor: ['build db']
- id: 'deploy app'
# use vanilla kubectl container b/c this isn't GKE
name: 'bitnami/kubectl'
args: [
'apply',
'-f',
'k8s/',
'--kubeconfig=kubeconfig.microk8s'
]
waitFor: ['patch kubeconfig']
- id: 'get endpoint'
name: 'gcr.io/cloud-builders/kubectl'
entrypoint: 'bash'
args:
- '-c'
- |
# determine which node port the service was exposed on
get_nodeport() {
kubectl get service cookieshop-web -o=jsonpath='{.spec.ports[0].nodePort}' --kubeconfig=kubeconfig.microk8s
}
until [[ -n "$(get_nodeport)" ]]; do
echo "querying for nodeport"
sleep 3
done
echo "$(get_nodeport)" > _nodeport
waitFor: ['deploy app']
- id: 'integration test'
name: 'gcr.io/cloud-builders/curl'
entrypoint: '/bin/bash'
args:
- '-c'
- |
# cat _endpoint
### -r = retries; -i = interval; -k = keyword to search for ###
./test/test-connection.sh -r 20 -i 5 -u http://$(cat _clusterip):$(cat _nodeport) &&
./test/test-content.sh -r 20 -i 5 -u http://$(cat _clusterip):$(cat _nodeport) -k 'Chocolate Chip'
waitFor: ['get endpoint']
- id: 'delete vm'
name: 'gcr.io/$PROJECT_ID/terraform'
args: [
'destroy',
'-var=project-name=$PROJECT_ID',
'-var=instance-name=test-$BUILD_ID',
'-auto-approve'
]
waitFor: ['integration test']
timeout:
3600s