k8s deployment #58
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: k8s deployment | |
on: | |
pull_request: | |
push: | |
branches: | |
- master | |
- dev | |
- release/** | |
- hotfix/** | |
env: | |
DD_DOCKER_REPO: defectdojo | |
DD_HOSTNAME: defectdojo.default.minikube.local | |
GITHUB_CACHE_REPO: containers.pkg.github.com | |
HELM_RABBIT_BROKER_SETTINGS: " \ | |
--set redis.enabled=false \ | |
--set rabbitmq.enabled=true \ | |
--set celery.broker=rabbitmq \ | |
--set createRabbitMqSecret=true \ | |
" | |
HELM_REDIS_BROKER_SETTINGS: " \ | |
--set redis.enabled=false \ | |
--set rabbitmq.enabled=true \ | |
--set celery.broker=rabbitmq \ | |
--set createRabbitMqSecret=true \ | |
" | |
HELM_MYSQL_DATABASE_SETTINGS: " \ | |
--set database=mysql \ | |
--set postgresql.enabled=false \ | |
--set mysql.enabled=true \ | |
--set createMysqlSecret=true \ | |
" | |
HELM_PG_DATABASE_SETTINGS: " \ | |
--set database=postgresql \ | |
--set postgresql.enabled=true \ | |
--set mysql.enabled=false \ | |
--set createPostgresqlSecret=true \ | |
" | |
jobs: | |
build: | |
name: Build Image | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
docker-image: [django, nginx] | |
steps: | |
# - name: Login to DockerHub | |
# uses: docker/login-action@v1 | |
# with: | |
# username: ${{ secrets.DOCKERHUB_USERNAME }} | |
# password: ${{ secrets.DOCKERHUB_TOKEN }} | |
- name: Checkout | |
uses: actions/checkout@v3 | |
with: | |
persist-credentials: false | |
- name: Read Docker Image Identifiers | |
id: read-docker-image-identifiers | |
run: echo "IMAGE_REPOSITORY=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV | |
- name: Set up Docker Buildx | |
uses: docker/setup-buildx-action@v2 | |
- name: Cache Docker layers | |
uses: actions/cache@v3 | |
env: | |
docker-image: ${{ matrix.docker-image }} | |
with: | |
path: /tmp/.buildx-cache-${{ env.docker-image }} | |
key: ${{ runner.os }}-buildx-${{ env.docker-image }}-${{ github.workflow }}-${{ github.sha }}-${{ github.run_id }} | |
restore-keys: | | |
${{ runner.os }}-buildx-${{ env.docker-image }}-${{ github.workflow }}-${{ github.sha }} | |
${{ runner.os }}-buildx-${{ env.docker-image }}-${{ github.workflow }} | |
${{ runner.os }}-buildx-${{ env.docker-image }} | |
- name: Build | |
id: docker_build | |
uses: docker/build-push-action@v3 | |
env: | |
docker-image: ${{ matrix.docker-image }} | |
with: | |
context: . | |
push: false | |
tags: | | |
${{ env.DD_DOCKER_REPO }}/defectdojo-${{ env.docker-image }}:latest | |
file: Dockerfile.${{ env.docker-image }} | |
outputs: type=docker,dest=${{ env.docker-image }}_img | |
cache-from: type=local,src=/tmp/.buildx-cache-${{ env.docker-image }} | |
cache-to: type=local,dest=/tmp/.buildx-cache-${{ env.docker-image }} | |
- name: Upload image ${{ env.docker-image }} as artifact | |
uses: actions/upload-artifact@v2 | |
with: | |
name: ${{ matrix.docker-image }} | |
path: ${{ matrix.docker-image }}_img | |
retention-days: 1 | |
setting_minikube_cluster: | |
name: Kubernetes Deployment | |
runs-on: ubuntu-18.04 | |
needs: build | |
strategy: | |
matrix: | |
include: | |
# databases, broker and k8s are independent, so we don't need to test each combination | |
# lastest k8s version (https://kubernetes.io/releases/) and oldest supported version from aws | |
# are tested (https://docs.aws.amazon.com/eks/latest/userguide/kubernetes-versions.html#available-versions) | |
- databases: pgsql | |
brokers: redis | |
k8s: 'v1.18.16' | |
- databases: mysql | |
brokers: rabbit | |
k8s: 'v1.18.16' | |
- databases: pgsql | |
brokers: rabbit | |
k8s: 'v1.22.0' | |
- databases: mysql | |
brokers: redis | |
k8s: 'v1.22.0' | |
steps: | |
# - name: Login to DockerHub | |
# uses: docker/login-action@v1 | |
# with: | |
# username: ${{ secrets.DOCKERHUB_USERNAME }} | |
# password: ${{ secrets.DOCKERHUB_TOKEN }} | |
- name: Checkout | |
uses: actions/checkout@v3 | |
- name: Setup Minikube | |
uses: manusa/actions-setup-minikube@v2.6.0 | |
with: | |
minikube version: 'v1.24.0' | |
kubernetes version: ${{ matrix.k8s }} | |
driver: docker | |
start args: '--addons=ingress' | |
- name: Status of minikube | |
run: |- | |
minikube status | |
- name: Load images from artifacts | |
uses: actions/download-artifact@v3 | |
- name: Load docker images | |
run: |- | |
eval $(minikube docker-env) | |
docker load -i nginx/nginx_img | |
docker load -i django/django_img | |
docker images | |
- name: Configure HELM repos | |
run: |- | |
helm repo add bitnami https://charts.bitnami.com/bitnami | |
helm dependency list ./helm/defectdojo | |
helm dependency update ./helm/defectdojo | |
- name: Set confings into Outputs | |
id: set | |
run: |- | |
echo ::set-output name=pgsql:: "${{ env.HELM_PG_DATABASE_SETTINGS }}" | |
echo ::set-output name=mysql:: "${{ env.HELM_MYSQL_DATABASE_SETTINGS }}" | |
echo ::set-output name=redis:: "${{ env.HELM_REDIS_BROKER_SETTINGS }}" | |
echo ::set-output name=rabbit:: "${{ env.HELM_RABBIT_BROKER_SETTINGS }}" | |
# - name: Create image pull Secrets | |
# run: |- | |
# kubectl create secret docker-registry defectdojoregistrykey --docker-username=${{ secrets.DOCKERHUB_USERNAME }} --docker-password=${{ secrets.DOCKERHUB_TOKEN }} | |
# kubectl get secrets | |
- name: Deploying Djano application with ${{ matrix.databases }} ${{ matrix.brokers }} | |
run: |- | |
helm install \ | |
defectdojo \ | |
./helm/defectdojo \ | |
--set django.ingress.enabled=true \ | |
--set imagePullPolicy=Never \ | |
${{ steps.set.outputs[matrix.databases] }} \ | |
${{ steps.set.outputs[matrix.brokers] }} \ | |
--set createSecret=true \ | |
# --set imagePullSecrets=defectdojoregistrykey | |
- name: Check deployment status | |
run: |- | |
kubectl get pods | |
kubectl get ingress | |
kubectl get services | |
- name: Check Application | |
run: |- | |
to_complete () { | |
kubectl wait --for=$1 $2 --timeout=500s --selector=$3 2>/tmp/test || true | |
if [[ -s /tmp/test ]]; then | |
echo "ERROR: $2" | |
cat /tmp/test | |
echo "INFO: status:" | |
kubectl get pods | |
echo "INFO: logs:" | |
kubectl logs --selector=$3 --all-containers=true | |
exit 1 | |
fi | |
return ${?} | |
} | |
echo "Waiting for init job..." | |
to_complete "condition=Complete" job "defectdojo.org/component=initializer" | |
echo "Waiting for celery pods..." | |
to_complete "condition=ready" pod "defectdojo.org/component=celery" | |
echo "Waiting for django pod..." | |
to_complete "condition=ready" pod "defectdojo.org/component=django" | |
echo "Pods up and ready to rumbole" | |
kubectl get pods | |
RETRY=0 | |
while : | |
do | |
OUT=$(kubectl run curl --quiet=true --image=curlimages/curl:7.73.0 \ | |
--overrides='{ "apiVersion": "v1" }' \ | |
--restart=Never -i --rm -- -s -m 20 -I --header "Host: $DD_HOSTNAME" http://`kubectl get service defectdojo-django -o json \ | |
| jq -r '.spec.clusterIP'`/login?next=/) | |
echo $OUT | |
CR=`echo $OUT | egrep "^HTTP" | cut -d' ' -f2` | |
echo $CR | |
if [[ $CR -ne 200 ]]; then | |
echo $RETRY | |
if [[ $RETRY -gt 2 ]]; then | |
kubectl get pods | |
echo `kubectl logs --tail=30 -l defectdojo.org/component=django -c uwsgi` | |
echo "ERROR: cannot display login screen; got HTTP code $CR" | |
exit 1 | |
else | |
((RETRY++)) | |
echo "Attempt $RETRY to get login page" | |
sleep 5 | |
fi | |
else | |
echo "Result received" | |
break | |
fi | |
done | |
echo "Final Check of components" | |
errors=`kubectl get pods | grep Error | awk '{print $1}'` | |
if [[ ! -z $errors ]]; then | |
echo "Few pods with errors" | |
for line in $errors; do | |
echo "Dumping log from $line" | |
kubectl logs --tail 50 $line | |
done | |
exit 1 | |
else | |
echo "DD K8S successfully deployed" | |
fi |