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