Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • s28840/ss22-devops-project-app
1 result
Show changes
Commits on Source (2)
workflow:
rules:
- if: '$CI_COMMIT_BRANCH == "staging" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- if: >-
$CI_COMMIT_BRANCH == "staging"
|| ($CI_COMMIT_BRANCH == "main" && $CI_COMMIT_TITLE =~ /Merge branch 'staging' into 'main'/)
when: always
- when: never
......@@ -23,29 +25,13 @@ stages:
.gke-initialization:
image: google/cloud-sdk:${GOOGLE_CLOUD_SDK_IMAGE_VERSION}
before_script:
# BASE64_GOOGLE_CREDENTIALS is a masked CI/CD GitLab variable
- echo $BASE64_GOOGLE_CREDENTIALS | base64 -d > ~/service_account.json
- gcloud auth activate-service-account --key-file ~/service_account.json
- gcloud config set project ${GCP_PROJECT_ID}
- gcloud config set compute/zone ${GCP_COMPUTE_REGION}
- gcloud container clusters get-credentials ${GCP_PROJECT_ID}-gke
.gke-deployment:
extends: .gke-initialization
tags:
- docker
script:
- IMAGE="${CI_REGISTRY_IMAGE}:$VERSION"
- cd "./k8s-manifests"
- kubectl apply -f gitlab-registry-credentials.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
- SECRETS_MANIFEST=$(sed -e "s,{{jwtSecret}},${JWT_SECRET},g" ./secrets.yaml.tmpl)
- echo "${SECRETS_MANIFEST}" | kubectl apply --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}" --filename -
- kubectl apply -f configmap.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
- DEPLOYMENT_MANIFEST=$(sed -e "s,{{image}},${IMAGE},g" ./deployment.yaml.tmpl)
- echo "${DEPLOYMENT_MANIFEST}" | kubectl apply --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}" --filename -
- kubectl apply -f service.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
- INGRESS_MANIFEST=$(sed -e "s,{{static-ip-name}},${STATIC_IP},g" -e "s,{{allowHttpFlag}},true,g" -e "s,{{portNumber}},80,g" ./ingress.yaml.tmpl)
- echo "${INGRESS_MANIFEST}" | kubectl apply --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}" --filename -
run-tests:
stage: test
tags:
......@@ -108,7 +94,7 @@ create-release-image:
- docker login -u ${CI_REGISTRY_USER} -p ${CI_REGISTRY_PASSWORD} ${CI_REGISTRY}
- docker pull "${CONTAINER_TAG}"
script:
- VERSION=$(grep '"version"' ./app/client/package.json | cut -d '"' -f 4 | head -n 1)
- VERSION=$(grep '"version"' ./app/app-version.json | cut -d '"' -f 4 | head -n 1)
- docker tag "${CONTAINER_TAG}" "${CI_REGISTRY_IMAGE}:${VERSION}"
- docker push "${CI_REGISTRY_IMAGE}:${VERSION}"
after_script:
......@@ -132,17 +118,19 @@ create-release-tag:
- PROJECT_URL=$(echo $CI_PROJECT_URL | sed 's/https:\/\///')
- git remote set-url origin https://oauth2:${APP_CI_ACCESS_TOKEN}@${PROJECT_URL}
script:
- VERSION=$(grep '"version"' ./app/client/package.json | cut -d '"' -f 4 | head -n 1)
- VERSION=$(grep '"version"' ./app/app-version.json | cut -d '"' -f 4 | head -n 1)
- echo ${VERSION}
- TAG=v${VERSION}
- git tag $TAG && git push origin $TAG
allow_failure: true
deploy-new-staging-version:
extends: .gke-deployment
extends: .gke-initialization
stage: deploy
needs:
- 'build-image'
tags:
- docker
rules:
- if: $CI_COMMIT_REF_NAME =~ /staging/
when: 'always'
......@@ -151,6 +139,19 @@ deploy-new-staging-version:
STATIC_IP: staging-todoapp-ip
VERSION: ${CI_PIPELINE_IID}-${CI_COMMIT_SHORT_SHA}
- when: never
script:
- IMAGE="${CI_REGISTRY_IMAGE}:$VERSION"
- cd "./k8s-manifests"
- kubectl apply -f gitlab-registry-credentials.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
# JWT_SECRET is a masked CI/CD GitLab variable
- SECRETS_MANIFEST=$(sed -e "s,{{jwtSecret}},${JWT_SECRET},g" ./secrets.yaml.tmpl)
- echo "${SECRETS_MANIFEST}" | kubectl apply --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}" --filename -
- kubectl apply -f configmap.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
- DEPLOYMENT_MANIFEST=$(sed -e "s,{{image}},${IMAGE},g" ./deployment.yaml.tmpl)
- echo "${DEPLOYMENT_MANIFEST}" | kubectl apply --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}" --filename -
- kubectl apply -f service.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
- INGRESS_MANIFEST=$(sed -e "s,{{static-ip-name}},${STATIC_IP},g" -e "s,{{allowHttpFlag}},true,g" -e "s,{{portNumber}},80,g" -e "s,{{suffix}},${ENVIRONMENT_NAME},g" ./ingress.yaml.tmpl)
- echo "${INGRESS_MANIFEST}" | kubectl apply --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}" --filename -
deploy-new-release:
extends: .gke-initialization
......@@ -167,17 +168,18 @@ deploy-new-release:
tags:
- docker
script:
- VERSION=$(grep '"version"' ./app/client/package.json | cut -d '"' -f 4 | head -n 1)
- VERSION=$(grep '"version"' ./app/app-version.json | cut -d '"' -f 4 | head -n 1)
- IMAGE="${CI_REGISTRY_IMAGE}:$VERSION"
- cd "./k8s-manifests"
- kubectl apply -f gitlab-registry-credentials.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
# JWT_SECRET is a masked CI/CD GitLab variable
- SECRETS_MANIFEST=$(sed -e "s,{{jwtSecret}},${JWT_SECRET},g" ./secrets.yaml.tmpl)
- echo "${SECRETS_MANIFEST}" | kubectl apply --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}" --filename -
- kubectl apply -f configmap.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
- DEPLOYMENT_MANIFEST=$(sed -e "s,{{image}},${IMAGE},g" ./deployment.yaml.tmpl)
- echo "${DEPLOYMENT_MANIFEST}" | kubectl apply --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}" --filename -
- kubectl apply -f service.yaml --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}"
- INGRESS_MANIFEST=$(sed -e "s,{{static-ip-name}},${STATIC_IP},g" -e "s,{{allowHttpFlag}},true,g" -e "s,{{portNumber}},80,g" -e "s,{{suffix}},production,g" ./ingress.yaml.tmpl)
- INGRESS_MANIFEST=$(sed -e "s,{{static-ip-name}},${STATIC_IP},g" -e "s,{{allowHttpFlag}},true,g" -e "s,{{portNumber}},80,g" -e "s,{{suffix}},${ENVIRONMENT_NAME},g" ./ingress.yaml.tmpl)
- echo "${INGRESS_MANIFEST}" | kubectl apply --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}" --filename -
switch-to-https:
......@@ -197,6 +199,6 @@ switch-to-https:
tags:
- docker
script:
- INGRESS_MANIFEST=$(sed -e "s,{{static-ip-name}},${STATIC_IP},g" -e "s,{{allowHttpFlag}},false,g" -e "s,{{portNumber}},443,g" ./k8s-manifests/ingress.yaml.tmpl)
- INGRESS_MANIFEST=$(sed -e "s,{{static-ip-name}},${STATIC_IP},g" -e "s,{{allowHttpFlag}},false,g" -e "s,{{portNumber}},443,g" -e "s,{{suffix}},${ENVIRONMENT_NAME},g" ./k8s-manifests/ingress.yaml.tmpl)
- echo "${INGRESS_MANIFEST}" | kubectl apply --namespace "${ENVIRONMENT_NAME}-${K8S_NAMESPACE}" --filename -
when: manual
......@@ -8,6 +8,9 @@ These branches are protected, meaning that commits targetting them will fail.
Changes to the codebase are realized through the use of other temporary branches and Merge Requests to **staging**. Merge Requests to **main** should
only be opened from **staging** as a source branch.
# Workflow
## Automated jobs
As soon as a new change through a MR is commited to **staging**, the [pipeline](.gitlab-ci.yml) is triggered. It deploys the application to the **staging-todoapp-devops** namespace in a Kubernetes cluster, run on GKE. After that, the application is accessible in its test/pre-production version under the domain:
> staging.todoapp-devops.software
......@@ -19,5 +22,5 @@ The web application is then accessible in its production version under:
## Manual jobs
The pipeline job `switch-to-https` should be manually triggered, after the app has been deployed. Due to Google's requirements, this process can only be triggered manually after the Google-managed Load Balancer is set up correctly and is operational.
The pipeline job `switch-to-https` corresponds to an upgrade from HTTP to HTTPS regarding the "client <-> Google's external Load Balancer" connection. Due to Google's requirements, this process should be only manually initialized after the Google-managed Load Balancer is set up correctly and is operational. Therefore, this job is not automatically executed in the pipeline and can be started manually.
{
"version": "2.0.1"
}
......@@ -3,4 +3,4 @@ kind: ConfigMap
metadata:
name: todo-app-config
data:
MONGODB_URL: mongodb://mongodb-service:27017/todo-app
MONGODB_URL: mongodb://mongodb-service:27017/todo-app # the "mongodb-service" is defined in the app's infrastructure repository (https://gitlab.bht-berlin.de/s28840/ss22-devops-project)
# Used to establish a connection to the GitLab Container Registry so an image can be pulled from there.
apiVersion: v1
kind: Secret
metadata:
......
......@@ -4,9 +4,9 @@ metadata:
name: todo-app-ingress
annotations:
kubernetes.io/ingress.class: "gce" # Google's external load-balancer
kubernetes.io/ingress.allow-http: "{{allowHttpFlag}}" # disabling HTTP
kubernetes.io/ingress.allow-http: "{{allowHttpFlag}}" # disabling HTTP, "true" by default, set to "false" from a manually triggered job
kubernetes.io/ingress.global-static-ip-name: {{static-ip-name}}
networking.gke.io/managed-certificates: todoapp-managed-cert-{{suffix}} # defined in the infrastructure repository
networking.gke.io/managed-certificates: todoapp-managed-cert-{{suffix}} # defined in the infrastructure repository (https://gitlab.bht-berlin.de/s28840/ss22-devops-project)
spec:
defaultBackend:
service:
......
......@@ -4,4 +4,4 @@ metadata:
name: todo-app-secrets
type: Opaque
data:
JWT_SECRET: {{jwtSecret}}
JWT_SECRET: {{jwtSecret}} # set from the pipeline in .gitlab-ci.yml