├── blue-green-pipeline ├── util │ ├── color │ ├── delete.sh │ └── test.sh ├── pipelines │ └── run-products │ │ ├── 2-pipelinerun-products-switch.yaml │ │ ├── 2-pipelinerun-products-switch-rollback.yaml │ │ ├── 3-pipelinerun-products-scale-down.yaml │ │ └── 1-pipelinerun-products-new-version.yaml ├── application-shop-blue-green.yaml └── application-cluster-config.yaml ├── images ├── Shop.png ├── ArgoCD-UI.png ├── Shop-helm.png ├── blue-green.png ├── ArgoCD-login.png ├── applications.png ├── gitops-link.png ├── ArgoCD-webhook.png ├── Shop-blue-green.png ├── pipeline-step-1.png ├── pipeline-step-3.png ├── pipeline-step-4.png ├── Shop-helm-rollouts.png ├── blue-green-step-0.png ├── blue-green-step-1.png ├── blue-green-step-2.png ├── blue-green-step-3.png ├── blue-green-switch.png ├── canary-mesh-step-0.png ├── canary-mesh-step-1.png ├── canary-mesh-step-2.png ├── canary-mesh-step-3.png ├── ArgoCD-Applications.png ├── ArgoCD-Shop-Refresh.png ├── blue-green-step-2-5.png ├── canary-mesh-initial.png ├── Deployment strategies.vsdx ├── canary-knative-initial.png ├── canary-knative-step-0.png ├── canary-knative-step-1.png ├── canary-knative-step-2.png ├── canary-knative-step-3.png ├── canary-rollout-initial.png ├── canary-rollout-step-0.png ├── canary-rollout-step-1.png ├── canary-rollout-step-2.png ├── canary-rollout-step-3.png ├── Shop-blue-green-rollouts.png ├── Shop-helm-canary-rollouts.png ├── canary-knative-initial-2.png ├── pipeline-step-3-rollback.png ├── rollout-blue-green-step-0.png ├── rollout-blue-green-step-1.png ├── rollout-blue-green-step-2.png ├── canary-knative-step-rollback.png ├── canary-rollout-mesh-initial.png ├── canary-rollout-mesh-step-0.png ├── canary-rollout-mesh-step-1.png ├── canary-rollout-mesh-step-2.png ├── canary-rollout-mesh-step-3.png ├── canary-rollout-step-Rollback.png ├── application-cluster-config-sync.png ├── canary-rollout-mesh-step-rollback.png ├── rollout-blue-green-step-2-initial.png ├── rollout-blue-green-step-rollback.png ├── application-cluster-config-outofsync.png └── rollout-blue-green-step-rollback-initial.png ├── helm ├── quarkus-helm-networking │ └── chart │ │ ├── values.yaml │ │ ├── quarkus-base-networking-0.1.0.tgz │ │ ├── .helmignore │ │ ├── templates │ │ ├── prometheus-app-monitor.yaml │ │ ├── router.yaml │ │ ├── service.yaml │ │ └── _helpers.tpl │ │ └── Chart.yaml ├── quarkus-helm-base │ └── chart │ │ ├── quarkus-base-0.1.0.tgz │ │ ├── Chart.yaml │ │ ├── .helmignore │ │ ├── templates │ │ ├── configmap-env-base.yaml │ │ ├── analysis-template.yaml │ │ ├── _helpers.tpl │ │ └── deployment.yaml │ │ └── values.yaml ├── quarkus-helm-products │ └── chart │ │ ├── values.yaml │ │ ├── charts │ │ └── quarkus-base-0.1.0.tgz │ │ ├── quarkus-helm-products-0.1.0.tgz │ │ ├── Chart.yaml │ │ ├── .helmignore │ │ └── templates │ │ ├── configmap-env.yaml │ │ └── _helpers.tpl ├── quarkus-helm-discounts │ └── chart │ │ ├── values.yaml │ │ ├── charts │ │ └── quarkus-base-0.1.0.tgz │ │ ├── quarkus-helm-discounts-0.1.0.tgz │ │ ├── Chart.yaml │ │ ├── templates │ │ ├── configmap-env.yaml │ │ └── _helpers.tpl │ │ └── .helmignore └── quarkus-helm-umbrella │ └── chart │ ├── charts │ ├── quarkus-helm-products-0.1.0.tgz │ ├── quarkus-base-networking-0.1.0.tgz │ └── quarkus-helm-discounts-0.1.0.tgz │ ├── README.md │ ├── .helmignore │ ├── values │ ├── values.yaml │ ├── values-mesh.yaml │ ├── values-rollouts-blue-green.yaml │ ├── values-canary-rollouts.yaml │ └── values-canary-rollouts-mesh.yaml │ ├── Chart.yaml │ ├── templates │ ├── _helpers.tpl │ └── istio.yaml │ └── values.yaml ├── gitops ├── cluster-config │ ├── templates │ │ ├── namespace.yaml │ │ ├── service-mesh │ │ │ ├── distributed-tracing-namespace.yaml │ │ │ ├── istio-system-namespace.yaml │ │ │ ├── distributed-tracing-group.yaml │ │ │ ├── service-mesh-member-roll.yaml │ │ │ ├── kiali-subscription.yaml │ │ │ ├── isto-prom-rbac.yaml │ │ │ ├── jaeger-subscription.yaml │ │ │ ├── service-mesh-subscription.yaml │ │ │ ├── elasticsearch-subscription.yaml │ │ │ ├── role-binding.yaml │ │ │ ├── service-monitor.yaml │ │ │ └── service-mesh-control-plane.yaml │ │ ├── argo-rollouts │ │ │ ├── namespace.yaml │ │ │ ├── rollout-manager.yaml │ │ │ └── role-binding.yaml │ │ ├── pipelines │ │ │ ├── tekton-cluster-rol.yaml │ │ │ ├── applications │ │ │ │ ├── secret-quay-token.yaml │ │ │ │ ├── application-applicatins-ci.yaml │ │ │ │ ├── job-link-githu-token.yaml │ │ │ │ └── tekton-task-kaniko.yaml │ │ │ ├── secret-github-token.yaml │ │ │ ├── pipelines-operator.yaml │ │ │ ├── tekton-task-shop-e2e-test.yaml │ │ │ ├── role-binding.yaml │ │ │ ├── tekton-task-openshift-client.yaml │ │ │ ├── pipeline-e2e-tests.yaml │ │ │ ├── tekton-task-git-pr.yaml │ │ │ └── tekton-task-git-cli.yaml │ │ ├── role-binding.yaml │ │ ├── cluster-monitoring.yaml │ │ ├── _helpers.tpl │ │ └── openshift-gitops-argocd.yaml │ ├── values.yaml │ ├── .helmignore │ └── Chart.yaml └── gitops-operator.yaml ├── tests ├── deleteAll.sh └── testAll.sh ├── .gitignore ├── canary-argo-rollouts ├── application-shop-canary-rollouts.yaml ├── application-cluster-config.yaml └── util │ ├── delete.sh │ └── test.sh ├── blue-green-argo-rollouts ├── application-shop-blue-green-rollouts.yaml ├── application-cluster-config.yaml └── util │ ├── delete.sh │ └── test.sh ├── canary-service-mesh ├── application-shop-mesh.yaml ├── application-cluster-config.yaml ├── util │ ├── delete.sh │ └── test.sh └── README.md ├── canary-argo-rollouts-service-mesh ├── application-shop-canary-rollouts-mesh.yaml ├── application-cluster-config.yaml ├── util │ ├── testdemo.sh │ ├── delete.sh │ └── test.sh └── README.md └── README.md /blue-green-pipeline/util/color: -------------------------------------------------------------------------------- 1 | green -------------------------------------------------------------------------------- /images/Shop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/Shop.png -------------------------------------------------------------------------------- /images/ArgoCD-UI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/ArgoCD-UI.png -------------------------------------------------------------------------------- /images/Shop-helm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/Shop-helm.png -------------------------------------------------------------------------------- /images/blue-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/blue-green.png -------------------------------------------------------------------------------- /images/ArgoCD-login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/ArgoCD-login.png -------------------------------------------------------------------------------- /images/applications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/applications.png -------------------------------------------------------------------------------- /images/gitops-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/gitops-link.png -------------------------------------------------------------------------------- /images/ArgoCD-webhook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/ArgoCD-webhook.png -------------------------------------------------------------------------------- /images/Shop-blue-green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/Shop-blue-green.png -------------------------------------------------------------------------------- /images/pipeline-step-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/pipeline-step-1.png -------------------------------------------------------------------------------- /images/pipeline-step-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/pipeline-step-3.png -------------------------------------------------------------------------------- /images/pipeline-step-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/pipeline-step-4.png -------------------------------------------------------------------------------- /helm/quarkus-helm-networking/chart/values.yaml: -------------------------------------------------------------------------------- 1 | service: 2 | type: ClusterIP 3 | port: 8080 4 | 5 | router: 6 | enabled: true 7 | -------------------------------------------------------------------------------- /images/Shop-helm-rollouts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/Shop-helm-rollouts.png -------------------------------------------------------------------------------- /images/blue-green-step-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/blue-green-step-0.png -------------------------------------------------------------------------------- /images/blue-green-step-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/blue-green-step-1.png -------------------------------------------------------------------------------- /images/blue-green-step-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/blue-green-step-2.png -------------------------------------------------------------------------------- /images/blue-green-step-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/blue-green-step-3.png -------------------------------------------------------------------------------- /images/blue-green-switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/blue-green-switch.png -------------------------------------------------------------------------------- /images/canary-mesh-step-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-mesh-step-0.png -------------------------------------------------------------------------------- /images/canary-mesh-step-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-mesh-step-1.png -------------------------------------------------------------------------------- /images/canary-mesh-step-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-mesh-step-2.png -------------------------------------------------------------------------------- /images/canary-mesh-step-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-mesh-step-3.png -------------------------------------------------------------------------------- /images/ArgoCD-Applications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/ArgoCD-Applications.png -------------------------------------------------------------------------------- /images/ArgoCD-Shop-Refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/ArgoCD-Shop-Refresh.png -------------------------------------------------------------------------------- /images/blue-green-step-2-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/blue-green-step-2-5.png -------------------------------------------------------------------------------- /images/canary-mesh-initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-mesh-initial.png -------------------------------------------------------------------------------- /images/Deployment strategies.vsdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/Deployment strategies.vsdx -------------------------------------------------------------------------------- /images/canary-knative-initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-knative-initial.png -------------------------------------------------------------------------------- /images/canary-knative-step-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-knative-step-0.png -------------------------------------------------------------------------------- /images/canary-knative-step-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-knative-step-1.png -------------------------------------------------------------------------------- /images/canary-knative-step-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-knative-step-2.png -------------------------------------------------------------------------------- /images/canary-knative-step-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-knative-step-3.png -------------------------------------------------------------------------------- /images/canary-rollout-initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-initial.png -------------------------------------------------------------------------------- /images/canary-rollout-step-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-step-0.png -------------------------------------------------------------------------------- /images/canary-rollout-step-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-step-1.png -------------------------------------------------------------------------------- /images/canary-rollout-step-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-step-2.png -------------------------------------------------------------------------------- /images/canary-rollout-step-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-step-3.png -------------------------------------------------------------------------------- /images/Shop-blue-green-rollouts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/Shop-blue-green-rollouts.png -------------------------------------------------------------------------------- /images/Shop-helm-canary-rollouts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/Shop-helm-canary-rollouts.png -------------------------------------------------------------------------------- /images/canary-knative-initial-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-knative-initial-2.png -------------------------------------------------------------------------------- /images/pipeline-step-3-rollback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/pipeline-step-3-rollback.png -------------------------------------------------------------------------------- /images/rollout-blue-green-step-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/rollout-blue-green-step-0.png -------------------------------------------------------------------------------- /images/rollout-blue-green-step-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/rollout-blue-green-step-1.png -------------------------------------------------------------------------------- /images/rollout-blue-green-step-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/rollout-blue-green-step-2.png -------------------------------------------------------------------------------- /images/canary-knative-step-rollback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-knative-step-rollback.png -------------------------------------------------------------------------------- /images/canary-rollout-mesh-initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-mesh-initial.png -------------------------------------------------------------------------------- /images/canary-rollout-mesh-step-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-mesh-step-0.png -------------------------------------------------------------------------------- /images/canary-rollout-mesh-step-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-mesh-step-1.png -------------------------------------------------------------------------------- /images/canary-rollout-mesh-step-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-mesh-step-2.png -------------------------------------------------------------------------------- /images/canary-rollout-mesh-step-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-mesh-step-3.png -------------------------------------------------------------------------------- /images/canary-rollout-step-Rollback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-step-Rollback.png -------------------------------------------------------------------------------- /images/application-cluster-config-sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/application-cluster-config-sync.png -------------------------------------------------------------------------------- /images/canary-rollout-mesh-step-rollback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/canary-rollout-mesh-step-rollback.png -------------------------------------------------------------------------------- /images/rollout-blue-green-step-2-initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/rollout-blue-green-step-2-initial.png -------------------------------------------------------------------------------- /images/rollout-blue-green-step-rollback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/rollout-blue-green-step-rollback.png -------------------------------------------------------------------------------- /images/application-cluster-config-outofsync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/application-cluster-config-outofsync.png -------------------------------------------------------------------------------- /helm/quarkus-helm-base/chart/quarkus-base-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/helm/quarkus-helm-base/chart/quarkus-base-0.1.0.tgz -------------------------------------------------------------------------------- /images/rollout-blue-green-step-rollback-initial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/images/rollout-blue-green-step-rollback-initial.png -------------------------------------------------------------------------------- /helm/quarkus-helm-base/chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: quarkus-base 3 | description: A Helm chart for Quarkus 4 | type: application 5 | version: 0.1.0 6 | appVersion: "1.0.0" 7 | -------------------------------------------------------------------------------- /helm/quarkus-helm-products/chart/values.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: products 2 | 3 | mode: none 4 | 5 | quarkus-base: 6 | nameOverride: products 7 | image: 8 | repository: quay.io/dseveria/products -------------------------------------------------------------------------------- /helm/quarkus-helm-discounts/chart/values.yaml: -------------------------------------------------------------------------------- 1 | nameOverride: discounts 2 | 3 | mode: none 4 | 5 | quarkus-base: 6 | nameOverride: discounts 7 | image: 8 | repository: quay.io/dseveria/discounts -------------------------------------------------------------------------------- /helm/quarkus-helm-discounts/chart/charts/quarkus-base-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/helm/quarkus-helm-discounts/chart/charts/quarkus-base-0.1.0.tgz -------------------------------------------------------------------------------- /helm/quarkus-helm-products/chart/charts/quarkus-base-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/helm/quarkus-helm-products/chart/charts/quarkus-base-0.1.0.tgz -------------------------------------------------------------------------------- /helm/quarkus-helm-products/chart/quarkus-helm-products-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/helm/quarkus-helm-products/chart/quarkus-helm-products-0.1.0.tgz -------------------------------------------------------------------------------- /helm/quarkus-helm-discounts/chart/quarkus-helm-discounts-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/helm/quarkus-helm-discounts/chart/quarkus-helm-discounts-0.1.0.tgz -------------------------------------------------------------------------------- /helm/quarkus-helm-networking/chart/quarkus-base-networking-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/helm/quarkus-helm-networking/chart/quarkus-base-networking-0.1.0.tgz -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/charts/quarkus-helm-products-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/helm/quarkus-helm-umbrella/chart/charts/quarkus-helm-products-0.1.0.tgz -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/charts/quarkus-base-networking-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/helm/quarkus-helm-umbrella/chart/charts/quarkus-base-networking-0.1.0.tgz -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/charts/quarkus-helm-discounts-0.1.0.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidseve/cloud-native-deployment-strategies/HEAD/helm/quarkus-helm-umbrella/chart/charts/quarkus-helm-discounts-0.1.0.tgz -------------------------------------------------------------------------------- /gitops/cluster-config/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: {{ .Values.namespace }} 5 | labels: 6 | argocd.argoproj.io/managed-by: openshift-gitops 7 | spec: 8 | finalizers: 9 | - kubernetes -------------------------------------------------------------------------------- /helm/quarkus-helm-discounts/chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: quarkus-helm-discounts 3 | description: A Helm chart for Quarkus 4 | type: application 5 | version: 0.1.0 6 | appVersion: "1.0.0" 7 | 8 | dependencies: 9 | - name: quarkus-base 10 | version: 0.1.0 11 | -------------------------------------------------------------------------------- /helm/quarkus-helm-products/chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: quarkus-helm-products 3 | description: A Helm chart for Quarkus 4 | type: application 5 | version: 0.1.0 6 | appVersion: "1.0.0" 7 | 8 | dependencies: 9 | - name: quarkus-base 10 | version: 0.1.0 11 | -------------------------------------------------------------------------------- /helm/quarkus-helm-discounts/chart/templates/configmap-env.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: "{{ include "discounts.fullname" $ }}-configmap-env" 5 | labels: 6 | {{- include "discounts.labels" $ | nindent 4 }} 7 | data: 8 | application.mode: {{ .Values.mode }} 9 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/distributed-tracing-namespace.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "-1" 7 | name: openshift-distributed-tracing 8 | spec: {} 9 | {{ end }} 10 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/argo-rollouts/namespace.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.argoRollouts.enabled }} 2 | --- 3 | apiVersion: v1 4 | kind: Namespace 5 | metadata: 6 | name: argo-rollouts 7 | labels: 8 | argocd.argoproj.io/managed-by: openshift-gitops 9 | spec: 10 | finalizers: 11 | - kubernetes 12 | {{ end }} -------------------------------------------------------------------------------- /gitops/cluster-config/templates/argo-rollouts/rollout-manager.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.argoRollouts.enabled }} 2 | --- 3 | apiVersion: argoproj.io/v1alpha1 4 | kind: RolloutManager 5 | metadata: 6 | name: argo-rollout 7 | namespace: argo-rollouts 8 | spec: 9 | extraCommandArgs: 10 | - '--namespaced=false' 11 | {{ end }} 12 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/tekton-cluster-rol.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.enabled }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: tekton-admin-view 6 | rules: 7 | - apiGroups: ["triggers.tekton.dev"] 8 | resources: ["clusterinterceptors"] 9 | verbs: ["get", "watch", "list"] 10 | --- 11 | {{ end }} -------------------------------------------------------------------------------- /gitops/gitops-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operators.coreos.com/v1alpha1 2 | kind: Subscription 3 | metadata: 4 | name: openshift-gitops-operator 5 | namespace: openshift-operators 6 | spec: 7 | channel: gitops-1.13 8 | installPlanApproval: Automatic 9 | name: openshift-gitops-operator 10 | source: redhat-operators 11 | sourceNamespace: openshift-marketplace -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/istio-system-namespace.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "0" 7 | name: istio-system 8 | labels: 9 | argocd.argoproj.io/managed-by: openshift-gitops 10 | spec: 11 | finalizers: 12 | - kubernetes 13 | {{ end }} -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/distributed-tracing-group.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: operators.coreos.com/v1 3 | kind: OperatorGroup 4 | metadata: 5 | generateName: openshift-distributed-tracing- 6 | name: openshift-distributed-tracing 7 | namespace: openshift-distributed-tracing 8 | annotations: 9 | argocd.argoproj.io/sync-wave: "5" 10 | {{ end }} 11 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/role-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: gitops-cluster-role-binding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: cluster-admin 9 | subjects: 10 | - kind: ServiceAccount 11 | name: openshift-gitops-argocd-application-controller 12 | namespace: openshift-gitops -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/service-mesh-member-roll.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: maistra.io/v1 3 | kind: ServiceMeshMemberRoll 4 | metadata: 5 | name: default 6 | namespace: istio-system 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/sync-wave: "21" 10 | spec: 11 | members: 12 | - {{ .Values.namespace }} 13 | {{ end }} -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/applications/secret-quay-token.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.applications.enabled }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: docker-config 6 | namespace: {{ .Values.namespace }} 7 | annotations: 8 | tekton.dev/docker-0: 'https://quay.io/dseveria' 9 | data: 10 | .dockerconfigjson: {{ .Values.pipeline.applications.dockerconfigjson }} 11 | type: kubernetes.io/dockerconfigjson 12 | {{ end }} -------------------------------------------------------------------------------- /gitops/cluster-config/templates/argo-rollouts/role-binding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.argoRollouts.enabled }} 2 | --- 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | kind: ClusterRoleBinding 5 | metadata: 6 | name: argo-rollouts-cluster-role-binding 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: cluster-admin 11 | subjects: 12 | - kind: ServiceAccount 13 | name: argo-rollouts 14 | namespace: argo-rollouts 15 | {{ end }} -------------------------------------------------------------------------------- /gitops/cluster-config/values.yaml: -------------------------------------------------------------------------------- 1 | namespace: gitops 2 | istio: 3 | enabled: false 4 | pipeline: 5 | enabled: true 6 | applications: 7 | enabled: false 8 | dockerconfigjson: changeme 9 | bluegreen: 10 | enabled: false 11 | valuesyaml: values/values.yaml 12 | github: 13 | enabled: true 14 | token: changeme 15 | user: changeme 16 | mail: changeme 17 | repository: changeme 18 | monitoring: 19 | enabled: true 20 | argoRollouts: 21 | enabled: false 22 | -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/README.md: -------------------------------------------------------------------------------- 1 | # Shop Umbrella Helm Chart for Blue/Green deployment 2 | 3 | ## Chart Details 4 | This chart will do the following: 5 | 6 | * Deploy two quarkus microservices Product and Discounts for Blue/Green deployment 7 | 8 | ## Installing the Chart 9 | 10 | To install the chart with the release name `my-release`: 11 | 12 | ```bash 13 | $ helm upgrade --install my-release . --values values/values.yaml 14 | ``` 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /blue-green-pipeline/pipelines/run-products/2-pipelinerun-products-switch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: shop-products-switch- 5 | spec: 6 | pipelineRef: 7 | name: pipeline-blue-green 8 | params: 9 | - name: APP 10 | value: products 11 | - name: STEP 12 | value: "switch" 13 | workspaces: 14 | - name: app-source 15 | persistentVolumeClaim: 16 | claimName: workspace-pvc-shop-cd-new-version -------------------------------------------------------------------------------- /gitops/cluster-config/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/secret-github-token.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.github.enabled }} 2 | kind: Secret 3 | apiVersion: v1 4 | metadata: 5 | name: github-token 6 | namespace: {{ .Values.namespace }} 7 | annotations: 8 | tekton.dev/git-0: 'https://github.com/{{ .Values.github.user }}' 9 | data: 10 | password: {{ .Values.github.token | b64enc | quote }} 11 | username: {{ .Values.github.user | b64enc | quote }} 12 | type: kubernetes.io/basic-auth 13 | {{ end }} -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/kiali-subscription.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: operators.coreos.com/v1alpha1 3 | kind: Subscription 4 | metadata: 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "12" 7 | name: kiali-ossm 8 | namespace: openshift-operators 9 | spec: 10 | channel: stable 11 | installPlanApproval: Automatic 12 | name: kiali-ossm 13 | source: redhat-operators 14 | sourceNamespace: openshift-marketplace 15 | {{ end }} -------------------------------------------------------------------------------- /helm/quarkus-helm-base/chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/quarkus-helm-discounts/chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/quarkus-helm-networking/chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/quarkus-helm-products/chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /blue-green-pipeline/pipelines/run-products/2-pipelinerun-products-switch-rollback.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: shop-products-rollback- 5 | spec: 6 | pipelineRef: 7 | name: pipeline-blue-green 8 | params: 9 | - name: APP 10 | value: products 11 | - name: STEP 12 | value: "switch-rollback" 13 | workspaces: 14 | - name: app-source 15 | persistentVolumeClaim: 16 | claimName: workspace-pvc-shop-cd-new-version -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/isto-prom-rbac.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "1" 7 | name: view 8 | namespace: istio-system 9 | roleRef: 10 | apiGroup: rbac.authorization.k8s.io 11 | kind: ClusterRole 12 | name: view 13 | subjects: 14 | - kind: ServiceAccount 15 | name: prometheus-k8s 16 | namespace: openshift-monitoring 17 | {{ end }} 18 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/jaeger-subscription.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: operators.coreos.com/v1alpha1 3 | kind: Subscription 4 | metadata: 5 | name: jaeger-product 6 | namespace: openshift-distributed-tracing 7 | annotations: 8 | argocd.argoproj.io/sync-wave: "10" 9 | spec: 10 | channel: stable 11 | installPlanApproval: Automatic 12 | name: jaeger-product 13 | source: redhat-operators 14 | sourceNamespace: openshift-marketplace 15 | {{ end }} -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/service-mesh-subscription.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: operators.coreos.com/v1alpha1 3 | kind: Subscription 4 | metadata: 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "13" 7 | name: servicemeshoperator 8 | namespace: openshift-operators 9 | spec: 10 | channel: stable 11 | installPlanApproval: Automatic 12 | name: servicemeshoperator 13 | source: redhat-operators 14 | sourceNamespace: openshift-marketplace 15 | {{ end }} -------------------------------------------------------------------------------- /helm/quarkus-helm-networking/chart/templates/prometheus-app-monitor.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: monitoring.coreos.com/v1 2 | kind: ServiceMonitor 3 | metadata: 4 | labels: 5 | {{- include "networking.labels" . | nindent 4 }} 6 | name: "{{ include "networking.fullname" . }}-prometheus-monitor" 7 | spec: 8 | endpoints: 9 | - interval: 30s 10 | targetPort: 8080 11 | path: /q/metrics 12 | scheme: http 13 | selector: 14 | matchLabels: 15 | {{- include "networking.labels" . | nindent 6 }} 16 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/elasticsearch-subscription.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: operators.coreos.com/v1alpha1 3 | kind: Subscription 4 | metadata: 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "10" 7 | name: elasticsearch-operator 8 | namespace: openshift-operators 9 | spec: 10 | channel: stable-5.8 11 | name: elasticsearch-operator 12 | source: redhat-operators 13 | sourceNamespace: openshift-marketplace 14 | installPlanApproval: Automatic 15 | {{ end }} -------------------------------------------------------------------------------- /helm/quarkus-helm-networking/chart/templates/router.yaml: -------------------------------------------------------------------------------- 1 | {{ if .Values.router.enabled }} 2 | apiVersion: route.openshift.io/v1 3 | kind: Route 4 | metadata: 5 | labels: 6 | {{- include "networking.labels" . | nindent 4 }} 7 | name: {{ include "networking.fullname" . }} 8 | spec: 9 | port: 10 | targetPort: {{ .Values.service.port }} 11 | to: 12 | kind: Service 13 | name: {{ include "networking.fullname" . }} 14 | tls: 15 | termination: edge 16 | insecureEdgeTerminationPolicy: Redirect 17 | {{ end }} -------------------------------------------------------------------------------- /tests/deleteAll.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo ¡¡blue-green-pipeline!! 4 | cd ../blue-green-pipeline/util 5 | ./delete.sh 6 | 7 | echo ¡¡blue-green-argo-rollouts!! 8 | cd ../../blue-green-argo-rollouts/util 9 | ./delete.sh 10 | 11 | echo ¡¡canary-argo-rollouts!! 12 | cd ../../canary-argo-rollouts/util 13 | ./delete.sh 14 | 15 | echo ¡¡canary-service-mesh!! 16 | cd ../../canary-service-mesh/util 17 | ./delete.sh 18 | 19 | echo ¡¡canary-argo-rollouts-service-mesh!! 20 | cd ../../canary-argo-rollouts-service-mesh/util 21 | ./delete.sh 22 | -------------------------------------------------------------------------------- /blue-green-pipeline/pipelines/run-products/3-pipelinerun-products-scale-down.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: shop-products-scale-down-offline- 5 | spec: 6 | pipelineRef: 7 | name: pipeline-blue-green 8 | params: 9 | - name: APP 10 | value: products 11 | - name: NEW_IMAGE_TAG 12 | value: "v1.1.1" 13 | - name: STEP 14 | value: "scale-down-offline" 15 | workspaces: 16 | - name: app-source 17 | persistentVolumeClaim: 18 | claimName: workspace-pvc-shop-cd-new-version -------------------------------------------------------------------------------- /helm/quarkus-helm-networking/chart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "networking.fullname" . }} 5 | labels: 6 | {{- include "networking.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: {{ .Values.service.port }} 12 | name: http 13 | selector: 14 | {{- include "networking.selectorLabels" . | nindent 4 }} 15 | {{- with .Values.version }} 16 | version: {{ . }} 17 | {{- end }} 18 | -------------------------------------------------------------------------------- /blue-green-pipeline/pipelines/run-products/1-pipelinerun-products-new-version.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: PipelineRun 3 | metadata: 4 | generateName: shop-products-new-version- 5 | spec: 6 | pipelineRef: 7 | name: pipeline-blue-green 8 | params: 9 | - name: APP 10 | value: products 11 | - name: NEW_IMAGE_TAG 12 | value: "v1.1.1" 13 | - name: STEP 14 | value: "new-version" 15 | - name: REPLICA_COUNT 16 | value: "2" 17 | workspaces: 18 | - name: app-source 19 | persistentVolumeClaim: 20 | claimName: workspace-pvc-shop-cd-new-version -------------------------------------------------------------------------------- /helm/quarkus-helm-products/chart/templates/configmap-env.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: "{{ include "products.fullname" $ }}-configmap-env" 5 | labels: 6 | {{- include "products.labels" $ | nindent 4 }} 7 | data: 8 | application.mode: {{ .Values.mode }} 9 | 10 | quarkus.rest-client.discounts-api.url: {{ printf "http://discounts-umbrella-%s:8080" .Values.mode }} 11 | quarkus.rest-client.discounts-api.scope: javax.inject.RequestScoped 12 | #quarkus.rest-client.discounts-api.connection-pool-size: "50" 13 | quarkus.rest-client.discounts-api.connection-ttl: "1" 14 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/pipelines-operator.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.enabled }} 2 | apiVersion: operators.coreos.com/v1alpha1 3 | kind: Subscription 4 | metadata: 5 | labels: 6 | operators.coreos.com/openshift-pipelines-operator-rh.openshift-operators: '' 7 | name: openshift-pipelines-operator-rh 8 | namespace: openshift-operators 9 | annotations: 10 | argocd.argoproj.io/sync-wave: "-10" 11 | spec: 12 | channel: pipelines-1.16 13 | installPlanApproval: Automatic 14 | name: openshift-pipelines-operator-rh 15 | source: redhat-operators 16 | sourceNamespace: openshift-marketplace 17 | {{ end }} -------------------------------------------------------------------------------- /blue-green-pipeline/application-shop-blue-green.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: shop 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | name: '' 9 | namespace: gitops 10 | server: 'https://kubernetes.default.svc' 11 | source: 12 | path: helm/quarkus-helm-umbrella/chart 13 | repoURL: https://github.com/change_me/cloud-native-deployment-strategies.git 14 | targetRevision: blue-green 15 | helm: 16 | valueFiles: 17 | - values/values.yaml 18 | project: default 19 | syncPolicy: 20 | automated: 21 | prune: true 22 | selfHeal: true -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/applications/application-applicatins-ci.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.applications.enabled }} 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: applications-ci 6 | namespace: openshift-gitops 7 | spec: 8 | destination: 9 | name: '' 10 | namespace: openshift-gitops 11 | server: 'https://kubernetes.default.svc' 12 | source: 13 | path: ci/pipeline 14 | repoURL: 'https://github.com/davidseve/poc-quarkus-applications.git' 15 | targetRevision: HEAD 16 | project: default 17 | syncPolicy: 18 | automated: 19 | prune: true 20 | selfHeal: true 21 | {{ end }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | quarkus-discounts/target/ 3 | quarkus-products/target/ 4 | pom.xml.tag 5 | pom.xml.releaseBackup 6 | pom.xml.versionsBackup 7 | pom.xml.next 8 | release.properties 9 | dependency-reduced-pom.xml 10 | buildNumber.properties 11 | .mvn/timing.properties 12 | 13 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) 14 | !/.mvn/wrapper/maven-wrapper.jar 15 | 16 | .gradle/ 17 | build/ 18 | .gradletasknamecache 19 | 20 | *.log 21 | graph-output.dot 22 | 23 | .settings 24 | .vscode 25 | .project 26 | .classpath 27 | *.iml 28 | .idea 29 | .factorypath 30 | 31 | settings.xml 32 | quarkus.log 33 | 34 | bin/ 35 | .DS_Store 36 | ObjectStore 37 | 38 | lsp/ 39 | 40 | *.swp 41 | *.swo 42 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/cluster-monitoring.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.monitoring.enabled }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: cluster-monitoring-config 6 | namespace: openshift-monitoring 7 | data: 8 | config.yaml: | 9 | enableUserWorkload: true 10 | --- 11 | apiVersion: rbac.authorization.k8s.io/v1 12 | kind: RoleBinding 13 | metadata: 14 | name: gitops-role-binding-monitoring-edit 15 | namespace: {{ .Values.namespace }} 16 | roleRef: 17 | apiGroup: rbac.authorization.k8s.io 18 | kind: ClusterRole 19 | name: monitoring-edit 20 | subjects: 21 | - kind: ServiceAccount 22 | name: openshift-gitops-argocd-application-controller 23 | namespace: openshift-gitops 24 | {{ end }} -------------------------------------------------------------------------------- /canary-argo-rollouts/application-shop-canary-rollouts.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: shop 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | name: '' 9 | namespace: gitops 10 | server: 'https://kubernetes.default.svc' 11 | source: 12 | path: helm/quarkus-helm-umbrella/chart 13 | repoURL: https://github.com/change_me/cloud-native-deployment-strategies.git 14 | targetRevision: canary 15 | helm: 16 | parameters: 17 | - name: "global.namespace" 18 | value: gitops 19 | valueFiles: 20 | - values/values-canary-rollouts.yaml 21 | project: default 22 | syncPolicy: 23 | automated: 24 | prune: true 25 | selfHeal: true -------------------------------------------------------------------------------- /blue-green-argo-rollouts/application-shop-blue-green-rollouts.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: shop 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | name: '' 9 | namespace: gitops 10 | server: 'https://kubernetes.default.svc' 11 | source: 12 | path: helm/quarkus-helm-umbrella/chart 13 | repoURL: https://github.com/change_me/cloud-native-deployment-strategies.git 14 | targetRevision: rollouts-blue-green 15 | helm: 16 | parameters: 17 | - name: "global.namespace" 18 | value: gitops 19 | valueFiles: 20 | - values/values-rollouts-blue-green.yaml 21 | project: default 22 | syncPolicy: 23 | automated: 24 | prune: true 25 | selfHeal: true -------------------------------------------------------------------------------- /canary-service-mesh/application-shop-mesh.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: shop 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | name: '' 9 | namespace: gitops 10 | server: 'https://kubernetes.default.svc' 11 | source: 12 | path: helm/quarkus-helm-umbrella/chart 13 | repoURL: https://github.com/change_me/cloud-native-deployment-strategies.git 14 | targetRevision: canary-mesh 15 | helm: 16 | valueFiles: 17 | - values/values-mesh.yaml 18 | parameters: 19 | - name: "global.namespace" 20 | value: gitops 21 | - name: "domain" 22 | value: "change_domain" 23 | project: default 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/applications/job-link-githu-token.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.applications.enabled }} 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | namespace: {{ .Values.namespace }} 6 | generateName: link-docker-config- 7 | annotations: 8 | argocd.argoproj.io/hook: Sync 9 | argocd.argoproj.io/hook-delete-policy: HookSucceeded 10 | spec: 11 | template: 12 | spec: 13 | containers: 14 | - name: link-docker-config 15 | image: quay.io/openshift/origin-cli:4.7 16 | command: 17 | - "oc" 18 | - "secrets" 19 | - "link" 20 | - "pipeline" 21 | - "docker-config" 22 | - "-n" 23 | - "{{ .Values.namespace }}" 24 | restartPolicy: Never 25 | backoffLimit: 10 26 | {{ end }} -------------------------------------------------------------------------------- /canary-service-mesh/application-cluster-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: cluster-configuration 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | name: '' 9 | namespace: openshift-gitops 10 | server: 'https://kubernetes.default.svc' 11 | source: 12 | path: gitops/cluster-config 13 | repoURL: 'https://github.com/davidseve/cloud-native-deployment-strategies.git' 14 | targetRevision: HEAD 15 | helm: 16 | parameters: 17 | - name: "istio.enabled" 18 | value: "true" 19 | - name: "pipeline.enabled" 20 | value: "false" 21 | - name: "github.enabled" 22 | value: "false" 23 | project: default 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true -------------------------------------------------------------------------------- /canary-argo-rollouts/application-cluster-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: cluster-configuration 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | name: '' 9 | namespace: openshift-gitops 10 | server: 'https://kubernetes.default.svc' 11 | source: 12 | path: gitops/cluster-config 13 | repoURL: 'https://github.com/davidseve/cloud-native-deployment-strategies.git' 14 | targetRevision: HEAD 15 | helm: 16 | parameters: 17 | - name: "pipeline.enabled" 18 | value: "false" 19 | - name: "github.enabled" 20 | value: "false" 21 | - name: "argoRollouts.enabled" 22 | value: "true" 23 | project: default 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true -------------------------------------------------------------------------------- /blue-green-argo-rollouts/application-cluster-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: cluster-configuration 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | name: '' 9 | namespace: openshift-gitops 10 | server: 'https://kubernetes.default.svc' 11 | source: 12 | path: gitops/cluster-config 13 | repoURL: 'https://github.com/davidseve/cloud-native-deployment-strategies.git' 14 | targetRevision: HEAD 15 | helm: 16 | parameters: 17 | - name: "pipeline.enabled" 18 | value: "false" 19 | - name: "github.enabled" 20 | value: "false" 21 | - name: "argoRollouts.enabled" 22 | value: "true" 23 | project: default 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true -------------------------------------------------------------------------------- /canary-argo-rollouts-service-mesh/application-shop-canary-rollouts-mesh.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: shop 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | name: '' 9 | namespace: gitops 10 | server: 'https://kubernetes.default.svc' 11 | source: 12 | path: helm/quarkus-helm-umbrella/chart 13 | repoURL: https://github.com/change_me/cloud-native-deployment-strategies.git 14 | targetRevision: rollouts-mesh 15 | helm: 16 | parameters: 17 | - name: "global.namespace" 18 | value: gitops 19 | - name: "domain" 20 | value: "change_domain" 21 | valueFiles: 22 | - values/values-canary-rollouts-mesh.yaml 23 | project: default 24 | syncPolicy: 25 | automated: 26 | prune: true 27 | selfHeal: true -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/values/values.yaml: -------------------------------------------------------------------------------- 1 | discountsNetworkingOnline: 2 | version: blue 3 | discountsNetworkingOffline: 4 | version: green 5 | 6 | productsNetworkingOnline: 7 | version: blue 8 | router: 9 | enabled: true 10 | productsNetworkingOffline: 11 | version: green 12 | router: 13 | enabled: true 14 | 15 | products-green: 16 | quarkus-base: 17 | replicaCount: 1 18 | image: 19 | tag: v1.0.1 20 | mode: offline 21 | products-blue: 22 | quarkus-base: 23 | replicaCount: 2 24 | image: 25 | tag: v1.0.1 26 | mode: online 27 | 28 | discounts-green: 29 | quarkus-base: 30 | replicaCount: 1 31 | image: 32 | tag: v1.0.1 33 | mode: offline 34 | discounts-blue: 35 | quarkus-base: 36 | replicaCount: 2 37 | image: 38 | tag: v1.0.1 39 | mode: online 40 | 41 | -------------------------------------------------------------------------------- /canary-argo-rollouts-service-mesh/application-cluster-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: cluster-configuration 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | name: '' 9 | namespace: openshift-gitops 10 | server: 'https://kubernetes.default.svc' 11 | source: 12 | path: gitops/cluster-config 13 | repoURL: 'https://github.com/davidseve/cloud-native-deployment-strategies.git' 14 | targetRevision: HEAD 15 | helm: 16 | parameters: 17 | - name: "pipeline.enabled" 18 | value: "false" 19 | - name: "github.enabled" 20 | value: "false" 21 | - name: "argoRollouts.enabled" 22 | value: "true" 23 | - name: "istio.enabled" 24 | value: "true" 25 | project: default 26 | syncPolicy: 27 | automated: 28 | prune: true 29 | selfHeal: true -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/role-binding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: gitops-istio-role-binding 6 | namespace: istio-system 7 | annotations: 8 | argocd.argoproj.io/sync-wave: "1" 9 | roleRef: 10 | apiGroup: rbac.authorization.k8s.io 11 | kind: ClusterRole 12 | name: edit 13 | subjects: 14 | - kind: ServiceAccount 15 | name: openshift-gitops-argocd-application-controller 16 | namespace: openshift-gitops 17 | --- 18 | apiVersion: rbac.authorization.k8s.io/v1 19 | kind: RoleBinding 20 | metadata: 21 | name: mesh-edit-pipeline 22 | namespace: istio-system 23 | roleRef: 24 | apiGroup: rbac.authorization.k8s.io 25 | kind: ClusterRole 26 | name: edit 27 | subjects: 28 | - kind: ServiceAccount 29 | name: pipeline 30 | namespace: {{ .Values.namespace }} 31 | {{ end }} -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/service-monitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | annotations: 6 | argocd.argoproj.io/sync-wave: "30" 7 | name: istio-federation 8 | namespace: istio-system 9 | labels: 10 | app.kubernetes.io/name: prometheus 11 | spec: 12 | namespaceSelector: 13 | matchNames: 14 | - istio-system 15 | selector: 16 | matchLabels: 17 | app: prometheus 18 | endpoints: 19 | - interval: 30s 20 | scrapeTimeout: 30s 21 | params: 22 | 'match[]': 23 | - '{job="pilot"}' 24 | - '{job="envoy-stats"}' 25 | path: /federate 26 | targetPort: 9090 27 | honorLabels: true 28 | metricRelabelings: 29 | - sourceLabels: ["__name__"] 30 | regex: 'workload:(.*)' 31 | targetLabel: "__name__" 32 | action: replace 33 | {{ end }} 34 | -------------------------------------------------------------------------------- /helm/quarkus-helm-base/chart/templates/configmap-env-base.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: "{{ include "quarkus.fullname" . }}-configmap-env-base" 5 | labels: 6 | {{- include "quarkus.labels" . | nindent 4 }} 7 | data: 8 | application.version: {{ .Values.image.tag }} 9 | application.colour: {{ .Values.version }} 10 | 11 | quarkus.log.level: {{ .Values.log.level }} 12 | 13 | # quarkus.http.ssl-port: "8443" 14 | # quarkus.http.ssl.certificate.file: "/var/run/secret/kubernetes.io/ssl/cert.pem" 15 | # quarkus.http.ssl.certificate.key-file: "/var/run/secret/kubernetes.io/ssl/key.pem" 16 | 17 | quarkus.jaeger.service-name: {{ include "quarkus.fullname" $ | quote }} 18 | quarkus.jaeger.sampler-type: "const" 19 | quarkus.jaeger.sampler-param: "1" 20 | quarkus.jaeger.endpoint: {{ .Values.jaeger.endpoint | quote }} 21 | quarkus.jaeger.propagation: "b3" 22 | quarkus.jaeger.reporter-log-spans: "true" -------------------------------------------------------------------------------- /blue-green-pipeline/application-cluster-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: cluster-configuration 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | name: '' 9 | namespace: openshift-gitops 10 | server: 'https://kubernetes.default.svc' 11 | source: 12 | path: gitops/cluster-config 13 | repoURL: 'https://github.com/davidseve/cloud-native-deployment-strategies.git' 14 | targetRevision: HEAD 15 | helm: 16 | parameters: 17 | - name: "bluegreen.enabled" 18 | value: "true" 19 | - name: "github.token" 20 | value: "changeme_token" 21 | - name: "github.user" 22 | value: "changeme_user" 23 | - name: "github.mail" 24 | value: "changeme_mail" 25 | - name: "github.repository" 26 | value: "changeme_repository" 27 | project: default 28 | syncPolicy: 29 | automated: 30 | prune: true 31 | selfHeal: true -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/tekton-task-shop-e2e-test.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.enabled }} 2 | apiVersion: tekton.dev/v1beta1 3 | kind: Task 4 | metadata: 5 | name: shop-e2e-test 6 | namespace: {{ .Values.namespace }} 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | spec: 10 | params: 11 | - name: TARGET_VERSION 12 | - name: JQ_PATH 13 | - name: LABEL 14 | steps: 15 | - name: set-results 16 | image: quay.io/jsimas/alpine-curl-jq:1.0 17 | script: | 18 | version="none" 19 | cat $(workspaces.source.path)/url 20 | while [[ "$version" != "$(params.TARGET_VERSION)" ]] 21 | do 22 | sleep 5 23 | curl -k $(cat $(workspaces.source.path)/url) | jq -r '$(params.JQ_PATH)' > metadata 24 | cat metadata 25 | version=$(jq -r '$(params.LABEL)' metadata) 26 | echo $version 27 | done 28 | workspaces: 29 | - name: source 30 | {{ end }} 31 | -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml: -------------------------------------------------------------------------------- 1 | tags: 2 | productsNetworkingOffline: false 3 | discountsNetworkingOffline: false 4 | 5 | discountsNetworkingOnline: 6 | router: 7 | enabled: false 8 | 9 | productsNetworkingOnline: 10 | router: 11 | enabled: false 12 | 13 | domain: change_me 14 | 15 | global: 16 | istio: 17 | enabled: true 18 | rollouts: 19 | enabled: false 20 | productsblueWeight: 100 21 | productsgreenWeight: 0 22 | discountsblueWeight: 100 23 | discountsgreenWeight: 0 24 | 25 | 26 | products-green: 27 | quarkus-base: 28 | replicaCount: 0 29 | image: 30 | tag: v1.1.1 31 | mode: online 32 | products-blue: 33 | quarkus-base: 34 | replicaCount: 4 35 | image: 36 | tag: v1.0.1 37 | mode: online 38 | 39 | discounts-blue: 40 | quarkus-base: 41 | replicaCount: 2 42 | image: 43 | tag: v1.0.1 44 | mode: online 45 | discounts-green: 46 | quarkus-base: 47 | replicaCount: 1 48 | image: 49 | tag: v1.0.1 50 | mode: online 51 | 52 | fullnameOverride: "shop-umbrella" 53 | -------------------------------------------------------------------------------- /helm/quarkus-helm-base/chart/templates/analysis-template.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rollouts.enabled }} 2 | 3 | apiVersion: argoproj.io/v1alpha1 4 | kind: AnalysisTemplate 5 | metadata: 6 | name: {{ include "quarkus.fullname" . }}-analysis-template 7 | labels: 8 | {{- include "quarkus.labels" . | nindent 4 }} 9 | spec: 10 | metrics: 11 | {{- if .Values.rollouts.analysis.web }} 12 | - name: {{ include "quarkus.fullname" . }}-webmetric 13 | successCondition: result == 'UP' 14 | provider: 15 | web: 16 | url: "http://{{ .Values.rollouts.analysis.service }}.{{ .Values.global.namespace }}.svc.cluster.local:8080/q/health/ready" 17 | jsonPath: "{$.status}" 18 | {{- else if .Values.rollouts.analysis.prometheus }} 19 | #this have to be tested 20 | - name: {{ include "quarkus.fullname" . }}-prometheus-metric 21 | interval: 10s 22 | successCondition: len(result) > 0 && (isNaN(result[0]) || result[0] >= 0.95) 23 | failureLimit: 2 24 | provider: 25 | prometheus: 26 | insecure: true 27 | address: {{ .Values.global.prometheusAddress }} 28 | query: | 29 | {{ .Values.rollouts.analysis.query | indent 10 }} 30 | {{- end }} 31 | {{- end }} -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/role-binding.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.enabled }} 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: gitops-edit-pipeline 6 | namespace: {{ .Values.namespace }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: edit 11 | subjects: 12 | - kind: ServiceAccount 13 | name: pipeline 14 | namespace: {{ .Values.namespace }} 15 | --- 16 | apiVersion: rbac.authorization.k8s.io/v1 17 | kind: RoleBinding 18 | metadata: 19 | name: gitops-admin 20 | namespace: {{ .Values.namespace }} 21 | roleRef: 22 | apiGroup: rbac.authorization.k8s.io 23 | kind: ClusterRole 24 | name: admin 25 | subjects: 26 | - kind: ServiceAccount 27 | name: default 28 | namespace: {{ .Values.namespace }} 29 | --- 30 | {{ end }} 31 | {{- if .Values.github.enabled }} 32 | kind: ServiceAccount 33 | apiVersion: v1 34 | metadata: 35 | name: pipeline 36 | namespace: {{ .Values.namespace }} 37 | annotations: 38 | argocd.argoproj.io/sync-options: ServerSideApply=true 39 | argocd.argoproj.io/sync-wave: "20" 40 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 41 | secrets: 42 | - name: github-token 43 | {{ end }} -------------------------------------------------------------------------------- /blue-green-pipeline/util/delete.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd /tmp/deployment/cloud-native-deployment-strategies 4 | 5 | argocd login --core 6 | oc project openshift-gitops 7 | argocd app delete shop -y 8 | oc delete -f blue-green-pipeline/application-shop-blue-green.yaml 9 | 10 | if [ ${1:-no} = "no" ] 11 | then 12 | 13 | oc delete -f blue-green-pipeline/application-cluster-config.yaml 14 | 15 | currentCSV=$(oc get subscription openshift-pipelines-operator-rh -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 16 | echo $currentCSV 17 | oc delete subscription openshift-pipelines-operator-rh -n openshift-operators 18 | oc delete clusterserviceversion $currentCSV -n openshift-operators 19 | 20 | currentCSV=$(oc get subscription openshift-gitops-operator -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 21 | echo $currentCSV 22 | oc delete -f gitops/gitops-operator.yaml 23 | oc delete subscription openshift-gitops-operator -n openshift-operators 24 | oc delete clusterserviceversion $currentCSV -n openshift-operators 25 | 26 | oc delete project gitops 27 | fi 28 | 29 | git checkout main 30 | git branch -d blue-green 31 | git push origin --delete blue-green 32 | -------------------------------------------------------------------------------- /gitops/cluster-config/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: cluster-config 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 1.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.0.0" 25 | -------------------------------------------------------------------------------- /canary-argo-rollouts/util/delete.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd /tmp/deployment/cloud-native-deployment-strategies 4 | 5 | argocd login --core 6 | oc project openshift-gitops 7 | argocd app delete shop -y 8 | oc delete -f canary-argo-rollouts/application-shop-canary-rollouts.yaml 9 | 10 | if [ ${1:-no} = "no" ] 11 | then 12 | 13 | oc delete -f canary-argo-rollouts/application-cluster-config.yaml 14 | 15 | currentCSV=$(oc get subscription openshift-pipelines-operator-rh -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 16 | echo $currentCSV 17 | oc delete subscription openshift-pipelines-operator-rh -n openshift-operators 18 | oc delete clusterserviceversion $currentCSV -n openshift-operators 19 | 20 | currentCSV=$(oc get subscription openshift-gitops-operator -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 21 | echo $currentCSV 22 | oc delete -f gitops/gitops-operator.yaml 23 | oc delete subscription openshift-gitops-operator -n openshift-operators 24 | oc delete clusterserviceversion $currentCSV -n openshift-operators 25 | 26 | oc delete project gitops 27 | fi 28 | 29 | git checkout main 30 | git branch -d canary 31 | git push origin --delete canary 32 | 33 | 34 | -------------------------------------------------------------------------------- /helm/quarkus-helm-networking/chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: quarkus-base-networking 3 | description: A Helm chart for Quarkus 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.0.0" 25 | -------------------------------------------------------------------------------- /blue-green-argo-rollouts/util/delete.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd /tmp/deployment/cloud-native-deployment-strategies 4 | 5 | argocd login --core 6 | oc project openshift-gitops 7 | argocd app delete shop -y 8 | oc delete -f blue-green-argo-rollouts/application-shop-blue-green-rollouts.yaml 9 | 10 | if [ ${1:-no} = "no" ] 11 | then 12 | 13 | oc delete -f blue-green-argo-rollouts/application-cluster-config.yaml 14 | currentCSV=$(oc get subscription openshift-pipelines-operator-rh -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 15 | echo $currentCSV 16 | oc delete subscription openshift-pipelines-operator-rh -n openshift-operators 17 | oc delete clusterserviceversion $currentCSV -n openshift-operators 18 | 19 | currentCSV=$(oc get subscription openshift-gitops-operator -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 20 | echo $currentCSV 21 | oc delete -f gitops/gitops-operator.yaml 22 | oc delete subscription openshift-gitops-operator -n openshift-operators 23 | oc delete clusterserviceversion $currentCSV -n openshift-operators 24 | 25 | oc delete project gitops 26 | fi 27 | 28 | git checkout main 29 | git branch -d rollouts-blue-green 30 | git push origin --delete rollouts-blue-green 31 | -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: shop-umbrella-blue-green 3 | description: A Helm chart for Kubernetes 4 | type: application 5 | version: 0.1.0 6 | appVersion: "1.16.0" 7 | 8 | dependencies: 9 | - name: quarkus-helm-discounts 10 | version: 0.1.0 11 | alias: discounts-blue 12 | tags: 13 | - discounts-blue 14 | - name: quarkus-helm-discounts 15 | version: 0.1.0 16 | alias: discounts-green 17 | tags: 18 | - discounts-green 19 | - name: quarkus-base-networking 20 | version: 0.1.0 21 | alias: discountsNetworkingOnline 22 | tags: 23 | - discountsNetworkingOnline 24 | - name: quarkus-base-networking 25 | version: 0.1.0 26 | alias: discountsNetworkingOffline 27 | tags: 28 | - discountsNetworkingOffline 29 | - name: quarkus-helm-products 30 | version: 0.1.0 31 | alias: products-blue 32 | tags: 33 | - products-blue 34 | - name: quarkus-helm-products 35 | version: 0.1.0 36 | alias: products-green 37 | tags: 38 | - products-green 39 | - name: quarkus-base-networking 40 | version: 0.1.0 41 | alias: productsNetworkingOnline 42 | tags: 43 | - productsNetworkingOnline 44 | - name: quarkus-base-networking 45 | version: 0.1.0 46 | alias: productsNetworkingOffline 47 | tags: 48 | - productsNetworkingOffline 49 | -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/values/values-rollouts-blue-green.yaml: -------------------------------------------------------------------------------- 1 | tags: 2 | discounts-green: false 3 | products-green: false 4 | 5 | global: 6 | namespace: test 7 | #needed for rollouts analysis 8 | prometheusAddress: https://prometheus-user-workload.openshift-user-workload-monitoring.svc.cluster.local:9091 9 | 10 | discounts-blue: 11 | mode: online 12 | quarkus-base: 13 | fullnameOverride: "discounts" 14 | image: 15 | tag: v1.0.1 16 | version: none 17 | rollouts: 18 | enabled: true 19 | analysis: 20 | web: true 21 | service: "discounts-umbrella-offline" 22 | blueGreen: 23 | enabled: true 24 | activeService: "discounts-umbrella-online" 25 | previewService: "discounts-umbrella-offline" 26 | fullnameOverride: "discounts" 27 | 28 | products-blue: 29 | mode: online 30 | quarkus-base: 31 | image: 32 | tag: v1.0.1 33 | replicaCount: 2 34 | fullnameOverride: "products" 35 | version: none 36 | rollouts: 37 | enabled: true 38 | analysis: 39 | web: true 40 | service: "products-umbrella-online" 41 | blueGreen: 42 | enabled: true 43 | activeService: "products-umbrella-online" 44 | previewService: "products-umbrella-offline" 45 | fullnameOverride: "products" 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /tests/testAll.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #./testAll.sh si no github_pat_ rollouts.sandbox61.opentlc.com 4 | 5 | echo $1 #fist installation 6 | echo $2 # github branch 7 | echo $3 # github token 8 | echo $4 #OCP domain 9 | echo ¡¡blue-green-pipeline!! 10 | cd ../blue-green-pipeline/util 11 | 12 | ./test.sh $1 $2 no $3 13 | sleep 1m 14 | echo ¡¡Fin blue-green-pipeline!! 15 | cd ../../blue-green-pipeline/util 16 | ./delete.sh 17 | 18 | sleep 30s 19 | echo ¡¡blue-green-argo-rollouts!! 20 | cd ../../blue-green-argo-rollouts/util 21 | ./test.sh no $2 no 22 | sleep 1m 23 | echo ¡¡Fin blue-green-argo-rollouts!! 24 | cd ../../blue-green-argo-rollouts/util 25 | ./delete.sh 26 | 27 | sleep 30s 28 | echo ¡¡canary-argo-rollouts!! 29 | cd ../../canary-argo-rollouts/util 30 | ./test.sh no $2 no 31 | sleep 1m 32 | echo ¡¡Fin canary-argo-rollouts!! 33 | cd ../../canary-argo-rollouts/util 34 | ./delete.sh 35 | 36 | sleep 30s 37 | echo ¡¡canary-service-mesh!! 38 | cd ../../canary-service-mesh/util 39 | ./test.sh no $2 no $4 40 | sleep 1m 41 | echo ¡¡Fin canary-service-mesh!! 42 | cd ../../canary-service-mesh/util 43 | ./delete.sh 44 | 45 | sleep 1m 46 | echo ¡¡canary-argo-rollouts-service-mesh!! 47 | cd ../../canary-argo-rollouts-service-mesh/util 48 | ./test.sh no $2 no $4 49 | sleep 1m 50 | echo ¡¡Fin canary-argo-rollouts-service-mesh!! 51 | cd ../../canary-argo-rollouts-service-mesh/util 52 | ./delete.sh 53 | -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts.yaml: -------------------------------------------------------------------------------- 1 | tags: 2 | discounts-green: false 3 | products-green: false 4 | discountsNetworkingOffline: false 5 | productsNetworkingOffline: false 6 | 7 | global: 8 | namespace: test 9 | #needed for rollouts analysis 10 | prometheusAddress: https://prometheus-user-workload.openshift-user-workload-monitoring.svc.cluster.local:9091 11 | 12 | discounts-blue: 13 | mode: online 14 | quarkus-base: 15 | fullnameOverride: "discounts" 16 | image: 17 | tag: v1.0.1 18 | version: none 19 | rollouts: 20 | enabled: true 21 | analysis: 22 | web: true 23 | service: "discounts-umbrella-online" 24 | canary: 25 | steps: 26 | - setWeight: 50 27 | - pause: 28 | duration: 1m 29 | fullnameOverride: "discounts" 30 | 31 | products-blue: 32 | mode: online 33 | quarkus-base: 34 | image: 35 | tag: v1.0.1 36 | version: none 37 | replicaCount: 4 38 | fullnameOverride: "products" 39 | rollouts: 40 | enabled: true 41 | analysis: 42 | web: true 43 | service: "products-umbrella-online" 44 | canary: 45 | steps: 46 | - setWeight: 10 47 | - pause: 48 | duration: 30s 49 | - setWeight: 50 50 | - pause: 51 | duration: 30s 52 | fullnameOverride: "products" 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/service-mesh/service-mesh-control-plane.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.istio.enabled }} 2 | apiVersion: maistra.io/v2 3 | kind: ServiceMeshControlPlane 4 | metadata: 5 | name: basic 6 | namespace: istio-system 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | argocd.argoproj.io/sync-wave: "21" 10 | spec: 11 | runtime: 12 | components: 13 | pilot: 14 | deployment: 15 | replicas: 3 16 | tracing: 17 | sampling: 10000 18 | type: Jaeger 19 | gateways: 20 | enabled: true 21 | egress: 22 | enabled: true 23 | runtime: 24 | deployment: 25 | replicas: 3 26 | ingress: 27 | enabled: true 28 | runtime: 29 | deployment: 30 | replicas: 3 31 | openshiftRoute: 32 | enabled: false 33 | policy: 34 | type: Istiod 35 | addons: 36 | grafana: 37 | enabled: true 38 | jaeger: 39 | install: 40 | storage: 41 | type: Memory 42 | kiali: 43 | enabled: true 44 | prometheus: 45 | enabled: true 46 | version: v2.4 47 | telemetry: 48 | type: Istiod 49 | --- 50 | kind: Service 51 | apiVersion: v1 52 | metadata: 53 | name: prometheus-backdoor 54 | namespace: istio-system 55 | spec: 56 | ports: 57 | - name: http-prometheus 58 | protocol: TCP 59 | port: 9090 60 | targetPort: 9090 61 | type: ClusterIP 62 | selector: 63 | app: prometheus 64 | {{ end }} -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "shop.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "shop.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "shop.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "shop.labels" -}} 37 | helm.sh/chart: {{ include "shop.chart" . }} 38 | {{ include "shop.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "shop.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "shop.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "shop.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "shop.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /helm/quarkus-helm-networking/chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "networking.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "networking.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "networking.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "networking.labels" -}} 37 | helm.sh/chart: {{ include "networking.chart" . }} 38 | {{ include "networking.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "networking.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "networking.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "networking.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "networking.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /helm/quarkus-helm-base/chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "quarkus.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "quarkus.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "quarkus.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "quarkus.labels" -}} 37 | helm.sh/chart: {{ include "quarkus.chart" . }} 38 | {{ include "quarkus.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "quarkus.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "quarkus.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | app: {{ include "quarkus.fullname" . }} 52 | {{- end }} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "quarkus.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create }} 59 | {{- default (include "quarkus.fullname" .) .Values.serviceAccount.name }} 60 | {{- else }} 61 | {{- default "default" .Values.serviceAccount.name }} 62 | {{- end }} 63 | {{- end }} 64 | -------------------------------------------------------------------------------- /helm/quarkus-helm-products/chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "products.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "products.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "products.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "products.labels" -}} 37 | helm.sh/chart: {{ include "products.chart" . }} 38 | {{ include "products.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "products.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "products.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | app: {{ include "products.name" . }} 52 | {{- end }} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "products.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create }} 59 | {{- default (include "products.fullname" .) .Values.serviceAccount.name }} 60 | {{- else }} 61 | {{- default "default" .Values.serviceAccount.name }} 62 | {{- end }} 63 | {{- end }} 64 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "cluster-config.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "cluster-config.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "cluster-config.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "cluster-config.labels" -}} 37 | helm.sh/chart: {{ include "cluster-config.chart" . }} 38 | {{ include "cluster-config.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "cluster-config.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "cluster-config.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "cluster-config.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "cluster-config.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /helm/quarkus-helm-discounts/chart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "discounts.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "discounts.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "discounts.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "discounts.labels" -}} 37 | helm.sh/chart: {{ include "discounts.chart" . }} 38 | {{ include "discounts.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "discounts.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "discounts.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | app: {{ include "discounts.name" . }} 52 | {{- end }} 53 | 54 | {{/* 55 | Create the name of the service account to use 56 | */}} 57 | {{- define "discounts.serviceAccountName" -}} 58 | {{- if .Values.serviceAccount.create }} 59 | {{- default (include "discounts.fullname" .) .Values.serviceAccount.name }} 60 | {{- else }} 61 | {{- default "default" .Values.serviceAccount.name }} 62 | {{- end }} 63 | {{- end }} 64 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/tekton-task-openshift-client.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.enabled }} 2 | apiVersion: tekton.dev/v1beta1 3 | kind: Task 4 | metadata: 5 | name: openshift-client 6 | namespace: {{ .Values.namespace }} 7 | labels: 8 | app.kubernetes.io/version: "0.2" 9 | annotations: 10 | tekton.dev/categories: Openshift 11 | tekton.dev/pipelines.minVersion: "0.17.0" 12 | tekton.dev/tags: cli 13 | tekton.dev/displayName: "openshift client" 14 | tekton.dev/platforms: "linux/amd64" 15 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 16 | spec: 17 | workspaces: 18 | - name: manifest-dir 19 | optional: true 20 | description: >- 21 | The workspace which contains kubernetes manifests which we want to apply on the cluster. 22 | - name: kubeconfig-dir 23 | optional: true 24 | description: >- 25 | The workspace which contains the the kubeconfig file if in case we want to run the oc command on another cluster. 26 | description: >- 27 | This task runs commands against the cluster provided by user 28 | and if not provided then where the Task is being executed. 29 | 30 | OpenShift is a Kubernetes distribution from Red Hat which provides oc, 31 | the OpenShift CLI that complements kubectl for simplifying deployment 32 | and configuration applications on OpenShift. 33 | 34 | params: 35 | - name: SCRIPT 36 | description: The OpenShift CLI arguments to run 37 | type: string 38 | default: "oc help" 39 | - name: VERSION 40 | description: The OpenShift Version to use 41 | type: string 42 | default: "4.7" 43 | steps: 44 | - name: oc 45 | image: quay.io/openshift/origin-cli:$(params.VERSION) 46 | script: | 47 | #!/usr/bin/env bash 48 | 49 | [[ "$(workspaces.manifest-dir.bound)" == "true" ]] && \ 50 | cd $(workspaces.manifest-dir.path) 51 | 52 | [[ "$(workspaces.kubeconfig-dir.bound)" == "true" ]] && \ 53 | [[ -f $(workspaces.kubeconfig-dir.path)/kubeconfig ]] && \ 54 | export KUBECONFIG=$(workspaces.kubeconfig-dir.path)/kubeconfig 55 | 56 | $(params.SCRIPT) 57 | {{ end }} -------------------------------------------------------------------------------- /helm/quarkus-helm-base/chart/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for discounts. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | 6 | jaeger: 7 | endpoint: http://jaeger-collector.gitops.svc:14268/api/traces 8 | log: 9 | level: INFO 10 | 11 | fullnameOverride: "" 12 | 13 | service: 14 | type: ClusterIP 15 | port: 8080 16 | 17 | replicaCount: 1 18 | 19 | version: none 20 | 21 | image: 22 | pullPolicy: Always 23 | # Overrides the image tag whose default is the chart appVersion. 24 | tag: "latest" 25 | 26 | imagePullSecrets: [] 27 | 28 | serviceAccount: 29 | # Specifies whether a service account should be created 30 | create: false 31 | # Annotations to add to the service account 32 | annotations: {} 33 | # The name of the service account to use. 34 | # If not set and create is true, a name is generated using the fullname template 35 | name: "" 36 | 37 | podSecurityContext: {} 38 | # fsGroup: 2000 39 | 40 | securityContext: {} 41 | # capabilities: 42 | # drop: 43 | # - ALL 44 | # readOnlyRootFilesystem: true 45 | # runAsNonRoot: true 46 | # runAsUser: 1000 47 | 48 | 49 | 50 | resources: {} 51 | # We usually recommend not to specify default resources and to leave this as a conscious 52 | # choice for the user. This also increases chances charts run on environments with little 53 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 54 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 55 | # limits: 56 | # cpu: 100m 57 | # memory: 128Mi 58 | # requests: 59 | # cpu: 100m 60 | # memory: 128Mi 61 | 62 | autoscaling: 63 | enabled: false 64 | minReplicas: 1 65 | maxReplicas: 100 66 | targetCPUUtilizationPercentage: 80 67 | # targetMemoryUtilizationPercentage: 80 68 | 69 | nodeSelector: {} 70 | 71 | tolerations: [] 72 | 73 | affinity: {} 74 | 75 | #needed for rollouts analysis 76 | global: 77 | namespace: changeme 78 | 79 | rollouts: 80 | enabled: false 81 | analysis: 82 | web: false 83 | prometheus: false 84 | blueGreen: 85 | enabled: false 86 | activeService: changeme 87 | previewService: changeme 88 | autoPromotionEnabled: false -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/pipeline-e2e-tests.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.enabled }} 2 | apiVersion: tekton.dev/v1beta1 3 | kind: Pipeline 4 | metadata: 5 | name: pipeline-blue-green-e2e-test 6 | namespace: {{ .Values.namespace }} 7 | annotations: 8 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 9 | spec: 10 | params: 11 | 12 | - name: NAMESPACE 13 | type: string 14 | default: {{ .Values.namespace }} 15 | description: namespace 16 | - name: APP 17 | type: string 18 | description: discounts or products 19 | - name: NEW_IMAGE_TAG 20 | type: string 21 | default: None 22 | - name: JQ_PATH 23 | type: string 24 | default: .metadata 25 | - name: LABEL 26 | type: string 27 | default: .version 28 | - name: MODE 29 | type: string 30 | default: offline 31 | - name: MESH 32 | type: string 33 | default: "false" 34 | workspaces: 35 | - name: app-source 36 | 37 | tasks: 38 | 39 | - name: get-application-url-new-image-tag 40 | taskRef: 41 | kind: Task 42 | name: openshift-client 43 | params: 44 | - name: SCRIPT 45 | value: | 46 | MESH=$(params.MESH) 47 | if [ $MESH = "true" ] 48 | then 49 | host=$(oc get routes shop-umbrella-$(params.APP)-route -n istio-system -o=jsonpath='{.spec.host}') 50 | else 51 | host=$(oc get routes $(params.APP)-umbrella-$(params.MODE) -n $(params.NAMESPACE) -o=jsonpath='{.spec.host}') 52 | fi 53 | url=https://${host}/$(params.APP) 54 | echo $url > $(workspaces.manifest-dir.path)/url 55 | cat $(workspaces.manifest-dir.path)/url 56 | workspaces: 57 | - name: manifest-dir 58 | workspace: app-source 59 | - name: e2e-test-new-image-tag 60 | runAfter: 61 | - get-application-url-new-image-tag 62 | params: 63 | - name: TARGET_VERSION 64 | value: $(params.NEW_IMAGE_TAG) 65 | - name: JQ_PATH 66 | value: $(params.JQ_PATH) 67 | - name: LABEL 68 | value: $(params.LABEL) 69 | taskRef: 70 | kind: Task 71 | name: shop-e2e-test 72 | timeout: "8m30s" 73 | workspaces: 74 | - name: source 75 | workspace: app-source 76 | --- 77 | apiVersion: v1 78 | kind: PersistentVolumeClaim 79 | metadata: 80 | namespace: {{ .Values.namespace }} 81 | name: workspace-pvc-shop-cd-e2e-tests 82 | annotations: 83 | argocd.argoproj.io/sync-wave: "1000" # issue: https://github.com/argoproj-labs/argocd-operator/issues/936 84 | spec: 85 | accessModes: 86 | - ReadWriteOnce 87 | resources: 88 | requests: 89 | storage: 2Gi 90 | {{ end }} -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/values.yaml: -------------------------------------------------------------------------------- 1 | discounts-blue: 2 | nameOverride: discounts-umbrella 3 | fullnameOverride: "discounts-blue" 4 | quarkus-base: 5 | replicaCount: 2 6 | nameOverride: discounts-umbrella 7 | fullnameOverride: "discounts-blue" 8 | log: 9 | level: DEBUG 10 | version: blue 11 | image: 12 | # Overrides the image tag whose default is the chart appVersion. 13 | tag: "latest" 14 | podAnnotations: 15 | prometheus.io/scrape: "true" 16 | prometheus.io/port: "8080" 17 | prometheus.io/path: "/q/metrics" 18 | discounts-green: 19 | nameOverride: discounts-umbrella 20 | fullnameOverride: "discounts-green" 21 | quarkus-base: 22 | nameOverride: discounts-umbrella 23 | fullnameOverride: "discounts-green" 24 | log: 25 | level: DEBUG 26 | version: green 27 | image: 28 | tag: "latest" 29 | podAnnotations: 30 | prometheus.io/scrape: "true" 31 | prometheus.io/port: "8080" 32 | prometheus.io/path: "/q/metrics" 33 | discountsNetworkingOnline: 34 | nameOverride: discounts-umbrella 35 | fullnameOverride: "discounts-umbrella-online" 36 | router: 37 | enabled: false 38 | discountsNetworkingOffline: 39 | nameOverride: discounts-umbrella 40 | fullnameOverride: "discounts-umbrella-offline" 41 | router: 42 | enabled: false 43 | 44 | products-blue: 45 | nameOverride: products-umbrella 46 | fullnameOverride: "products-blue" 47 | quarkus-base: 48 | replicaCount: 2 49 | nameOverride: products-umbrella 50 | fullnameOverride: "products-blue" 51 | log: 52 | level: DEBUG 53 | version: blue 54 | image: 55 | tag: "latest" 56 | podAnnotations: 57 | prometheus.io/scrape: "true" 58 | prometheus.io/port: "8080" 59 | prometheus.io/path: "/q/metrics" 60 | products-green: 61 | nameOverride: products-umbrella 62 | fullnameOverride: "products-green" 63 | quarkus-base: 64 | nameOverride: products-umbrella 65 | fullnameOverride: "products-green" 66 | log: 67 | level: DEBUG 68 | version: green 69 | image: 70 | tag: "latest" 71 | podAnnotations: 72 | prometheus.io/scrape: "true" 73 | prometheus.io/port: "8080" 74 | prometheus.io/path: "/q/metrics" 75 | productsNetworkingOnline: 76 | nameOverride: products-umbrella 77 | fullnameOverride: products-umbrella-online 78 | 79 | productsNetworkingOffline: 80 | nameOverride: products-umbrella 81 | fullnameOverride: "products-umbrella-offline" 82 | 83 | global: 84 | istio: 85 | enabled: false 86 | rollouts: 87 | enabled: false 88 | prometheusAddress: https://prometheus-k8s.openshift-monitoring.svc.cluster.local 89 | 90 | nameOverride: "shop-umbrella" 91 | 92 | fullnameOverride: "" 93 | 94 | 95 | -------------------------------------------------------------------------------- /canary-argo-rollouts-service-mesh/util/testdemo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #./test.sh si mesh-rollouts-test no rollouts.sandbox61.opentlc.com 4 | 5 | # oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 6 | # Add Argo CD Git Webhook to make it faster 7 | 8 | waitpodup(){ 9 | x=1 10 | test="" 11 | while [ -z "${test}" ] 12 | do 13 | echo "Waiting ${x} times for pod ${1} in ns ${2}" $(( x++ )) 14 | sleep 1 15 | test=$(oc get po -n ${2} | grep ${1}) 16 | done 17 | } 18 | 19 | waitoperatorpod() { 20 | NS=openshift-operators 21 | waitpodup $1 ${NS} 22 | oc get pods -n ${NS} | grep ${1} | awk '{print "oc wait --for condition=Ready -n '${NS}' pod/" $1 " --timeout 300s"}' | sh 23 | } 24 | 25 | waitjaegerpod() { 26 | NS=openshift-distributed-tracing 27 | waitpodup $1 ${NS} 28 | oc get pods -n ${NS} | grep ${1} | awk '{print "oc wait --for condition=Ready -n '${NS}' pod/" $1 " --timeout 300s"}' | sh 29 | } 30 | 31 | rm -rf /tmp/deployment 32 | mkdir /tmp/deployment 33 | cd /tmp/deployment 34 | 35 | git clone https://github.com/davidseve/cloud-native-deployment-strategies.git 36 | cd cloud-native-deployment-strategies 37 | #To work with a branch that is not main. ./test.sh no helm_base 38 | if [ ${2:-no} != "no" ] 39 | then 40 | git fetch 41 | git switch $2 42 | fi 43 | git checkout -b rollouts-mesh 44 | git push origin rollouts-mesh 45 | 46 | if [ ${3:-no} = "no" ] 47 | then 48 | oc apply -f gitops/gitops-operator.yaml 49 | waitoperatorpod gitops 50 | 51 | #To work with a branch that is not main. ./test.sh no helm_base no rollouts.sandbox2229.opentlc.com 52 | if [ ${2:-no} != "no" ] 53 | then 54 | sed -i "s/HEAD/$2/g" canary-argo-rollouts-service-mesh/application-cluster-config.yaml 55 | fi 56 | 57 | sed -i '/pipeline.enabled/{n;s/.*/ value: "true"/}' canary-argo-rollouts-service-mesh/application-cluster-config.yaml 58 | 59 | oc apply -f canary-argo-rollouts-service-mesh/application-cluster-config.yaml --wait=true 60 | 61 | sleep 4m 62 | waitjaegerpod jaeger 63 | waitoperatorpod kiali 64 | waitoperatorpod istio 65 | fi 66 | 67 | sed -i 's/change_me/davidseve/g' canary-argo-rollouts-service-mesh/application-shop-canary-rollouts-mesh.yaml 68 | sed -i "s/change_domain/$4/g" canary-argo-rollouts-service-mesh/application-shop-canary-rollouts-mesh.yaml 69 | 70 | oc apply -f canary-argo-rollouts-service-mesh/application-shop-canary-rollouts-mesh.yaml --wait=true 71 | sleep 2m 72 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param JQ_PATH=.metadata --param MESH=true --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 73 | 74 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/applications/tekton-task-kaniko.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.applications.enabled }} 2 | apiVersion: tekton.dev/v1beta1 3 | kind: Task 4 | metadata: 5 | name: kaniko 6 | namespace: {{ .Values.namespace }} 7 | labels: 8 | app.kubernetes.io/version: "0.6" 9 | annotations: 10 | tekton.dev/pipelines.minVersion: "0.17.0" 11 | tekton.dev/categories: Image Build 12 | tekton.dev/tags: image-build 13 | tekton.dev/displayName: "Build and upload container image using Kaniko" 14 | tekton.dev/platforms: "linux/amd64,linux/arm64,linux/ppc64le" 15 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 16 | spec: 17 | description: >- 18 | This Task builds a simple Dockerfile with kaniko and pushes to a registry. 19 | This Task stores the image name and digest as results, allowing Tekton Chains to pick up 20 | that an image was built & sign it. 21 | params: 22 | - name: IMAGE 23 | description: Name (reference) of the image to build. 24 | - name: DOCKERFILE 25 | description: Path to the Dockerfile to build. 26 | default: ./Dockerfile 27 | - name: CONTEXT 28 | description: The build context used by Kaniko. 29 | default: ./ 30 | - name: EXTRA_ARGS 31 | type: array 32 | default: [] 33 | - name: BUILDER_IMAGE 34 | description: The image on which builds will run (default is v1.5.1) 35 | default: gcr.io/kaniko-project/executor:v1.5.1@sha256:c6166717f7fe0b7da44908c986137ecfeab21f31ec3992f6e128fff8a94be8a5 36 | workspaces: 37 | - name: source 38 | description: Holds the context and Dockerfile 39 | - name: dockerconfig 40 | description: Includes a docker `config.json` 41 | optional: true 42 | mountPath: /kaniko/.docker 43 | results: 44 | - name: IMAGE_DIGEST 45 | description: Digest of the image just built. 46 | - name: IMAGE_URL 47 | description: URL of the image just built. 48 | steps: 49 | - name: build-and-push 50 | workingDir: $(workspaces.source.path) 51 | image: $(params.BUILDER_IMAGE) 52 | args: 53 | - $(params.EXTRA_ARGS) 54 | - --dockerfile=$(params.DOCKERFILE) 55 | - --context=$(workspaces.source.path)/$(params.CONTEXT) # The user does not need to care the workspace and the source. 56 | - --destination=$(params.IMAGE) 57 | - --digest-file=$(results.IMAGE_DIGEST.path) 58 | # kaniko assumes it is running as root, which means this example fails on platforms 59 | # that default to run containers as random uid (like OpenShift). Adding this securityContext 60 | # makes it explicit that it needs to run as root. 61 | securityContext: 62 | runAsUser: 0 63 | - name: write-url 64 | image: docker.io/library/bash:5.1.4@sha256:c523c636b722339f41b6a431b44588ab2f762c5de5ec3bd7964420ff982fb1d9 65 | script: | 66 | set -e 67 | image="$(params.IMAGE)" 68 | echo -n "${image}" | tee "$(results.IMAGE_URL.path)" 69 | {{ end }} -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts-mesh.yaml: -------------------------------------------------------------------------------- 1 | tags: 2 | discounts-green: false 3 | products-green: false 4 | discountsNetworkingOffline: false 5 | productsNetworkingOffline: false 6 | 7 | discountsNetworkingOnline: 8 | router: 9 | enabled: false 10 | 11 | productsNetworkingOnline: 12 | router: 13 | enabled: false 14 | 15 | global: 16 | istio: 17 | enabled: true 18 | rollouts: 19 | enabled: true 20 | namespace: test 21 | #TODO fixme prometheus pass 22 | prometheusAddress: http://prometheus-backdoor.istio-system.svc.cluster.local:9090 23 | 24 | discounts-blue: 25 | mode: online 26 | quarkus-base: 27 | fullnameOverride: "discounts" 28 | image: 29 | tag: v1.0.1 30 | version: none 31 | rollouts: 32 | enabled: true 33 | analysis: 34 | prometheus: true 35 | query: sum(irate( 36 | istio_requests_total{reporter="source",destination_service_name=~"discounts-umbrella-online",response_code!~"5.*"}[30s] 37 | )) / 38 | sum(irate( 39 | istio_requests_total{reporter="source",destination_service_name=~"discounts-umbrella-online"}[30s] 40 | )) 41 | canary: 42 | trafficRouting: 43 | istio: 44 | virtualService: 45 | routes: 46 | - primary 47 | name: shop-umbrella-vs-discounts 48 | destinationRule: 49 | name: shop-umbrella-discounts-rule 50 | canarySubsetName: canary 51 | stableSubsetName: stable 52 | 53 | fullnameOverride: "discounts" 54 | 55 | products-blue: 56 | mode: online 57 | quarkus-base: 58 | image: 59 | tag: v1.0.1 60 | version: none 61 | replicaCount: 4 62 | fullnameOverride: "products" 63 | rollouts: 64 | enabled: true 65 | analysis: 66 | prometheus: true 67 | query: sum(irate( 68 | istio_requests_total{reporter="source",destination_service_name=~"products-umbrella-online",response_code!~"5.*"}[30s] 69 | )) / 70 | sum(irate( 71 | istio_requests_total{reporter="source",destination_service_name=~"products-umbrella-online"}[30s] 72 | )) 73 | canary: 74 | trafficRouting: 75 | istio: 76 | virtualService: 77 | routes: 78 | - primary 79 | name: shop-umbrella-vs-products 80 | destinationRule: 81 | name: shop-umbrella-products-rule 82 | canarySubsetName: canary 83 | stableSubsetName: stable 84 | steps: 85 | - setWeight: 10 86 | - pause: 87 | duration: 30s 88 | - setWeight: 50 89 | - pause: 90 | duration: 30s 91 | fullnameOverride: "products" 92 | 93 | fullnameOverride: "shop-umbrella" 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/openshift-gitops-argocd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1beta1 2 | kind: ArgoCD 3 | metadata: 4 | name: openshift-gitops 5 | namespace: openshift-gitops 6 | annotations: 7 | argocd.argoproj.io/sync-options: ServerSideApply=true 8 | spec: 9 | resourceHealthChecks: 10 | - group: operators.coreos.com 11 | kind: Subscription 12 | check: | 13 | health_status = {} 14 | if obj.status ~= nil then 15 | if obj.status.conditions ~= nil then 16 | numDegraded = 0 17 | numPending = 0 18 | msg = "" 19 | for i, condition in pairs(obj.status.conditions) do 20 | msg = msg .. i .. ": " .. condition.type .. " | " .. condition.status .. "\n" 21 | if condition.type == "InstallPlanPending" and condition.status == "True" then 22 | numPending = numPending + 1 23 | elseif (condition.type == "InstallPlanMissing" and condition.reason ~= "ReferencedInstallPlanNotFound") then 24 | numDegraded = numDegraded + 1 25 | elseif (condition.type == "CatalogSourcesUnhealthy" or condition.type == "InstallPlanFailed" or condition.type == "ResolutionFailed") and condition.status == "True" then 26 | numDegraded = numDegraded + 1 27 | end 28 | end 29 | if numDegraded == 0 and numPending == 0 then 30 | health_status.status = "Healthy" 31 | health_status.message = msg 32 | return health_status 33 | elseif numPending > 0 and numDegraded == 0 then 34 | health_status.status = "Progressing" 35 | health_status.message = "An install plan for a subscription is pending installation" 36 | return health_status 37 | else 38 | health_status.status = "Degraded" 39 | health_status.message = msg 40 | return health_status 41 | end 42 | end 43 | end 44 | health_status.status = "Progressing" 45 | health_status.message = "An install plan for a subscription is pending installation" 46 | return health_status 47 | - group: operators.coreos.com 48 | kind: InstallPlan 49 | check: | 50 | hs = {} 51 | if obj.status ~= nil then 52 | if obj.status.phase ~= nil then 53 | if obj.status.phase == "Complete" then 54 | hs.status = "Healthy" 55 | hs.message = obj.status.phase 56 | return hs 57 | end 58 | end 59 | end 60 | hs.status = "Progressing" 61 | hs.message = "Waiting for InstallPlan to complete" 62 | return hs 63 | # issue: https://github.com/argoproj-labs/argocd-operator/issues/936 64 | # - kind: PersistentVolumeClaim 65 | # check: | 66 | # hs = {} 67 | # if obj.status ~= nil then 68 | # if obj.status.phase ~= nil then 69 | # if obj.status.phase == "Pending" then 70 | # hs.status = "Healthy" 71 | # hs.message = obj.status.phase 72 | # return hs 73 | # end 74 | # if obj.status.phase == "Bound" then 75 | # hs.status = "Healthy" 76 | # hs.message = obj.status.phase 77 | # return hs 78 | # end 79 | # end 80 | # end 81 | # hs.status = "Progressing" 82 | # hs.message = "Waiting for certificate" 83 | # return hs -------------------------------------------------------------------------------- /canary-service-mesh/util/delete.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd /tmp/deployment/cloud-native-deployment-strategies 4 | 5 | argocd login --core 6 | oc project openshift-gitops 7 | argocd app delete shop -y 8 | oc delete -f canary-service-mesh/application-shop-mesh.yaml 9 | 10 | if [ ${1:-no} = "no" ] 11 | then 12 | oc delete smmr -n istio-system default 13 | oc delete smcp -n istio-system basic 14 | oc delete validatingwebhookconfiguration/openshift-operators.servicemesh-resources.maistra.io 15 | oc delete mutatingwebhookconfiguration/openshift-operators.servicemesh-resources.maistra.io 16 | oc delete -n openshift-operators daemonset/istio-node 17 | oc delete clusterrole/istio-admin clusterrole/istio-cni clusterrolebinding/istio-cni 18 | oc delete clusterrole istio-view istio-edit 19 | oc delete clusterrole jaegers.jaegertracing.io-v1-admin jaegers.jaegertracing.io-v1-crdview jaegers.jaegertracing.io-v1-edit jaegers.jaegertracing.io-v1-view 20 | oc get crds -o name | grep '.*\.istio\.io' | xargs -r -n 1 oc delete 21 | oc get crds -o name | grep '.*\.maistra\.io' | xargs -r -n 1 oc delete 22 | oc get crds -o name | grep '.*\.kiali\.io' | xargs -r -n 1 oc delete 23 | oc delete crds jaegers.jaegertracing.io 24 | #oc delete svc admission-controller -n 25 | oc delete project istio-system 26 | 27 | oc delete -f canary-service-mesh/application-cluster-config.yaml 28 | 29 | currentCSV=$(oc get subscription openshift-pipelines-operator-rh -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 30 | echo $currentCSV 31 | oc delete subscription openshift-pipelines-operator-rh -n openshift-operators 32 | oc delete clusterserviceversion $currentCSV -n openshift-operators 33 | 34 | currentCSV=$(oc get subscription jaeger-product -n openshift-distributed-tracing -o yaml | grep currentCSV | sed 's/ currentCSV: //') 35 | echo $currentCSV 36 | oc delete subscription jaeger-product -n openshift-distributed-tracing 37 | oc delete clusterserviceversion $currentCSV -n openshift-distributed-tracing 38 | 39 | currentCSV=$(oc get subscription elasticsearch-operator -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 40 | echo $currentCSV 41 | oc delete subscription elasticsearch-operator -n openshift-operators 42 | oc delete clusterserviceversion $currentCSV -n openshift-operators 43 | 44 | currentCSV=$(oc get subscription kiali-ossm -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 45 | echo $currentCSV 46 | oc delete subscription kiali-ossm -n openshift-operators 47 | oc delete clusterserviceversion $currentCSV -n openshift-operators 48 | 49 | currentCSV=$(oc get subscription servicemeshoperator -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 50 | echo $currentCSV 51 | oc delete subscription servicemeshoperator -n openshift-operators 52 | oc delete clusterserviceversion $currentCSV -n openshift-operators 53 | 54 | 55 | currentCSV=$(oc get subscription openshift-gitops-operator -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 56 | echo $currentCSV 57 | oc delete -f gitops/gitops-operator.yaml 58 | oc delete subscription openshift-gitops-operator -n openshift-operators 59 | oc delete clusterserviceversion $currentCSV -n openshift-operators 60 | 61 | oc delete project argo-rollouts 62 | 63 | oc delete project gitops 64 | fi 65 | 66 | 67 | 68 | git checkout main 69 | git branch -d canary-mesh 70 | git push origin --delete canary-mesh 71 | 72 | 73 | -------------------------------------------------------------------------------- /canary-argo-rollouts-service-mesh/util/delete.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd /tmp/deployment/cloud-native-deployment-strategies 4 | 5 | argocd login --core 6 | oc project openshift-gitops 7 | argocd app delete shop -y 8 | oc delete -f canary-argo-rollouts-service-mesh/application-shop-canary-rollouts-mesh.yaml 9 | 10 | if [ ${1:-no} = "no" ] 11 | then 12 | oc delete smmr -n istio-system default 13 | oc delete smcp -n istio-system basic 14 | oc delete validatingwebhookconfiguration/openshift-operators.servicemesh-resources.maistra.io 15 | oc delete mutatingwebhookconfiguration/openshift-operators.servicemesh-resources.maistra.io 16 | oc delete -n openshift-operators daemonset/istio-node 17 | oc delete clusterrole/istio-admin clusterrole/istio-cni clusterrolebinding/istio-cni 18 | oc delete clusterrole istio-view istio-edit 19 | oc delete clusterrole jaegers.jaegertracing.io-v1-admin jaegers.jaegertracing.io-v1-crdview jaegers.jaegertracing.io-v1-edit jaegers.jaegertracing.io-v1-view 20 | oc get crds -o name | grep '.*\.istio\.io' | xargs -r -n 1 oc delete 21 | oc get crds -o name | grep '.*\.maistra\.io' | xargs -r -n 1 oc delete 22 | oc get crds -o name | grep '.*\.kiali\.io' | xargs -r -n 1 oc delete 23 | oc delete crds jaegers.jaegertracing.io 24 | #oc delete svc admission-controller -n 25 | oc delete project istio-system 26 | 27 | oc delete -f canary-argo-rollouts-service-mesh/application-cluster-config.yaml 28 | 29 | currentCSV=$(oc get subscription openshift-pipelines-operator-rh -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 30 | echo $currentCSV 31 | oc delete subscription openshift-pipelines-operator-rh -n openshift-operators 32 | oc delete clusterserviceversion $currentCSV -n openshift-operators 33 | 34 | currentCSV=$(oc get subscription jaeger-product -n openshift-distributed-tracing -o yaml | grep currentCSV | sed 's/ currentCSV: //') 35 | echo $currentCSV 36 | oc delete subscription jaeger-product -n openshift-distributed-tracing 37 | oc delete clusterserviceversion $currentCSV -n openshift-distributed-tracing 38 | 39 | currentCSV=$(oc get subscription elasticsearch-operator -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 40 | echo $currentCSV 41 | oc delete subscription elasticsearch-operator -n openshift-operators 42 | oc delete clusterserviceversion $currentCSV -n openshift-operators 43 | 44 | currentCSV=$(oc get subscription kiali-ossm -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 45 | echo $currentCSV 46 | oc delete subscription kiali-ossm -n openshift-operators 47 | oc delete clusterserviceversion $currentCSV -n openshift-operators 48 | 49 | currentCSV=$(oc get subscription servicemeshoperator -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 50 | echo $currentCSV 51 | oc delete subscription servicemeshoperator -n openshift-operators 52 | oc delete clusterserviceversion $currentCSV -n openshift-operators 53 | 54 | 55 | currentCSV=$(oc get subscription openshift-gitops-operator -n openshift-operators -o yaml | grep currentCSV | sed 's/ currentCSV: //') 56 | echo $currentCSV 57 | oc delete -f gitops/gitops-operator.yaml 58 | oc delete subscription openshift-gitops-operator -n openshift-operators 59 | oc delete clusterserviceversion $currentCSV -n openshift-operators 60 | 61 | oc delete project argo-rollouts 62 | 63 | oc delete project gitops 64 | fi 65 | 66 | 67 | 68 | git checkout main 69 | git branch -d rollouts-mesh 70 | git push origin --delete rollouts-mesh 71 | 72 | 73 | -------------------------------------------------------------------------------- /helm/quarkus-helm-base/chart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rollouts.enabled }} 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Rollout 4 | {{- else }} 5 | apiVersion: apps/v1 6 | kind: Deployment 7 | {{- end }} 8 | metadata: 9 | name: {{ include "quarkus.fullname" . }} 10 | labels: 11 | {{- include "quarkus.labels" . | nindent 4 }} 12 | spec: 13 | {{- if not .Values.autoscaling.enabled }} 14 | replicas: {{ .Values.replicaCount }} 15 | revisionHistoryLimit: 2 16 | {{- end }} 17 | selector: 18 | matchLabels: 19 | {{- include "quarkus.selectorLabels" . | nindent 6 }} 20 | {{- with .Values.version }} 21 | version: {{ . }} 22 | {{- end }} 23 | template: 24 | metadata: 25 | {{- with .Values.podAnnotations }} 26 | annotations: 27 | {{- toYaml . | nindent 8 }} 28 | {{- if $.Values.global.istio.enabled }} 29 | sidecar.istio.io/inject: "true" 30 | {{- end }} 31 | {{- end }} 32 | labels: 33 | {{- include "quarkus.selectorLabels" . | nindent 8 }} 34 | {{- with .Values.version }} 35 | version: {{ . }} 36 | {{- end }} 37 | spec: 38 | {{- with .Values.imagePullSecrets }} 39 | imagePullSecrets: 40 | {{- toYaml . | nindent 8 }} 41 | {{- end }} 42 | serviceAccountName: {{ include "quarkus.serviceAccountName" . }} 43 | securityContext: 44 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 45 | containers: 46 | - name: {{ .Chart.Name }} 47 | securityContext: 48 | {{- toYaml .Values.securityContext | nindent 12 }} 49 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 50 | imagePullPolicy: {{ .Values.image.pullPolicy }} 51 | ports: 52 | - name: http 53 | containerPort: {{ .Values.service.port }} 54 | protocol: TCP 55 | envFrom: 56 | - configMapRef: 57 | name: "{{ include "quarkus.fullname" $ }}-configmap-env" 58 | - configMapRef: 59 | name: "{{ include "quarkus.fullname" $ }}-configmap-env-base" 60 | livenessProbe: 61 | failureThreshold: 3 62 | httpGet: 63 | path: /q/health/live 64 | port: 8080 65 | scheme: HTTP 66 | initialDelaySeconds: 0 67 | periodSeconds: 30 68 | successThreshold: 1 69 | timeoutSeconds: 10 70 | readinessProbe: 71 | failureThreshold: 3 72 | httpGet: 73 | path: /q/health/ready 74 | port: 8080 75 | scheme: HTTP 76 | initialDelaySeconds: 0 77 | periodSeconds: 30 78 | successThreshold: 1 79 | timeoutSeconds: 10 80 | resources: 81 | {{- toYaml .Values.resources | nindent 12 }} 82 | {{- with .Values.nodeSelector }} 83 | nodeSelector: 84 | {{- toYaml . | nindent 8 }} 85 | {{- end }} 86 | {{- with .Values.affinity }} 87 | affinity: 88 | {{- toYaml . | nindent 8 }} 89 | {{- end }} 90 | {{- with .Values.tolerations }} 91 | tolerations: 92 | {{- toYaml . | nindent 8 }} 93 | {{- end }} 94 | {{- if .Values.rollouts.blueGreen.enabled }} 95 | strategy: 96 | blueGreen: 97 | prePromotionAnalysis: 98 | templates: 99 | - templateName: {{ include "quarkus.fullname" . }}-analysis-template 100 | activeService: {{ .Values.rollouts.blueGreen.activeService }} 101 | previewService: {{ .Values.rollouts.blueGreen.previewService }} 102 | autoPromotionEnabled: {{ .Values.rollouts.blueGreen.autoPromotionEnabled }} 103 | {{- end }} 104 | {{- with .Values.rollouts.canary }} 105 | strategy: 106 | canary: 107 | {{- if $.Values.global.istio.enabled }} 108 | dynamicStableScale: true 109 | {{- end }} 110 | analysis: 111 | templates: 112 | - templateName: {{ include "quarkus.fullname" $ }}-analysis-template 113 | {{- toYaml .| nindent 6 }} 114 | {{- end }} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cloud Native Deployment Strategies 2 | 3 | ## Introduction 4 | 5 | One important topic in the `Cloud Native` is the `Microservice Architecture`. We are no longer dealing with one monolithic application. We have several applications that have dependencies on each other and also have other dependencies like brokers or databases. 6 | 7 | Applications have their own life cycle, so we should be able to execute independent deployment. All the applications and dependencies will not change their version at the same time. 8 | 9 | Another important topic in the `Cloud Native` is the `Continuous Delivery`. If we are going to have several applications doing deployments independently we have to automate it. We will use **Helm**, **Openshift GitOps**, and of course **Red Hat Openshift** to help us. 10 | 11 | **In this repository, we are going to test and compare different deployments strategies with `Cloud Native` applications. We will see real examples of how to install, deploy and manage the life cycle of `Cloud Native` applications using those strategies.** 12 | 13 | ## Deployment Strategies 14 | 15 | Those are the different `Cloud Native` deployment strategies that we have developed, you can click on each one and test it. 16 | 17 | - [**Blue/Green** using **Openshift Pipelines**](/blue-green-pipeline) 18 | - [**Blue/Green** using **Argo Rollouts**](/blue-green-argo-rollouts) 19 | - [**Canary** using **Openshift Service Mesh**](/canary-service-mesh) 20 | - [**Canary** using **Argo Rollouts**](/canary-argo-rollouts) 21 | - [**Canary** using **Argo Rollouts** and **Openshift Service Mesh**](/canary-argo-rollouts-service-mesh) 22 | 23 | 24 | 25 | ## Deployment Strategies comparison 26 | 27 | Here is a comparison table of the advantages and disadvantages of each deployment strategy based on the provided articles: 28 | 29 | | **Deployment Strategy** | **Advantages** | **Disadvantages** | 30 | |-------------------------|----------------|--------------------| 31 | | **Blue-Green Deployment with OpenShift Pipelines** | - **Minimal Downtime**: Near-instantaneous switch between environments reduces downtime.
- **Easy Rollback**: Immediate rollback capability if the new version fails.
- **Isolation**: Complete isolation of new version for thorough testing. | - **High Resource Cost**: Requires maintaining two identical environments, doubling infrastructure costs.
- **Complex Data Management**: Challenges in synchronizing databases across environments.
- **Configuration Complexity**: Requires significant setup and maintenance effort. | 32 | | **Blue-Green Deployment with Argo Rollouts** | - **Flexible Traffic Management**: Allows for easy traffic redirection during deployment.
- **Rollback Capability**: Simplified rollback to previous version in case of issues.
- **Seamless Transition**: Users experience minimal interruption during deployment. | - **Configuration Complexity**: Requires careful configuration and maintenance.
- **Limited Traffic Management**: Does not offer fine-grained control over traffic distribution​ | 33 | | **Canary Deployment with OpenShift Service Mesh** | - **Flexible Traffic Management**: Allows for easy traffic redirection during deployment.
- **Fine-Grained Control**: Offers detailed traffic management and performance monitoring.
- **Reduced Risk**: Identifies issues early with limited user impact. | - **Monitoring Requirement**: Requires continuous monitoring and analysis to manage rollout.
- **Complex Setup**: Traffic routing and management can be technically challenging. | 34 | | **Canary Deployment with Argo Rollouts** | - **Flexible Traffic Management**: Allows for easy traffic redirection during deployment.
- **Rollback Capability**: Easily pauses and rolls back in case of issues.
- **Seamless Updates**: Minimizes user disruption by gradually introducing changes. | - **Increased Complexity**: Requires sophisticated traffic routing and monitoring tools.
- **Constant Monitoring Needed**: Demands continuous observation to detect and address issues.
- **Resource Overuse Potential**: Gradual rollouts can temporarily increase resource usage. | 35 | | **Canary Deployment with Argo Rollouts and OpenShift Service Mesh** | - **Combined Strengths**: Leverages both tools for enhanced traffic management and observability.
- **Enhanced Observability**: Provides comprehensive monitoring capabilities.
- **Reduced Risk**: Combines incremental rollout with robust monitoring to minimize failure impact. | - **High Complexity**: Requires expertise in both tools for effective deployment and management.
- **Increased Monitoring**: Demands more extensive monitoring efforts.
- **Complex Setup**: Integration of multiple tools can complicate the deployment process. | 36 | 37 | -------------------------------------------------------------------------------- /canary-argo-rollouts/util/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #./test.sh si rollouts no 4 | 5 | # oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 6 | # Add Argo CD Git Webhook to make it faster 7 | 8 | waitpodup(){ 9 | x=1 10 | test="" 11 | while [ -z "${test}" ] 12 | do 13 | echo "Waiting ${x} times for pod ${1} in ns ${2}" $(( x++ )) 14 | sleep 1 15 | test=$(oc get po -n ${2} | grep ${1}) 16 | done 17 | } 18 | 19 | waitoperatorpod() { 20 | NS=openshift-operators 21 | waitpodup $1 ${NS} 22 | oc get pods -n ${NS} | grep ${1} | awk '{print "oc wait --for condition=Ready -n '${NS}' pod/" $1 " --timeout 300s"}' | sh 23 | } 24 | 25 | waitjaegerpod() { 26 | NS=openshift-distributed-tracing 27 | waitpodup $1 ${NS} 28 | oc get pods -n ${NS} | grep ${1} | awk '{print "oc wait --for condition=Ready -n '${NS}' pod/" $1 " --timeout 300s"}' | sh 29 | } 30 | 31 | rm -rf /tmp/deployment 32 | mkdir /tmp/deployment 33 | cd /tmp/deployment 34 | 35 | git clone https://github.com/davidseve/cloud-native-deployment-strategies.git 36 | cd cloud-native-deployment-strategies 37 | #To work with a branch that is not main. ./test.sh no helm_base 38 | if [ ${2:-no} != "no" ] 39 | then 40 | git fetch 41 | git switch $2 42 | fi 43 | git checkout -b canary 44 | git push origin canary 45 | 46 | if [ ${3:-no} = "no" ] 47 | then 48 | oc apply -f gitops/gitops-operator.yaml 49 | waitoperatorpod gitops 50 | 51 | #To work with a branch that is not main. ./test.sh no helm_base 52 | if [ ${2:-no} != "no" ] 53 | then 54 | sed -i "s/HEAD/$2/g" canary-argo-rollouts/application-cluster-config.yaml 55 | fi 56 | 57 | sed -i '/pipeline.enabled/{n;s/.*/ value: "true"/}' canary-argo-rollouts/application-cluster-config.yaml 58 | 59 | oc apply -f canary-argo-rollouts/application-cluster-config.yaml --wait=true 60 | 61 | waitoperatorpod pipelines 62 | fi 63 | 64 | sed -i 's/change_me/davidseve/g' canary-argo-rollouts/application-shop-canary-rollouts.yaml 65 | 66 | oc apply -f canary-argo-rollouts/application-shop-canary-rollouts.yaml --wait=true 67 | sleep 2m 68 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 69 | 70 | sed -i '/products-blue/{n;n;n;n;s/.*/ tag: v1.1.1/}' helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts.yaml 71 | 72 | git add helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts.yaml 73 | git commit -m "Change products version to v1.1.1" 74 | git push origin canary 75 | 76 | status=none 77 | while [[ "$status" != "Paused - CanaryPauseStep" ]] 78 | do 79 | sleep 5 80 | status=$(kubectlArgo argo rollouts status products -n gitops --watch=false) 81 | echo $status 82 | done 83 | 84 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 85 | 86 | status=none 87 | while [[ "$status" != "Healthy" ]] 88 | do 89 | sleep 5 90 | status=$(kubectlArgo argo rollouts status products -n gitops --watch=false) 91 | echo $status 92 | done 93 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 94 | 95 | #Rollback 96 | #this is not neccesary becase argo rollouts do the rollback because of scaleDownDelaySeconds (default 30 seconds), just to make it work I add the sleep 97 | git revert HEAD --no-edit 98 | sed -i '/products-blue/{n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;N;N;N;N;d;}' helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts.yaml 99 | sed -i '/products-blue/{n;n;n;n;n;n;n;n;n;n;n;n;n;n;n;s/.*/ - setWeight: 100/}' helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts.yaml 100 | git add . 101 | git commit -m "delete steps for rollout" 102 | git push origin canary 103 | 104 | status=none 105 | while [[ "$status" != "Healthy" ]] 106 | do 107 | sleep 5 108 | status=$(kubectlArgo argo rollouts status products -n gitops --watch=false) 109 | echo $status 110 | done 111 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 112 | -------------------------------------------------------------------------------- /canary-argo-rollouts-service-mesh/util/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #./test.sh si mesh-rollouts-test no rollouts.sandbox61.opentlc.com 4 | 5 | # oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 6 | # Add Argo CD Git Webhook to make it faster 7 | 8 | waitpodup(){ 9 | x=1 10 | test="" 11 | while [ -z "${test}" ] 12 | do 13 | echo "Waiting ${x} times for pod ${1} in ns ${2}" $(( x++ )) 14 | sleep 1 15 | test=$(oc get po -n ${2} | grep ${1}) 16 | done 17 | } 18 | 19 | waitoperatorpod() { 20 | NS=openshift-operators 21 | waitpodup $1 ${NS} 22 | oc get pods -n ${NS} | grep ${1} | awk '{print "oc wait --for condition=Ready -n '${NS}' pod/" $1 " --timeout 300s"}' | sh 23 | } 24 | 25 | waitjaegerpod() { 26 | NS=openshift-distributed-tracing 27 | waitpodup $1 ${NS} 28 | oc get pods -n ${NS} | grep ${1} | awk '{print "oc wait --for condition=Ready -n '${NS}' pod/" $1 " --timeout 300s"}' | sh 29 | } 30 | 31 | rm -rf /tmp/deployment 32 | mkdir /tmp/deployment 33 | cd /tmp/deployment 34 | 35 | git clone https://github.com/davidseve/cloud-native-deployment-strategies.git 36 | cd cloud-native-deployment-strategies 37 | #To work with a branch that is not main. ./test.sh no helm_base 38 | if [ ${2:-no} != "no" ] 39 | then 40 | git fetch 41 | git switch $2 42 | fi 43 | git checkout -b rollouts-mesh 44 | git push origin rollouts-mesh 45 | 46 | if [ ${3:-no} = "no" ] 47 | then 48 | oc apply -f gitops/gitops-operator.yaml 49 | waitoperatorpod gitops 50 | 51 | #To work with a branch that is not main. ./test.sh no helm_base no rollouts.sandbox2229.opentlc.com 52 | if [ ${2:-no} != "no" ] 53 | then 54 | sed -i "s/HEAD/$2/g" canary-argo-rollouts-service-mesh/application-cluster-config.yaml 55 | fi 56 | 57 | sed -i '/pipeline.enabled/{n;s/.*/ value: "true"/}' canary-argo-rollouts-service-mesh/application-cluster-config.yaml 58 | 59 | oc apply -f canary-argo-rollouts-service-mesh/application-cluster-config.yaml --wait=true 60 | 61 | sleep 4m 62 | waitjaegerpod jaeger 63 | waitoperatorpod kiali 64 | waitoperatorpod istio 65 | fi 66 | 67 | sed -i 's/change_me/davidseve/g' canary-argo-rollouts-service-mesh/application-shop-canary-rollouts-mesh.yaml 68 | sed -i "s/change_domain/$4/g" canary-argo-rollouts-service-mesh/application-shop-canary-rollouts-mesh.yaml 69 | 70 | oc apply -f canary-argo-rollouts-service-mesh/application-shop-canary-rollouts-mesh.yaml --wait=true 71 | sleep 2m 72 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param JQ_PATH=.metadata --param MESH=true --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 73 | 74 | sed -i '/products-blue/{n;n;n;n;s/.*/ tag: v1.1.1/}' helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts-mesh.yaml 75 | 76 | git add helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts-mesh.yaml 77 | git commit -m "Change products version to v1.1.1" 78 | git push origin rollouts-mesh 79 | 80 | status=none 81 | while [[ "$status" != "Paused - CanaryPauseStep" ]] 82 | do 83 | sleep 5 84 | status=$(kubectlArgo argo rollouts status products -n gitops --watch=false) 85 | echo $status 86 | done 87 | 88 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=true --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 89 | 90 | status=none 91 | while [[ "$status" != "Healthy" ]] 92 | do 93 | sleep 5 94 | status=$(kubectlArgo argo rollouts status products -n gitops --watch=false) 95 | echo $status 96 | done 97 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=true --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 98 | 99 | #Rollback 100 | #this is not neccesary becase argo rollouts do the rollback because of scaleDownDelaySeconds (default 30 seconds), just to make it work I add the sleep 101 | git revert HEAD --no-edit 102 | sed -i '/setWeight: 10/{n;N;N;N;N;d;}' helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts-mesh.yaml 103 | sed -i 's/setWeight: 10/setWeight: 100/' helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts-mesh.yaml 104 | git add . 105 | git commit -m "delete steps for rollout" 106 | git push origin rollouts-mesh 107 | 108 | status=none 109 | while [[ "$status" != "Healthy" ]] 110 | do 111 | sleep 5 112 | status=$(kubectlArgo argo rollouts status products -n gitops --watch=false) 113 | echo $status 114 | done 115 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=true --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 116 | -------------------------------------------------------------------------------- /blue-green-argo-rollouts/util/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #./test.sh si rollouts no 4 | 5 | # oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 6 | # Add Argo CD Git Webhook to make it faster 7 | 8 | waitpodup(){ 9 | x=1 10 | test="" 11 | while [ -z "${test}" ] 12 | do 13 | echo "Waiting ${x} times for pod ${1} in ns ${2}" $(( x++ )) 14 | sleep 1 15 | test=$(oc get po -n ${2} | grep ${1}) 16 | done 17 | } 18 | 19 | waitoperatorpod() { 20 | NS=openshift-operators 21 | waitpodup $1 ${NS} 22 | oc get pods -n ${NS} | grep ${1} | awk '{print "oc wait --for condition=Ready -n '${NS}' pod/" $1 " --timeout 300s"}' | sh 23 | } 24 | 25 | rm -rf /tmp/deployment 26 | mkdir /tmp/deployment 27 | cd /tmp/deployment 28 | 29 | git clone https://github.com/davidseve/cloud-native-deployment-strategies.git 30 | cd cloud-native-deployment-strategies 31 | #To work with a branch that is not main. ./test.sh no helm_base 32 | if [ ${2:-no} != "no" ] 33 | then 34 | git fetch 35 | git switch $2 36 | fi 37 | git checkout -b rollouts-blue-green 38 | git push origin rollouts-blue-green 39 | 40 | if [ ${3:-no} = "no" ] 41 | then 42 | oc apply -f gitops/gitops-operator.yaml 43 | waitoperatorpod gitops 44 | 45 | #To work with a branch that is not main. ./test.sh no helm_base 46 | if [ ${2:-no} != "no" ] 47 | then 48 | sed -i "s/HEAD/$2/g" blue-green-argo-rollouts/application-cluster-config.yaml 49 | fi 50 | 51 | sed -i '/pipeline.enabled/{n;s/.*/ value: "true"/}' blue-green-argo-rollouts/application-cluster-config.yaml 52 | 53 | # #$4 quay token 54 | # #To install applicatins ci pipeline ./test.sh no helm_base no eHBZwYVc5djhsdkpfhWphVHBEVTBaWsTUkRGV1EwNHlTVlRraE5OUldUSXlWak 55 | # if [ ${4:-no} != "no" ] 56 | # then 57 | # sed -i '/project: default/i \ \ - name: "pipeline.applications.enabled"' blue-green-argo-rollouts/application-cluster-config.yaml 58 | # sed -i '/project: default/i \ \ value: "true"' blue-green-argo-rollouts/application-cluster-config.yaml 59 | # sed -i '/project: default/i \ \ - name: "pipeline.applications.dockerconfigjson"' blue-green-argo-rollouts/application-cluster-config.yaml 60 | # sed -i "/project: default/i \ \ value: $4" blue-green-argo-rollouts/application-cluster-config.yaml 61 | # fi 62 | 63 | oc apply -f blue-green-argo-rollouts/application-cluster-config.yaml --wait=true 64 | 65 | #First time we install operators take logger 66 | if [ ${1:-no} = "no" ] 67 | then 68 | sleep 1m 69 | else 70 | sleep 2m 71 | fi 72 | fi 73 | 74 | sed -i 's/change_me/davidseve/g' blue-green-argo-rollouts/application-shop-blue-green-rollouts.yaml 75 | 76 | oc apply -f blue-green-argo-rollouts/application-shop-blue-green-rollouts.yaml --wait=true 77 | sleep 2m 78 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 79 | 80 | sed -i '/products-blue/{n;n;n;n;s/.*/ tag: v1.1.1/}' helm/quarkus-helm-umbrella/chart/values/values-rollouts-blue-green.yaml 81 | 82 | git add helm/quarkus-helm-umbrella/chart/values/values-rollouts-blue-green.yaml 83 | git commit -m "Change products version to v1.1.1" 84 | git push origin rollouts-blue-green 85 | 86 | status=none 87 | while [[ "$status" != "Paused - BlueGreenPause" ]] 88 | do 89 | sleep 5 90 | status=$(kubectlArgo argo rollouts status products -n gitops --watch=false) 91 | echo $status 92 | done 93 | 94 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=offline --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 95 | 96 | oc project gitops 97 | kubectlArgo argo rollouts promote products -n gitops 98 | 99 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 100 | 101 | #Rollback 102 | #this is not neccesary becase argo rollouts do the rollback because of scaleDownDelaySeconds (default 30 seconds), just to make it work I add the sleep 103 | sleep 10 104 | git revert HEAD --no-edit 105 | git push origin rollouts-blue-green 106 | 107 | status=none 108 | while [[ "$status" != "Paused - BlueGreenPause" ]] 109 | do 110 | sleep 5 111 | status=$(kubectlArgo argo rollouts status products -n gitops --watch=false) 112 | echo $status 113 | done 114 | kubectlArgo argo rollouts promote products -n gitops 115 | 116 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 117 | -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/tekton-task-git-pr.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.enabled }} 2 | --- 3 | apiVersion: tekton.dev/v1beta1 4 | kind: Task 5 | metadata: 6 | name: github-open-pr 7 | namespace: {{ .Values.namespace }} 8 | labels: 9 | app.kubernetes.io/version: "0.2" 10 | annotations: 11 | tekton.dev/categories: Git 12 | tekton.dev/pipelines.minVersion: "0.12.1" 13 | tekton.dev/tags: github 14 | tekton.dev/displayName: "open github pull request" 15 | tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le" 16 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 17 | spec: 18 | description: >- 19 | This task will open a PR on Github based on several parameters. 20 | This could be useful in GitOps repositories for example. 21 | 22 | params: 23 | - name: GITHUB_HOST_URL 24 | description: | 25 | The GitHub host, adjust this if you run a GitHub enteprise. 26 | default: "api.github.com" 27 | type: string 28 | 29 | - name: API_PATH_PREFIX 30 | description: | 31 | The API path prefix, GitHub Enterprise has a prefix e.g. /api/v3 32 | default: "" 33 | type: string 34 | 35 | - name: REPO_FULL_NAME 36 | description: | 37 | The GitHub repository full name, e.g.: tektoncd/catalog 38 | type: string 39 | 40 | - name: GITHUB_TOKEN_SECRET_NAME 41 | description: | 42 | The name of the kubernetes secret that contains the GitHub token, default: github 43 | type: string 44 | default: github 45 | 46 | - name: GITHUB_TOKEN_SECRET_KEY 47 | description: | 48 | The key within the kubernetes secret that contains the GitHub token, default: token 49 | type: string 50 | default: token 51 | 52 | - name: AUTH_TYPE 53 | description: | 54 | The type of authentication to use. You could use the less secure "Basic" for example 55 | type: string 56 | default: Bearer 57 | 58 | - name: HEAD 59 | description: | 60 | The name of the branch where your changes are implemented. 61 | type: string 62 | 63 | - name: BASE 64 | description: | 65 | The name of the branch you want the changes pulled into. 66 | type: string 67 | 68 | - name: BODY 69 | description: | 70 | The body description of the pull request. 71 | type: string 72 | 73 | - name: TITLE 74 | description: | 75 | The title of the pull request. 76 | type: string 77 | 78 | results: 79 | - name: NUMBER 80 | description: Number of the created pull request. 81 | 82 | - name: URL 83 | description: URL of the created pull request. 84 | 85 | volumes: 86 | - name: githubtoken 87 | secret: 88 | secretName: $(params.GITHUB_TOKEN_SECRET_NAME) 89 | 90 | steps: 91 | - name: open-pr 92 | volumeMounts: 93 | - name: githubtoken 94 | readOnly: true 95 | mountPath: /etc/github-open-pr 96 | env: 97 | - name: PULLREQUEST_NUMBER_PATH 98 | value: $(results.NUMBER.path) 99 | - name: PULLREQUEST_URL_PATH 100 | value: $(results.URL.path) 101 | 102 | image: registry.access.redhat.com/ubi8/python-38:1-34.1599745032 103 | script: | 104 | #!/usr/libexec/platform-python 105 | 106 | """This script will open a PR on Github""" 107 | 108 | import json 109 | import os 110 | import sys 111 | import http.client 112 | 113 | github_token = open("/etc/github-open-pr/$(params.GITHUB_TOKEN_SECRET_KEY)", "r").read() 114 | 115 | open_pr_url = "$(params.API_PATH_PREFIX)" + "/repos/$(params.REPO_FULL_NAME)/pulls" 116 | 117 | data = { 118 | "head": "$(params.HEAD)", 119 | "base": "$(params.BASE)", 120 | "title": "$(params.TITLE)", 121 | "body": """$(params.BODY)""" 122 | } 123 | print("Sending this data to GitHub: ") 124 | print(data) 125 | 126 | authHeader = "$(params.AUTH_TYPE) " + github_token 127 | 128 | # This is for our fake github server 129 | if "$(params.GITHUB_HOST_URL)".startswith("http://"): 130 | conn = http.client.HTTPConnection("$(params.GITHUB_HOST_URL)" 131 | .replace("http://", "")) 132 | else: 133 | conn = http.client.HTTPSConnection("$(params.GITHUB_HOST_URL)") 134 | 135 | conn.request( 136 | "POST", 137 | open_pr_url, 138 | body=json.dumps(data), 139 | headers={ 140 | "User-Agent": "TektonCD, the peaceful cat", 141 | "Authorization": authHeader, 142 | "Accept": "application/vnd.github.v3+json ", 143 | }) 144 | resp = conn.getresponse() 145 | if not str(resp.status).startswith("2"): 146 | print("Error: %d" % (resp.status)) 147 | print(resp.read()) 148 | sys.exit(1) 149 | else: 150 | # https://docs.github.com/en/rest/reference/pulls#create-a-pull-request 151 | body = json.loads(resp.read().decode()) 152 | 153 | open(os.environ.get('PULLREQUEST_NUMBER_PATH'), 'w').write(f'{body["number"]}') 154 | open(os.environ.get('PULLREQUEST_URL_PATH'), 'w').write(body["html_url"]) 155 | 156 | print("GitHub pull request created for $(params.REPO_FULL_NAME): " 157 | f'number={body["number"]} url={body["html_url"]}') 158 | {{ end }} -------------------------------------------------------------------------------- /gitops/cluster-config/templates/pipelines/tekton-task-git-cli.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.pipeline.enabled }} 2 | apiVersion: tekton.dev/v1beta1 3 | kind: Task 4 | metadata: 5 | name: git-cli 6 | namespace: {{ .Values.namespace }} 7 | labels: 8 | app.kubernetes.io/version: "0.3" 9 | annotations: 10 | tekton.dev/pipelines.minVersion: "0.21.0" 11 | tekton.dev/categories: Git 12 | tekton.dev/tags: git 13 | tekton.dev/displayName: "git cli" 14 | tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le" 15 | argocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true 16 | spec: 17 | description: >- 18 | This task can be used to perform git operations. 19 | 20 | Git command that needs to be run can be passed as a script to 21 | the task. This task needs authentication to git in order to push 22 | after the git operation. 23 | 24 | workspaces: 25 | - name: source 26 | description: A workspace that contains the fetched git repository. 27 | 28 | - name: input 29 | optional: true 30 | description: | 31 | An optional workspace that contains the files that need to be added to git. You can 32 | access the workspace from your script using `$(workspaces.input.path)`, for instance: 33 | 34 | cp $(workspaces.input.path)/file_that_i_want . 35 | git add file_that_i_want 36 | # etc 37 | 38 | - name: ssh-directory 39 | optional: true 40 | description: | 41 | A .ssh directory with private key, known_hosts, config, etc. Copied to 42 | the user's home before git commands are executed. Used to authenticate 43 | with the git remote when performing the clone. Binding a Secret to this 44 | Workspace is strongly recommended over other volume types. 45 | 46 | - name: basic-auth 47 | optional: true 48 | description: | 49 | A Workspace containing a .gitconfig and .git-credentials file. These 50 | will be copied to the user's home before any git commands are run. Any 51 | other files in this Workspace are ignored. It is strongly recommended 52 | to use ssh-directory over basic-auth whenever possible and to bind a 53 | Secret to this Workspace over other volume types. 54 | params: 55 | - name: BASE_IMAGE 56 | description: | 57 | The base image for the task. 58 | type: string 59 | default: docker.io/alpine/git:v2.26.2@sha256:23618034b0be9205d9cc0846eb711b12ba4c9b468efdd8a59aac1d7b1a23363f #tag: v2.26.2 60 | 61 | - name: GIT_USER_NAME 62 | type: string 63 | description: | 64 | Git user name for performing git operation. 65 | default: "" 66 | 67 | - name: GIT_USER_EMAIL 68 | type: string 69 | description: | 70 | Git user email for performing git operation. 71 | default: "" 72 | 73 | - name: GIT_SCRIPT 74 | description: The git script to run. 75 | type: string 76 | default: | 77 | git help 78 | 79 | - name: USER_HOME 80 | description: | 81 | Absolute path to the user's home directory. Set this explicitly if you are running the image as a non-root user or have overridden 82 | the gitInitImage param with an image containing custom user configuration. 83 | type: string 84 | default: "/root" 85 | 86 | - name: VERBOSE 87 | description: Log the commands that are executed during `git-clone`'s operation. 88 | type: string 89 | default: "true" 90 | 91 | results: 92 | - name: commit 93 | description: The precise commit SHA after the git operation. 94 | 95 | steps: 96 | - name: git 97 | image: $(params.BASE_IMAGE) 98 | workingDir: $(workspaces.source.path) 99 | env: 100 | - name: PARAM_VERBOSE 101 | value: $(params.VERBOSE) 102 | - name: PARAM_USER_HOME 103 | value: $(params.USER_HOME) 104 | - name: WORKSPACE_OUTPUT_PATH 105 | value: $(workspaces.output.path) 106 | - name: WORKSPACE_SSH_DIRECTORY_BOUND 107 | value: $(workspaces.ssh-directory.bound) 108 | - name: WORKSPACE_SSH_DIRECTORY_PATH 109 | value: $(workspaces.ssh-directory.path) 110 | - name: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND 111 | value: $(workspaces.basic-auth.bound) 112 | - name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH 113 | value: $(workspaces.basic-auth.path) 114 | script: | 115 | #!/usr/bin/env sh 116 | set -eu 117 | 118 | if [ "${PARAM_VERBOSE}" = "true" ] ; then 119 | set -x 120 | fi 121 | 122 | if [ "${WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND}" = "true" ] ; then 123 | cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" "${PARAM_USER_HOME}/.git-credentials" 124 | cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" "${PARAM_USER_HOME}/.gitconfig" 125 | chmod 400 "${PARAM_USER_HOME}/.git-credentials" 126 | chmod 400 "${PARAM_USER_HOME}/.gitconfig" 127 | fi 128 | 129 | if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then 130 | cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh 131 | chmod 700 "${PARAM_USER_HOME}"/.ssh 132 | chmod -R 400 "${PARAM_USER_HOME}"/.ssh/* 133 | fi 134 | 135 | # Setting up the config for the git. 136 | git config --global user.email "$(params.GIT_USER_EMAIL)" 137 | git config --global user.name "$(params.GIT_USER_NAME)" 138 | 139 | $(params.GIT_SCRIPT) 140 | 141 | RESULT_SHA="$(git rev-parse HEAD | tr -d '\n')" 142 | EXIT_CODE="$?" 143 | if [ "$EXIT_CODE" != 0 ] 144 | then 145 | exit $EXIT_CODE 146 | fi 147 | # Make sure we don't add a trailing newline to the result! 148 | echo -n "$RESULT_SHA" > $(results.commit.path) 149 | {{ end }} -------------------------------------------------------------------------------- /blue-green-pipeline/util/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #./test.sh si rollouts no github_pat_XXXXXXXXXXXXXXX 4 | 5 | # oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 6 | # Add Argo CD Git Webhook to make it faster 7 | 8 | waitpodup(){ 9 | x=1 10 | test="" 11 | while [ -z "${test}" ] 12 | do 13 | echo "Waiting ${x} times for pod ${1} in ns ${2}" $(( x++ )) 14 | sleep 1 15 | test=$(oc get po -n ${2} | grep ${1}) 16 | done 17 | } 18 | 19 | waitoperatorpod() { 20 | NS=openshift-operators 21 | waitpodup $1 ${NS} 22 | oc get pods -n ${NS} | grep ${1} | awk '{print "oc wait --for condition=Ready -n '${NS}' pod/" $1 " --timeout 300s"}' | sh 23 | } 24 | 25 | rm -rf /tmp/deployment 26 | mkdir /tmp/deployment 27 | cd /tmp/deployment 28 | 29 | git clone https://github.com/davidseve/cloud-native-deployment-strategies.git 30 | cd cloud-native-deployment-strategies 31 | 32 | if [ ${2:-no} != "no" ] 33 | then 34 | git fetch 35 | git switch $2 36 | fi 37 | git checkout -b blue-green 38 | git push origin blue-green 39 | 40 | if [ ${3:-no} = "no" ] 41 | then 42 | oc apply -f gitops/gitops-operator.yaml 43 | waitoperatorpod gitops 44 | sleep 30s 45 | sed -i "s/changeme_token/$4/g" blue-green-pipeline/application-cluster-config.yaml 46 | sed -i 's/changeme_user/davidseve/g' blue-green-pipeline/application-cluster-config.yaml 47 | sed -i 's/changeme_mail/davidseve@gmail.com/g' blue-green-pipeline/application-cluster-config.yaml 48 | sed -i 's/changeme_repository/davidseve/g' blue-green-pipeline/application-cluster-config.yaml 49 | 50 | if [ ${2:-no} != "no" ] 51 | then 52 | sed -i "s/HEAD/$2/g" blue-green-pipeline/application-cluster-config.yaml 53 | fi 54 | oc apply -f blue-green-pipeline/application-cluster-config.yaml --wait=true 55 | 56 | #First time we install operators take logger 57 | if [ ${1:-no} = "no" ] 58 | then 59 | sleep 2m 60 | else 61 | sleep 3m 62 | fi 63 | 64 | fi 65 | 66 | sed -i 's/change_me/davidseve/g' blue-green-pipeline/application-shop-blue-green.yaml 67 | 68 | oc apply -f blue-green-pipeline/application-shop-blue-green.yaml --wait=true 69 | sleep 1m 70 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 71 | 72 | cd blue-green-pipeline/pipelines/run-products 73 | oc create -f 1-pipelinerun-products-new-version.yaml -n gitops 74 | 75 | oc get service products-umbrella-offline -n gitops --output="jsonpath={.spec.selector.version}" > color 76 | replicas=-1 77 | while [ $replicas != 0 ] 78 | do 79 | sleep 5 80 | replicas=$(oc get deployments products-$(cat color) -n gitops --output="jsonpath={.spec.replicas}" 2>&1) 81 | echo $replicas 82 | done 83 | while [ $replicas != 2 ] 84 | do 85 | sleep 5 86 | replicas=$(oc get deployments products-$(cat color) -n gitops --output="jsonpath={.spec.replicas}" 2>&1) 87 | echo $replicas 88 | 89 | done 90 | 91 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=online --param MODE=offline --param LABEL=.mode --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.products[0].discountInfo.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 92 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=offline --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 93 | 94 | oc create -f 2-pipelinerun-products-switch.yaml -n gitops 95 | sleep 20s 96 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 97 | 98 | #Rollback 99 | oc create -f 2-pipelinerun-products-switch-rollback.yaml -n gitops 100 | sleep 20s 101 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 102 | 103 | 104 | oc create -f 2-pipelinerun-products-switch.yaml -n gitops 105 | sleep 20s 106 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 107 | 108 | 109 | oc create -f 3-pipelinerun-products-scale-down.yaml -n gitops 110 | sleep 30s 111 | 112 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=online --param MODE=online --param LABEL=.mode --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.products[0].discountInfo.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 113 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=offline --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 114 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param MESH=False --param JQ_PATH=.metadata --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 115 | 116 | 117 | -------------------------------------------------------------------------------- /canary-service-mesh/util/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | #./test.sh si rollouts no rollouts.sandbox2653.opentlc.com 4 | 5 | # oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 6 | # Add Argo CD Git Webhook to make it faster 7 | 8 | waitpodup(){ 9 | x=1 10 | test="" 11 | while [ -z "${test}" ] 12 | do 13 | echo "Waiting ${x} times for pod ${1} in ns ${2}" $(( x++ )) 14 | sleep 1 15 | test=$(oc get po -n ${2} | grep ${1}) 16 | done 17 | } 18 | 19 | waitoperatorpod() { 20 | NS=openshift-operators 21 | waitpodup $1 ${NS} 22 | oc get pods -n ${NS} | grep ${1} | awk '{print "oc wait --for condition=Ready -n '${NS}' pod/" $1 " --timeout 300s"}' | sh 23 | } 24 | 25 | waitjaegerpod() { 26 | NS=openshift-distributed-tracing 27 | waitpodup $1 ${NS} 28 | oc get pods -n ${NS} | grep ${1} | awk '{print "oc wait --for condition=Ready -n '${NS}' pod/" $1 " --timeout 300s"}' | sh 29 | } 30 | 31 | rm -rf /tmp/deployment 32 | mkdir /tmp/deployment 33 | cd /tmp/deployment 34 | 35 | git clone https://github.com/davidseve/cloud-native-deployment-strategies.git 36 | cd cloud-native-deployment-strategies 37 | #To work with a branch that is not main. ./test.sh no helm_base 38 | if [ ${2:-no} != "no" ] 39 | then 40 | git fetch 41 | git switch $2 42 | fi 43 | git checkout -b canary-mesh 44 | git push origin canary-mesh 45 | 46 | if [ ${3:-no} = "no" ] 47 | then 48 | oc apply -f gitops/gitops-operator.yaml 49 | waitoperatorpod gitops 50 | 51 | #To work with a branch that is not main. ./test.sh no helm_base no rollouts.sandbox2229.opentlc.com 52 | if [ ${2:-no} != "no" ] 53 | then 54 | sed -i "s/HEAD/$2/g" canary-service-mesh/application-cluster-config.yaml 55 | fi 56 | 57 | sed -i '/pipeline.enabled/{n;s/.*/ value: "true"/}' canary-service-mesh/application-cluster-config.yaml 58 | 59 | oc apply -f canary-service-mesh/application-cluster-config.yaml --wait=true 60 | 61 | sleep 4m 62 | waitjaegerpod jaeger 63 | waitoperatorpod kiali 64 | waitoperatorpod istio 65 | fi 66 | 67 | 68 | sed -i 's/change_me/davidseve/g' canary-service-mesh/application-shop-mesh.yaml 69 | sed -i "s/change_domain/$4/g" canary-service-mesh/application-shop-mesh.yaml 70 | 71 | oc apply -f canary-service-mesh/application-shop-mesh.yaml --wait=true 72 | sleep 30 73 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param JQ_PATH=.metadata --param MESH=true --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 74 | 75 | #Deploy products v1.1.1 with 10% traffic 76 | sed -i '/ productsblueWeight: 100/{s/.*/ productsblueWeight: 90/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 77 | sed -i '/ productsgreenWeight: 0/{s/.*/ productsgreenWeight: 10/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 78 | sed -i '/products-green:/{n;n;s/.*/ replicaCount: 1/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 79 | 80 | git add helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 81 | git commit -m "Deploy products v1.1.1 with 10% traffic" 82 | git push origin canary-mesh 83 | sleep 30 84 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param JQ_PATH=.metadata --param MESH=true --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 85 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param JQ_PATH=.metadata --param MESH=true --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 86 | 87 | #Deploy products v1.1.1 with 50% traffic 88 | sed -i '/ productsblueWeight: 90/{s/.*/ productsblueWeight: 50/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 89 | sed -i '/ productsgreenWeight: 10/{s/.*/ productsgreenWeight: 50/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 90 | sed -i '/products-green:/{n;n;s/.*/ replicaCount: 2/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 91 | sed -i '/products-blue:/{n;n;s/.*/ replicaCount: 2/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 92 | 93 | git add helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 94 | git commit -m "Deploy products v1.1.1 with 50% traffic" 95 | git push origin canary-mesh 96 | sleep 30 97 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.0.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param JQ_PATH=.metadata --param MESH=true --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 98 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param JQ_PATH=.metadata --param MESH=true --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 99 | 100 | #Delete product v1.0.1 101 | sed -i '/ productsblueWeight: 50/{s/.*/ productsblueWeight: 0/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 102 | sed -i '/ productsgreenWeight: 50/{s/.*/ productsgreenWeight: 100/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 103 | sed -i '/products-green:/{n;n;s/.*/ replicaCount: 4/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 104 | sed -i '/products-blue:/{n;n;s/.*/ replicaCount: 0/}' helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 105 | 106 | git add helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml 107 | git commit -m "Delete product v1.0.1" 108 | git push origin canary-mesh 109 | sleep 30 110 | tkn pipeline start pipeline-blue-green-e2e-test --param NEW_IMAGE_TAG=v1.1.1 --param MODE=online --param LABEL=.version --param APP=products --param NAMESPACE=gitops --param JQ_PATH=.metadata --param MESH=true --workspace name=app-source,claimName=workspace-pvc-shop-cd-e2e-tests -n gitops --showlog 111 | 112 | -------------------------------------------------------------------------------- /helm/quarkus-helm-umbrella/chart/templates/istio.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.global.istio.enabled }} 2 | --- 3 | apiVersion: networking.istio.io/v1alpha3 4 | kind: Gateway 5 | metadata: 6 | name: {{ include "shop.fullname" $ }}-products-gateway 7 | labels: 8 | {{- include "shop.labels" . | nindent 4 }} 9 | spec: 10 | selector: 11 | istio: ingressgateway # use istio default controller 12 | servers: 13 | - port: 14 | number: 80 15 | name: http 16 | protocol: HTTP 17 | hosts: 18 | - {{ include "shop.fullname" $ }}-products-route-istio-system.apps.{{ .Values.domain }} 19 | --- 20 | apiVersion: networking.istio.io/v1alpha3 21 | kind: VirtualService 22 | metadata: 23 | name: {{ include "shop.fullname" $ }}-vs-products 24 | labels: 25 | {{- include "shop.labels" . | nindent 4 }} 26 | spec: 27 | gateways: 28 | - {{ include "shop.fullname" $ }}-products-gateway 29 | hosts: 30 | - {{ include "shop.fullname" $ }}-products-route-istio-system.apps.{{ .Values.domain }} 31 | http: 32 | - name: primary # referenced in canary.trafficRouting.istio.virtualService.routes 33 | route: 34 | {{- if .Values.global.istio.rollouts.enabled }} 35 | - destination: 36 | host: {{ .Values.productsNetworkingOnline.fullnameOverride }}.{{ .Values.global.namespace }}.svc.cluster.local 37 | subset: stable 38 | weight: 100 39 | - destination: 40 | host: {{ .Values.productsNetworkingOnline.fullnameOverride }}.{{ .Values.global.namespace }}.svc.cluster.local 41 | subset: canary 42 | weight: 0 43 | {{ else}} 44 | - destination: 45 | host: {{ .Values.productsNetworkingOnline.fullnameOverride }}.{{ .Values.global.namespace }}.svc.cluster.local 46 | subset: blue 47 | weight: {{ .Values.global.istio.productsblueWeight}} 48 | - destination: 49 | host: {{ .Values.productsNetworkingOnline.fullnameOverride }}.{{ .Values.global.namespace }}.svc.cluster.local 50 | subset: green 51 | weight: {{ .Values.global.istio.productsgreenWeight}} 52 | {{ end }} 53 | --- 54 | apiVersion: networking.istio.io/v1beta1 55 | kind: DestinationRule 56 | metadata: 57 | name: {{ include "shop.fullname" $ }}-products-rule 58 | labels: 59 | {{- include "shop.labels" . | nindent 4 }} 60 | spec: 61 | host: {{ .Values.productsNetworkingOnline.fullnameOverride }} 62 | subsets: 63 | {{- if .Values.global.istio.rollouts.enabled }} 64 | - name: canary 65 | labels: 66 | app: products 67 | - name: stable 68 | labels: 69 | app: products 70 | {{ else}} 71 | - name: blue 72 | labels: 73 | version: blue 74 | - name: green 75 | labels: 76 | version: green 77 | {{ end }} 78 | --- 79 | apiVersion: networking.istio.io/v1alpha3 80 | kind: Gateway 81 | metadata: 82 | name: {{ include "shop.fullname" $ }}-discounts-gateway 83 | labels: 84 | {{- include "shop.labels" . | nindent 4 }} 85 | spec: 86 | selector: 87 | istio: ingressgateway # use istio default controller 88 | servers: 89 | - port: 90 | number: 80 91 | name: http 92 | protocol: HTTP 93 | hosts: 94 | - {{ include "shop.fullname" $ }}-discounts-route-istio-system.apps.{{ .Values.domain }} 95 | --- 96 | apiVersion: networking.istio.io/v1alpha3 97 | kind: VirtualService 98 | metadata: 99 | name: {{ include "shop.fullname" $ }}-vs-discounts 100 | labels: 101 | {{- include "shop.labels" . | nindent 4 }} 102 | spec: 103 | gateways: 104 | - {{ include "shop.fullname" $ }}-discounts-gateway 105 | - mesh #intramesh traffic 106 | hosts: 107 | - {{ include "shop.fullname" $ }}-discounts-route-istio-system.apps.{{ .Values.domain }} 108 | - {{ .Values.discountsNetworkingOnline.fullnameOverride }}.{{ .Values.global.namespace }}.svc.cluster.local #intramesh traffic 109 | http: 110 | - name: primary # referenced in canary.trafficRouting.istio.virtualService.routes 111 | route: 112 | {{- if .Values.global.istio.rollouts.enabled }} 113 | - destination: 114 | host: {{ .Values.discountsNetworkingOnline.fullnameOverride }}.{{ .Values.global.namespace }}.svc.cluster.local 115 | subset: stable 116 | weight: 100 117 | - destination: 118 | host: {{ .Values.discountsNetworkingOnline.fullnameOverride }}.{{ .Values.global.namespace }}.svc.cluster.local 119 | subset: canary 120 | weight: 0 121 | {{ else}} 122 | - destination: 123 | host: {{ .Values.discountsNetworkingOnline.fullnameOverride }}.{{ .Values.global.namespace }}.svc.cluster.local 124 | subset: blue 125 | weight: {{ .Values.global.istio.discountsblueWeight}} 126 | - destination: 127 | host: {{ .Values.discountsNetworkingOnline.fullnameOverride }}.{{ .Values.global.namespace }}.svc.cluster.local 128 | subset: green 129 | weight: {{ .Values.global.istio.discountsgreenWeight}} 130 | {{ end }} 131 | --- 132 | apiVersion: networking.istio.io/v1beta1 133 | kind: DestinationRule 134 | metadata: 135 | name: {{ include "shop.fullname" $ }}-discounts-rule 136 | labels: 137 | {{- include "shop.labels" . | nindent 4 }} 138 | spec: 139 | host: {{ .Values.discountsNetworkingOnline.fullnameOverride }} 140 | subsets: 141 | {{- if .Values.global.istio.rollouts.enabled }} 142 | - name: canary 143 | labels: 144 | app: discounts 145 | - name: stable 146 | labels: 147 | app: discounts 148 | {{ else}} 149 | - name: blue 150 | labels: 151 | version: blue 152 | - name: green 153 | labels: 154 | version: green 155 | {{ end }} 156 | --- 157 | apiVersion: route.openshift.io/v1 158 | kind: Route 159 | metadata: 160 | name: {{ include "shop.fullname" $ }}-discounts-route 161 | namespace: istio-system 162 | spec: 163 | to: 164 | kind: Service 165 | name: istio-ingressgateway 166 | tls: 167 | termination: edge 168 | insecureEdgeTerminationPolicy: Redirect 169 | port: 170 | targetPort: http2 171 | --- 172 | apiVersion: route.openshift.io/v1 173 | kind: Route 174 | metadata: 175 | name: {{ include "shop.fullname" $ }}-products-route 176 | namespace: istio-system 177 | spec: 178 | to: 179 | kind: Service 180 | name: istio-ingressgateway 181 | tls: 182 | termination: edge 183 | insecureEdgeTerminationPolicy: Redirect 184 | port: 185 | targetPort: http2 186 | {{ end }} 187 | -------------------------------------------------------------------------------- /canary-service-mesh/README.md: -------------------------------------------------------------------------------- 1 | # Cloud Native Canary Deployment Strategy using Openshift Service Mesh 2 | 3 | ## Introduction 4 | 5 | A critical topic in `Cloud Native` is the `Microservice Architecture`. We are no longer dealing with one monolithic application. We have several applications that have dependencies on each other and also have other dependencies like brokers or databases. 6 | 7 | Applications have their own life cycle, so we should be able to execute independent canary deployment. All the applications and dependencies will not change their version at the same time. 8 | 9 | Another important topic in the `Cloud Native` is `Continuous Delivery`. If we are going to have several applications doing canary deployment independently we have to automate it. We will use **Helm**, **Openshift Service Mesh**, **Openshift GitOps**, and of course **Red Hat Openshift** to help us. 10 | 11 | **In the next steps, we will see a real example of how to install, deploy and manage the life cycle of Cloud Native applications doing canary deployment using Openshift Service Mesh.** 12 | 13 | Let's start with some theory...after that, we will have a **hands-on example**. 14 | 15 | ## Canary Deployment 16 | 17 | A canary deployment is a strategy where the operator releases a new version of their application to a small percentage of the production traffic. This small percentage may test the new version and provide feedback. If the new version is working well the operator may increase the percentage, till all the traffic is using the new version. Unlike Blue/Green, canary deployments are smoother, and failures have limited impact. 18 | 19 | ## Shop application 20 | 21 | We are going to use very simple applications to test canary deployment. We have created two Quarkus applications `Products` and `Discounts` 22 | 23 | ![Shop Application](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/Shop.png) 24 | 25 | `Products` call `Discounts` to get the product`s discount and expose an API with a list of products with its discounts. 26 | 27 | ## Shop Canary 28 | 29 | To achieve canary deployment with `Cloud Native` applications using **Openshift Service Mesh**, we have designed this architecture. This is a simplification. 30 | 31 | ![Shop initial status](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/canary-mesh-initial.png) 32 | 33 | OpenShift Components - Online 34 | 35 | - Route, Gateway and Virtual Services. 36 | - Services mapped to the deployment. 37 | 38 | In Blue/Green deployment we always have an offline service to test the version that is not in production. In the case of canary deployment we do not need it because progressively we will have the new version in production. 39 | 40 | 41 | We have defined an active or online service 'products-umbrella-online'. The final user will always use 'products-umbrella-online'. When a new version is deployed **Openshift Service Mesh** will send the amount of traffic that has been defined in the Virtual Service. We have to take care of the number of replicas in the new release and the old release, based on the amount of traffic that we have defined in the Virtual Service. 42 | 43 | ## Shop Umbrella Helm Chart 44 | 45 | One of the best ways to package `Cloud Native` applications is `Helm`. In canary deployment, it makes even more sense. 46 | We have created a chart for each application that does not know anything about canary deployment. Then we pack everything together in an umbrella helm chart. 47 | 48 | ## Demo!! 49 | 50 | ### Prerequisites: 51 | 52 | - **Red Hat Openshift 4.16** with admin rights. 53 | - You can download [Red Hat Openshift Local for OCP 4.16](https://developers.redhat.com/content-gateway/rest/mirror/pub/openshift-v4/clients/crc/2.6.0). 54 | - [Getting Started Guide](https://access.redhat.com/documentation/en-us/red_hat_openshift_local/2.5/html/getting_started_guide/using_gsg) 55 | - [Git](https://git-scm.com/) 56 | - [GitHub account](https://github.com/) 57 | - [oc 4.16 CLI] (https://docs.openshift.com/container-platform/4.16/cli_reference/openshift_cli/getting-started-cli.html) 58 | 59 | We have a GitHub [repository](https://github.com/davidseve/cloud-native-deployment-strategies) for this demo. As part of the demo, you will have to make some changes and commits. So **it is important that you fork the repository and clone it in your local**. 60 | 61 | ``` 62 | git clone https://github.com/your_user/cloud-native-deployment-strategies 63 | ``` 64 | 65 | ### Install OpenShift GitOps 66 | 67 | Go to the folder where you have cloned your forked repository and create a new branch `canary-mesh` 68 | ``` 69 | git checkout -b canary-mesh 70 | git push origin canary-mesh 71 | ``` 72 | 73 | Log into OpenShift as a cluster admin and install the OpenShift GitOps operator with the following command. This may take some minutes. 74 | ``` 75 | oc apply -f gitops/gitops-operator.yaml 76 | ``` 77 | 78 | Once OpenShift GitOps is installed, an instance of Argo CD is automatically installed on the cluster in the `openshift-gitops` namespace and a link to this instance is added to the application launcher in OpenShift Web Console. 79 | 80 | ![Application Launcher](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/gitops-link.png) 81 | 82 | ### Log into the Argo CD dashboard 83 | 84 | Argo CD upon installation generates an initial admin password which is stored in a Kubernetes secret. To retrieve this password, run the following command to decrypt the admin password: 85 | 86 | ``` 87 | oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 88 | ``` 89 | 90 | Click on Argo CD from the OpenShift Web Console application launcher and then log into Argo CD with `admin` username and the password retrieved from the previous step. 91 | 92 | ![Argo CD](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/ArgoCD-login.png) 93 | 94 | ![Argo CD](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/ArgoCD-UI.png) 95 | 96 | ### Configure OpenShift with Argo CD 97 | 98 | We are going to follow, as much as we can, a GitOps methodology in this demo. So we will have everything in our Git repository and use **ArgoCD** to deploy it in the cluster. 99 | 100 | In the current Git repository, the [gitops/cluster-config](https://github.com/davidseve/cloud-native-deployment-strategies/tree/main/gitops/cluster-config) directory contains OpenShift cluster configurations such as: 101 | 102 | - namespaces `gitops`. 103 | - role binding for ArgoCD to the namespace `gitops`. 104 | - **OpenShift Service Mesh** 105 | - **Kiali Operator** 106 | - **OpenShift Elasticsearch Operator** 107 | - **Red Hat OpenShift distributed tracing platform** 108 | 109 | Let's configure Argo CD to recursively sync the content of the [gitops/cluster-config](https://github.com/davidseve/cloud-native-deployment-strategies/tree/main/gitops/cluster-config) directory into the OpenShift cluster. 110 | 111 | Execute this command to add a new Argo CD application that syncs a Git repository containing cluster configurations with the OpenShift cluster. 112 | 113 | ``` 114 | oc apply -f canary-service-mesh/application-cluster-config.yaml 115 | ``` 116 | 117 | Looking at the Argo CD dashboard, you will notice that an application has been created. 118 | 119 | You can click on the `cluster-configuration` application to check the details of sync resources and their status on the cluster. 120 | 121 | ### Create Shop application 122 | 123 | We are going to create the application `shop`, that we will use to test canary deployment. Because we will make changes in the application's GitHub repository, we have to use the repository that you have just forked. Please edit the file `canary-service-mesh/application-shop-mesh.yaml` and set your own GitHub repository in the `reportURL` and the OCP cluster domain in `change_domain`. 124 | 125 | ```yaml 126 | apiVersion: argoproj.io/v1alpha1 127 | kind: Application 128 | metadata: 129 | name: shop 130 | namespace: openshift-gitops 131 | spec: 132 | destination: 133 | name: '' 134 | namespace: gitops 135 | server: 'https://kubernetes.default.svc' 136 | source: 137 | path: helm/quarkus-helm-umbrella/chart 138 | repoURL: https://github.com/change_me/cloud-native-deployment-strategies.git 139 | targetRevision: canary-mesh 140 | helm: 141 | valueFiles: 142 | - values/values-mesh.yaml 143 | parameters: 144 | - name: "global.namespace" 145 | value: gitops 146 | - name: "domain" 147 | value: "change_domain" 148 | project: default 149 | syncPolicy: 150 | automated: 151 | prune: true 152 | selfHeal: true 153 | 154 | ``` 155 | 156 | ``` 157 | oc apply -f canary-service-mesh/application-shop-mesh.yaml 158 | ``` 159 | 160 | Looking at the Argo CD dashboard, you will notice that we have a new `shop` application. 161 | 162 | 163 | ## Test Shop application 164 | 165 | We have deployed the `shop` with ArgoCD. We can test that it is up and running. 166 | 167 | We have to get the route that we have created. 168 | ``` 169 | oc get routes shop-umbrella-products-route -n istio-system --template='https://{{.spec.host}}/products' 170 | ``` 171 | 172 | Notice that in each microservice response, we have added metadata information to see better the `version` of each application. This will help us to see the changes while we do the canary deployment. 173 | We can see that the current version is `v1.0.1`: 174 | ```json 175 | { 176 | "products":[ 177 | { 178 | ... 179 | "name":"TV 4K", 180 | "price":"1500€" 181 | } 182 | ], 183 | "metadata":{ 184 | "version":"v1.0.1", <-- 185 | "colour":"none", 186 | "mode":"online" 187 | } 188 | } 189 | ``` 190 | ## Products Canary deployment 191 | 192 | We have already deployed the products version v1.0.1 with 2 replicas, and we are ready to use a new products version v1.1.1 that has a new `description` attribute. 193 | 194 | This is our current status: 195 | ![Shop initial status](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/canary-mesh-step-0.png) 196 | 197 | We have split a `Cloud Native` Canary deployment into three automatic step: 198 | 199 | 1. Deploy canary version for 10% 200 | 2. Scale canary version to 50% 201 | 3. Scale canary version to 100% 202 | 203 | This is just an example. The key point here is that, very easily we can have the canary deployment that better fits our needs. 204 | 205 | ### Step 1 - Deploy canary version for 10% 206 | 207 | We will deploy a new version v1.1.1. To do it, we have already configured products-green with the new version v1.1.1. And we have to edit the file `helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml` and do some changes: 208 | 209 | 1. In `global.istio` change the weight to send 10% of the traffic to the new version. 210 | 211 | ```yaml 212 | global: 213 | istio: 214 | productsblueWeight: 90 215 | productsgreenWeight: 10 216 | ``` 217 | 218 | 2. Increase the number of replicas to be able to support 10% of the traffic in the new version. 219 | 220 | ```yaml 221 | products-green: 222 | quarkus-base: 223 | replicaCount: 1 224 | ``` 225 | 226 | Push the changes to start the deployment. 227 | ``` 228 | git add . 229 | git commit -m "Deploy products v1.1.1 with 10% traffic" 230 | git push origin canary-mesh 231 | ``` 232 | 233 | ArgoCD will refresh the status after some minutes. If you don't want to wait you can refresh it manually from ArgoCD UI or configure the Argo CD Git Webhook.[^note2]. 234 | 235 | [^note2]: 236 | Here you can see how to configure the Argo CD Git [Webhook]( https://argo-cd.readthedocs.io/en/stable/operator-manual/webhook/) 237 | ![Argo CD Git Webhook](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/ArgoCD-webhook.png) 238 | 239 | This is our current status: 240 | ![Shop Step 1](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/canary-mesh-step-1.png) 241 | 242 | 243 | In the products url`s response you will have the new version in 10% of the requests. 244 | 245 | New revision: 246 | ```json 247 | { 248 | "products":[ 249 | { 250 | "discountInfo":{...}, 251 | "name":"TV 4K", 252 | "price":"1500€", 253 | "description":"The best TV" <-- 254 | } 255 | ], 256 | "metadata":{ 257 | "version":"v1.1.1", <-- 258 | } 259 | } 260 | ``` 261 | 262 | Old revision: 263 | ```json 264 | { 265 | "products":[ 266 | { 267 | "discountInfo":{...}, 268 | "name":"TV 4K", 269 | "price":"1500€" 270 | } 271 | ], 272 | "metadata":{ 273 | "version":"v1.0.1", <-- 274 | } 275 | } 276 | ``` 277 | ### Step 2 - Scale canary version to 50% 278 | 279 | Now we have to make the changes to send 50% of the traffic to the new version v1.1.1. We have to edit the file `helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml`. 280 | 281 | 1. In `global.istio` change the weight to send 50% of the traffic to the new version. 282 | 283 | ```yaml 284 | global: 285 | istio: 286 | productsblueWeight: 50 287 | productsgreenWeight: 50 288 | ``` 289 | 290 | 2. Increase the number of replicas to be able to support 50% of the traffic in the new version. 291 | 292 | ```yaml 293 | products-green: 294 | quarkus-base: 295 | replicaCount: 2 296 | ``` 297 | 298 | Push the changes to start the deployment. 299 | ``` 300 | git add . 301 | git commit -m "Deploy products v1.1.1 with 50% traffic" 302 | git push origin canary-mesh 303 | ``` 304 | 305 | This is our current status: 306 | ![Shop Step 2](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/canary-mesh-step-2.png) 307 | 308 | In the products url`s response, you will have the new version in 50% of the requests. 309 | 310 | 311 | ### Step 3 - Scale canary version to 100% 312 | 313 | Now we have to make the changes to send 100% of the traffic to the new version v1.1.1. We have to edit the file `helm/quarkus-helm-umbrella/chart/values/values-mesh.yaml`. 314 | 315 | 1. In `global.istio` change the weight to send 50% of the traffic to the new version. 316 | 317 | ```yaml 318 | global: 319 | istio: 320 | productsblueWeight: 0 321 | productsgreenWeight: 100 322 | ``` 323 | 324 | 2. We can decrease the number of replicas in the old version because it will not receive traffic. 325 | 326 | ```yaml 327 | products-blue: 328 | quarkus-base: 329 | replicaCount: 0 330 | ``` 331 | 332 | Push the changes to start the deployment. 333 | ``` 334 | git add . 335 | git commit -m "Delete product v1.0.1" 336 | git push origin canary-mesh 337 | ``` 338 | This is our current status: 339 | ![Shop Step 3](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/canary-mesh-step-3.png) 340 | 341 | In the products url`s response, you will only have the new version v1.1.1!!! 342 | ```json 343 | { 344 | "products":[ 345 | { 346 | "discountInfo":{...}, 347 | "name":"TV 4K", 348 | "price":"1500€", 349 | "description":"The best TV" <-- 350 | } 351 | ], 352 | "metadata":{ 353 | "version":"v1.1.1", <-- 354 | } 355 | } 356 | ``` 357 | 358 | ## Delete environment 359 | 360 | To delete all the things that we have done for the demo you have to: 361 | 362 | - In GitHub delete the branch `canary-mesh` 363 | - In ArgoCD delete the application `cluster-configuration` and `shop` 364 | - In Openshift, go to project `openshift-operators` and delete the installed operators **Openshift GitOps**, **OpenShift Service Mesh**, **Kiali Operator**, **OpenShift Elasticsearch Operator**, **Red Hat OpenShift distributed tracing platform** 365 | 366 | 367 | -------------------------------------------------------------------------------- /canary-argo-rollouts-service-mesh/README.md: -------------------------------------------------------------------------------- 1 | # Cloud Native Canary Deployment Strategy using Argo Rollouts with Openshift Service Mesh 2 | 3 | ## Introduction 4 | 5 | A critical topic in `Cloud Native` is the `Microservice Architecture`. We are no longer dealing with one monolithic application. We have several applications that have dependencies on each other and also have other dependencies like brokers or databases. 6 | 7 | Applications have their own life cycle, so we should be able to execute independent canary deployment. All the applications and dependencies will not change their version at the same time. 8 | 9 | Another important topic in the `Cloud Native` is `Continuous Delivery`. If we are going to have several applications doing canary deployment independently we have to automate it. We will use **Helm**, **Argo Rollouts**, **Openshift Service Mesh**, **Openshift GitOps**, and of course **Red Hat Openshift** to help us. 10 | 11 | [**Argo Rollouts**](https://argoproj.github.io/argo-rollouts/) is a Kubernetes controller and set of CRDs which provide advanced deployment capabilities such as blue-green, canary, canary analysis, experimentation, and progressive delivery features to Kubernetes. 12 | In this demo we are going to use canary capabilities. 13 | 14 | **In the next steps, we will see a real example of how to install, deploy and manage the life cycle of Cloud Native applications doing canary deployment using Argo Rollouts and Openshift Service Mesh.** 15 | 16 | Let's start with some theory...after that, we will have a **hands-on example**. 17 | 18 | ## Canary Deployment 19 | 20 | A canary deployment is a strategy where the operator releases a new version of their application to a small percentage of the production traffic. This small percentage may test the new version and provide feedback. If the new version is working well the operator may increase the percentage, till all the traffic is using the new version. Unlike Blue/Green, canary deployments are smoother, and failures have limited impact. 21 | 22 | ## Shop application 23 | 24 | We are going to use very simple applications to test canary deployment. We have created two Quarkus applications `Products` and `Discounts` 25 | 26 | ![Shop Application](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/Shop.png) 27 | 28 | `Products` call `Discounts` to get the product`s discount and expose an API with a list of products with its discounts. 29 | 30 | ## Shop Canary 31 | 32 | To achieve canary deployment with `Cloud Native` applications using **Argo Rollouts** and **Openshift Service Mesh**, we have designed this architecture. This is a simplification. 33 | 34 | ![Shop initial status](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/canary-rollout-mesh-initial.png) 35 | 36 | OpenShift Components - Online 37 | 38 | - Route, Gateway and Virtual Services. 39 | - Services mapped to the rollout. 40 | 41 | In Blue/Green deployment we always have an offline service to test the version that is not in production. In the case of canary deployment we do not need it because progressively we will have the new version in production. 42 | 43 | 44 | We have defined an active or online service 'products-umbrella-online'. The final user will always use 'products-umbrella-online'. When a new version is deployed **Argo Rollouts** create a new revision (ReplicaSet). The number of replicas in the new release increases based on the information in the steps, the number of replicas in the old release decreases in the same number. **Argo Rollouts** will also automatically change in the Virtual Service, the amount of traffic that is sent to each revision. We have configured a pause duration between each step. To learn more about **Argo Rollouts**, please read [this](https://argoproj.github.io/argo-rollouts/features/canary/). 45 | 46 | 47 | ## Shop Umbrella Helm Chart 48 | 49 | One of the best ways to package `Cloud Native` applications is `Helm`. In canary deployment it makes even more sense. 50 | We have created a chart for each application that does not know anything about canary. Then we pack everything together in an umbrella helm chart. 51 | 52 | ![Shop Umbrella Helm Chart](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/Shop-helm-canary-rollouts.png) 53 | 54 | In the `Shop Umbrella Chart` we use several times the same charts as helm dependencies but with different names. 55 | 56 | We have packaged both applications in one chart, but we may have different umbrella charts per application. 57 | 58 | ## Demo!! 59 | 60 | ### Prerequisites: 61 | 62 | - **Red Hat Openshift 4.16** with admin rights. 63 | - You can download [Red Hat Openshift Local for OCP 4.16](https://developers.redhat.com/content-gateway/rest/mirror/pub/openshift-v4/clients/crc/2.6.0). 64 | - [Getting Started Guide](https://access.redhat.com/documentation/en-us/red_hat_openshift_local/2.5/html/getting_started_guide/using_gsg) 65 | - [Git](https://git-scm.com/) 66 | - [GitHub account](https://github.com/) 67 | - [oc 4.16 CLI](https://docs.openshift.com/container-platform/4.16/cli_reference/openshift_cli/getting-started-cli.html) 68 | - [Argo Rollouts CLI](https://argoproj.github.io/argo-rollouts/installation/#kubectl-plugin-installation ) 69 | 70 | We have a GitHub [repository](https://github.com/davidseve/cloud-native-deployment-strategies) for this demo. As part of the demo, you will have to do some changes and commits. So **it is important that you fork the repository and clone it in your local**. 71 | 72 | ``` 73 | git clone https://github.com/your_user/cloud-native-deployment-strategies 74 | ``` 75 | 76 | If we want to have a `Cloud Native` deployment we can not forget `CI/CD`. **Red Hat OpenShift GitOps** will help us. 77 | 78 | ### Install OpenShift GitOps 79 | 80 | Go to the folder where you have cloned your forked repository and create a new branch `rollouts-mesh` 81 | ``` 82 | git checkout -b rollouts-mesh 83 | git push origin rollouts-mesh 84 | ``` 85 | 86 | Log into OpenShift as a cluster admin and install the OpenShift GitOps operator with the following command. This may take some minutes. 87 | ``` 88 | oc apply -f gitops/gitops-operator.yaml 89 | ``` 90 | 91 | Once OpenShift GitOps is installed, an instance of Argo CD is automatically installed on the cluster in the `openshift-gitops` namespace and a link to this instance is added to the application launcher in OpenShift Web Console. 92 | 93 | ![Application Launcher](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/gitops-link.png) 94 | 95 | ### Log into Argo CD dashboard 96 | 97 | Argo CD upon installation generates an initial admin password which is stored in a Kubernetes secret. In order to retrieve this password, run the following command to decrypt the admin password: 98 | 99 | ``` 100 | oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 101 | ``` 102 | 103 | Click on Argo CD from the OpenShift Web Console application launcher and then log into Argo CD with `admin` username and the password retrieved from the previous step. 104 | 105 | ![Argo CD](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/ArgoCD-login.png) 106 | 107 | ![Argo CD](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/ArgoCD-UI.png) 108 | 109 | ### Configure OpenShift with Argo CD 110 | 111 | We are going to follow, as much as we can, a GitOps methodology in this demo. So we will have everything in our Git repository and use **ArgoCD** to deploy it in the cluster. 112 | 113 | In the current Git repository, the [gitops/cluster-config](https://github.com/davidseve/cloud-native-deployment-strategies/tree/main/gitops/cluster-config) directory contains OpenShift cluster configurations such as: 114 | 115 | - namespaces `gitops`. 116 | - role binding for ArgoCD to the namespace `gitops`. 117 | - Argo Rollouts project. 118 | - **OpenShift Service Mesh** 119 | - **Kiali Operator** 120 | - **OpenShift Elasticsearch Operator** 121 | - **Red Hat OpenShift distributed tracing platform** 122 | 123 | Let's configure Argo CD to recursively sync the content of the [gitops/cluster-config](https://github.com/davidseve/cloud-native-deployment-strategies/tree/main/gitops/cluster-config) directory into the OpenShift cluster. 124 | 125 | Execute this command to add a new Argo CD application that syncs a Git repository containing cluster configurations with the OpenShift cluster. 126 | 127 | ``` 128 | oc apply -f canary-argo-rollouts-service-mesh/application-cluster-config.yaml 129 | ``` 130 | 131 | Looking at the Argo CD dashboard, you will notice that an application has been created. 132 | 133 | You can click on the `cluster-configuration` application to check the details of sync resources and their status on the cluster. 134 | 135 | ### Create Shop application 136 | 137 | We are going to create the application `shop`, that we will use to test canary deployment. Because we will make changes in the application's GitHub repository, we have to use the repository that you have just forked. Please edit the file `canary-argo-rollouts-service-mesh/application-shop-canary-rollouts-mesh.yaml` and set your own GitHub repository in the `reportURL`and the OCP cluster domain in `change_domain`. 138 | 139 | ```yaml 140 | apiVersion: argoproj.io/v1alpha1 141 | kind: Application 142 | metadata: 143 | name: shop 144 | namespace: openshift-gitops 145 | spec: 146 | destination: 147 | name: '' 148 | namespace: gitops 149 | server: 'https://kubernetes.default.svc' 150 | source: 151 | path: helm/quarkus-helm-umbrella/chart 152 | repoURL: https://github.com/change_me/cloud-native-deployment-strategies.git 153 | targetRevision: rollouts-mesh 154 | helm: 155 | parameters: 156 | - name: "global.namespace" 157 | value: gitops 158 | - name: "domain" 159 | value: "change_domain" 160 | valueFiles: 161 | - values/values-canary-rollouts-mesh.yaml 162 | project: default 163 | syncPolicy: 164 | automated: 165 | prune: true 166 | selfHeal: true 167 | ``` 168 | 169 | ``` 170 | oc apply -f canary-argo-rollouts-service-mesh/application-shop-canary-rollouts-mesh.yaml 171 | ``` 172 | 173 | Looking at the Argo CD dashboard, you will notice that we have a new `shop` application. 174 | 175 | ![Argo CD - Cluster Config](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/ArgoCD-Applications.png) 176 | 177 | ## Test Shop application 178 | 179 | We have deployed the `shop` with ArgoCD. We can test that it is up and running. 180 | 181 | We have to get the route that we have created. 182 | ``` 183 | oc get routes shop-umbrella-products-route -n istio-system --template='https://{{.spec.host}}/products' 184 | ``` 185 | 186 | Notice that in each microservice response, we have added metadata information to see better the `version` of each application. This will help us to see the changes while we do the canary deployment. 187 | We can see that the current version is `v1.0.1`: 188 | ```json 189 | { 190 | "products":[ 191 | { 192 | ... 193 | "name":"TV 4K", 194 | "price":"1500€" 195 | } 196 | ], 197 | "metadata":{ 198 | "version":"v1.0.1", <-- 199 | "colour":"none", 200 | "mode":"online" 201 | } 202 | } 203 | ``` 204 | 205 | We can also see the rollout`s status[^note]. 206 | 207 | [^note]: 208 | Argo Rollouts offers a Kubectl plugin to enrich the experience with Rollouts https://argoproj.github.io/argo-rollouts/installation/#kubectl-plugin-installation 209 | 210 | ``` 211 | kubectl argo rollouts get rollout products --watch -n gitops 212 | ``` 213 | 214 | ``` 215 | NAME KIND STATUS AGE INFO 216 | ⟳ products Rollout ✔ Healthy 38s 217 | └──# revision:1 218 | └──⧉ products-67fc9fb79b ReplicaSet ✔ Healthy 38s stable 219 | ├──□ products-67fc9fb79b-4ql4z Pod ✔ Running 38s ready:1/1 220 | ├──□ products-67fc9fb79b-7c4jw Pod ✔ Running 38s ready:1/1 221 | ├──□ products-67fc9fb79b-lz86j Pod ✔ Running 38s ready:1/1 222 | └──□ products-67fc9fb79b-xlkhp Pod ✔ Running 38s ready:1/1 223 | ``` 224 | 225 | 226 | ## Products Canary deployment 227 | 228 | We have already deployed the products version v1.0.1 with 4 replicas, and we are ready to use a new products version v1.1.1 that has a new `description` attribute. 229 | 230 | This is our current status: 231 | ![Shop initial status](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/canary-rollout-mesh-step-0.png) 232 | 233 | This is how we have configure **Argo Rollouts** for this demo: 234 | ```yaml 235 | strategy: 236 | canary: 237 | steps: 238 | - setWeight: 10 239 | - pause: 240 | duration: 30s 241 | - setWeight: 50 242 | - pause: 243 | duration: 30s 244 | ``` 245 | 246 | We have split a `Cloud Native` Canary deployment into three automatic step: 247 | 248 | 1. Deploy canary version for 10% 249 | 2. Scale canary version to 50% 250 | 3. Scale canary version to 100% 251 | 252 | This is just an example. The key point here is that, very easily we can have the canary deployment that better fits our needs. To make this demo faster we have not set a pause without duration in any step, so **Argo Rollouts** will go throw each step automatically. 253 | 254 | ### Step 1 - Deploy canary version for 10% 255 | 256 | We will deploy a new version v1.1.1. To do it, we have to edit the file `helm/quarkus-helm-umbrella/chart/values/values-canary-rollouts-mesh.yaml` under `products-blue` set `tag` value to `v1.1.1` 257 | 258 | ```yaml 259 | products-blue: 260 | quarkus-base: 261 | image: 262 | tag: v1.1.1 263 | ``` 264 | 265 | **Argo Rollouts** will automatically deploy a new products revision and change the Virtual Service to send 10% of the traffic to the canary version. **Argo Rollouts** also makes a best effort attempt to achieve the percentage listed in the last setWeight step between the new and old version. This means that it will create only one replica in the new revision, because it is rounded up. All the requests are load balanced between the old and the new replicas. 266 | 267 | Push the changes to start the deployment. 268 | ``` 269 | git add . 270 | git commit -m "Change products version to v1.1.1" 271 | git push origin rollouts-mesh 272 | ``` 273 | 274 | ArgoCD will refresh the status after some minutes. If you don't want to wait you can refresh it manually from ArgoCD UI or configure the Argo CD Git Webhook.[^note2]. 275 | 276 | [^note2]: 277 | Here you can see how to configure the Argo CD Git [Webhook]( https://argo-cd.readthedocs.io/en/stable/operator-manual/webhook/) 278 | ![Argo CD Git Webhook](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/ArgoCD-webhook.png) 279 | 280 | ![Refresh Shop](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/ArgoCD-Shop-Refresh.png) 281 | 282 | This is our current status: 283 | ![Shop Step 1](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/canary-rollout-mesh-step-1.png) 284 | 285 | ``` 286 | kubectl argo rollouts get rollout products --watch -n gitops 287 | ``` 288 | ``` 289 | NAME KIND STATUS AGE INFO 290 | ⟳ products Rollout ॥ Paused 3m13s 291 | ├──# revision:2 292 | │ └──⧉ products-9dc6f576f ReplicaSet ✔ Healthy 8s canary 293 | │ └──□ products-9dc6f576f-fwq8m Pod ✔ Running 8s ready:1/1 294 | └──# revision:1 295 | └──⧉ products-67fc9fb79b ReplicaSet ✔ Healthy 3m13s stable 296 | ├──□ products-67fc9fb79b-4ql4z Pod ✔ Running 3m13s ready:1/1 297 | ├──□ products-67fc9fb79b-lz86j Pod ✔ Running 3m13s ready:1/1 298 | └──□ products-67fc9fb79b-xlkhp Pod ✔ Running 3m13s ready:1/1 299 | ``` 300 | 301 | In the products url`s response you will have the new version in 10% of the requests. 302 | 303 | New revision: 304 | ```json 305 | { 306 | "products":[ 307 | { 308 | "discountInfo":{...}, 309 | "name":"TV 4K", 310 | "price":"1500€", 311 | "description":"The best TV" <-- 312 | } 313 | ], 314 | "metadata":{ 315 | "version":"v1.1.1", <-- 316 | } 317 | } 318 | ``` 319 | 320 | Old revision: 321 | ```json 322 | { 323 | "products":[ 324 | { 325 | "discountInfo":{...}, 326 | "name":"TV 4K", 327 | "price":"1500€" 328 | } 329 | ], 330 | "metadata":{ 331 | "version":"v1.0.1", <-- 332 | } 333 | } 334 | ``` 335 | 336 | ### Step 2 - Scale canary version to 50% 337 | After 30 seconds **Argo Rollouts** automatically will increase the number of replicas in the new release to 2 and change the Virtual Service to send 50% of the traffic to the canary version. Instead of increasing automatically after 30 seconds we can configure **Argo Rollouts** to wait indefinitely until that `Pause` condition is removed. But this is not part of this demo. 338 | 339 | This is our current status: 340 | ![Shop Step 2](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/canary-rollout-mesh-step-2.png) 341 | 342 | ``` 343 | kubectl argo rollouts get rollout products --watch -n gitops 344 | ``` 345 | ``` 346 | NAME KIND STATUS AGE INFO 347 | ⟳ products Rollout ॥ Paused 3m47s 348 | ├──# revision:2 349 | │ └──⧉ products-9dc6f576f ReplicaSet ✔ Healthy 42s canary 350 | │ ├──□ products-9dc6f576f-fwq8m Pod ✔ Running 42s ready:1/1 351 | │ └──□ products-9dc6f576f-8qppq Pod ✔ Running 6s ready:1/1 352 | └──# revision:1 353 | └──⧉ products-67fc9fb79b ReplicaSet ✔ Healthy 3m47s stable 354 | ├──□ products-67fc9fb79b-lz86j Pod ✔ Running 3m47s ready:1/1 355 | └──□ products-67fc9fb79b-xlkhp Pod ✔ Running 3m47s ready:1/1 356 | ``` 357 | 358 | ### Step 3 - Scale canary version to 100% 359 | After other 30 seconds **Argo Rollouts** will increase the number of replicas in the new release to 4 and scale down the old revision. It also changes the Virtual Service to send 100% of the traffic to the canary version. 360 | 361 | 362 | This is our current status: 363 | ![Shop Step 3](https://github.com/davidseve/cloud-native-deployment-strategies/raw/main/images/canary-rollout-mesh-step-3.png) 364 | 365 | ``` 366 | kubectl argo rollouts get rollout products --watch -n gitops 367 | ``` 368 | ``` 369 | NAME KIND STATUS AGE INFO 370 | ⟳ products Rollout ✔ Healthy 4m32s 371 | ├──# revision:2 372 | │ └──⧉ products-9dc6f576f ReplicaSet ✔ Healthy 87s stable 373 | │ ├──□ products-9dc6f576f-fwq8m Pod ✔ Running 87s ready:1/1 374 | │ ├──□ products-9dc6f576f-8qppq Pod ✔ Running 51s ready:1/1 375 | │ ├──□ products-9dc6f576f-5ch92 Pod ✔ Running 17s ready:1/1 376 | │ └──□ products-9dc6f576f-kmvdh Pod ✔ Running 17s ready:1/1 377 | └──# revision:1 378 | └──⧉ products-67fc9fb79b ReplicaSet • ScaledDown 4m32s 379 | ``` 380 | 381 | **We have in the online environment the new version v1.1.1!!!** 382 | ```json 383 | { 384 | "products":[ 385 | { 386 | "discountInfo":{...}, 387 | "name":"TV 4K", 388 | "price":"1500€", 389 | "description":"The best TV" <-- 390 | } 391 | ], 392 | "metadata":{ 393 | "version":"v1.1.1", <-- 394 | } 395 | } 396 | ``` 397 | 398 | ## Delete environment 399 | 400 | To delete all the things that we have done for the demo you have to: 401 | 402 | - In GitHub delete the branch `rollouts-mesh` 403 | - In ArgoCD delete the application `cluster-configuration` and `shop` 404 | - In Openshift, go to project `openshift-operators` and delete the installed operators **Openshift GitOps**, **OpenShift Service Mesh**, **Kiali Operator**, **OpenShift Elasticsearch Operator**, **Red Hat OpenShift distributed tracing platform** 405 | 406 | 407 | 408 | 409 | --------------------------------------------------------------------------------