diff --git a/azure-pipelines.yml b/azure-pipelines.yml index dd9a61e29..51a0fee25 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,5 +1,5 @@ trigger: -- master + - master pr: none @@ -11,179 +11,179 @@ variables: kubernetes_cluster_resource_group: "RG_CLEANAIR_KUBERNETES_CLUSTER" stages: -- stage: Docker - displayName: Add new Docker images to ACR - jobs: - - job: BuildAndPushDocker - displayName: Build and register Docker images - pool: - vmImage: 'ubuntu-latest' - steps: - - task: AzureKeyVault@1 - displayName: 'Read KeyVault secrets' - inputs: - azureSubscription: 'urbanair-scn' - KeyVaultName: 'cleanair-secrets' - SecretsFilter: 'container-registry-admin-password,container-registry-admin-username,container-registry-login-server' - # Login to ACR - - script: | - echo "$(CONTAINER-REGISTRY-ADMIN-PASSWORD)" | docker login -u "$(CONTAINER-REGISTRY-ADMIN-USERNAME)" --password-stdin "$(CONTAINER-REGISTRY-LOGIN-SERVER)" - displayName: 'Login to ACR' + - stage: Docker + displayName: Add new Docker images to ACR + jobs: + - job: BuildAndPushDocker + displayName: Build and register Docker images + pool: + vmImage: "ubuntu-latest" + steps: + - task: AzureKeyVault@1 + displayName: "Read KeyVault secrets" + inputs: + azureSubscription: "urbanair-scn" + KeyVaultName: "cleanair-secrets" + SecretsFilter: "container-registry-admin-password,container-registry-admin-username,container-registry-login-server" + # Login to ACR + - script: | + echo "$(CONTAINER-REGISTRY-ADMIN-PASSWORD)" | docker login -u "$(CONTAINER-REGISTRY-ADMIN-USERNAME)" --password-stdin "$(CONTAINER-REGISTRY-LOGIN-SERVER)" + displayName: "Login to ACR" - # Set cleanair version - - bash: | - echo "##vso[task.setvariable variable=urbanair_version]$(git tag --sort=creatordate | tail -1 | sed 's/^.//')" - displayName: 'Set cleanair version' + # Set cleanair version + - bash: | + echo "##vso[task.setvariable variable=urbanair_version]$(git tag --sort=creatordate | tail -1 | sed 's/^.//')" + displayName: "Set cleanair version" - # CleanAir base image - - script: docker build -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair_base:$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair_base:latest -f containers/dockerfiles/cleanair_base.Dockerfile containers - displayName: 'Build dependencies of cleanair' + # CleanAir base image + - script: docker build -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair_base:$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair_base:latest -f containers/dockerfiles/cleanair_base.Dockerfile containers + displayName: "Build dependencies of cleanair" - # CleanAir Package - - script: docker build --build-arg urbanair_version=$(urbanair_version) --build-arg CLEANAIR_BASE_TAG=$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair:$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair:latest -f containers/dockerfiles/cleanair.Dockerfile containers - displayName: 'Build cleanair image' + # CleanAir Package + - script: docker build --build-arg urbanair_version=$(urbanair_version) --build-arg CLEANAIR_BASE_TAG=$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair:$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair:latest -f containers/dockerfiles/cleanair.Dockerfile containers + displayName: "Build cleanair image" - # Process static dataset - - script: docker build --build-arg urbanair_version=$(urbanair_version) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/process_static_dataset:$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/process_static_dataset:latest -f containers/dockerfiles/process_static_dataset.Dockerfile containers - displayName: 'Build cleanair image' + # Process static dataset + - script: docker build --build-arg urbanair_version=$(urbanair_version) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/process_static_dataset:$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/process_static_dataset:latest -f containers/dockerfiles/process_static_dataset.Dockerfile containers + displayName: "Build cleanair image" - # Urbanair API - - script: docker build --build-arg urbanair_version=$(urbanair_version) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/urbanairapi:$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/urbanairapi:latest -f containers/dockerfiles/urbanairapi.Dockerfile containers - displayName: 'Build urbanair API image' + # Urbanair API + - script: docker build --build-arg urbanair_version=$(urbanair_version) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/urbanairapi:$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/urbanairapi:latest -f containers/dockerfiles/urbanairapi.Dockerfile containers + displayName: "Build urbanair API image" - # JamCam cronjobs - - script: | - docker build --build-arg urbanair_version=$(urbanair_version) --build-arg git_hash=$(git show -s --format=%H) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/jamcamcron:$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/jamcamcron:$(Build.SourceVersion):latest -f containers/dockerfiles/jamcam.Dockerfile containers - displayName: "Build jamcam cronjob image" + # JamCam cronjobs + - script: | + docker build --build-arg urbanair_version=$(urbanair_version) --build-arg git_hash=$(git show -s --format=%H) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/jamcamcron:$(Build.SourceVersion) -t $(CONTAINER-REGISTRY-LOGIN-SERVER)/jamcamcron:latest -f containers/dockerfiles/jamcam.Dockerfile containers + displayName: "Build jamcam cronjob image" - # List available images - - script: | - docker images - displayName: 'List images' + # List available images + - script: | + docker images + displayName: "List images" - # Push to ACR and remove local images - - script: | - docker push $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair_base --all-tags - docker push $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair --all-tags - docker push $(CONTAINER-REGISTRY-LOGIN-SERVER)/process_static_dataset --all-tags - docker push $(CONTAINER-REGISTRY-LOGIN-SERVER)/urbanairapi --all-tags - docker push $(CONTAINER-REGISTRY-LOGIN-SERVER)/jamcamcron --all-tags - docker image rmi $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair_base $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair $(CONTAINER-REGISTRY-LOGIN-SERVER)/urbanairapi $(CONTAINER-REGISTRY-LOGIN-SERVER)/jamcamcron - displayName: 'Push CleanAir and UrbanAir and remove images' + # Push to ACR and remove local images + - script: | + docker push $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair_base --all-tags + docker push $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair --all-tags + docker push $(CONTAINER-REGISTRY-LOGIN-SERVER)/process_static_dataset --all-tags + docker push $(CONTAINER-REGISTRY-LOGIN-SERVER)/urbanairapi --all-tags + docker push $(CONTAINER-REGISTRY-LOGIN-SERVER)/jamcamcron --all-tags + docker image rmi $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair_base $(CONTAINER-REGISTRY-LOGIN-SERVER)/cleanair $(CONTAINER-REGISTRY-LOGIN-SERVER)/urbanairapi $(CONTAINER-REGISTRY-LOGIN-SERVER)/jamcamcron + displayName: "Push CleanAir and UrbanAir and remove images" -- stage: Kubernetes - displayName: Update Helm chart on Azure Kubernetes cluster - jobs: - - job: UpdateAzureKubernetesHelmChart - displayName: Install Kubectl and install/upgrade helm - pool: - vmImage: 'ubuntu-latest' - steps: - # Connect to Azure - - task: AzureCLI@1 - displayName: 'Connect to Azure' - inputs: - azureSubscription: 'urbanair-scn' - scriptLocation: 'inlineScript' - inlineScript: | - az aks get-credentials -n $(KUBERNETES_CLUSTER_NAME) -g $(KUBERNETES_CLUSTER_RESOURCE_GROUP) - KUBERNETES_VERSION=$(az aks show -n $(KUBERNETES_CLUSTER_NAME) -g $(KUBERNETES_CLUSTER_RESOURCE_GROUP) --query "kubernetesVersion" -o tsv) - echo "##vso[task.setvariable variable=kubernetes_version]$KUBERNETES_VERSION" - # Read Azure key vault - - task: AzureKeyVault@1 - displayName: 'Read KeyVault secrets' - inputs: - azureSubscription: 'urbanair-scn' - KeyVaultName: 'cleanair-secrets' - SecretsFilter: 'scoot-aws-key,scoot-aws-key-id,satellite-copernicus-key,cleanair-inputs-db-name,cleanair-inputs-2021-db-cluster-password,cleanair-inputs-2021-db-cluster-username,cleanair-inputs-2021-db-server-name, container-registry-admin-password,container-registry-admin-username,container-registry-login-server,sentry-dsn,tomtom-api-key,cleanair-log-storage-key,cleanair-log-storage-connection-string,cleanair-experiment-archive-key,http-basic-prime-cache' - # Install matching Kubectl version - - task: KubectlInstaller@0 - displayName: 'Install matching Kubectl version' - inputs: - kubectlVersion: $(KUBERNETES_VERSION) - # Install latest Helm version - - task: HelmInstaller@1 - displayName: 'Install latest Helm version' - inputs: - helmVersionToInstall: 3.1.2 - # List installed versions - - script: | - echo "Kubernetes version on the cluster is ${KUBERNETES_VERSION}" - echo "Kubectl details:" - kubectl version - echo "Helm details:" - echo "Helm $(NAMESPACE) namespace:" - helm list --namespace $(NAMESPACE) - displayName: 'List installed versions' - # Add secrets to Kubernetes - - script: | - # Check whether we need to create a new namespace - if [ "$(kubectl get namespace $(NAMESPACE) 2> /dev/null | grep $(NAMESPACE))" == "" ]; then - kubectl create namespace $(NAMESPACE) - fi - echo "Adding secrets to Kubernetes" - if [ "$(kubectl get secret regcred --namespace cleanair 2> /dev/null | grep regcred)" == "" ]; then - kubectl create secret docker-registry --namespace cleanair regcred --docker-server=$(CONTAINER-REGISTRY-LOGIN-SERVER) --docker-username=$(CONTAINER-REGISTRY-ADMIN-USERNAME) --docker-password=$(CONTAINER-REGISTRY-ADMIN-PASSWORD) - fi - if [ "$(kubectl get secret secrets --namespace cleanair 2> /dev/null | grep secrets)" == "" ]; then - echo '{ - "aws_key_id": "$(SCOOT-AWS-KEY-ID)", - "aws_key": "$(SCOOT-AWS-KEY)" - }' > aws_secrets.json - echo '{ - "username": "$(CLEANAIR-INPUTS-2021-DB-CLUSTER-USERNAME)@$(CLEANAIR-INPUTS-2021-DB-SERVER-NAME)", - "password": "$(CLEANAIR-INPUTS-2021-DB-CLUSTER-PASSWORD)", - "host": "$(CLEANAIR-INPUTS-2021-DB-SERVER-NAME).postgres.database.azure.com", - "port": 5432, - "db_name": "$(CLEANAIR-INPUTS-DB-NAME)", - "ssl_mode": "require" - }' > db_secrets.json - echo '{ - "copernicus_key": "$(SATELLITE-COPERNICUS-KEY)" - }' > copernicus_secrets.json - echo "${HTTP-BASIC-PRIME-CACHE}" > http_priming_secret - kubectl create secret generic --namespace cleanair secrets --from-file=aws_secrets.json --from-file=db_secrets.json --from-file=copernicus_secrets.json --from-file=http_priming_secret - kubectl create secret generic --namespace cleanair sentry --from-literal=SENTRY_DSN='$(SENTRY-DSN)' - rm -f aws_secrets.json db_secrets.json copernicus_secrets.json http_priming_secret - # kubectl create secret generic --namespace cleanair secrets --from-literal=host='$(CLEANAIR-INPUTS-2021-DB-SERVER-NAME).postgres.database.azure.com' --from-literal=port=5432 --from-literal=db_name='$(CLEANAIR-INPUTS-DB-NAME)' --from-literal=username='$(CLEANAIR-INPUTS-2021-DB-CLUSTER-USERNAME)@$(CLEANAIR-INPUTS-2021-DB-SERVER-NAME)' --from-literal=password='$(CLEANAIR-INPUTS-2021-DB-CLUSTER-PASSWORD)' --from-literal=ssl_mode='require' --from-literal=aws_key_id='$(SCOOT-AWS-KEY-ID)' --from-literal=aws_key='$(SCOOT-AWS-KEY)' - fi - if [ "$(kubectl get secret --namespace cleanair 2> /dev/null | grep tomtom-api-key)" == "" ]; then - kubectl create secret generic --namespace cleanair tomtom-api-key --from-literal=TOMTOM_API_KEY='$(TOMTOM-API-KEY)' - fi - if [ "$(kubectl get secret --namespace cleanair 2> /dev/null | grep cleanair-log-storage-connection-string)" == "" ]; then - kubectl create secret generic --namespace cleanair cleanair-log-storage-connection-string --from-literal=CLEANAIR_LOG_STORAGE_CONNECTION_STRING='$(CLEANAIR-LOG-STORAGE-CONNECTION-STRING)' - fi - if [ "$(kubectl get secret --namespace cleanair 2> /dev/null | grep cleanair-log-storage-key)" == "" ]; then - kubectl create secret generic --namespace cleanair cleanair-log-storage-key --from-literal=CLEANAIR_LOG_STORAGE_KEY='$(CLEANAIR-LOG-STORAGE-KEY)' - fi - if [ "$(kubectl get secret --namespace cleanair 2> /dev/null | grep cleanair-experiment-archive-key)" == "" ]; then - kubectl create secret generic --namespace cleanair cleanair-experiment-archive-key --from-literal=CLEANAIR_EXPERIMENT_ARCHIVE_KEY='$(CLEANAIR-EXPERIMENT-ARCHIVE-KEY)' - fi - displayName: 'Add secrets to Kubernetes' - # Prepare Helm chart - - script: | - echo "Setting image tag to $(Build.SourceVersion)" - sed -i 's/^imageTag:.*$/imageTag: $(Build.SourceVersion)/' kubernetes/cleanair/values_prod.yaml - displayName: 'Prepare Helm chart' - # Install certmanager custom resource definition - - script: | - kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/v0.13.1/deploy/manifests/00-crds.yaml --namespace cleanair - helm dependency update kubernetes/cleanair - displayName: 'Install cert manager components' - # Install/upgrade Helm chart - - task: HelmDeploy@0 - displayName: 'Install/upgrade Helm chart' - inputs: - connectionType: Azure Resource Manager - azureSubscriptionEndpoint: 'urbanair-scn' - azureResourceGroup: $(KUBERNETES_CLUSTER_RESOURCE_GROUP) - kubernetesCluster: $(KUBERNETES_CLUSTER_NAME) - namespace: $(NAMESPACE) - command: upgrade - arguments: --cleanup-on-fail --set nginx-ingress.controller.service.externalTrafficPolicy=Local --timeout 1800s - chartType: filepath - chartPath: kubernetes/cleanair - releaseName: cleanair - valueFile: kubernetes/cleanair/values_prod.yaml - updatedependency: true - install: true + - stage: Kubernetes + displayName: Update Helm chart on Azure Kubernetes cluster + jobs: + - job: UpdateAzureKubernetesHelmChart + displayName: Install Kubectl and install/upgrade helm + pool: + vmImage: "ubuntu-latest" + steps: + # Connect to Azure + - task: AzureCLI@1 + displayName: "Connect to Azure" + inputs: + azureSubscription: "urbanair-scn" + scriptLocation: "inlineScript" + inlineScript: | + az aks get-credentials -n $(KUBERNETES_CLUSTER_NAME) -g $(KUBERNETES_CLUSTER_RESOURCE_GROUP) + KUBERNETES_VERSION=$(az aks show -n $(KUBERNETES_CLUSTER_NAME) -g $(KUBERNETES_CLUSTER_RESOURCE_GROUP) --query "kubernetesVersion" -o tsv) + echo "##vso[task.setvariable variable=kubernetes_version]$KUBERNETES_VERSION" + # Read Azure key vault + - task: AzureKeyVault@1 + displayName: "Read KeyVault secrets" + inputs: + azureSubscription: "urbanair-scn" + KeyVaultName: "cleanair-secrets" + SecretsFilter: "scoot-aws-key,scoot-aws-key-id,satellite-copernicus-key,cleanair-inputs-db-name,cleanair-inputs-2021-db-cluster-password,cleanair-inputs-2021-db-cluster-username,cleanair-inputs-2021-db-server-name, container-registry-admin-password,container-registry-admin-username,container-registry-login-server,sentry-dsn,tomtom-api-key,cleanair-log-storage-key,cleanair-log-storage-connection-string,cleanair-experiment-archive-key,http-basic-prime-cache" + # Install matching Kubectl version + - task: KubectlInstaller@0 + displayName: "Install matching Kubectl version" + inputs: + kubectlVersion: $(KUBERNETES_VERSION) + # Install latest Helm version + - task: HelmInstaller@1 + displayName: "Install latest Helm version" + inputs: + helmVersionToInstall: 3.1.2 + # List installed versions + - script: | + echo "Kubernetes version on the cluster is ${KUBERNETES_VERSION}" + echo "Kubectl details:" + kubectl version + echo "Helm details:" + echo "Helm $(NAMESPACE) namespace:" + helm list --namespace $(NAMESPACE) + displayName: "List installed versions" + # Add secrets to Kubernetes + - script: | + # Check whether we need to create a new namespace + if [ "$(kubectl get namespace $(NAMESPACE) 2> /dev/null | grep $(NAMESPACE))" == "" ]; then + kubectl create namespace $(NAMESPACE) + fi + echo "Adding secrets to Kubernetes" + if [ "$(kubectl get secret regcred --namespace cleanair 2> /dev/null | grep regcred)" == "" ]; then + kubectl create secret docker-registry --namespace cleanair regcred --docker-server=$(CONTAINER-REGISTRY-LOGIN-SERVER) --docker-username=$(CONTAINER-REGISTRY-ADMIN-USERNAME) --docker-password=$(CONTAINER-REGISTRY-ADMIN-PASSWORD) + fi + if [ "$(kubectl get secret secrets --namespace cleanair 2> /dev/null | grep secrets)" == "" ]; then + echo '{ + "aws_key_id": "$(SCOOT-AWS-KEY-ID)", + "aws_key": "$(SCOOT-AWS-KEY)" + }' > aws_secrets.json + echo '{ + "username": "$(CLEANAIR-INPUTS-2021-DB-CLUSTER-USERNAME)@$(CLEANAIR-INPUTS-2021-DB-SERVER-NAME)", + "password": "$(CLEANAIR-INPUTS-2021-DB-CLUSTER-PASSWORD)", + "host": "$(CLEANAIR-INPUTS-2021-DB-SERVER-NAME).postgres.database.azure.com", + "port": 5432, + "db_name": "$(CLEANAIR-INPUTS-DB-NAME)", + "ssl_mode": "require" + }' > db_secrets.json + echo '{ + "copernicus_key": "$(SATELLITE-COPERNICUS-KEY)" + }' > copernicus_secrets.json + echo "${HTTP-BASIC-PRIME-CACHE}" > http_priming_secret + kubectl create secret generic --namespace cleanair secrets --from-file=aws_secrets.json --from-file=db_secrets.json --from-file=copernicus_secrets.json --from-file=http_priming_secret + kubectl create secret generic --namespace cleanair sentry --from-literal=SENTRY_DSN='$(SENTRY-DSN)' + rm -f aws_secrets.json db_secrets.json copernicus_secrets.json http_priming_secret + # kubectl create secret generic --namespace cleanair secrets --from-literal=host='$(CLEANAIR-INPUTS-2021-DB-SERVER-NAME).postgres.database.azure.com' --from-literal=port=5432 --from-literal=db_name='$(CLEANAIR-INPUTS-DB-NAME)' --from-literal=username='$(CLEANAIR-INPUTS-2021-DB-CLUSTER-USERNAME)@$(CLEANAIR-INPUTS-2021-DB-SERVER-NAME)' --from-literal=password='$(CLEANAIR-INPUTS-2021-DB-CLUSTER-PASSWORD)' --from-literal=ssl_mode='require' --from-literal=aws_key_id='$(SCOOT-AWS-KEY-ID)' --from-literal=aws_key='$(SCOOT-AWS-KEY)' + fi + if [ "$(kubectl get secret --namespace cleanair 2> /dev/null | grep tomtom-api-key)" == "" ]; then + kubectl create secret generic --namespace cleanair tomtom-api-key --from-literal=TOMTOM_API_KEY='$(TOMTOM-API-KEY)' + fi + if [ "$(kubectl get secret --namespace cleanair 2> /dev/null | grep cleanair-log-storage-connection-string)" == "" ]; then + kubectl create secret generic --namespace cleanair cleanair-log-storage-connection-string --from-literal=CLEANAIR_LOG_STORAGE_CONNECTION_STRING='$(CLEANAIR-LOG-STORAGE-CONNECTION-STRING)' + fi + if [ "$(kubectl get secret --namespace cleanair 2> /dev/null | grep cleanair-log-storage-key)" == "" ]; then + kubectl create secret generic --namespace cleanair cleanair-log-storage-key --from-literal=CLEANAIR_LOG_STORAGE_KEY='$(CLEANAIR-LOG-STORAGE-KEY)' + fi + if [ "$(kubectl get secret --namespace cleanair 2> /dev/null | grep cleanair-experiment-archive-key)" == "" ]; then + kubectl create secret generic --namespace cleanair cleanair-experiment-archive-key --from-literal=CLEANAIR_EXPERIMENT_ARCHIVE_KEY='$(CLEANAIR-EXPERIMENT-ARCHIVE-KEY)' + fi + displayName: "Add secrets to Kubernetes" + # Prepare Helm chart + - script: | + echo "Setting image tag to $(Build.SourceVersion)" + sed -i 's/^imageTag:.*$/imageTag: $(Build.SourceVersion)/' kubernetes/cleanair/values_prod.yaml + displayName: "Prepare Helm chart" + # Install certmanager custom resource definition + - script: | + kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/v0.13.1/deploy/manifests/00-crds.yaml --namespace cleanair + helm dependency update kubernetes/cleanair + displayName: "Install cert manager components" + # Install/upgrade Helm chart + - task: HelmDeploy@0 + displayName: "Install/upgrade Helm chart" + inputs: + connectionType: Azure Resource Manager + azureSubscriptionEndpoint: "urbanair-scn" + azureResourceGroup: $(KUBERNETES_CLUSTER_RESOURCE_GROUP) + kubernetesCluster: $(KUBERNETES_CLUSTER_NAME) + namespace: $(NAMESPACE) + command: upgrade + arguments: --cleanup-on-fail --set nginx-ingress.controller.service.externalTrafficPolicy=Local --timeout 1800s + chartType: filepath + chartPath: kubernetes/cleanair + releaseName: cleanair + valueFile: kubernetes/cleanair/values_prod.yaml + updatedependency: true + install: true