├── README.md ├── argo ├── vote-app-dev.yaml └── vote-app-prod.yaml ├── environments ├── dev │ └── kustomization.yaml └── prod │ └── kustomization.yaml ├── helm ├── argocd │ ├── Chart.yaml │ ├── templates │ │ ├── argocd.yaml │ │ ├── namespace.yaml │ │ ├── rolebinding-user-argocd.yaml │ │ └── secret-argo-repo.yaml │ └── values.yaml ├── bootstrap │ ├── Chart.yaml │ ├── templates │ │ ├── _helpers.tpl │ │ ├── application-guides.yaml │ │ ├── application-usertool.yaml │ │ ├── applicationset-argocd.yaml │ │ ├── applicationset-devspaces.yaml │ │ ├── applicationset-tekton.yaml │ │ ├── clusterrole-cvsreader.yaml │ │ ├── configmap-userinfo.yaml │ │ └── subscription-webterminal.yaml │ └── values.yaml ├── devspaces │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ │ ├── configmap.yaml │ │ ├── devworkspace.yaml │ │ ├── namespace.yaml │ │ ├── role-binding-user.yaml │ │ ├── secret.yaml │ │ └── vscode.yaml │ └── values.yaml └── tekton │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ ├── git-update-deployment-task.yaml │ ├── namespace-dev.yaml │ ├── namespace-prod.yaml │ ├── namespace-tekton.yaml │ ├── pipeline-api.yaml │ ├── pipeline-promote-to-prod.yaml │ ├── pipeline-ui.yaml │ ├── pvc-api.yaml │ ├── pvc-ui.yaml │ ├── rolebinding-cvsreader.yaml │ ├── rolebinding-pipeline-edit-dev.yaml │ ├── rolebinding-pipeline-edit-prod.yaml │ ├── rolebinding-user-dev.yaml │ ├── rolebinding-user-prod.yaml │ ├── rolebinding-user-tekton.yaml │ ├── secret-gitea-repo.yaml │ ├── serviceaccount-pipeline.yaml │ ├── task-image-tag-to-digest.yaml │ ├── trigger-binding.yaml │ ├── trigger-eventlistener-api.yaml │ ├── trigger-eventlistener-route-api.yaml │ ├── trigger-eventlistener-route-ui.yaml │ ├── trigger-eventlistener-ui.yaml │ ├── trigger-template-api.yaml │ └── trigger-template-ui.yaml │ └── values.yaml ├── images ├── argocd-create-vote-app-prod.png ├── argocd-sync-app.png ├── argocd-vote-app-dev-details.png ├── argocd-vote-app-dev-out-of-sync.png ├── argocd-vote-app-dev.png ├── argocd-vote-app-prod-sync.png ├── argocd-vote-app-prod.png ├── codeready-installation.png ├── crw-vote-ui.png ├── demo-architecture.png ├── el-trigger-vote-ui.png ├── el-trigger.vote-api.png ├── pipeline-triggers.png ├── pipeline-vote-ui-start.png ├── pipelines.png ├── quay-create-repo.png ├── quay-encrypted-key.png ├── quay-repo-created.png ├── quay-vote-ui-scan.png ├── start-api-pipeline.png ├── topology-vote-app-dev.png ├── topology-vote-app-prod-scaled.png ├── topology.png ├── vote-app.png ├── vote-ui.png ├── vote-ui2.png ├── webhook-vote-api.png └── webhook-vote-ui.png └── k8s ├── api-deployment.yaml ├── api-service.yaml ├── kustomization.yaml ├── ui-deployment.yaml ├── ui-route.yaml └── ui-service.yaml /README.md: -------------------------------------------------------------------------------- 1 | # OpenShift GitOps Demo (Tekton + Argo CD) 2 | 3 | The 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). 4 | 5 | ![Architecture](images/demo-architecture.png) 6 | 7 | The flow of this demo is: 8 | 9 | * Create and start manually or automatically [OpenShift Pipelines](https://www.openshift.com/learn/topics/ci-cd) to build container images 10 | * Edit code from [OpenShift DevSpaces](https://developers.redhat.com/products/codeready-workspaces/overview) 11 | * Scan container images with [Quay.io](https://quay.io) 12 | * Sync application with [OpenShift GitOps](https://www.openshift.com/learn/topics/gitops/) in Dev and Prod environments 13 | 14 | The demo is based on the [Vote App](https://github.com/openshift/pipelines-tutorial) 2-tier app (Python Flask frontend + Go backend): 15 | 16 | 17 | 18 | 19 | ## Assets and repos 20 | 21 | ### Git 22 | 23 | We use three git repos. 24 | 25 | #### App source repos 26 | 27 | Vote App source repos (Frontend + Backend): 28 | * [Vote App UI](https://github.com/blues-man/pipelines-vote-ui) 29 | * [Vote App API](https://github.com/blues-man/pipelines-vote-api) 30 | 31 | #### GitOps repo 32 | 33 | This repo, used to store Kubernetes manifests and Argo application: 34 | * [Vote App GitOps](https://github.com/blues-man/vote-app-gitops) 35 | 36 | There are 2 environments managed with Kustomize: 37 | * **dev**: used to deploy and sync manifests in a **Dev** environment 38 | * **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. 39 | 40 | #### Create a Personal Access Token for GitHub 41 | 42 | The 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. 43 | 44 | Create 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. 45 | 46 | ### Container Registry 47 | 48 | In this demo we use [Quay.io](https://quay.io) as public container registry with private access to store container images. 49 | 50 | Example: 51 | 52 | * quay.io/bluesman/vote-api:latest 53 | * quay.io/bluesman/vote-ui:latest 54 | 55 | 56 | ## Setup 57 | 58 | To run this demo you need **OpenShift >=4.7** with cluster-admin privileges. 59 | 60 | ### Quay.io 61 | 62 | #### Account 63 | 64 | Create an account on [Quay.io](https://quay.io) if you do not already have one. 65 | 66 | #### Repositories 67 | 68 | Create two repositories with public access (pull), you will use credentials in the next step to push container images. 69 | 70 | From right-side menu, click **Create New Repository** 71 | 72 | Create two repositories: 73 | 74 | * vote-ui 75 | * vote-api 76 | 77 | Flag it as **Public Repository** and click **Create Public Repository** 78 | 79 | ![Create repo](images/quay-create-repo.png) 80 | 81 | Repositories are created and listed: 82 | 83 | ![Create repo](images/quay-repo-created.png) 84 | 85 | 86 | 87 | #### Create secret 88 | 89 | * Login to quay.io in the web user interface and click on your username in the top right corner. 90 | * Select **account settings**. 91 | * Click the blue hyperlink **Generate Encrypted Password**. 92 | * Re-enter your password when prompted. 93 | * Copy the password 94 | 95 | ![Create repo](images/quay-encrypted-key.png) 96 | 97 | ### Setup OpenShift 98 | 99 | Login to OpenShift Web Console to install prerequisites. 100 | 101 | ### Install Operators 102 | 103 | 104 | #### OpenShift Pipelines 105 | 106 | OpenShift 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. 107 | 108 | 109 | From the left-side menu under **Administrator** perspective, go to **Operators**-> **OperatorHub**. In the search box, search for _pipelines_, then click to **OpenShift Pipelines Operator**: 110 | 111 | ![OperatorHub](https://redhat-scholars.github.io/openshift-starter-guides/rhs-openshift-starter-guides/4.7/_images/prerequisites_operatorhub.png) 112 | 113 | From the description view, click *Install* to review all installation settings. 114 | 115 | ![Install Pipelines](https://redhat-scholars.github.io/openshift-starter-guides/rhs-openshift-starter-guides/4.7/_images/prerequisites_operatorhub_install_pipelines.png) 116 | 117 | Ensure *Update Channel* is set to *stable* , and click *Install* to start installing the Operator. 118 | 119 | ![Install Operator](https://redhat-scholars.github.io/openshift-starter-guides/rhs-openshift-starter-guides/4.7/_images/prerequisites_operatorhub_install_operator.png) 120 | 121 | After few seconds, the installation should be completed with success and you can verify it looking at *Status* column, check if the status is *Succeeded*. 122 | 123 | ![Pipelines Installed](https://redhat-scholars.github.io/openshift-starter-guides/rhs-openshift-starter-guides/4.7/_images/prerequisites_operatorhub_pipelines_installed.png) 124 | 125 | #### OpenShift GitOps 126 | 127 | Log into OpenShift Web Console as a cluster admin and navigate to the **Administrator** perspective and then **Operators** → **OperatorHub**. 128 | 129 | In the **OperatorHub**, search for *OpenShift GitOps* and follow the operator install flow to install it. 130 | 131 | ![OpenShift GitOps operator](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-01.png) 132 | 133 | ![OpenShift GitOps operator](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-02.png) 134 | 135 | ![OpenShift GitOps operator](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-03.png) 136 | 137 | ##### Add permission to Argo CD service account 138 | 139 | **IMPORTANT** Give permission to the Argo CD service account to control the cluster: 140 | ```bash 141 | oc adm policy add-cluster-role-to-user cluster-admin -z openshift-gitops-argocd-application-controller -n openshift-gitops 142 | ``` 143 | 144 | Once 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. 145 | 146 | ![Application Launcher](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-04.png) 147 | 148 | ##### Log into Argo CD dashboard 149 | 150 | 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: 151 | 152 | ``` 153 | oc extract secret/openshift-gitops-cluster -n openshift-gitops --to=- 154 | ``` 155 | 156 | 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. 157 | 158 | ![Argo CD](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-05.png) 159 | 160 | ![Argo CD](https://raw.githubusercontent.com/siamaksade/openshift-gitops-getting-started/1.1/images/gitops-06.png) 161 | 162 | 163 | #### OpenShift DevSpaces 164 | 165 | CodeReady 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. 166 | 167 | Log into OpenShift Web Console as a cluster admin and navigate to the **Administrator** perspective and then **Operators** → **OperatorHub**. 168 | 169 | In the **OperatorHub**, search for *OpenShift DevSpaces* and follow the operator install flow to install it. 170 | 171 | In the Red Hat OpenShift DevSpaces pop-up window, click the **Install** button. 172 | 173 | ![CRW](images/codeready-installation.png) 174 | 175 | On the Install Operator screen, leave default option: 176 | 177 | * Installation mode: A specific project on the cluster 178 | * Installed Namespace: Pick an existing project → openshift-workspaces 179 | 180 | ##### Creating an instance of OpenShift DevSpaces 181 | 182 | To create an instance of the Red Hat OpenShift DevSpaces Operator, in the left panel, navigate to the **Operators** → **Installed Operators** section. 183 | 184 | In the Installed Operators screen, click the Red Hat OpenShift DevSpaces name. 185 | 186 | In the Operator Details screen, in the **Details** tab, inside of the Provided APIs section, click the **Create Instance** link. 187 | 188 | The Create CheCluster page contains the configuration of the overall OpenShift DevSpaces instance to create. It is the CheCluster Custom Resource. Keep the default values. 189 | 190 | To create the codeready-workspaces cluster, click the **Create** button in the lower left corner of the window. 191 | 192 | On the Operator Details screen, in the Red Hat OpenShift DevSpaces Cluster tab, click on the codeready-workspaces link. 193 | 194 | To navigate to the codeready-workspaces instance, click the link under Red Hat OpenShift DevSpaces URL. 195 | 196 | NOTE 197 | The installation might take more than 5 minutes. The URL appears after the Red Hat OpenShift DevSpaces installation finishes. 198 | 199 | ### Setup vote-ci project 200 | 201 | 1. Create a new Project for the CI part with Tekton. 202 | 203 | ```bash 204 | oc new-project vote-ci 205 | ``` 206 | 207 | 208 | 2. Create a Secret with your Quay.io credentials with the encrypted password you copied before: 209 | 210 | ```bash 211 | oc create secret docker-registry quay-secret --docker-server=quay.io --docker-username= --docker-password= 212 | ``` 213 | 3. Create a Secret with your GitHub Personal Access Token 214 | 215 | ```yaml 216 | apiVersion: v1 217 | kind: Secret 218 | metadata: 219 | name: git-user-pass 220 | annotations: 221 | tekton.dev/git-0: https://github.com 222 | type: kubernetes.io/basic-auth 223 | stringData: 224 | username: 225 | password: 226 | ``` 227 | Save it to a file with your credentials and create the secret: 228 | 229 | ```bash 230 | oc create -f git-user-pass.yaml 231 | ``` 232 | 233 | 3. Link Secrets to pipeline Service Account. 234 | 235 | NOTE: 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. 236 | 237 | ```bash 238 | oc secret link pipeline quay-secret 239 | oc secret link pipeline git-user-pass 240 | ``` 241 | 242 | 4. Fork repos 243 | 244 | In order to enable webhooks, fork source code repos to use them in pipelines: 245 | 246 | * [vote-api](https://github.com/blues-man/pipelines-vote-api) 247 | * [vote-ui](https://github.com/blues-man/pipelines-vote-ui) 248 | 249 | 250 | 4. Clone vote-api repo 251 | 252 | 253 | ```bash 254 | git clone https://github.com/blues-man/pipelines-vote-api 255 | cd pipelines-vote-api 256 | ``` 257 | 258 | 5. Create Tekton pipeline manifests 259 | 260 | Change the GitOps repo to your fork: 261 | ```bash 262 | sed -i 's/bluesman/yourquayuser/g' k8s/pipeline.yaml 263 | sed -i 's/blues-man/yourgithubuser/g' k8s/pipeline.yaml 264 | ``` 265 | 266 | ```bash 267 | oc create -f k8s/vote-api-pvc.yaml 268 | oc create -f k8s/git-update-deployment-task.yaml 269 | oc create -f k8s/pipeline.yaml 270 | oc create -f k8s/triggertemplate.yaml 271 | oc create -f k8s/triggerbinding.yaml 272 | oc create -f k8s/eventlistener.yaml 273 | oc create -f k8s/el-route.yaml 274 | ``` 275 | 276 | 277 | 278 | 7. Clone vote-ui repo 279 | 280 | ```bash 281 | cd .. 282 | git clone https://github.com/blues-man/pipelines-vote-ui 283 | cd pipelines-vote-ui 284 | ``` 285 | 286 | 287 | 8. Create pipeline manifests 288 | 289 | Change the GitOps repo to your fork: 290 | ```bash 291 | sed -i 's/bluesman/yourquayuser/g' k8s/pipeline.yaml 292 | sed -i 's/blues-man/yourgithubuser/g' k8s/pipeline.yaml 293 | ``` 294 | 295 | ```bash 296 | oc create -f k8s/vote-ui-pvc.yaml 297 | oc apply -f k8s/git-update-deployment-task.yaml 298 | oc create -f k8s/pipeline.yaml 299 | oc create -f k8s/triggertemplate.yaml 300 | oc create -f k8s/triggerbinding.yaml 301 | oc create -f k8s/eventlistener.yaml 302 | oc create -f k8s/el-route.yaml 303 | ``` 304 | 305 | ## Demo flow 306 | 307 | The 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. 308 | 309 | ### 1. Pipelines overview 310 | 311 | ![Pipelines](images/pipelines.png) 312 | 313 | #### 1. Start vote-api pipeline 314 | 315 | Start vote-api pipeline manually. 316 | 317 | From the left-side menu under **Developer** perspective, go to **Pipelines**. 318 | 319 | Click to **vote-api** pipeline. 320 | 321 | From right side menu, click **Start**. 322 | 323 | In **GIT_REPO** use your fork of the **vote-api** repo 324 | 325 | In **IMAGE_NAME** put your **vote-api** container image from Quay.io 326 | 327 | Leave all other settings as default. 328 | 329 | Select **PVC** under **Workspace** section and select **vote-api-pvc** persistent volume claim. 330 | 331 | Click **Start** 332 | 333 | ![Vote API Pipeline](images/start-api-pipeline.png) 334 | 335 | 336 | #### 2. Start vote-ui with a Webhook 337 | 338 | Tekton 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. 339 | 340 | ![Triggers](images/pipeline-triggers.png) 341 | 342 | From **Topology** view, click to **el-vote-ui** Deployment, go into Routes section and and copy the **el-vote-ui** Route URL. 343 | 344 | ![Vote API Pipeline](images/el-trigger-vote-ui.png) 345 | 346 | Once you have the URL copied to your clipboard, navigate to the code repository fork that you have on GitHub. 347 | 348 | From your fork page top-right menu, click **Settings**. Then from result left-side menu, click **Webhook**, then from right side click **Add webhooks**. 349 | 350 | In the next screen, paste your link into the **Payload URL** field. You can leave the secret token field blank. 351 | 352 | Change the Content Type to **application/json**. 353 | 354 | Finally, click on **Add Webhook**. 355 | 356 | ![Vote UI Web Hook](images/webhook-vote-ui.png) 357 | 358 | 359 | NOTE: 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`: 360 | 361 | ```bash 362 | oc edit triggertemplate vote-ui 363 | ``` 364 | 365 | ```yaml 366 | ... 367 | spec: 368 | params: 369 | - name: APP_NAME 370 | value: $(tt.params.git-repo-name) 371 | - name: GIT_REPO 372 | value: $(tt.params.git-repo-url) 373 | - name: GIT_REVISION 374 | value: $(tt.params.git-revision) 375 | - name: IMAGE_NAME 376 | value: quay.io//vote-ui 377 | ``` 378 | 379 | Do some change to the source code and verify that the pipeline starts. 380 | 381 | You can also use CodeReadyWorkspaces for that (change this URL with the one for your OpenShift DevSpaces): 382 | 383 | [![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&policies.create=peruser) 384 | 385 | 386 | ![Vote UI Pipeline start](images/pipeline-vote-ui-start.png) 387 | 388 | NOTE: you can also trigger the Pipeline start by changing and pushing the code at the CRW step later 389 | 390 | #### 3. Quay.io security scan 391 | 392 | * Verify generated images have been pushed to Quay. 393 | * Verify **vote-ui** image has been scanned with no vulnerabilities found 394 | 395 | 396 | ![Vote UI Security scan](images/quay-vote-ui-scan.png) 397 | 398 | 399 | ### 2. Argo CD for DEV project 400 | 401 | We will pre-deploy the DEV environment in the **vote-app-dev** project. 402 | 403 | 1. Fork this [vote-app-gitops](https://github.com/blues-man/vote-app-gitops) repository 404 | 2. Clone your repository fork in the **main** branch: 405 | 406 | ```bash 407 | git clone https://github.com/blues-man/vote-app-gitops.git 408 | cd vote-app-gitops 409 | ``` 410 | 411 | 2. Update Argo CD application **repoURL** with your fork, this will be used to deploy the app to the DEV environment 412 | 413 | ```yaml 414 | apiVersion: argoproj.io/v1alpha1 415 | kind: Application 416 | metadata: 417 | name: vote-app-dev 418 | namespace: openshift-gitops 419 | spec: 420 | destination: 421 | namespace: vote-app-dev 422 | server: https://kubernetes.default.svc 423 | project: default 424 | source: 425 | path: environments/dev 426 | repoURL: https://github.com/blues-man/vote-app-gitops 427 | targetRevision: main 428 | syncPolicy: 429 | automated: 430 | prune: true 431 | selfHeal: false 432 | syncOptions: 433 | - CreateNamespace=true 434 | ``` 435 | 3. Update all references to quay.io with your repos for vote-ui and vote-api images: 436 | ```bash 437 | sed -i 's/bluesman/yourquayuser/g' k8s/api-deployment.yaml k8s/ui-deployment.yaml 438 | git commit 439 | git push 440 | ``` 441 | 4. Create Argo CD Application to deploy DEV env 442 | ```bash 443 | oc apply -f argo/vote-app-dev.yaml 444 | ``` 445 | 446 | 447 | 448 | 449 | ![Vote App Dev details](images/argocd-vote-app-dev-details.png) 450 | 451 | 452 | #### 1. Verify App deployment 453 | 454 | Go to **Topology** view in **vote-app-dev** Project. 455 | 456 | ![Vote App Dev view](images/topology-vote-app-dev.png) 457 | 458 | #### 2. Access the app 459 | 460 | Access the app from vote-ui **Route** clicking on the Python icon and then accessing Route URL. 461 | 462 | 463 | 464 | #### 3. Edit app in OpenShift DevSpaces 465 | 466 | 467 | Edit 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. 468 | 469 | This will open CRW and you can demo how to edit and run the app from an IDE. 470 | 471 | In CRW, from **Run Tasks** click **Install dependencies** and **Run Python app**. 472 | 473 | This will open an embedded window with the app running locally. 474 | 475 | ![CRW Vote App](images/crw-vote-ui.png) 476 | 477 | 478 | #### 4. Detect drifts 479 | 480 | Let Argo CD detect a drift between what declared in Git and what it is available in the cluster. 481 | 482 | Change **vote-ui** replicas to 2 from OpenShift and verify the status is **Out of Sync** on Argo CD. 483 | 484 | TIP: if the dashboard page doesn't update, try to hit the Refresh button from the Argo CD web console 485 | 486 | ![Out of Sync](images/argocd-vote-app-dev-out-of-sync.png) 487 | 488 | #### 5. Sync the app 489 | 490 | Sync 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. 491 | 492 | From top menu, click **SYNC**. 493 | 494 | From right side window, click **SYNCHRONIZE** and leave default settings. 495 | 496 | This will rollback the **vote-ui** deployment replicas to 1. 497 | 498 | 499 | ### 3. Argo CD for PROD project 500 | 501 | We create the PROD environment directly from Argo CD Web console this time. 502 | 503 | Before doing that, update all the references to quay.io with your images also for the **main** branch. 504 | 505 | ```bash 506 | git checkout main 507 | sed -i 's/bluesman/yourquayuser/g' k8s/api-deployment.yaml k8s/ui-deployment.yaml 508 | git commit 509 | git push 510 | ``` 511 | 512 | Access Argo CD Web console, from homepage click on top-left to the **+NEW APP** button. 513 | 514 | Under **General**: 515 | 516 | * **Application**: vote-app-prod 517 | * **Project**: default 518 | * **Sync Policy**: Automatic 519 | * * Prune resources: true 520 | * * Self Heal: true 521 | * **Sync Options**: Auto-create namespace 522 | 523 | 524 | Under **Source** section: 525 | 526 | * **Reposiroty URL**: Add your forked repo, e.g. https://github.com/blues-man/vote-app-gitops 527 | * **Revision**: main 528 | * **Path**: environments/prod 529 | 530 | Under **Destination** section: 531 | 532 | * **Cluster URL**: https://kubernetes.default.svc 533 | * **Namespace**: vote-app-prod 534 | 535 | Click **CREATE** 536 | 537 | 538 | ![Create Vote App Prod](images/argocd-create-vote-app-prod.png) 539 | 540 | Review auto-generated `Application` manifest: 541 | 542 | 543 | ```yaml 544 | apiVersion: argoproj.io/v1alpha1 545 | kind: Application 546 | metadata: 547 | name: vote-app-prod 548 | namespace: openshift-gitops 549 | spec: 550 | destination: 551 | namespace: vote-app-prod 552 | server: https://kubernetes.default.svc 553 | project: default 554 | source: 555 | path: environments/prod 556 | repoURL: https://github.com/blues-man/vote-app-gitops 557 | targetRevision: main 558 | syncPolicy: 559 | automated: 560 | prune: true 561 | selfHeal: true 562 | syncOptions: 563 | - CreateNamespace=true 564 | ``` 565 | 566 | 567 | #### 1. Review deployment order 568 | 569 | PROD environment is using Sync Waves, this means Kubernetes manifests in the _main_ branch are 570 | annotated with sync weves to order manifests deployment. 571 | 572 | ```yaml 573 | metadata: 574 | annotations: 575 | argocd.argoproj.io/sync-wave: "0" 576 | ``` 577 | 578 | 1. API Deployment 579 | 2. API Service 580 | 3. UI Deployment 581 | 4. UI Service 582 | 5. UI Route 583 | 584 | 585 | ![Create Vote App Prod](images/argocd-vote-app-prod-sync.png) 586 | 587 | #### 2. Verify app is deployed in vote-app-prod Project 588 | 589 | Verify vote-ui and vote-api are deployed also in **vote-app-prod** project now. 590 | 591 | NOTE: 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! 592 | 593 | #### 3. Auto detect drift 594 | 595 | Change **vote-ui** replicas to 2 from OpenShift Web Console, Argo CD will automatically sync and auto-heal in this case. 596 | 597 | 598 | ![Vote App Prod](images/argocd-vote-app-prod.png) 599 | 600 | ### 4. Make a change to PROD from GitHub with a Pull Request 601 | 602 | 1. Create a new feature branch in the GitHub repo called **feature-ha** 603 | 2. Change **ui-deployment.yaml** with ```replicas:2``` 604 | 3. Create PR 605 | 4. Merge into main 606 | 5. Prod app is with 2 replicas 607 | 608 | ![Vote App Prod Scaled](images/topology-vote-app-prod-scaled.png) 609 | 610 | 611 | 612 | 613 | Well done! 614 | 615 | -------------------------------------------------------------------------------- /argo/vote-app-dev.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: vote-app-dev 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | namespace: vote-app-dev 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | path: environments/dev 13 | repoURL: https://github.com/blues-man/vote-app-gitops 14 | targetRevision: main 15 | syncPolicy: 16 | automated: 17 | prune: true 18 | selfHeal: true 19 | syncOptions: 20 | - CreateNamespace=true 21 | -------------------------------------------------------------------------------- /argo/vote-app-prod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: Application 3 | metadata: 4 | name: vote-app-prod 5 | namespace: openshift-gitops 6 | spec: 7 | destination: 8 | namespace: vote-app-prod 9 | server: https://kubernetes.default.svc 10 | project: default 11 | source: 12 | path: environments/prod 13 | repoURL: https://github.com/blues-man/vote-app-gitops 14 | targetRevision: main 15 | syncPolicy: 16 | automated: 17 | prune: true 18 | selfHeal: true 19 | syncOptions: 20 | - CreateNamespace=true 21 | -------------------------------------------------------------------------------- /environments/dev/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - ../../k8s/ 5 | images: 6 | - digest: sha256:a7b077635a43a187d1641610c7e134537d3ae5bc8911702fd3b5e5c0543e622e 7 | name: quay.io/bluesman/vote-ui 8 | newName: quay.io/bluesman/vote-ui 9 | -------------------------------------------------------------------------------- /environments/prod/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | bases: 4 | - ../../k8s/ 5 | replicas: 6 | - name: vote-ui 7 | count: 1 8 | patches: 9 | - patch: |- 10 | - op: add 11 | path: /metadata/annotations 12 | value: 13 | argocd.argoproj.io/sync-wave: "0" 14 | target: 15 | group: apps 16 | kind: Deployment 17 | name: vote-api 18 | version: v1 19 | - patch: |- 20 | - op: add 21 | path: /metadata/annotations 22 | value: 23 | argocd.argoproj.io/sync-wave: "1" 24 | target: 25 | kind: Service 26 | name: vote-api 27 | version: v1 28 | - patch: |- 29 | - op: add 30 | path: /metadata/annotations 31 | value: 32 | argocd.argoproj.io/sync-wave: "2" 33 | target: 34 | group: apps 35 | kind: Deployment 36 | name: vote-ui 37 | version: v1 38 | - patch: |- 39 | - op: add 40 | path: /metadata/annotations 41 | value: 42 | argocd.argoproj.io/sync-wave: "3" 43 | target: 44 | kind: Service 45 | name: vote-ui 46 | version: v1 47 | - patch: |- 48 | - op: add 49 | path: /metadata/annotations 50 | value: 51 | argocd.argoproj.io/sync-wave: "4" 52 | target: 53 | kind: Route 54 | name: vote-ui 55 | version: v1 56 | 57 | -------------------------------------------------------------------------------- /helm/argocd/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: argocd 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: 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 | -------------------------------------------------------------------------------- /helm/argocd/templates/argocd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: argoproj.io/v1alpha1 2 | kind: ArgoCD 3 | metadata: 4 | name: argocd 5 | namespace: {{ .Values.argocdNamespace }} 6 | spec: 7 | sso: 8 | dex: 9 | openShiftOAuth: true 10 | provider: dex 11 | rbac: 12 | policy: | 13 | g, system:cluster-admins, role:admin 14 | g, cluster-admins, role:admin 15 | g, {{ .Values.namespacePermissions.user }}, role:admin 16 | scopes: '[name,groups]' 17 | server: 18 | route: 19 | enabled: true 20 | tls: 21 | insecureEdgeTerminationPolicy: Redirect 22 | termination: reencrypt 23 | -------------------------------------------------------------------------------- /helm/argocd/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: {{ .Values.argocdNamespace }} 6 | annotations: 7 | openshift.io/description: "ArgoCD GitOps Namespace" 8 | openshift.io/display-name: "ArgoCD GitOps Namespace" 9 | -------------------------------------------------------------------------------- /helm/argocd/templates/rolebinding-user-argocd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: argocd-{{ .Values.namespacePermissions.user }} 6 | namespace: {{ .Values.argocdNamespace }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: {{ .Values.namespacePermissions.role }} 11 | subjects: 12 | - apiGroup: rbac.authorization.k8s.io 13 | kind: User 14 | name: {{ .Values.namespacePermissions.user }} 15 | -------------------------------------------------------------------------------- /helm/argocd/templates/secret-argo-repo.yaml: -------------------------------------------------------------------------------- 1 | {{- range .Values.repos }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ .name }} 6 | namespace: {{ $.Values.argocdNamespace }} 7 | labels: 8 | argocd.argoproj.io/secret-type: repository 9 | stringData: 10 | type: {{ .type }} 11 | url: {{ .url }} 12 | username: {{ .username }} 13 | password: {{ .password }} 14 | --- 15 | {{- end }} 16 | -------------------------------------------------------------------------------- /helm/argocd/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for argocd. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | argocdNamespace: argocd 6 | 7 | namespacePermissions: 8 | user: user 9 | role: edit 10 | 11 | repos: [] 12 | # - type: git 13 | # name: app1 14 | # url: http://repo/user/app1 15 | # username: user1 16 | # password: password 17 | # - type: git 18 | # name: app2 19 | # url: http://repo/user/app2 20 | # username: user2 21 | # password: password 22 | -------------------------------------------------------------------------------- /helm/bootstrap/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: bootstrap 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: 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 | -------------------------------------------------------------------------------- /helm/bootstrap/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{- define "usertool.labExtraUrls" }} 2 | {{- $domain := .Values.deployer.domain }} 3 | {{- $consoleUrl := printf "https://console-openshift-console.%s;OpenShift Console" $domain }} 4 | {{- $gitea := printf "https://gitea.%s/%%USERNAME%%;Gitea" $domain }} 5 | {{- $argocdUrl := printf "https://argocd-server-argocd-%%USERNAME%%.%s;ArgoCD" $domain }} 6 | {{- $urls := list $consoleUrl $gitea $argocdUrl }} 7 | {{- join "," $urls }} 8 | {{- end }} 9 | 10 | {{- define "usertool.labModuleUrls" }} 11 | {{- $domain := .Values.deployer.domain }} 12 | {{- $params := printf "?USERID=%%USERNAME%%&SUBDOMAIN=%s" $domain }} 13 | {{- $module1 := printf "https://guides-guides.%s/inner-outer-guides/main/m1/intro.html%s;Module 1 Overview" $domain $params }} 14 | {{- $module2 := printf "https://guides-guides.%s/inner-outer-guides/main/m2/intro.html%s;Module 2 Development" $domain $params }} 15 | {{- $module3 := printf "https://guides-guides.%s/inner-outer-guides/main/m3/production.html%s;Module 3 Production" $domain $params }} 16 | {{- $module4 := printf "https://guides-guides.%s/inner-outer-guides/main/m4/finish.html%s;Module 4 Conclusion" $domain $params }} 17 | {{- $urls := list $module1 $module2 $module3 $module4 }} 18 | {{- join "," $urls }} 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /helm/bootstrap/templates/application-guides.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: guides 6 | namespace: openshift-gitops 7 | spec: 8 | project: default 9 | source: 10 | repoURL: {{ .Values.guides.repoUrl }} 11 | targetRevision: {{ .Values.guides.repoRevision }} 12 | path: {{ .Values.guides.repoPath }} 13 | helm: 14 | values: | 15 | namespace: {{ .Values.guides.namespace }} 16 | image: {{ .Values.guides.image }} 17 | destination: 18 | namespace: {{ .Values.guides.namespace }} 19 | server: https://kubernetes.default.svc 20 | syncPolicy: 21 | automated: {} 22 | -------------------------------------------------------------------------------- /helm/bootstrap/templates/application-usertool.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: Application 4 | metadata: 5 | name: usertool 6 | namespace: openshift-gitops 7 | spec: 8 | project: default 9 | source: 10 | repoURL: {{ .Values.usertool.repoUrl }} 11 | targetRevision: {{ .Values.usertool.repoRevision }} 12 | path: {{ .Values.usertool.repoPath }} 13 | helm: 14 | values: | 15 | usertoolNamespace: {{ .Values.usertool.namespace }} 16 | image: {{ .Values.usertool.image }} 17 | redis: 18 | image: {{ .Values.usertool.redisImage }} 19 | labAdminPassword: {{ .Values.usertool.labAdminPassword }} 20 | labDuration: {{ .Values.usertool.labDuration }} 21 | labAccessToken: {{ .Values.usertool.labAccessToken }} 22 | labUserCount: "{{ .Values.user.count }}" 23 | labUserPassword: {{ .Values.usertool.labUserPassword }} 24 | labUserPrefix: {{ .Values.user.prefix }} 25 | labExtraUrls: |- 26 | {{ include "usertool.labExtraUrls" . }} 27 | labModuleUrls: |- 28 | {{ include "usertool.labModuleUrls" . }} 29 | destination: 30 | namespace: {{ .Values.usertool.namespace }} 31 | server: https://kubernetes.default.svc 32 | syncPolicy: 33 | automated: {} 34 | -------------------------------------------------------------------------------- /helm/bootstrap/templates/applicationset-argocd.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: ApplicationSet 4 | metadata: 5 | name: argocd 6 | namespace: openshift-gitops 7 | spec: 8 | generators: 9 | - list: 10 | elements: 11 | {{- $userCount := int .Values.user.count }} 12 | {{- range $index := until $userCount }} 13 | - user: {{ $.Values.user.prefix }}{{ add $index 1}} 14 | {{- end }} 15 | template: 16 | metadata: 17 | name: argocd-{{- "{{" }} user {{- " }}" }} 18 | namespace: openshift-gitops 19 | spec: 20 | project: default 21 | source: 22 | repoURL: {{ .Values.argocd.git.url }}/{{- "{{" }} user {{- " }}" }}/{{ .Values.argocd.git.repo }} 23 | targetRevision: {{ .Values.argocd.git.revision }} 24 | path: {{ .Values.argocd.git.path }} 25 | helm: 26 | values: | 27 | argocdNamespace: {{ .Values.argocd.values.namespacePrefix }}{{- "{{" }} user {{- " }}" }} 28 | namespacePermissions: 29 | user: '{{- "{{" }} user {{- " }}" }}' 30 | role: edit 31 | repos: 32 | {{- range $repo := .Values.argocd.values.repos }} 33 | - type: {{ $repo.type }} 34 | name: {{ $repo.name }} 35 | url: {{ $.Values.argocd.git.url }}/{{- "{{" }} user {{- " }}" }}/{{ $repo.name }} 36 | username: '{{- "{{" }} user {{- " }}" }}' 37 | password: {{ $repo.password }} 38 | {{- end }} 39 | destination: 40 | server: https://kubernetes.default.svc 41 | syncPolicy: 42 | automated: 43 | prune: false 44 | selfHeal: false 45 | -------------------------------------------------------------------------------- /helm/bootstrap/templates/applicationset-devspaces.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: ApplicationSet 4 | metadata: 5 | name: devspaces 6 | namespace: openshift-gitops 7 | spec: 8 | generators: 9 | - list: 10 | elements: 11 | {{- $userCount := int .Values.user.count }} 12 | {{- range $index := until $userCount }} 13 | - user: {{ $.Values.user.prefix }}{{ add $index 1}} 14 | {{- end }} 15 | template: 16 | metadata: 17 | name: devspaces-{{- "{{" }} user {{- " }}" }} 18 | namespace: openshift-gitops 19 | spec: 20 | project: default 21 | source: 22 | repoURL: {{ .Values.devspaces.git.url }}/{{- "{{" }} user {{- " }}" }}/{{ .Values.devspaces.git.repo }} 23 | targetRevision: {{ .Values.devspaces.git.revision }} 24 | path: {{ .Values.devspaces.git.path }} 25 | helm: 26 | values: | 27 | namespace: '{{- "{{" }} user {{- " }}" }}{{ .Values.devspaces.values.namespacePostfix }}' 28 | user: '{{- "{{" }} user {{- " }}" }}' 29 | argocdNamespace: {{ .Values.argocd.values.namespacePrefix }}{{- "{{" }} user {{- " }}" }} 30 | subdomain: {{ .Values.deployer.domain }} 31 | namespacePermissions: 32 | user: '{{- "{{" }} user {{- " }}" }}' 33 | role: edit 34 | git: 35 | url: {{ .Values.devspaces.git.url | replace "http://" "" }} 36 | app: 37 | repo: 38 | ui: 39 | url: {{ .Values.devspaces.git.url }}/{{- "{{" }} user {{- " }}" }}/{{ .Values.devspaces.values.app.repo.ui.name }} 40 | revision: {{ .Values.devspaces.values.app.repo.ui.revision }} 41 | user: '{{- "{{" }} user {{- " }}" }}' 42 | password: {{ .Values.devspaces.values.app.repo.ui.password }} 43 | destination: 44 | server: https://kubernetes.default.svc 45 | syncPolicy: 46 | automated: 47 | prune: false 48 | selfHeal: true 49 | -------------------------------------------------------------------------------- /helm/bootstrap/templates/applicationset-tekton.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: argoproj.io/v1alpha1 3 | kind: ApplicationSet 4 | metadata: 5 | name: tekton 6 | namespace: openshift-gitops 7 | spec: 8 | generators: 9 | - list: 10 | elements: 11 | {{- $userCount := int .Values.user.count }} 12 | {{- range $index := until $userCount }} 13 | - user: {{ $.Values.user.prefix }}{{ add $index 1}} 14 | {{- end }} 15 | template: 16 | metadata: 17 | name: vote-app-ci-{{- "{{" }} user {{- " }}" }} 18 | namespace: openshift-gitops 19 | spec: 20 | project: default 21 | source: 22 | repoURL: {{ .Values.tekton.git.url }}/{{- "{{" }} user {{- " }}" }}/{{ .Values.tekton.git.repo }} 23 | targetRevision: {{ .Values.tekton.git.revision }} 24 | path: {{ .Values.tekton.git.path }} 25 | helm: 26 | values: | 27 | tektonNamespace: {{ .Values.tekton.values.namespacePrefix }}{{- "{{" }} user {{- " }}" }} 28 | argocdNamespace: {{ .Values.argocd.values.namespacePrefix }}{{- "{{" }} user {{- " }}" }} 29 | namespacePermissions: 30 | user: '{{- "{{" }} user {{- " }}" }}' 31 | role: edit 32 | app: 33 | namespaceDev: '{{ .Values.tekton.values.app.namespacePrefixDev }}{{- "{{" }} user {{- " }}" }}' 34 | namespaceProd: '{{ .Values.tekton.values.app.namespacePrefixProd }}{{- "{{" }} user {{- " }}" }}' 35 | repo: 36 | api: 37 | url: {{ .Values.tekton.git.url }}/{{- "{{" }} user {{- " }}" }}/{{ .Values.tekton.values.app.repo.api.name }} 38 | revision: {{ .Values.tekton.values.app.repo.api.revision }} 39 | user: '{{- "{{" }} user {{- " }}" }}' 40 | password: {{ .Values.tekton.values.app.repo.api.password }} 41 | ui: 42 | url: {{ .Values.tekton.git.url }}/{{- "{{" }} user {{- " }}" }}/{{ .Values.tekton.values.app.repo.ui.name }} 43 | revision: {{ .Values.tekton.values.app.repo.ui.revision }} 44 | user: '{{- "{{" }} user {{- " }}" }}' 45 | password: {{ .Values.tekton.values.app.repo.ui.password }} 46 | gitops: 47 | url: {{ .Values.tekton.git.url }}/{{- "{{" }} user {{- " }}" }}/{{ .Values.tekton.values.app.repo.gitops.name }} 48 | revision: {{ .Values.tekton.values.app.repo.gitops.revision }} 49 | user: '{{- "{{" }} user {{- " }}" }}' 50 | password: {{ .Values.tekton.values.app.repo.gitops.password }} 51 | destination: 52 | server: https://kubernetes.default.svc 53 | syncPolicy: 54 | automated: 55 | prune: false 56 | selfHeal: false 57 | -------------------------------------------------------------------------------- /helm/bootstrap/templates/clusterrole-cvsreader.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: clusterserviceversions-reader 5 | rules: 6 | - apiGroups: 7 | - operators.coreos.com 8 | resources: 9 | - clusterserviceversions 10 | verbs: 11 | - get 12 | - list 13 | -------------------------------------------------------------------------------- /helm/bootstrap/templates/configmap-userinfo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: userinfo 6 | namespace: {{ .Values.infoNamespace }} 7 | labels: 8 | demo.redhat.com/userinfo: "" 9 | data: 10 | usertool_url: "https://get-a-username-{{ .Values.usertool.namespace }}.{{ .Values.deployer.domain }}" 11 | argocd_url: "https://openshift-gitops-server-openshift-gitops.{{ .Values.deployer.domain }}" 12 | -------------------------------------------------------------------------------- /helm/bootstrap/templates/subscription-webterminal.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: operators.coreos.com/v1alpha1 2 | kind: Subscription 3 | metadata: 4 | labels: 5 | operators.coreos.com/web-terminal.openshift-operators: '' 6 | name: web-terminal 7 | namespace: openshift-operators 8 | spec: 9 | channel: fast 10 | installPlanApproval: Automatic 11 | name: web-terminal 12 | source: redhat-operators 13 | sourceNamespace: openshift-marketplace 14 | -------------------------------------------------------------------------------- /helm/bootstrap/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for bootstrap. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | user: 6 | count: 2 7 | prefix: user 8 | 9 | deployer: 10 | domain: apps.cluster-guid.sandbox.opentlc.com 11 | 12 | infoNamespace: openshift-gitops 13 | 14 | argocd: 15 | git: 16 | url: http://unknown:3000 17 | repo: vote-app-gitops 18 | revision: main 19 | path: helm/argocd 20 | values: 21 | namespacePrefix: argocd- 22 | # repos: 23 | # - type: git 24 | # name: app1 25 | # password: password 26 | 27 | tekton: 28 | git: 29 | url: http://unknown:3000 30 | repo: vote-app-gitops 31 | revision: main 32 | path: helm/tekton 33 | values: 34 | namespacePrefix: vote-app-ci- 35 | app: 36 | namespacePrefixDev: vote-app-dev- 37 | namespacePrefixProd: vote-app-prod- 38 | repo: 39 | api: 40 | name: pipelines-vote-api 41 | revision: master 42 | password: password 43 | ui: 44 | name: pipelines-vote-ui 45 | revision: master 46 | password: password 47 | gitops: 48 | name: vote-app-gitops 49 | revision: main 50 | password: password 51 | 52 | devspaces: 53 | git: 54 | url: http://unknown:3000 55 | repo: vote-app-gitops 56 | revision: main 57 | path: helm/devspaces 58 | values: 59 | namespacePostfix: -devspaces 60 | app: 61 | repo: 62 | ui: 63 | name: pipelines-vote-ui 64 | revision: master 65 | password: password 66 | 67 | usertool: 68 | repoUrl: https://github.com/redhat-gpte-devopsautomation/user-distribution 69 | repoRevision: v0.0.1 70 | repoPath: chart 71 | namespace: usertool 72 | image: quay.io/openshiftlabs/username-distribution:1.4 73 | redisImage: registry.redhat.io/rhel8/redis-6:1-118 74 | labDuration: 1week 75 | labAdminPassword: password 76 | labUserPassword: password 77 | labAccessToken: password 78 | 79 | guides: 80 | repoUrl: https://github.com/redhat-scholars/inner-outer-guides 81 | repoRevision: main 82 | repoPath: chart 83 | namespace: guides 84 | image: ghcr.io/redhat-scholars/inner-outer-guides:latest 85 | -------------------------------------------------------------------------------- /helm/devspaces/.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/devspaces/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: devspaces 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: 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 | -------------------------------------------------------------------------------- /helm/devspaces/templates/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: git-config 5 | namespace: {{ .Values.namespace }} 6 | annotations: 7 | controller.devfile.io/mount-as: subpath 8 | controller.devfile.io/mount-path: /etc/ 9 | labels: 10 | controller.devfile.io/mount-to-devworkspace: "true" 11 | controller.devfile.io/watch-configmap: "true" 12 | data: 13 | gitconfig: | 14 | [user] 15 | email = {{ .Values.user }}@redhat.com 16 | name = {{ .Values.user }} 17 | [alias] 18 | st = status 19 | co = checkout 20 | ci = commit -------------------------------------------------------------------------------- /helm/devspaces/templates/devworkspace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workspace.devfile.io/v1alpha2 2 | kind: DevWorkspace 3 | metadata: 4 | name: vote-ui 5 | namespace: {{ .Values.namespace }} 6 | spec: 7 | routingClass: che 8 | started: true 9 | contributions: 10 | - name: editor 11 | kubernetes: 12 | name: vscode 13 | template: 14 | components: 15 | - name: python 16 | container: 17 | image: quay.io/devfile/universal-developer-image:ubi8-latest 18 | env: 19 | - name: VOTING_API_SERVICE_HOST 20 | value: vote-api.vote-app-dev-{{ .Values.user }}.svc.cluster.local 21 | - name: VOTING_API_SERVICE_PORT 22 | value: '9000' 23 | cpuRequest: '30m' 24 | memoryRequest: '256Mi' 25 | cpuLimit: '1' 26 | memoryLimit: '2Gi' 27 | endpoints: 28 | - name: vote-ui 29 | targetPort: 8080 30 | commands: 31 | - id: run-python-app 32 | exec: 33 | label: Run Python App 34 | component: python 35 | commandLine: python app.py 36 | - id: install-dependencies 37 | exec: 38 | label: Install Dependencies 39 | component: python 40 | commandLine: pip install --user -r requirements.txt 41 | projects: 42 | - name: vote-ui-python 43 | git: 44 | remotes: 45 | origin: '{{ .Values.app.repo.ui.url }}.git' 46 | -------------------------------------------------------------------------------- /helm/devspaces/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: {{ .Values.namespace }} 6 | annotations: 7 | openshift.io/description: "Devspaces Namespace" 8 | openshift.io/display-name: "Devspaces Namespace" 9 | che.eclipse.org/username: {{ .Values.user }} 10 | openshift.io/requester: 'system:serviceaccount:openshift-operators:che' 11 | labels: 12 | argocd.argoproj.io/managed-by: {{ .Values.argocdNamespace }} 13 | app.kubernetes.io/component: workspaces-namespace 14 | app.kubernetes.io/part-of: che.eclipse.org 15 | kubernetes.io/metadata.name: {{ .Values.namespace }} 16 | -------------------------------------------------------------------------------- /helm/devspaces/templates/role-binding-user.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: {{ .Values.namespacePermissions.user }} 6 | namespace: {{ .Values.namespace }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: {{ .Values.namespacePermissions.role }} 11 | subjects: 12 | - apiGroup: rbac.authorization.k8s.io 13 | kind: User 14 | name: {{ .Values.namespacePermissions.user }} 15 | -------------------------------------------------------------------------------- /helm/devspaces/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: git-credentials 5 | namespace: {{ .Values.namespace }} 6 | annotations: 7 | controller.devfile.io/mount-path: /tmp/.git-credentials/ 8 | labels: 9 | controller.devfile.io/git-credential: "true" 10 | controller.devfile.io/watch-secret: "true" 11 | type: Opaque 12 | stringData: 13 | credentials: http://{{ .Values.app.repo.ui.user }}:{{ .Values.app.repo.ui.password }}@{{ .Values.git.url }} -------------------------------------------------------------------------------- /helm/devspaces/templates/vscode.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: workspace.devfile.io/v1alpha2 2 | kind: DevWorkspaceTemplate 3 | metadata: 4 | name: vscode 5 | namespace: {{ .Values.namespace }} 6 | spec: 7 | components: 8 | - name: vscode-injector 9 | container: 10 | image: quay.io/che-incubator/che-code:insiders 11 | command: 12 | - /entrypoint-init-container.sh 13 | volumeMounts: 14 | - name: checode 15 | path: /checode 16 | memoryLimit: 128Mi 17 | memoryRequest: 32Mi 18 | cpuLimit: 500m 19 | cpuRequest: 30m 20 | - name: vscode-runtime-description 21 | attributes: 22 | app.kubernetes.io/component: vscode-runtime 23 | app.kubernetes.io/part-of: vscode.eclipse.org 24 | controller.devfile.io/container-contribution: true 25 | container: 26 | image: noop/will/be/ignored 27 | volumeMounts: 28 | - name: checode 29 | path: /checode 30 | memoryLimit: 1024Mi 31 | memoryRequest: 256Mi 32 | cpuLimit: 500m 33 | cpuRequest: 30m 34 | env: 35 | - name: CODE_HOST 36 | value: "0.0.0.0" 37 | endpoints: 38 | - name: che-code 39 | attributes: 40 | type: main 41 | cookiesAuthEnabled: true 42 | discoverable: false 43 | urlRewriteSupported: true 44 | targetPort: 3100 45 | exposure: public 46 | secure: false 47 | protocol: https 48 | - name: code-redirect-1 49 | attributes: 50 | discoverable: false 51 | urlRewriteSupported: true 52 | targetPort: 13131 53 | exposure: public 54 | protocol: http 55 | - name: code-redirect-2 56 | attributes: 57 | discoverable: false 58 | urlRewriteSupported: true 59 | targetPort: 13132 60 | exposure: public 61 | protocol: http 62 | - name: code-redirect-3 63 | attributes: 64 | discoverable: false 65 | urlRewriteSupported: true 66 | targetPort: 13133 67 | exposure: public 68 | protocol: http 69 | - name: checode 70 | volume: {ephemeral: true} 71 | events: 72 | preStart: 73 | - init-container-command 74 | postStart: 75 | - inject-and-start-vscode 76 | commands: 77 | - id: init-container-command 78 | apply: 79 | component: vscode-injector 80 | - id: inject-and-start-vscode 81 | exec: 82 | component: vscode-runtime-description 83 | commandLine: 'nohup /checode/entrypoint-volume.sh > /checode/entrypoint-logs.txt 2>&1 &' 84 | -------------------------------------------------------------------------------- /helm/devspaces/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for tekton. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | namespace: devspaces 6 | 7 | argocdNamespace: argocd 8 | 9 | namespacePermissions: 10 | user: user 11 | role: edit 12 | 13 | user: user 14 | 15 | subdomain: subdomain.tld 16 | 17 | git: 18 | url: http://unknown:3000 19 | app: 20 | repo: 21 | ui: 22 | url: http://unknown:3000/user/my-app-ui 23 | revision: main 24 | user: user 25 | password: password 26 | -------------------------------------------------------------------------------- /helm/tekton/.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/tekton/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: tekton 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: 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 | -------------------------------------------------------------------------------- /helm/tekton/templates/git-update-deployment-task.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | annotations: 5 | tekton.dev/pipelines.minVersion: 0.12.1 6 | tekton.dev/tags: git 7 | name: git-update-deployment 8 | namespace: {{ .Values.tektonNamespace }} 9 | labels: 10 | app.kubernetes.io/version: '0.2' 11 | operator.tekton.dev/provider-type: community 12 | spec: 13 | description: >- 14 | This Task can be used to update image digest in a Git repo using kustomize. 15 | It requires a secret with credentials for accessing the git repo. 16 | params: 17 | - name: GIT_REPOSITORY 18 | type: string 19 | - name: GIT_REF 20 | type: string 21 | - name: CURRENT_IMAGE 22 | type: string 23 | - name: NEW_IMAGE 24 | type: string 25 | - name: NEW_DIGEST 26 | type: string 27 | - name: KUSTOMIZATION_PATH 28 | type: string 29 | results: 30 | - description: The commit SHA 31 | name: commit 32 | steps: 33 | - image: 'docker.io/alpine/git:v2.26.2' 34 | name: git-clone 35 | resources: {} 36 | script: > 37 | rm -rf git-update-digest-workdir 38 | 39 | git clone $(params.GIT_REPOSITORY) -b $(params.GIT_REF) 40 | git-update-digest-workdir 41 | workingDir: $(workspaces.workspace.path) 42 | - image: 'quay.io/wpernath/kustomize-ubi:latest' 43 | name: update-digest 44 | resources: {} 45 | script: > 46 | cd git-update-digest-workdir/$(params.KUSTOMIZATION_PATH) 47 | 48 | kustomize edit set image 49 | $(params.CURRENT_IMAGE)=$(params.NEW_IMAGE)@$(params.NEW_DIGEST) 50 | 51 | 52 | echo "##########################" 53 | 54 | echo "### kustomization.yaml ###" 55 | 56 | echo "##########################" 57 | 58 | cat kustomization.yaml 59 | workingDir: $(workspaces.workspace.path) 60 | - image: 'docker.io/alpine/git:v2.26.2' 61 | name: git-commit 62 | resources: {} 63 | script: | 64 | cd git-update-digest-workdir 65 | 66 | git config user.email "tektonbot@redhat.com" 67 | git config user.name "My Tekton Bot" 68 | 69 | git status 70 | git add $(params.KUSTOMIZATION_PATH)/kustomization.yaml 71 | git commit -m "[ci] Image digest updated" 72 | 73 | git push 74 | 75 | RESULT_SHA="$(git rev-parse HEAD | tr -d '\n')" 76 | EXIT_CODE="$?" 77 | if [ "$EXIT_CODE" != 0 ] 78 | then 79 | exit $EXIT_CODE 80 | fi 81 | # Make sure we don't add a trailing newline to the result! 82 | echo -n "$RESULT_SHA" > $(results.commit.path) 83 | workingDir: $(workspaces.workspace.path) 84 | workspaces: 85 | - description: The workspace consisting of maven project. 86 | name: workspace 87 | -------------------------------------------------------------------------------- /helm/tekton/templates/namespace-dev.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: {{ .Values.app.namespaceDev }} 6 | annotations: 7 | openshift.io/description: "Dev Namespace" 8 | openshift.io/display-name: "Dev Namespace" 9 | labels: 10 | argocd.argoproj.io/managed-by: {{ .Values.argocdNamespace }} 11 | -------------------------------------------------------------------------------- /helm/tekton/templates/namespace-prod.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: {{ .Values.app.namespaceProd }} 6 | annotations: 7 | openshift.io/description: "Prod Namespace" 8 | openshift.io/display-name: "Prod Namespace" 9 | labels: 10 | argocd.argoproj.io/managed-by: {{ .Values.argocdNamespace }} 11 | -------------------------------------------------------------------------------- /helm/tekton/templates/namespace-tekton.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Namespace 4 | metadata: 5 | name: {{ .Values.tektonNamespace }} 6 | annotations: 7 | openshift.io/description: "OpenShift Pipelines Namespace" 8 | openshift.io/display-name: "OpenShift Pipelines Namespace" 9 | -------------------------------------------------------------------------------- /helm/tekton/templates/pipeline-api.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: tekton.dev/v1beta1 3 | kind: Pipeline 4 | metadata: 5 | name: vote-app-api-pipeline 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | params: 9 | - name: SOURCE_GIT_URL 10 | type: string 11 | description: The application git repository url 12 | default: {{ .Values.app.repo.api.url }} 13 | - name: SOURCE_GIT_REVISION 14 | type: string 15 | default: {{ .Values.app.repo.api.revision }} 16 | description: The application git repository revision 17 | - default: image-registry.openshift-image-registry.svc:5000/{{ .Values.app.namespaceDev }}/vote-api 18 | name: IMAGE_NAME 19 | type: string 20 | - default: . 21 | name: PATH_CONTEXT 22 | type: string 23 | - default: {{ .Values.app.repo.gitops.url }} 24 | name: CONFIG_GIT_REPO 25 | type: string 26 | - default: {{ .Values.app.repo.gitops.revision }} 27 | name: CONFIG_GIT_REVISION 28 | type: string 29 | 30 | workspaces: 31 | - name: app-source 32 | 33 | tasks: 34 | 35 | - name: git-clone 36 | taskRef: 37 | kind: ClusterTask 38 | name: git-clone 39 | params: 40 | - name: url 41 | value: $(params.SOURCE_GIT_URL) 42 | - name: revision 43 | value: $(params.SOURCE_GIT_REVISION) 44 | - name: deleteExisting 45 | value: 'true' 46 | workspaces: 47 | - name: output 48 | workspace: app-source 49 | 50 | - name: build-and-push 51 | params: 52 | - name: IMAGE 53 | value: $(params.IMAGE_NAME) 54 | - name: TLSVERIFY 55 | value: "false" 56 | - name: CONTEXT 57 | value: $(params.PATH_CONTEXT) 58 | runAfter: 59 | - git-clone 60 | taskRef: 61 | kind: ClusterTask 62 | name: buildah 63 | workspaces: 64 | - name: source 65 | workspace: app-source 66 | 67 | - name: git-update-deployment 68 | params: 69 | - name: GIT_REPOSITORY 70 | value: $(params.CONFIG_GIT_REPO) 71 | - name: CURRENT_IMAGE 72 | value: quay.io/bluesman/vote-api:latest 73 | - name: NEW_IMAGE 74 | value: $(params.IMAGE_NAME) 75 | - name: NEW_DIGEST 76 | value: $(tasks.build-and-push.results.IMAGE_DIGEST) 77 | - name: KUSTOMIZATION_PATH 78 | value: environments/dev 79 | - name: GIT_REF 80 | value: $(params.CONFIG_GIT_REVISION) 81 | runAfter: 82 | - build-and-push 83 | taskRef: 84 | kind: Task 85 | name: git-update-deployment 86 | workspaces: 87 | - name: workspace 88 | workspace: app-source 89 | -------------------------------------------------------------------------------- /helm/tekton/templates/pipeline-promote-to-prod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Pipeline 3 | metadata: 4 | name: promote-to-prod 5 | namespace: {{ .Values.tektonNamespace }} 6 | spec: 7 | params: 8 | - default: {{ .Values.app.namespaceDev }}/vote-ui:latest 9 | name: SOURCE_IMAGE 10 | type: string 11 | - default: {{ .Values.app.namespaceProd }}/vote-ui:prod 12 | name: DEST_IMAGE 13 | type: string 14 | - default: {{ .Values.app.repo.gitops.url }} 15 | name: CONFIG_GIT_REPO 16 | type: string 17 | - default: {{ .Values.app.repo.gitops.revision }} 18 | name: CONFIG_GIT_REVISION 19 | type: string 20 | - default: >- 21 | image-registry.openshift-image-registry.svc:5000/{{ .Values.app.namespaceProd }}/vote-ui 22 | name: IMAGE_NAME 23 | type: string 24 | tasks: 25 | - name: tag-to-prod 26 | params: 27 | - name: SCRIPT 28 | value: oc tag $(params.SOURCE_IMAGE) $(params.DEST_IMAGE) 29 | - name: VERSION 30 | value: latest 31 | taskRef: 32 | kind: ClusterTask 33 | name: openshift-client 34 | - name: image-tag-to-digest 35 | params: 36 | - name: image_dest_url 37 | value: $(params.IMAGE_NAME) 38 | - name: image_dest_tag 39 | value: prod 40 | runAfter: 41 | - tag-to-prod 42 | taskRef: 43 | kind: Task 44 | name: image-tag-to-digest 45 | - name: git-update-deployment 46 | params: 47 | - name: GIT_REPOSITORY 48 | value: $(params.CONFIG_GIT_REPO) 49 | - name: GIT_REF 50 | value: $(params.CONFIG_GIT_REVISION) 51 | - name: CURRENT_IMAGE 52 | value: quay.io/bluesman/vote-ui:latest 53 | - name: NEW_IMAGE 54 | value: $(params.IMAGE_NAME) 55 | - name: NEW_DIGEST 56 | value: $(tasks.image-tag-to-digest.results.image_digest) 57 | - name: KUSTOMIZATION_PATH 58 | value: environments/prod 59 | runAfter: 60 | - image-tag-to-digest 61 | taskRef: 62 | kind: Task 63 | name: git-update-deployment 64 | workspaces: 65 | - name: workspace 66 | workspace: app-source 67 | workspaces: 68 | - name: app-source 69 | -------------------------------------------------------------------------------- /helm/tekton/templates/pipeline-ui.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: tekton.dev/v1beta1 3 | kind: Pipeline 4 | metadata: 5 | name: vote-app-ui-pipeline 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | params: 9 | - name: SOURCE_GIT_URL 10 | type: string 11 | description: The application git repository url 12 | default: {{ .Values.app.repo.ui.url }} 13 | - name: SOURCE_GIT_REVISION 14 | type: string 15 | default: {{ .Values.app.repo.ui.revision }} 16 | description: The application git repository revision 17 | - default: image-registry.openshift-image-registry.svc:5000/{{ .Values.app.namespaceDev }}/vote-ui 18 | name: IMAGE_NAME 19 | type: string 20 | - default: . 21 | name: PATH_CONTEXT 22 | type: string 23 | - default: {{ .Values.app.repo.gitops.url }} 24 | name: CONFIG_GIT_REPO 25 | type: string 26 | - default: {{ .Values.app.repo.gitops.revision }} 27 | name: CONFIG_GIT_REVISION 28 | type: string 29 | 30 | workspaces: 31 | - name: app-source 32 | 33 | tasks: 34 | 35 | - name: git-clone 36 | taskRef: 37 | kind: ClusterTask 38 | name: git-clone 39 | params: 40 | - name: url 41 | value: $(params.SOURCE_GIT_URL) 42 | - name: revision 43 | value: $(params.SOURCE_GIT_REVISION) 44 | - name: deleteExisting 45 | value: 'true' 46 | workspaces: 47 | - name: output 48 | workspace: app-source 49 | 50 | - name: build-and-push 51 | params: 52 | - name: IMAGE 53 | value: $(params.IMAGE_NAME) 54 | - name: TLSVERIFY 55 | value: "false" 56 | - name: CONTEXT 57 | value: $(params.PATH_CONTEXT) 58 | runAfter: 59 | - git-clone 60 | taskRef: 61 | kind: ClusterTask 62 | name: buildah 63 | workspaces: 64 | - name: source 65 | workspace: app-source 66 | 67 | - name: git-update-deployment 68 | params: 69 | - name: GIT_REPOSITORY 70 | value: $(params.CONFIG_GIT_REPO) 71 | - name: CURRENT_IMAGE 72 | value: quay.io/bluesman/vote-ui:latest 73 | - name: NEW_IMAGE 74 | value: $(params.IMAGE_NAME) 75 | - name: NEW_DIGEST 76 | value: $(tasks.build-and-push.results.IMAGE_DIGEST) 77 | - name: KUSTOMIZATION_PATH 78 | value: environments/dev 79 | - name: GIT_REF 80 | value: $(params.CONFIG_GIT_REVISION) 81 | runAfter: 82 | - build-and-push 83 | taskRef: 84 | kind: Task 85 | name: git-update-deployment 86 | workspaces: 87 | - name: workspace 88 | workspace: app-source 89 | -------------------------------------------------------------------------------- /helm/tekton/templates/pvc-api.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | name: workspace-api-app-source 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 2Gi 13 | -------------------------------------------------------------------------------- /helm/tekton/templates/pvc-ui.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | name: workspace-ui-app-source 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | accessModes: 9 | - ReadWriteOnce 10 | resources: 11 | requests: 12 | storage: 2Gi 13 | -------------------------------------------------------------------------------- /helm/tekton/templates/rolebinding-cvsreader.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: clusterserviceversions-reader-binding-{{ .Values.namespacePermissions.user }} 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: clusterserviceversions-reader 9 | subjects: 10 | - kind: User 11 | name: {{ .Values.namespacePermissions.user }} 12 | 13 | -------------------------------------------------------------------------------- /helm/tekton/templates/rolebinding-pipeline-edit-dev.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: {{ .Values.tektonNamespace }}-pipeline-edit 6 | namespace: {{ .Values.app.namespaceDev }} 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.tektonNamespace }} 15 | -------------------------------------------------------------------------------- /helm/tekton/templates/rolebinding-pipeline-edit-prod.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: {{ .Values.tektonNamespace }}-pipeline-edit 6 | namespace: {{ .Values.app.namespaceProd }} 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.tektonNamespace }} 15 | -------------------------------------------------------------------------------- /helm/tekton/templates/rolebinding-user-dev.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: dev-{{ .Values.namespacePermissions.user }} 6 | namespace: {{ .Values.app.namespaceDev }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: {{ .Values.namespacePermissions.role }} 11 | subjects: 12 | - apiGroup: rbac.authorization.k8s.io 13 | kind: User 14 | name: {{ .Values.namespacePermissions.user }} 15 | -------------------------------------------------------------------------------- /helm/tekton/templates/rolebinding-user-prod.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: dev-{{ .Values.namespacePermissions.user }} 6 | namespace: {{ .Values.app.namespaceProd }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: {{ .Values.namespacePermissions.role }} 11 | subjects: 12 | - apiGroup: rbac.authorization.k8s.io 13 | kind: User 14 | name: {{ .Values.namespacePermissions.user }} 15 | -------------------------------------------------------------------------------- /helm/tekton/templates/rolebinding-user-tekton.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: RoleBinding 4 | metadata: 5 | name: tekton-{{ .Values.namespacePermissions.user }} 6 | namespace: {{ .Values.tektonNamespace }} 7 | roleRef: 8 | apiGroup: rbac.authorization.k8s.io 9 | kind: ClusterRole 10 | name: {{ .Values.namespacePermissions.role }} 11 | subjects: 12 | - apiGroup: rbac.authorization.k8s.io 13 | kind: User 14 | name: {{ .Values.namespacePermissions.user }} 15 | -------------------------------------------------------------------------------- /helm/tekton/templates/secret-gitea-repo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: gitea-source 6 | namespace: {{ .Values.tektonNamespace }} 7 | annotations: 8 | tekton.dev/git-0: {{ .Values.app.repo.api.url }} 9 | type: kubernetes.io/basic-auth 10 | stringData: 11 | username: {{ .Values.app.repo.api.user }} 12 | password: {{ .Values.app.repo.api.password }} 13 | --- 14 | apiVersion: v1 15 | kind: Secret 16 | metadata: 17 | name: gitea-ui 18 | namespace: {{ .Values.tektonNamespace }} 19 | annotations: 20 | tekton.dev/git-0: {{ .Values.app.repo.ui.url }} 21 | type: kubernetes.io/basic-auth 22 | stringData: 23 | username: {{ .Values.app.repo.ui.user }} 24 | password: {{ .Values.app.repo.ui.password }} 25 | --- 26 | apiVersion: v1 27 | kind: Secret 28 | metadata: 29 | name: gitea-gitops 30 | namespace: {{ .Values.tektonNamespace }} 31 | annotations: 32 | tekton.dev/git-0: {{ .Values.app.repo.gitops.url }} 33 | type: kubernetes.io/basic-auth 34 | stringData: 35 | username: {{ .Values.app.repo.gitops.user }} 36 | password: {{ .Values.app.repo.gitops.password }} 37 | -------------------------------------------------------------------------------- /helm/tekton/templates/serviceaccount-pipeline.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: pipeline 6 | namespace: {{ .Values.tektonNamespace }} 7 | secrets: 8 | - name: gitea-source 9 | -------------------------------------------------------------------------------- /helm/tekton/templates/task-image-tag-to-digest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: tekton.dev/v1beta1 2 | kind: Task 3 | metadata: 4 | name: image-tag-to-digest 5 | namespace: {{ .Values.tektonNamespace }} 6 | spec: 7 | params: 8 | - name: image_dest_url 9 | description: The location of the image without the tag 10 | type: string 11 | - name: image_dest_tag 12 | description: the tag of the image to return the hash for 13 | type: string 14 | results: 15 | - description: The digest for the image created 16 | name: image_digest 17 | steps: 18 | - name: get-image-digest 19 | image: quay.io/gnunn/tools:4.10-1 20 | script: | 21 | #!/usr/bin/env bash 22 | 23 | DIGEST=$(skopeo inspect docker://$(params.image_dest_url):$(params.image_dest_tag) | jq -r .Digest) 24 | 25 | echo "Digest for image $(params.image_dest_url):$(params.image_dest_tag) is '${DIGEST}'" 26 | 27 | echo -n "$DIGEST" > $(results.image_digest.path) -------------------------------------------------------------------------------- /helm/tekton/templates/trigger-binding.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: triggers.tekton.dev/v1alpha1 3 | kind: TriggerBinding 4 | metadata: 5 | name: gitea 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | params: 9 | - name: git-repo-url 10 | value: $(body.repository.clone_url) 11 | - name: git-revision 12 | value: $(body.after) 13 | -------------------------------------------------------------------------------- /helm/tekton/templates/trigger-eventlistener-api.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: triggers.tekton.dev/v1alpha1 3 | kind: EventListener 4 | metadata: 5 | name: eventlistener-api 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | serviceAccountName: pipeline 9 | triggers: 10 | - name: gitea-vote-app-api-pipeline 11 | bindings: 12 | - ref: gitea 13 | template: 14 | ref: vote-app-api-pipeline 15 | -------------------------------------------------------------------------------- /helm/tekton/templates/trigger-eventlistener-route-api.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: route.openshift.io/v1 3 | kind: Route 4 | metadata: 5 | name: el-api 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | port: 9 | targetPort: http-listener 10 | to: 11 | kind: Service 12 | name: el-eventlistener-api 13 | weight: 100 14 | -------------------------------------------------------------------------------- /helm/tekton/templates/trigger-eventlistener-route-ui.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: route.openshift.io/v1 3 | kind: Route 4 | metadata: 5 | name: el-ui 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | port: 9 | targetPort: http-listener 10 | to: 11 | kind: Service 12 | name: el-eventlistener-ui 13 | weight: 100 14 | -------------------------------------------------------------------------------- /helm/tekton/templates/trigger-eventlistener-ui.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: triggers.tekton.dev/v1alpha1 3 | kind: EventListener 4 | metadata: 5 | name: eventlistener-ui 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | serviceAccountName: pipeline 9 | triggers: 10 | - name: gitea-vote-app-ui-pipeline 11 | bindings: 12 | - ref: gitea 13 | template: 14 | ref: vote-app-ui-pipeline 15 | -------------------------------------------------------------------------------- /helm/tekton/templates/trigger-template-api.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: triggers.tekton.dev/v1alpha1 3 | kind: TriggerTemplate 4 | metadata: 5 | name: vote-app-api-pipeline 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | params: 9 | - name: git-repo-url 10 | - name: git-revision 11 | resourcetemplates: 12 | - apiVersion: tekton.dev/v1beta1 13 | kind: PipelineRun 14 | metadata: 15 | generateName: vote-app-api-pipeline- 16 | spec: 17 | params: 18 | - name: SOURCE_GIT_URL 19 | value: $(tt.params.git-repo-url) 20 | - name: SOURCE_GIT_REVISION 21 | value: $(tt.params.git-revision) 22 | pipelineRef: 23 | name: vote-app-api-pipeline 24 | workspaces: 25 | - name: app-source 26 | persistentVolumeClaim: 27 | claimName: workspace-api-app-source 28 | 29 | -------------------------------------------------------------------------------- /helm/tekton/templates/trigger-template-ui.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: triggers.tekton.dev/v1alpha1 3 | kind: TriggerTemplate 4 | metadata: 5 | name: vote-app-ui-pipeline 6 | namespace: {{ .Values.tektonNamespace }} 7 | spec: 8 | params: 9 | - name: git-repo-url 10 | - name: git-revision 11 | resourcetemplates: 12 | - apiVersion: tekton.dev/v1beta1 13 | kind: PipelineRun 14 | metadata: 15 | generateName: vote-app-ui-pipeline- 16 | spec: 17 | params: 18 | - name: SOURCE_GIT_URL 19 | value: $(tt.params.git-repo-url) 20 | - name: SOURCE_GIT_REVISION 21 | value: $(tt.params.git-revision) 22 | pipelineRef: 23 | name: vote-app-ui-pipeline 24 | workspaces: 25 | - name: app-source 26 | persistentVolumeClaim: 27 | claimName: workspace-ui-app-source 28 | 29 | -------------------------------------------------------------------------------- /helm/tekton/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for tekton. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | tektonNamespace: tekton 6 | 7 | argocdNamespace: argocd 8 | 9 | namespacePermissions: 10 | user: user 11 | role: edit 12 | 13 | app: 14 | namespaceDev: dev 15 | namespaceProd: prod 16 | repo: 17 | api: 18 | url: http://unknown:3000/user/my-app 19 | revision: main 20 | user: user 21 | password: password 22 | ui: 23 | url: http://unknown:3000/user/my-app-ui 24 | revision: main 25 | user: user 26 | password: password 27 | gitops: 28 | url: http://unknown:3000/user/my-app 29 | revision: main 30 | user: user 31 | password: password 32 | -------------------------------------------------------------------------------- /images/argocd-create-vote-app-prod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/argocd-create-vote-app-prod.png -------------------------------------------------------------------------------- /images/argocd-sync-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/argocd-sync-app.png -------------------------------------------------------------------------------- /images/argocd-vote-app-dev-details.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/argocd-vote-app-dev-details.png -------------------------------------------------------------------------------- /images/argocd-vote-app-dev-out-of-sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/argocd-vote-app-dev-out-of-sync.png -------------------------------------------------------------------------------- /images/argocd-vote-app-dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/argocd-vote-app-dev.png -------------------------------------------------------------------------------- /images/argocd-vote-app-prod-sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/argocd-vote-app-prod-sync.png -------------------------------------------------------------------------------- /images/argocd-vote-app-prod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/argocd-vote-app-prod.png -------------------------------------------------------------------------------- /images/codeready-installation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/codeready-installation.png -------------------------------------------------------------------------------- /images/crw-vote-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/crw-vote-ui.png -------------------------------------------------------------------------------- /images/demo-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/demo-architecture.png -------------------------------------------------------------------------------- /images/el-trigger-vote-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/el-trigger-vote-ui.png -------------------------------------------------------------------------------- /images/el-trigger.vote-api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/el-trigger.vote-api.png -------------------------------------------------------------------------------- /images/pipeline-triggers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/pipeline-triggers.png -------------------------------------------------------------------------------- /images/pipeline-vote-ui-start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/pipeline-vote-ui-start.png -------------------------------------------------------------------------------- /images/pipelines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/pipelines.png -------------------------------------------------------------------------------- /images/quay-create-repo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/quay-create-repo.png -------------------------------------------------------------------------------- /images/quay-encrypted-key.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/quay-encrypted-key.png -------------------------------------------------------------------------------- /images/quay-repo-created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/quay-repo-created.png -------------------------------------------------------------------------------- /images/quay-vote-ui-scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/quay-vote-ui-scan.png -------------------------------------------------------------------------------- /images/start-api-pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/start-api-pipeline.png -------------------------------------------------------------------------------- /images/topology-vote-app-dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/topology-vote-app-dev.png -------------------------------------------------------------------------------- /images/topology-vote-app-prod-scaled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/topology-vote-app-prod-scaled.png -------------------------------------------------------------------------------- /images/topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/topology.png -------------------------------------------------------------------------------- /images/vote-app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/vote-app.png -------------------------------------------------------------------------------- /images/vote-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/vote-ui.png -------------------------------------------------------------------------------- /images/vote-ui2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/vote-ui2.png -------------------------------------------------------------------------------- /images/webhook-vote-api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/webhook-vote-api.png -------------------------------------------------------------------------------- /images/webhook-vote-ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blues-man/vote-app-gitops/239329d6b19c14ac52b269f834011d0e222460b9/images/webhook-vote-ui.png -------------------------------------------------------------------------------- /k8s/api-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | app: vote-api 6 | app.kubernetes.io/part-of: vote-app 7 | app.kubernetes.io/name: golang 8 | name: vote-api 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | app: vote-api 14 | strategy: 15 | rollingUpdate: 16 | maxSurge: 25% 17 | maxUnavailable: 25% 18 | type: RollingUpdate 19 | template: 20 | metadata: 21 | labels: 22 | app: vote-api 23 | spec: 24 | containers: 25 | - image: quay.io/bluesman/vote-api:latest 26 | imagePullPolicy: Always 27 | name: vote-api 28 | ports: 29 | - containerPort: 8080 30 | protocol: TCP 31 | resources: {} 32 | terminationMessagePath: /dev/termination-log 33 | terminationMessagePolicy: File 34 | dnsPolicy: ClusterFirst 35 | restartPolicy: Always 36 | schedulerName: default-scheduler 37 | securityContext: {} 38 | terminationGracePeriodSeconds: 30 39 | -------------------------------------------------------------------------------- /k8s/api-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: vote-api 6 | name: vote-api 7 | spec: 8 | ports: 9 | - name: 9000-tcp 10 | port: 9000 11 | protocol: TCP 12 | targetPort: 9000 13 | selector: 14 | app: vote-api 15 | sessionAffinity: None 16 | type: ClusterIP 17 | -------------------------------------------------------------------------------- /k8s/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - api-deployment.yaml 3 | - api-service.yaml 4 | - ui-deployment.yaml 5 | - ui-service.yaml 6 | - ui-route.yaml 7 | -------------------------------------------------------------------------------- /k8s/ui-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | app: vote-ui 6 | app.kubernetes.io/part-of: vote-app 7 | app.kubernetes.io/name: python 8 | name: vote-ui 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | app: vote-ui 14 | strategy: 15 | rollingUpdate: 16 | maxSurge: 25% 17 | maxUnavailable: 25% 18 | type: RollingUpdate 19 | template: 20 | metadata: 21 | labels: 22 | app: vote-ui 23 | spec: 24 | containers: 25 | - env: 26 | - name: VOTING_API_SERVICE_HOST 27 | value: vote-api 28 | - name: VOTING_API_SERVICE_PORT 29 | value: "9000" 30 | image: quay.io/bluesman/vote-ui:latest 31 | imagePullPolicy: Always 32 | name: vote-ui 33 | ports: 34 | - containerPort: 8080 35 | protocol: TCP 36 | resources: {} 37 | terminationMessagePath: /dev/termination-log 38 | terminationMessagePolicy: File 39 | dnsPolicy: ClusterFirst 40 | restartPolicy: Always 41 | schedulerName: default-scheduler 42 | securityContext: {} 43 | terminationGracePeriodSeconds: 30 44 | -------------------------------------------------------------------------------- /k8s/ui-route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | labels: 5 | app: vote-ui 6 | app.kubernetes.io/part-of: vote-app 7 | name: vote-ui 8 | spec: 9 | port: 10 | targetPort: 8080-tcp 11 | tls: 12 | insecureEdgeTerminationPolicy: Redirect 13 | termination: edge 14 | to: 15 | kind: Service 16 | name: vote-ui 17 | weight: 100 18 | wildcardPolicy: None 19 | -------------------------------------------------------------------------------- /k8s/ui-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | app: vote-ui 6 | app.kubernetes.io/part-of: vote-app 7 | name: vote-ui 8 | spec: 9 | ports: 10 | - name: 8080-tcp 11 | port: 8080 12 | protocol: TCP 13 | targetPort: 8080 14 | selector: 15 | app: vote-ui 16 | sessionAffinity: None 17 | type: ClusterIP 18 | --------------------------------------------------------------------------------