{"id":16144749,"url":"https://github.com/blues-man/vote-app-gitops","last_synced_at":"2025-04-10T00:19:19.019Z","repository":{"id":42000462,"uuid":"378068718","full_name":"blues-man/vote-app-gitops","owner":"blues-man","description":"A demo of cloud-native Inner Loop and Outer Loop controlling a 2-tier app (Python + Go) with Red Hat OpenShift using Tekton Pipelines, Argo CD GitOps, Eclipse Che aka OpenShift DevSpaces and Quay.io registry","archived":false,"fork":false,"pushed_at":"2024-11-06T14:36:01.000Z","size":2961,"stargazers_count":16,"open_issues_count":2,"forks_count":51,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-02T22:06:36.009Z","etag":null,"topics":["argocd","cicd","cloud-native","container-security","devsecops-pipeline","gitops","kubernetes","openshift","tekton-pipelines"],"latest_commit_sha":null,"homepage":"","language":"Smarty","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/blues-man.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-18T07:24:49.000Z","updated_at":"2024-11-06T14:36:05.000Z","dependencies_parsed_at":"2024-10-27T18:25:30.830Z","dependency_job_id":"53dde5a1-6477-4ec6-a215-974a9219da20","html_url":"https://github.com/blues-man/vote-app-gitops","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blues-man%2Fvote-app-gitops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blues-man%2Fvote-app-gitops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blues-man%2Fvote-app-gitops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/blues-man%2Fvote-app-gitops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/blues-man","download_url":"https://codeload.github.com/blues-man/vote-app-gitops/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248131485,"owners_count":21052855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argocd","cicd","cloud-native","container-security","devsecops-pipeline","gitops","kubernetes","openshift","tekton-pipelines"],"created_at":"2024-10-10T00:14:08.904Z","updated_at":"2025-04-10T00:19:18.992Z","avatar_url":"https://github.com/blues-man.png","language":"Smarty","readme":"# OpenShift GitOps Demo (Tekton + Argo CD)\n\nThe aim of this demo is to show how to interconnect [Tekton](https://tekton.dev/) Continuous Integration (CI) capabilities to [Argo CD](https://argoproj.github.io/argo-cd/) enhanced features for Continuous Delivery (CD) with [Red Hat OpenShift](https://try.openshift.com).\n\n![Architecture](images/demo-architecture.png)\n\nThe flow of this demo is:\n\n* Create and start manually or automatically [OpenShift Pipelines](https://www.openshift.com/learn/topics/ci-cd) to build container images\n* Edit code from [OpenShift DevSpaces](https://developers.redhat.com/products/codeready-workspaces/overview)\n* Scan container images with [Quay.io](https://quay.io)\n* Sync application with [OpenShift GitOps](https://www.openshift.com/learn/topics/gitops/) in Dev and Prod environments\n\nThe demo is based on the [Vote App](https://github.com/openshift/pipelines-tutorial) 2-tier app (Python Flask frontend + Go backend):\n\n\u003cimg src=\"images/topology.png\" width=400\u003e\n\n\n## Assets and repos\n\n### Git\n\nWe use three git repos.\n\n#### App source repos\n\nVote App source repos (Frontend + Backend):\n* [Vote App UI](https://github.com/blues-man/pipelines-vote-ui)\n* [Vote App API](https://github.com/blues-man/pipelines-vote-api)\n\n#### GitOps repo\n\nThis repo, used to store Kubernetes manifests and Argo application:\n* [Vote App GitOps](https://github.com/blues-man/vote-app-gitops)\n\nThere are 2 environments managed with Kustomize:\n* **dev**: used to deploy and sync manifests in a **Dev** environment\n* **prod**: used to deploy and sync manifests **Prod**, uses [Argo CD Sync Waves](https://argoproj.github.io/argo-cd/user-guide/sync-waves/) to order manifests sync.\n\n#### Create a Personal Access Token for GitHub\n\nThe pipelines will update the Kubernetes manifests for the applications, so they need to push to the both Vote App UI and Vote App API repos.\n\nCreate a [Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token) for your user, it will be used later.\n\n### Container Registry\n\nIn this demo we use [Quay.io](https://quay.io) as public container registry with private access to store container images.\n\nExample:\n\n* quay.io/bluesman/vote-api:latest\n* quay.io/bluesman/vote-ui:latest\n\n\n## Setup\n\nTo run this demo you need **OpenShift \u003e=4.7** with cluster-admin privileges.\n\n### Quay.io\n\n#### Account\n\nCreate an account on [Quay.io](https://quay.io) if you do not already have one.\n\n#### Repositories\n\nCreate two repositories with public access (pull), you will use credentials in the next step to push container images.\n\nFrom right-side menu, click **Create New Repository**\n\nCreate two repositories:\n\n* vote-ui\n* vote-api\n\nFlag it as **Public Repository** and click **Create Public Repository** \n\n![Create repo](images/quay-create-repo.png)\n\nRepositories are created and listed:\n\n![Create repo](images/quay-repo-created.png)\n\n\n\n#### Create secret\n\n* Login to quay.io in the web user interface and click on your username in the top right corner.\n* Select **account settings**.\n* Click the blue hyperlink **Generate Encrypted Password**.\n* Re-enter your password when prompted.\n* Copy the password\n\n![Create repo](images/quay-encrypted-key.png)\n\n### Setup OpenShift\n\nLogin to OpenShift Web Console to install prerequisites.\n\n### Install Operators\n\n\n#### OpenShift Pipelines\n\nOpenShift Pipelines is provided as an add-on on top of OpenShift that can be installed via an operator available in the OpenShift OperatorHub. Follow these instructions in order to install OpenShift Pipelines on OpenShift via the OperatorHub.\n\n\nFrom the left-side menu under **Administrator** perspective, go to **Operators**-\u003e **OperatorHub**. In the search box, search for _pipelines_, then click to **OpenShift Pipelines Operator**:\n\n![OperatorHub](https://redhat-scholars.github.io/openshift-starter-guides/rhs-openshift-starter-guides/4.7/_images/prerequisites_operatorhub.png)\n\nFrom the description view, click *Install* to review all installation settings.\n\n![Install Pipelines](https://redhat-scholars.github.io/openshift-starter-guides/rhs-openshift-starter-guides/4.7/_images/prerequisites_operatorhub_install_pipelines.png)\n\nEnsure *Update Channel* is set to *stable* , and click *Install* to start installing the Operator.\n\n![Install Operator](https://redhat-scholars.github.io/openshift-starter-guides/rhs-openshift-starter-guides/4.7/_images/prerequisites_operatorhub_install_operator.png)\n\nAfter few seconds, the installation should be completed with success and you can verify it looking at *Status* column, check if the status is *Succeeded*.\n\n![Pipelines Installed](https://redhat-scholars.github.io/openshift-starter-guides/rhs-openshift-starter-guides/4.7/_images/prerequisites_operatorhub_pipelines_installed.png)\n\n#### OpenShift GitOps\n\nLog into OpenShift Web Console as a cluster admin and navigate to the **Administrator** perspective and then **Operators** \u0026rarr; **OperatorHub**. \n\nIn the **OperatorHub**, search for *OpenShift GitOps* and follow the operator install flow to install it.\n\n![OpenShift GitOps operator](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-01.png)\n\n![OpenShift GitOps operator](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-02.png)\n\n![OpenShift GitOps operator](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-03.png)\n\n##### Add permission to Argo CD service account\n\n**IMPORTANT** Give permission to the Argo CD service account to control the cluster:\n```bash\noc adm policy add-cluster-role-to-user cluster-admin -z openshift-gitops-argocd-application-controller -n openshift-gitops\n```\n\nOnce OpenShift GitOps is installed, an instance of Argo CD is automatically installed on the cluster in the `openshift-gitops` namespace and link to this instance is added to the application launcher in OpenShift Web Console.\n\n![Application Launcher](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-04.png)\n\n##### Log into Argo CD dashboard\n\nArgo 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:\n\n```\noc extract secret/openshift-gitops-cluster -n openshift-gitops --to=-\n```\n\nClick 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.\n\n![Argo CD](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-05.png)\n\n![Argo CD](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-06.png)\n\n\n#### OpenShift DevSpaces\n\nCodeReady Workspace is an in-browser IDE  that will be used to edit and test the code from OpenShift with a pre-build Workspace from a Devfile.\n\nLog into OpenShift Web Console as a cluster admin and navigate to the **Administrator** perspective and then **Operators** \u0026rarr; **OperatorHub**. \n\nIn the **OperatorHub**, search for *OpenShift DevSpaces* and follow the operator install flow to install it.\n\nIn the Red Hat OpenShift DevSpaces pop-up window, click the **Install** button.\n\n![CRW](images/codeready-installation.png)\n\nOn the Install Operator screen, leave default option:\n\n* Installation mode: A specific project on the cluster\n* Installed Namespace: Pick an existing project → openshift-workspaces\n\n##### Creating an instance of OpenShift DevSpaces\n\nTo create an instance of the Red Hat OpenShift DevSpaces Operator, in the left panel, navigate to the **Operators** → **Installed Operators** section.\n\nIn the Installed Operators screen, click the Red Hat OpenShift DevSpaces name.\n\nIn the Operator Details screen, in the **Details** tab, inside of the Provided APIs section, click the **Create Instance** link.\n\nThe Create CheCluster page contains the configuration of the overall OpenShift DevSpaces instance to create. It is the CheCluster Custom Resource. Keep the default values.\n\nTo create the codeready-workspaces cluster, click the **Create** button in the lower left corner of the window.\n\nOn the Operator Details screen, in the Red Hat OpenShift DevSpaces Cluster tab, click on the codeready-workspaces link.\n\nTo navigate to the codeready-workspaces instance, click the link under Red Hat OpenShift DevSpaces URL.\n\nNOTE\nThe installation might take more than 5 minutes. The URL appears after the Red Hat OpenShift DevSpaces installation finishes.\n\n### Setup vote-ci project\n\n1. Create a new Project for the CI part with Tekton.\n\n```bash\noc new-project vote-ci\n```\n\n\n2. Create a Secret with your Quay.io credentials with the encrypted password you copied before:\n\n```bash\noc create secret docker-registry quay-secret --docker-server=quay.io --docker-username=\u003cQUAY_USERNAME\u003e --docker-password=\u003cENCRYPTED_PASSWORD\u003e\n```\n3. Create a Secret with your GitHub Personal Access Token\n\n```yaml\napiVersion: v1\nkind: Secret\nmetadata:\n  name: git-user-pass\n  annotations:\n    tekton.dev/git-0: https://github.com\ntype: kubernetes.io/basic-auth\nstringData:\n  username: \u003cgithub user\u003e\n  password: \u003cgithub personal access token\u003e\n```\nSave it to a file with your credentials and create the secret:\n\n```bash\noc create -f git-user-pass.yaml\n```\n\n3. Link Secrets to pipeline Service Account.\n\nNOTE: Pipelines Operator installs by default a `pipeline` Service Account in all projects. This service account is used to run non-privileged containers and builds across the cluster.  \n\n```bash\noc secret link pipeline quay-secret\noc secret link pipeline git-user-pass\n```\n\n4. Fork repos\n\nIn order to enable webhooks, fork source code repos to use them in pipelines:\n\n* [vote-api](https://github.com/blues-man/pipelines-vote-api)\n* [vote-ui](https://github.com/blues-man/pipelines-vote-ui)\n\n\n4. Clone vote-api repo\n\n\n```bash\ngit clone https://github.com/blues-man/pipelines-vote-api\ncd pipelines-vote-api\n```\n\n5. Create Tekton pipeline manifests\n\nChange the GitOps repo to your fork:\n```bash\nsed -i 's/bluesman/yourquayuser/g' k8s/pipeline.yaml\nsed -i 's/blues-man/yourgithubuser/g' k8s/pipeline.yaml\n```\n\n```bash\noc create -f k8s/vote-api-pvc.yaml\noc create -f k8s/git-update-deployment-task.yaml\noc create -f k8s/pipeline.yaml\noc create -f k8s/triggertemplate.yaml\noc create -f k8s/triggerbinding.yaml\noc create -f k8s/eventlistener.yaml\noc create -f k8s/el-route.yaml\n```\n\n\n\n7. Clone vote-ui repo\n\n```bash\ncd ..\ngit clone https://github.com/blues-man/pipelines-vote-ui\ncd pipelines-vote-ui\n```\n\n\n8. Create pipeline manifests\n\nChange the GitOps repo to your fork:\n```bash\nsed -i 's/bluesman/yourquayuser/g' k8s/pipeline.yaml\nsed -i 's/blues-man/yourgithubuser/g' k8s/pipeline.yaml\n```\n\n```bash\noc create -f k8s/vote-ui-pvc.yaml\noc apply  -f k8s/git-update-deployment-task.yaml\noc create -f k8s/pipeline.yaml\noc create -f k8s/triggertemplate.yaml\noc create -f k8s/triggerbinding.yaml\noc create -f k8s/eventlistener.yaml\noc create -f k8s/el-route.yaml\n```\n\n## Demo flow\n\nThe goal is to show how to OpenShift can create and connect the CI and CD part with Tekton and ArgoCD, using CRW and Quay.io for the Inner and Outer Loop.\n\n### 1. Pipelines overview\n\n![Pipelines](images/pipelines.png)\n\n#### 1. Start vote-api pipeline\n\nStart vote-api pipeline manually. \n\nFrom the left-side menu under **Developer** perspective, go to **Pipelines**.\n\nClick to **vote-api** pipeline.\n\nFrom right side menu, click **Start**.\n\nIn **GIT_REPO** use your fork of the **vote-api** repo\n\nIn **IMAGE_NAME** put your **vote-api** container image from Quay.io\n\nLeave all other settings as default.\n\nSelect **PVC** under **Workspace** section and select **vote-api-pvc** persistent volume claim.\n\nClick **Start**\n\n![Vote API Pipeline](images/start-api-pipeline.png)\n\n\n#### 2. Start vote-ui with a Webhook\n\nTekton supports **Tekton Triggers** to enable automation and web hooks to Pipelines. All settings have been already installed from previous command, and both pipelines support web hooks.\n\n![Triggers](images/pipeline-triggers.png)\n\nFrom **Topology** view, click to **el-vote-ui** Deployment, go into Routes section and and copy the **el-vote-ui**  Route URL.\n\n![Vote API Pipeline](images/el-trigger-vote-ui.png)\n\nOnce you have the URL copied to your clipboard, navigate to the code repository fork that you have on GitHub.\n\nFrom your fork page top-right menu, click **Settings**. Then from result left-side menu, click **Webhook**, then from right side click **Add webhooks**.\n\nIn the next screen, paste your link into the **Payload URL** field. You can leave the secret token field blank.\n\nChange the Content Type to **application/json**.\n\nFinally, click on **Add Webhook**.\n\n![Vote UI Web Hook](images/webhook-vote-ui.png)\n\n\nNOTE: If you forked the repo, update the `TriggerTemplate` with your vote-ui repo on quay.io reference adding the `IMAGE_NAME` parameter, otherwise it will fallback to `quay.io/bluesman/vote-ui`:\n\n```bash\noc edit triggertemplate vote-ui\n```\n\n```yaml\n...\n    spec:\n      params:\n      - name: APP_NAME\n        value: $(tt.params.git-repo-name)\n      - name: GIT_REPO\n        value: $(tt.params.git-repo-url)\n      - name: GIT_REVISION\n        value: $(tt.params.git-revision)\n      - name: IMAGE_NAME\n        value: quay.io/\u003cyour-username\u003e/vote-ui\n```\n\nDo some change to the source code and verify that the pipeline starts.\n\nYou can also use CodeReadyWorkspaces for that (change this URL with the one for your OpenShift DevSpaces):\n\n[![Contribute](https://raw.githubusercontent.com/blues-man/cloud-native-workshop/demo/factory-contribute.svg)](https://codeready-openshift-workspaces.apps.cluster-6ef7.6ef7.sandbox74.opentlc.com/factory?url=https://github.com/blues-man/pipelines-vote-ui\u0026policies.create=peruser)\n\n\n![Vote UI Pipeline start](images/pipeline-vote-ui-start.png)\n\nNOTE: you can also trigger the Pipeline start by changing and pushing the code at the CRW step later\n\n#### 3. Quay.io security scan\n\n* Verify generated images have been pushed to Quay.\n* Verify **vote-ui** image has been scanned with no vulnerabilities found\n\n\n![Vote UI Security scan](images/quay-vote-ui-scan.png)\n\n\n### 2. Argo CD for DEV project\n\nWe will pre-deploy the DEV environment in the **vote-app-dev** project.\n\n1. Fork this [vote-app-gitops](https://github.com/blues-man/vote-app-gitops) repository \n2. Clone your repository fork in the **main** branch:\n\n```bash\ngit clone https://github.com/blues-man/vote-app-gitops.git\ncd vote-app-gitops\n```\n\n2. Update Argo CD application **repoURL** with your fork, this will be used to deploy the app to the DEV environment\n\n```yaml\napiVersion: argoproj.io/v1alpha1\nkind: Application\nmetadata:\n  name: vote-app-dev\n  namespace: openshift-gitops\nspec:\n  destination:\n    namespace: vote-app-dev\n    server: https://kubernetes.default.svc \n  project: default \n  source: \n    path: environments/dev\n    repoURL: https://github.com/blues-man/vote-app-gitops\n    targetRevision: main\n  syncPolicy: \n    automated:\n      prune: true\n      selfHeal: false\n    syncOptions:\n    - CreateNamespace=true\n```\n3. Update all references to quay.io with your repos for vote-ui and vote-api images:\n```bash\nsed -i 's/bluesman/yourquayuser/g' k8s/api-deployment.yaml k8s/ui-deployment.yaml\ngit commit\ngit push\n```\n4. Create Argo CD Application to deploy DEV env\n```bash\noc apply -f argo/vote-app-dev.yaml\n```\n\n\u003cimg src=\"images/argocd-vote-app-dev.png\" width=500\u003e\n\n\n![Vote App Dev details](images/argocd-vote-app-dev-details.png)\n\n\n#### 1. Verify App deployment\n\nGo to **Topology** view in **vote-app-dev** Project.\n\n![Vote App Dev view](images/topology-vote-app-dev.png)\n\n#### 2. Access the app\n\nAccess the app from vote-ui **Route** clicking on the Python icon and then accessing Route URL.\n\n\u003cimg src=\"images/vote-app.png\"\u003e\n\n#### 3. Edit app in OpenShift DevSpaces\n\n\nEdit source code from CRW by clicking on the little crw icon next to the **vote-ui** in the Topology view. This will launch Eclipse Che Factory reading the dev environment from the Devfile in the vote-ui repository.\n\nThis will open CRW and you can demo how to edit and run the app from an IDE.\n\nIn CRW, from **Run Tasks** click **Install dependencies** and **Run Python app**.\n\nThis will open an embedded window with the app running locally.\n\n![CRW Vote App](images/crw-vote-ui.png)\n\n\n#### 4. Detect drifts\n\nLet Argo CD detect a drift between what declared in Git and what it is available in the cluster.\n\nChange **vote-ui** replicas to 2 from OpenShift and verify the status is **Out of Sync** on Argo CD.\n\nTIP: if the dashboard page doesn't update, try to hit the Refresh button from the Argo CD web console\n\n![Out of Sync](images/argocd-vote-app-dev-out-of-sync.png)\n\n#### 5. Sync the app\n\nSync manually the app from the Argo CD console, as we declared in our `Application` that we don't want to _self-heal_ for DEV project.\n\nFrom top menu, click **SYNC**.\n\nFrom right side window, click **SYNCHRONIZE** and leave default settings.\n\nThis will rollback the **vote-ui** deployment replicas to 1.\n\n\n### 3. Argo CD for PROD project\n\nWe create the PROD environment directly from Argo CD Web console this time.\n\nBefore doing that, update all the references to quay.io with your images also for the **main** branch.\n\n```bash\ngit checkout main\nsed -i 's/bluesman/yourquayuser/g' k8s/api-deployment.yaml k8s/ui-deployment.yaml\ngit commit\ngit push\n```\n\nAccess Argo CD Web console, from homepage click on top-left to the **+NEW APP** button.\n\nUnder **General**:\n\n* **Application**: vote-app-prod\n* **Project**: default\n* **Sync Policy**: Automatic\n* * Prune resources: true\n* * Self Heal: true\n* **Sync Options**: Auto-create namespace\n\n\nUnder **Source** section:\n\n* **Reposiroty URL**: Add your forked repo, e.g. https://github.com/blues-man/vote-app-gitops\n* **Revision**: main\n* **Path**: environments/prod\n\nUnder **Destination** section:\n\n* **Cluster URL**: https://kubernetes.default.svc\n* **Namespace**: vote-app-prod\n\nClick **CREATE**\n\n\n![Create Vote App Prod](images/argocd-create-vote-app-prod.png)\n\nReview auto-generated `Application` manifest:\n\n\n```yaml\napiVersion: argoproj.io/v1alpha1\nkind: Application\nmetadata:\n  name: vote-app-prod\n  namespace: openshift-gitops\nspec:\n  destination:\n    namespace: vote-app-prod\n    server: https://kubernetes.default.svc \n  project: default \n  source: \n    path: environments/prod\n    repoURL: https://github.com/blues-man/vote-app-gitops\n    targetRevision: main\n  syncPolicy: \n    automated:\n      prune: true\n      selfHeal: true\n    syncOptions:\n    - CreateNamespace=true\n```\n\n\n#### 1. Review deployment order\n\nPROD environment is using Sync Waves, this means Kubernetes manifests in the _main_ branch are\nannotated with sync weves to order manifests deployment.\n\n```yaml\nmetadata:\n  annotations:\n    argocd.argoproj.io/sync-wave: \"0\"\n```\n\n1. API Deployment\n2. API Service\n3. UI Deployment\n4. UI Service\n5. UI Route\n\n\n![Create Vote App Prod](images/argocd-vote-app-prod-sync.png)\n\n#### 2. Verify app is deployed in vote-app-prod Project\n\nVerify vote-ui and vote-api are deployed also in **vote-app-prod** project now.\n\nNOTE: OpenShift DevSpaces icons are not present in the Topology view this time, because we haven't annoted the Deployment for that, as this is a Prod app!\n\n#### 3. Auto detect drift\n\nChange **vote-ui** replicas to 2 from OpenShift Web Console, Argo CD will automatically sync and auto-heal in this case.\n\n\n![Vote App Prod](images/argocd-vote-app-prod.png)\n\n### 4. Make a change to PROD from GitHub with a Pull Request\n\n1. Create a new feature branch in the GitHub repo called **feature-ha**\n2. Change **ui-deployment.yaml** with ```replicas:2```\n3. Create PR\n4. Merge into main\n5. Prod app is with 2 replicas\n\n![Vote App Prod Scaled](images/topology-vote-app-prod-scaled.png)\n\n\u003cimg src=\"images/vote-ui2.png\" width=350\u003e\n\n\nWell done!\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblues-man%2Fvote-app-gitops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblues-man%2Fvote-app-gitops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblues-man%2Fvote-app-gitops/lists"}