# KubeRocketCI Documentation
> Explore KubeRocketCI Documentation for CI/CD, operator and user guides, quick start, and API. Learn how to enhance your DevOps practices with KubeRocketCI.
This file contains all documentation content in a single document following the llmstxt.org standard.
## About the KubeRocketCI Platform
# About the KubeRocketCI Platform
**KubeRocketCI (previously known as EPAM Delivery Platform)** is an **open-source** cloud-agnostic SaaS/PaaS solution for software development, licensed under **Apache License 2.0**. It provides a pre-defined set of CI/CD patterns and tools, which allow a user to start product development quickly with established **code review**, **release**, **versioning**, **branching**, **build** processes. These processes include static code analysis, security checks, linters, validators, dynamic feature environments provisioning. Platform consolidates the top Open-Source CI/CD tools by running them on Kubernetes/OpenShift, enabling web/app development in isolated (on-prem) or cloud environments.
KubeRocketCI, which is also called **"The Rocket"**, is a platform that allows shortening the time that is passed before an active development can start from several months to several hours.
The platform consists of the following blocks:
- The platform is based on managed infrastructure and container orchestration
- Security covering authentication, authorization, and SSO for platform services
- Development and testing toolset
- Well-established engineering process and EPAM practices (EngX) reflected in CI/CD pipelines and delivery analytics
- A set of pre-configured pipelines for different types of applications (polyglot microservices)
- Observability stack
## Features
- Deployed and configured CI/CD toolset ([Tekton](https://tekton.dev/), [ArgoCD](https://argoproj.github.io/cd/), [Nexus Repository Manager](https://help.sonatype.com/en/sonatype-nexus-repository.html), [SonarQube](https://www.sonarsource.com/), [DefectDojo](https://www.defectdojo.org/), [Dependency-Track](https://dependencytrack.org/)).
- [GitHub](https://about.gitlab.com/features/)(by default), [GitLab](https://about.gitlab.com/features/), [Bitbucket](https://www.atlassian.com/software/bitbucket/features/pipelines) or [Gerrit](https://gerrit-review.googlesource.com/Documentation/intro-quick.html).
- [Tekton](./operator-guide/install-tekton.md) is a pipeline orchestrator.
- [CI pipelines](./user-guide/index.md) for polyglot applications:
|Language|Framework|Build Tool|Application|Library|Autotest|
|:-|:-:|:-:|:-:|:-:|:-:|
|Java|Java 17, Java 21, Java 25|Gradle, Maven|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|Python|Python 3.8, FastAPI, Flask|Python|:white_check_mark:|:white_check_mark:||
|C#|.Net 3.1, .Net 6.0|.Net|:white_check_mark:|:white_check_mark:||
|C|None|Make,CMake|:white_check_mark:|||
|C++|None|Make,CMake|:white_check_mark:|||
|Go|Beego, Gin, Operator SDK|Go|:white_check_mark:|||
|JavaScript|React, Vue, Angular, Express, Next.js, Antora|NPM, PNPM|:white_check_mark:|:white_check_mark:||
|HCL|Terraform|Terraform||:white_check_mark:||
|Helm|Helm, Pipeline|Helm||:white_check_mark:||
|Groovy|Codenarc|Codenarc||:white_check_mark:||
|Rego|OPA|OPA||:white_check_mark:||
|Container|Docker|Kaniko||:white_check_mark:||
:::note
As of KubeRocketCI version 3.12, Java 8 and Java 11 frameworks have been deprecated.
:::
- [Portal UI](./user-guide/index.md) as a single entry point
- [Deployment Flows](./user-guide/add-cd-pipeline.md) for Microservice Deployment
- Kubernetes native approach ([CRD, CR](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/)) to declare CI/CD pipelines
## What's Inside KubeRocketCI
KubeRocketCI offers a comprehensive solution for the entire software delivery lifecycle, from development to deploying production environments. It's designed to be suitable for all aspects of delivery, ensuring a seamless and efficient process.
Platform modules are represented on a diagram below (more [on the Reference Architecture](./developer-guide/reference-architecture.md) page)

The architecture of KubeRocketCI is designed to support a broad range of delivery aspects effectively:
1. **Infrastructure as a Service (IaaS)**: The platform leverages managed infrastructure services, providing a robust foundation for container orchestration and other platform services. Central to our approach to IaaS is the adoption of the **Infrastructure as Code (IaC)** methodology. This methodology ensures that infrastructure is defined and managed through code, enabling the automation of infrastructure provisioning and management.
2. **GitOps Approach**: Embracing GitOps principles, KubeRocketCI ensures an efficient and reliable way to manage deployments and configurations using Git as the single source of truth. This approach is applied not only for deploying **business applications** but also for the robust **management of the platform itself**, utilizing an [add-ons methodology](https://github.com/epam/edp-cluster-add-ons). By treating both platform components and business applications as code, KubeRocketCI facilitates automated, transparent, and collaborative processes, significantly enhancing deployment velocity and platform governance.
3. **Container Orchestration and Centralized Services**: At its core, the platform utilizes Kubernetes/OpenShift for orchestrating containerized applications, coupled with centralized services to manage the lifecycle of these applications.
4. **Security**: Comprehensive security measures are in place, covering authentication, authorization, and Single Sign-On (SSO) for platform services, ensuring the safeguarding of your applications and data.
On top of the primary architectural pillars, KubeRocketCI integrates several key components to enhance the CI/CD process:
**CI/CD Components**: These components support various CI/CD functionalities, like artifacts storage and distribution (via Nexus or Artifactory), static code analysis (Sonar), and more.
**Artifacts Management**: Representing the deliverables within the pipelines, artifacts can range from frontend and backend applications to functional and non-functional autotests, and workloads for 3rd party components.
**Development and Production Deployment Flows**: Deployment Flows in KubeRocketCI maintain consistency across development and production, encapsulating artifacts with specific versions to ensure quality through the Software Development Life Cycle (SDLC).
**Pipelines**: Covering the end-to-end CI/CD process, pipelines in KubeRocketCI automate the integration and delivery workflows, connecting the above components seamlessly.
### Technology Stack
KubeRocketCI's technology stack is adaptable to most popular public clouds such as AWS, Azure, and GCP, with support for private/hybrid clouds based on OpenStack. The containerization layer is powered by Kubernetes or OpenShift, offering flexibility and choice in deployment options.
Explore the KubeRocketCI technology stack diagram

The platform provides two main options for Kubernetes:
- Managed Kubernetes in Public Clouds to avoid installation and management of Kubernetes cluster, and get all benefits of scaling, reliability of this solution;
- OpenShift is a Platform as a Service on the top of Kubernetes from Red Hat. OpenShift is the default option for on-premise installation and it can be considered whether the _solution built on the top of KubeRocketCI_ should be **cloud-agnostic** or require **enterprise support**;
There is **no limitation** to run KubeRocketCI on vanilla Kubernetes.
## Related Articles
- [Quick Start](./quick-start/platform-installation.md)
- [Basic Concepts](basic-concepts.md)
- [Glossary](glossary.md)
- [Supported Versions and Compatibility](supported-versions.md)
---
## Basic Concepts
# Basic Concepts
Consult [KubeRocketCI Glossary](./glossary.md) section for definitions mentioned on this page. The below table contains a list of capabilities provided by the platform.
|Features|Description|
|-|-|
|**Cloud Agnostic**|Platform runs on any Kubernetes cluster, including those provided by Public Cloud Providers or deployed on-premises.|
|**CI/CD for Microservices**|KubeRocketCI is designed to support CI/CD for [Microservices](https://microservices.io/) running as containerized applications inside a Kubernetes Cluster. It provides CI Pipelines for [different technology stacks](./about-platform.md#features).|
|**Version Control System (VCS)**|The platform integrates with **GitHub**, **GitLab**, **Bitbucket**, and **Gerrit**.|
|**Branching Strategy**|KubeRocketCI supports both [Trunk-based](https://trunkbaseddevelopment.com/) development and [GitHub/GitLab flow](https://docs.github.com/en/get-started/using-github/github-flow). It creates two Pipelines per Project branch: *Code Review* and *Build*.|
|**Repository Structure**|By default, the platform provides a separate Git repository for each Project (also Codebase). It does not support *Monorepo* out of the box, but can be customized to align with the *Monorepo* approach.|
|**Artifacts Versioning**|The platform supports two approaches for Artifacts versioning: - `default` (BRANCH-[DATETIME])- `SEMVER` (MAJOR.MINOR.PATCH-BUILD_ID), which follows [SemVer](https://semver.org/). You can also create custom versioning by implementing the `get-version` CI step.|
|**Application Library**|KubeRocketCI offers baseline codebase templates for Microservices and Libraries, using the *create* strategy when onboarding new Projects.|
|**CI Pipelines**|The platform provides CI Pipelines for [different technology stacks](./about-platform.md#features).|
|**CD Pipelines**|KubeRocketCI allows you to design CD Pipelines (in Portal UI) for Microservices and defines the logic for artifact flow (promotion) from lower to higher environments. Artifact promotion can be performed automatically (*Autotests*), manually (*User Approval*), or using a combination of both.|
|**Autotests**|KubeRocketCI provides a CI pipeline for autotests implemented in Java. These autotests can be used as *Quality Gates* in CD Pipelines.|
|**Custom Pipeline Library**|You can extend KubeRocketCI pipelines by introducing a Custom Pipeline Library.|
|**Dynamic Environments**|KubeRocketCI's CD Pipelines can create and destroy environments based on user requests, allowing for flexible and dynamic deployment of applications.|
|**GitOps Approach**| The platform adopts a GitOps approach for CI/CD, using Git repositories as the single source of truth for infrastructure and application configuration. This practice enhances collaboration, simplifies the deployment process, and improves the auditability of changes.|
|**Monitoring and Observability**| The platform includes an observability stack that enables logging, monitoring, and tracing of applications and infrastructure. This helps in identifying issues early and maintaining the health and performance of the deployed applications.|
|**Security Covering Authentication, Authorization, and SSO for Platform Services**| KubeRocketCI implements robust security mechanisms, including authentication, authorization, and Single Sign-On (SSO) capabilities for all platform services. This ensures that access to the platform is secure and controlled, aligning with best practices for cloud-native application development.|
|**Static Application Security Testing (SAST)**| KubeRocketCI integrates tools that perform [static analysis](operator-guide/devsecops/overview.md) of the source code to identify potential vulnerabilities early in the development process. This analysis is performed without executing the code and can pinpoint issues such as input validation errors, insecure dependencies, and other common vulnerabilities.|
|**Container Registries**| KubeRocketCI demonstrates adaptability and interoperability with leading [container registries](user-guide/manage-container-registries.md), empowering developers to select the most suitable tools and services based on their specific project requirements. The integration process is designed to be as simple as possible, making it easy for developers to connect their projects with the desired registries. The incorporation of these registries is pivotal in upholding the security, effectiveness, and dependability of the CI/CD pipeline.|
---
## Compliance
# Compliance
The integrity of your deployments is our paramount commitment. We are devoted to strengthening our Kubernetes platform to comply with the most stringent security standards. Trust is the bedrock of our relationships, and we manifest this commitment by undergoing rigorous third-party audits to ensure compliance. We pledge unwavering support as you manage and deploy solutions within your environment, emphasizing security and reliability. Examine our compliance with various frameworks, laws, and regulations to understand our dedication to upholding robust security standards for the solutions you manage and deploy.
[](https://cloudsecurityalliance.org/star/registry/epam/services/epam-delivery-platform/)
---
## Annotations and Labels
# Annotations and Labels
KubeRocketCI uses labels to interact with various resources in a Kubernetes cluster. This guide details the resources, annotations, and labels used by the platform to streamline operations, enhance monitoring, and enforce governance.
## Labels
The table below contains all the labels used in KubeRocketCI:
| Label Key | Target Resources | Possible Values | Description |
| :---------------------------------- |:---------------------------------| :----------------------------------------------------------------------------------| :-------------------------------------------------------------------------- |
| app.edp.epam.com/secret-type | Secrets | `jira`, `nexus`, `sonar`, `defectdojo`, `dependency-track`,`repository` | Identifies the type of the secret. |
| app.edp.epam.com/integration-secret | Secrets | `true` | Indicates if the secret is used for integration. |
| app.edp.epam.com/integration | Codebase | `codemie` | Indicates that the codebase should be integrated with Codemie. When applied, the Codemie operator reconciles the codebase and creates a Codemie Application. |
| app.edp.epam.com/codebase | PipelineRun, CodebaseImageStream | `` | Identifies the codebase associated with the PipelineRun and CodebaseImageStream. |
| app.edp.epam.com/codebasebranch | PipelineRun, CodebaseImageStream | `` | Identifies the codebase branch associated with the PipelineRun and CodebaseImageStream. |
| app.edp.epam.com/pipeline | PipelineRun, TaskRun | `` | Used by the KubeRocketCI to display autotests' status (on Deploy environment) |
| app.edp.epam.com/triggertemplate | Pipeline, PipelineRun | `` | Allows to pull default parameters from the TriggerTemplate resource. |
| app.edp.epam.com/pipelinetype | Pipeline, PipelineRun, TaskRun | `autotestRunner`, `build`, `review`, `deploy`, `clean` | Identifies the Pipeline type. |
| app.edp.epam.com/parentPipelineRun | PipelineRun | `` | Used by the KubeRocketCI to display autotests' status (on Deploy environment) |
| app.edp.epam.com/stage | PipelineRun, TaskRun | `` | Used by the KubeRocketCI to display autotests' status (on Deploy environment) |
| app.edp.epam.com/branch | PipelineRun | `` | Identifies the branch associated with the PipelineRun. |
| app.edp.epam.com/codebaseType | Codebase | `system`,`application` | Identifies the type of the codebase. |
| app.edp.epam.com/systemType | Codebase | `gitops` | Identifies system repositories. |
| app.edp.epam.com/gitServer | Ingress, EventListener, Trigger | `` | Identifies resources associated with the Git Server. On a Trigger, registers it with the Git Server's EventListener via its labelSelector. |
| app.edp.epam.com/cdpipeline | PipelineRun, TaskRun | `` | Identifies Deployment Flow associated with the Pipeline Run. |
| app.edp.epam.com/cdstage | PipelineRun, TaskRun | `` | Identifies Environment associated with the Pipeline Run. |
| app.edp.epam.com/edit-protection | Codebase, CodebaseBranch, CDPipeline, Stage | `delete-update`, `delete`, `update` | When applied to a resource, protects a resource from deletion and/or modification. |
### Labels Usage in Secrets
The table below shows what labels are used by specific secrets:
| Secret Name | Labels |
| :------------------- | :------------------------------------------------------------------------------------------- |
| ci-argocd | app.edp.epam.com/integration-secret=true app.edp.epam.com/secret-type=argocd |
| ci-defectdojo | app.edp.epam.com/integration-secret=true app.edp.epam.com/secret-type=defectdojo |
| ci-dependency-track | app.edp.epam.com/integration-secret=true app.edp.epam.com/secret-type=dependency-track |
| ci-jira | app.edp.epam.com/secret-type=jira |
| ci-nexus | app.edp.epam.com/integration-secret=true app.edp.epam.com/secret-type=nexus |
| ci-sonarqube | app.edp.epam.com/integration-secret=true app.edp.epam.com/secret-type=sonar |
| gerrit-ciuser-sshkey | app.edp.epam.com/secret-type=repository |
| kaniko-docker-config | app.edp.epam.com/integration-secret=true app.edp.epam.com/secret-type=registry |
| regcred | app.edp.epam.com/integration-secret=true app.edp.epam.com/secret-type=registry |
### Labels Usage in Tekton Pipeline Runs
The table below displays what labels are used in specific Tekton pipelines:
| PipelineRun | Labels |
| :----------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| review-pipeline | app.edp.epam.com/codebase: `` app.edp.epam.com/codebasebranch: ``-`` app.edp.epam.com/pipelinetype: `review` |
| build-pipeline | app.edp.epam.com/codebase: `` app.edp.epam.com/codebasebranch: ``-`` app.edp.epam.com/pipelinetype: `build` |
| autotest-runner-pipeline | app.edp.epam.com/pipeline: `` app.edp.epam.com/pipelinetype: `autotestRunner` app.edp.epam.com/stage: `` |
| autotest-pipeline | app.edp.epam.com/branch: `` app.edp.epam.com/codebase: `` app.edp.epam.com/parentPipelineRun: ``-`` app.edp.epam.com/pipeline: `` app.edp.epam.com/stage: `` |
| deploy | app.edp.epam.com/cdpipeline: `` app.edp.epam.com/cdstage: `` app.edp.epam.com/pipelinetype: `deploy` |
| clean | app.edp.epam.com/cdpipeline: `` app.edp.epam.com/cdstage: `` app.edp.epam.com/pipelinetype: `clean` |
### Pipeline Usage Example
To demonstrate label usage in the Tekton pipelines, find below some KubeRocketCI resource examples:
```yaml title="Codebase specification"
metadata:
...
name: demo
...
spec:
...
defaultBranch: main
type: application
framework: react
lang: javascript
...
```
```yaml title="CD Pipeline specification"
spec:
...
applications:
- demo
inputDockerStreams:
- demo-main
name: mypipe
...
```
```yaml title="Stage specification"
spec:
...
cdPipeline: mypipe
name: dev
namespace: krci-delivery-ms-delivery-dev-mypipe-dev
qualityGates:
- autotestName: autotests
branchName: master
qualityGateType: autotests
stepName: autotest
...
```
The table below shows all the pipelines associated with the `demo` codebase:
| Pipeline Name | Type | Labels |
| :--------------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| gerrit-npm-react-app-review | Review | app.edp.epam.com/codebase: demo app.edp.epam.com/codebasebranch: demo-main app.edp.epam.com/pipelinetype: review |
| gerrit-npm-react-app-build-default | Build | app.edp.epam.com/codebase: demo app.edp.epam.com/codebasebranch: demo-main app.edp.epam.com/pipelinetype: build |
| autotest-runner | Deploy | app.edp.epam.com/pipeline: mypipe app.edp.epam.com/pipelinetype: autotestRunner app.edp.epam.com/stage: dev |
| autotests-gradle, autotests-maven | Deploy | app.edp.epam.com/branch: master app.edp.epam.com/codebase: autotests app.edp.epam.com/parentPipelineRun: mypipe-dev-hash app.edp.epam.com/pipeline: mypipe app.edp.epam.com/stage: dev |
| deploy | Deploy | app.edp.epam.com/cdpipeline: deployapp.edp.epam.com/cdstage: deploy-dev app.edp.epam.com/pipelinetype: deploy |
| clean | Clean | app.edp.epam.com/cdpipeline: deployapp.edp.epam.com/cdstage: deploy-dev app.edp.epam.com/pipelinetype: clean |
The list of all the tasks associated with the `demo` codebase is presented below:
| Task Name | Labels |
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| init-autotest | app.edp.epam.com/pipeline: mypipe app.edp.epam.com/pipelinetype: autotestRunner app.edp.epam.com/stage: dev |
| run-autotest | app.edp.epam.com/branch: master app.edp.epam.com/codebase: autotests app.edp.epam.com/parentPipelineRun: mypipe-dev-hash app.edp.epam.com/pipeline: mypipe app.edp.epam.com/stage: dev |
| wait-for-autotests | app.edp.epam.com/pipeline: mypipe app.edp.epam.com/pipelinetype: autotestRunner app.edp.epam.com/stage: dev |
| promote-images | app.edp.epam.com/pipeline: mypipe app.edp.epam.com/pipelinetype: autotestRunner app.edp.epam.com/stage: dev |
---
## Verification of KubeRocketCI Artifacts
# Verification of KubeRocketCI Artifacts
This documentation outlines platform SLSA integration and guides verifying image authenticity and provenance.
Supply Chain Levels of [Software Assurance (SLSA)](https://slsa.dev/) is a framework for assessing and enhancing software supply chain security.
Software Supply Chain Security is a critical aspect of modern software development and deployment. Supply Chain Levels of Software Assurance (SLSA) provides a framework for assessing and enhancing the security of your software supply chain.
## Prerequisites
Ensure you have installed [rekor-cli](https://docs.sigstore.dev/logging/installation/) and [cosign](https://docs.sigstore.dev/cosign/system_config/installation/) on your environment before proceeding.
***
## Release Assets
The table below represents a list of KubeRocketCI components with corresponding images that are signed and pushed to DockerHub:
| Asset | Description |
|-------------------------|-------------------------------|
| [codebase-operator](https://github.com/epam/edp-codebase-operator/tree/master) | [Docker Image](https://hub.docker.com/r/epamedp/cd-pipeline-operator) |
| [edp-headlamp](https://github.com/epam/edp-headlamp) | [Docker Image](https://hub.docker.com/r/epamedp/edp-headlamp) |
| [edp-tekton](https://github.com/epam/edp-tekton) | [Docker Image](https://hub.docker.com/r/epamedp/edp-tekton) |
| [cd-pipeline-operator](https://github.com/epam/edp-cd-pipeline-operator) | [Docker Image](https://hub.docker.com/r/epamedp/cd-pipeline-operator) |
| [gerrit-operator](https://github.com/epam/edp-gerrit-operator) | [Docker Image](https://hub.docker.com/r/epamedp/gerrit-operator) |
| [edp-gerrit](https://github.com/epam/edp-gerrit) | [Docker Image](https://hub.docker.com/r/epamedp/edp-gerrit) |
***
## Verify Container Images
KubeRocketCI's container images are signed using cosign with the [cosign.pub](https://raw.githubusercontent.com/epam/edp-install/master/cosign.pub) key for signing and transparency. You can verify a container image's signature by executing the `cosign verify` command.
To confirm the authenticity of the image, run the `cosign verify` command. See the example below:
```bash
cosign verify --key https://raw.githubusercontent.com/epam/edp-install/master/cosign.pub epamedp/codebase-operator:2.20.0 | jq .
```
Verification for [epamedp/codebase-operator:2.20.0](https://hub.docker.com/layers/epamedp/codebase-operator/2.20.0/images/sha256-36585a13b5b5ff5a15138e9d16cc74eb3aac4560b77be15161d3b3db25b89e1d?context=repo):
```bash
Verification for index.docker.io/epamedp/codebase-operator:2.20.0
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The claims were present in the transparency log
- The signatures were integrated into the transparency log when the certificate was valid
- The signatures were verified against the specified public key
[
{
"critical": {
"identity": {
"docker-reference": "index.docker.io/epamedp/codebase-operator"
},
"image": {
"docker-manifest-digest": "sha256:36585a13b5b5ff5a15138e9d16cc74eb3aac4560b77be15161d3b3db25b89e1d"
},
"type": "cosign container image signature"
},
"optional": null
}
]
```
## Verify Container Image With SLSA Attestations
An [SLSA](https://slsa.dev/) Level 3 provenance is verified using. The following command will verify the signature of an attestation and how it was issued. It will contain the payloadType, payload, and signature.
Run the `cosign verify-attestation` command using the [cosign.pub](https://raw.githubusercontent.com/epam/edp-install/master/cosign.pub):
```bash
cosign verify-attestation --key https://raw.githubusercontent.com/epam/edp-install/master/cosign.pub --type slsaprovenance epamedp/codebase-operator:2.20.0 | jq .
```
Verification for [epamedp/codebase-operator:2.20.0](https://hub.docker.com/layers/epamedp/codebase-operator/2.20.0/images/sha256-36585a13b5b5ff5a15138e9d16cc74eb3aac4560b77be15161d3b3db25b89e1d?context=repo):
```bash
Verification for epamedp/codebase-operator:2.20.0
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The claims were present in the transparency log
- The signatures were integrated into the transparency log when the certificate was valid
- The signatures were verified against the specified public key
{
"payloadType": "application/vnd.in-toto+json",
"payload": "eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjAuMSIsInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjAuMiIsInN1YmplY3QiOlt7Im5hbWUiOiJpbmRleC5kb2NrZXIuaW8vZXBhbWVkcC9jb2RlYmFzZS1vcGVyYXRvciIsImRpZ2VzdCI6eyJzaGEyNTYiOiIzNjU4NWExM2I1YjVmZjVhMTUxMzhlOWQxNmNjNzRlYjNhYWM0NTYwYjc3YmUxNTE2MWQzYjNkYjI1Yjg5ZTFkIn19XSwicHJlZGljYXRlIjp7ImJ1aWxkZXIiOnsiaWQiOiJodHRwczovL3Rla3Rvbi5kZXYvY2hhaW5zL3YyIn0sImJ1aWxkVHlwZSI6InRla3Rvbi5kZXYvdjFiZXRhMS9UYXNrUnVuIiwiaW52b2NhdGlvbiI6eyJjb25maWdTb3VyY2UiOnt9LCJwYXJhbWV0ZXJzIjp7IkJVSUxERVJfSU1BR0UiOiJnY3IuaW8va2FuaWtvLXByb2plY3QvZXhlY3V0b3I6djEuMTIuMS1kZWJ1ZyIsIkNPTlRFWFQiOiIuLyIsIkRPQ0tFUkZJTEUiOiJEb2NrZXJmaWxlIiwiSU1BR0UiOiJlcGFtZWRwL2NvZGViYXNlLW9wZXJhdG9yOjIuMjAuMCIsIklNQUdFX1RBUiI6ImNvZGViYXNlLW9wZXJhdG9yXzIuMjAuMCJ9LCJlbnZpcm9ubWVudCI6eyJhbm5vdGF0aW9ucyI6eyJtZXRhLmhlbG0uc2gvcmVsZWFzZS1uYW1lIjoiZWRwLWN1c3RvbS1waXBlbGluZXMiLCJtZXRhLmhlbG0uc2gvcmVsZWFzZS1uYW1lc3BhY2UiOiJlZHAtZGVsaXZlcnkiLCJwaXBlbGluZS50ZWt0b24uZGV2L2FmZmluaXR5LWFzc2lzdGFudCI6ImFmZmluaXR5LWFzc2lzdGFudC1iZjRkNzRkMWM0IiwicGlwZWxpbmUudGVrdG9uLmRldi9yZWxlYXNlIjoiMjI5OWIxNSIsInRla3Rvbi5kZXYvY2F0ZWdvcmllcyI6IkltYWdlIEJ1aWxkIiwidGVrdG9uLmRldi9kaXNwbGF5TmFtZSI6IkJ1aWxkIGFuZCB1cGxvYWQgY29udGFpbmVyIGltYWdlIHVzaW5nIEthbmlrbyIsInRla3Rvbi5kZXYvcGlwZWxpbmVzLm1pblZlcnNpb24iOiIwLjE3LjAiLCJ0ZWt0b24uZGV2L3BsYXRmb3JtcyI6ImxpbnV4L2FtZDY0IiwidGVrdG9uLmRldi90YWdzIjoiaW1hZ2UtYnVpbGQifSwibGFiZWxzIjp7ImFwcC5rdWJlcm5ldGVzLmlvL21hbmFnZWQtYnkiOiJIZWxtIiwiYXBwLmt1YmVybmV0ZXMuaW8vdmVyc2lvbiI6IjAuOC4wIiwiaGVsbS5zaC9jaGFydCI6ImVkcC1jdXN0b20tcGlwZWxpbmVzLTAuOC4wIiwiazhzbGVucy1lZGl0LXJlc291cmNlLXZlcnNpb24iOiJ2MSIsInRla3Rvbi5kZXYvbWVtYmVyT2YiOiJ0YXNrcyIsInRla3Rvbi5kZXYvcGlwZWxpbmUiOiJnZXJyaXQtb3BlcmF0b3JzLWFwcC1yZWxlYXNlLWVkcCIsInRla3Rvbi5kZXYvcGlwZWxpbmVSdW4iOiJlZHAtY29kZWJhc2Utb3BlcmF0b3ItcmVsZWFzZSIsInRla3Rvbi5kZXYvcGlwZWxpbmVUYXNrIjoia2FuaWtvLWJ1aWxkIiwidGVrdG9uLmRldi90YXNrIjoia2FuaWtvLXJlbGVhc2UifX19LCJidWlsZENvbmZpZyI6eyJzdGVwcyI6W3siZW50cnlQb2ludCI6Ii9rYW5pa28vZXhlY3V0b3IgXFxcbiAgLS1kb2NrZXJmaWxlPS93b3Jrc3BhY2Uvc291cmNlL0RvY2tlcmZpbGUgXFxcbiAgLS1jb250ZXh0PS93b3Jrc3BhY2Uvc291cmNlLy4vIFxcXG4gIC0tZGVzdGluYXRpb249ZXBhbWVkcC9jb2RlYmFzZS1vcGVyYXRvcjoyLjIwLjAgXFxcbiAgLS1kaWdlc3QtZmlsZT0vdGVrdG9uL3Jlc3VsdHMvSU1BR0VfRElHRVNUIFxcXG4gIC0tdGFyLXBhdGg9Y29kZWJhc2Utb3BlcmF0b3JfMi4yMC4wLnRhciBcXFxuIiwiYXJndW1lbnRzIjpudWxsLCJlbnZpcm9ubWVudCI6eyJjb250YWluZXIiOiJidWlsZC1hbmQtcHVzaCIsImltYWdlIjoib2NpOi8vZ2NyLmlvL2thbmlrby1wcm9qZWN0L2V4ZWN1dG9yQHNoYTI1NjphN2VhOWY2OWQ3N2Q3ZTdhMGVhODIxZjE1MDY5YmU0NTQyMGE1MzZmODFhYjU3ODdhOTg4NjU5ZTQ4YzI1Mzc3In0sImFubm90YXRpb25zIjpudWxsfSx7ImVudHJ5UG9pbnQiOiJzZXQgLWVcbmltYWdlPVwiZXBhbWVkcC9jb2RlYmFzZS1vcGVyYXRvcjoyLjIwLjBcIlxuZWNobyAtbiBcIiR7aW1hZ2V9XCIgfCB0ZWUgXCIvdGVrdG9uL3Jlc3VsdHMvSU1BR0VfVVJMXCJcbiIsImFyZ3VtZW50cyI6bnVsbCwiZW52aXJvbm1lbnQiOnsiY29udGFpbmVyIjoid3JpdGUtdXJsIiwiaW1hZ2UiOiJvY2k6Ly9kb2NrZXIuaW8vbGlicmFyeS9hbHBpbmVAc2hhMjU2OjcxNDRmN2JhYjNkNGMyNjQ4ZDdlNTk0MDlmMTVlYzUyYTE4MDA2YTEyOGM3MzNmY2ZmMjBkM2E0YTU0YmE0NGEifSwiYW5ub3RhdGlvbnMiOm51bGx9XX0sIm1ldGFkYXRhIjp7ImJ1aWxkU3RhcnRlZE9uIjoiMjAyMy0xMS0wM1QxMzozMDo1NVoiLCJidWlsZEZpbmlzaGVkT24iOiIyMDIzLTExLTAzVDEzOjMxOjE1WiIsImNvbXBsZXRlbmVzcyI6eyJwYXJhbWV0ZXJzIjpmYWxzZSwiZW52aXJvbm1lbnQiOmZhbHNlLCJtYXRlcmlhbHMiOmZhbHNlfSwicmVwcm9kdWNpYmxlIjpmYWxzZX0sIm1hdGVyaWFscyI6W3sidXJpIjoib2NpOi8vZ2NyLmlvL2thbmlrby1wcm9qZWN0L2V4ZWN1dG9yIiwiZGlnZXN0Ijp7InNoYTI1NiI6ImE3ZWE5ZjY5ZDc3ZDdlN2EwZWE4MjFmMTUwNjliZTQ1NDIwYTUzNmY4MWFiNTc4N2E5ODg2NTllNDhjMjUzNzcifX0seyJ1cmkiOiJvY2k6Ly9kb2NrZXIuaW8vbGlicmFyeS9hbHBpbmUiLCJkaWdlc3QiOnsic2hhMjU2IjoiNzE0NGY3YmFiM2Q0YzI2NDhkN2U1OTQwOWYxNWVjNTJhMTgwMDZhMTI4YzczM2ZjZmYyMGQzYTRhNTRiYTQ0YSJ9fV19fQ==",
"signatures": [
{
"keyid": "SHA256:7E2nAQnycq4vfPlzmLZGzpK/Vr6oXKqqGokDyrBSLck",
"sig": "MEUCIAZLrA/wTkqmnCZXh85R9Y/Ue5f8wuGgjLMYdoFw9GRLAiEA/sE598EX5fppqbry+xvE+aap8+qHPioOin8t6Ttzx3k="
}
]
}
```
For more details about attestation, please refer to the official [cosign documentation](https://docs.sigstore.dev/cosign/verifying/verify/) page.
## Verify Release Pipeline
Within each release component, you will discover a [Rekor UUID](https://search.sigstore.dev/?uuid=24296fb24b8ad77a671b24f6b83f79e46fe5214cde46ed045ceba35d640a7e017cbc5524e90329ff), which serves to validate the flow of the release pipeline. Execute the following command to obtain comprehensive information about the release pipeline of [codebase-operator](https://github.com/epam/edp-codebase-operator/releases/tag/v2.20.0) with UUID:
```24296fb24b8ad77a671b24f6b83f79e46fe5214cde46ed045ceba35d640a7e017cbc5524e90329ff```:
```bash
rekor-cli get --uuid 24296fb24b8ad77a671b24f6b83f79e46fe5214cde46ed045ceba35d640a7e017cbc5524e90329ff --format json | jq -r .Attestation | jq .
```
The result:
```bash
{
"_type": "https://in-toto.io/Statement/v0.1",
"predicateType": "https://slsa.dev/provenance/v0.2",
"subject": [
{
"name": "index.docker.io/epamedp/codebase-operator",
"digest": {
"sha256": "36585a13b5b5ff5a15138e9d16cc74eb3aac4560b77be15161d3b3db25b89e1d"
}
}
],
"predicate": {
"builder": {
"id": "https://tekton.dev/chains/v2"
},
"buildType": "tekton.dev/v1beta1/TaskRun",
"invocation": {
"configSource": {},
"parameters": {
"BUILDER_IMAGE": "gcr.io/kaniko-project/executor:v1.12.1-debug",
"CONTEXT": "./",
"DOCKERFILE": "Dockerfile",
"IMAGE": "epamedp/codebase-operator:2.20.0",
"IMAGE_TAR": "codebase-operator_2.20.0"
},
"environment": {
"annotations": {
...
},
"labels": {
...
}
}
},
"buildConfig": {
"steps": [
{
"entryPoint": "/kaniko/executor \\\n --dockerfile=/workspace/source/Dockerfile \\\n --context=/workspace/source/./ \\\n --destination=epamedp/codebase-operator:2.20.0 \\\n --digest-file=/tekton/results/IMAGE_DIGEST \\\n --tar-path=codebase-operator_2.20.0.tar \\\n",
"arguments": null,
"environment": {
"container": "build-and-push",
"image": "oci://gcr.io/kaniko-project/executor@sha256:a7ea9f69d77d7e7a0ea821f15069be45420a536f81ab5787a988659e48c25377"
},
"annotations": null
},
{
"entryPoint": "set -e\nimage=\"epamedp/codebase-operator:2.20.0\"\necho -n \"${image}\" | tee \"/tekton/results/IMAGE_URL\"\n",
"arguments": null,
"environment": {
"container": "write-url",
"image": "oci://docker.io/library/alpine@sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a"
},
"annotations": null
}
]
},
"metadata": {
...
},
"materials": [
{
"uri": "oci://gcr.io/kaniko-project/executor",
"digest": {
"sha256": "a7ea9f69d77d7e7a0ea821f15069be45420a536f81ab5787a988659e48c25377"
}
},
{
"uri": "oci://docker.io/library/alpine",
"digest": {
"sha256": "7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a"
}
}
]
}
}
```
By signing all our artifacts, we assure you that they are trustworthy. This guide is indispensable for developers and administrators to enhance their software's reliability and meet modern security standards. The adoption of SLSA will bring you confidence while using the platform.
## Related Articles
* [In-Toto Attestations](https://docs.sigstore.dev/cosign/verifying/verify/)
---
## Quality Control
# Quality Control
In KubeRocketCI, we guarantee the quality of the product not only by using the most advanced tools and best practices but also by covering the whole product functionality with our dedicated automated tests.
## Autotest Coverage Scheme
Autotests are significant part of our verification flow. Continuous improvement of the verification mechanisms quality is performed to provide users with the most stable version of the platform.
The autotest coverage status is presented on the scheme below:

## Release Testing
In our testing flow, each release is verified by the following tests:
| Test Group | Description | What's Covered |
|-|:-------------------------------------------------------------------|:-|
| API Tests | Tekton Bitbucket, Gerrit, GitHub, and GitLab API long regression | Codebase provisioning, reviewing and building pipelines, adding new branches, deploying applications (in a custom namespace), Jira integration, and rechecking for review pipeline. |
| UI Tests | Tekton Bitbucket, Gerrit, GitHub, and GitLab UI long regression | Codebase provisioning, reviewing and building pipelines, adding new branches, deploying applications (in a custom namespace), Jira integration, and rechecking for review pipeline. |
| Short Tests | Tekton Bitbucket, Gerrit , GitHub, and GitLab API short regression | Codebase provisioning, reviewing and building pipelines, deploying applications (in a custom namespace), rechecking for review pipeline |
| Smoke | Tekton Gerrit Smoke | Codebase provisioning, reviewing and building pipelines, deploying applications. |
## Related Articles
* [KubeRocketCI Project Rules. Working Process](edp-workflow.md)
* [Operator Development](local-development.md)
---
## KubeRocketCI Deployment on AWS
# KubeRocketCI Deployment on AWS
This document describes the KubeRocketCI deployment architecture on AWS. It utilizes various AWS services such as Amazon Elastic Kubernetes Service (EKS), Amazon EC2, Amazon Route 53, and others to build and deploy software in a repeatable, automated way.
## Overview
The KubeRocketCI deployment architecture consists of two AWS accounts: Shared and Explorer. The *Shared* account hosts shared services, while the *Explorer* account runs the development team workload and KubeRocketCI services. Both accounts have an AWS EKS cluster deployed in multiple Availability Zones (AZs). The EKS cluster runs the KubeRocketCI Services, development team workload, and shared services in the case of the Shared account.

## Key Components
1. **AWS Elastic Kubernetes Service (EKS)**: A managed Kubernetes service used to run the KubeRocketCI Services, development team workload, and shared services. EKS provides easy deployment and management of Kubernetes clusters.
2. **Amazon EC2**: Instances running within private subnets that serve as nodes for the EKS cluster. Autoscaling Groups are used to deploy these instances, allowing for scalability based on demand.
3. **Amazon Route 53**: A DNS web service manages external and internal DNS records for the KubeRocketCI deployment. It enables easy access to resources using user-friendly domain names.
4. **AWS Application Load Balancer (ALB)**: Used for managing ingress traffic into the KubeRocketCI deployment. Depending on requirements, ALBs can be configured as internal or external load balancers.
5. **AWS WAF**: Web Application Firewall service used to protect external ALBs from common web exploits by filtering malicious requests.
6. **AWS Certificate Manager (ACM)**: A service that provisions manages, and deploys SSL/TLS certificates for use with AWS services. ACM is used to manage SSL certificates for secure communication within the KubeRocketCI deployment.
7. **AWS Elastic Container Registry (ECR)**: A fully-managed Docker container registry that stores and manages Docker images. ECR provides a secure and scalable solution for storing container images used in the KubeRocketCI deployment.
8. **AWS Systems Manager Parameter Store**: Used to securely store and manage secrets required by various components of the KubeRocketCI deployment. Parameter Store protects sensitive information such as API keys, database credentials, and other secrets.
## High Availability and Fault Tolerance
The EKS cluster is deployed across multiple AZs to ensure high availability and fault tolerance. This allows for automatic failover in case of an AZ outage or instance failure. Autoscaling Groups automatically adjust the number of EC2 instances based on demand, ensuring scalability while maintaining availability.
## Design Considerations
### Reliability
- Using multiple AZs ensures high availability and fault tolerance for the EKS cluster.
- Autoscaling Groups enable automatic scaling of EC2 instances based on demand, providing reliability during peak loads.
- Multiple NAT gateways are deployed in each AZ to ensure reliable outbound internet connectivity.
### Performance Efficiency
- Utilizing AWS EKS allows for efficient management of Kubernetes clusters without the need for manual configuration or maintenance.
- Spot instances can be utilized alongside on-demand instances within the EKS cluster to optimize costs while maintaining performance requirements.
- Amazon Route 53 enables efficient DNS resolution by managing external and internal DNS records.
### Security
- External ALBs are protected using AWS WAF, which filters out malicious traffic and protects against common web exploits.
- ACM is used to provision SSL/TLS certificates, ensuring secure communication within the KubeRocketCI deployment.
- Secrets required by various components are securely stored and managed using the AWS Systems Manager Parameter Store.
### Cost Optimization
- Utilizing spot and on-demand instances within the EKS cluster can significantly reduce costs while maintaining performance requirements.
- Autoscaling Groups allow for automatic scaling of EC2 instances based on demand, ensuring optimal resource utilization and cost efficiency.
## Conclusion
The KubeRocketCI deployment architecture on AWS follows best practices and patterns from the Well-Architected Framework. By leveraging AWS services such as EKS, EC2, Route 53, ALB, WAF, ACM, and Parameter Store, the KubeRocketCI provides a robust and scalable CI/CD system that enables developers to deploy and manage infrastructure and applications quickly. The architecture ensures high availability, fault tolerance, reliability, performance efficiency, security, and cost optimization for the KubeRocketCI deployment.
---
## AWS Infrastructure Cost Estimation
# AWS Infrastructure Cost Estimation
Effective planning and budgeting are essential for developing applications in cloud computing, with a key part being accurate infrastructure cost estimation. This not only helps in keeping within budget but also enables informed decision-making and resource optimization for project viability.
This guide aims to offer an in-depth look at the factors affecting AWS infrastructure costs for KubeRocketCI and includes analytics and tools for cost estimation.
## Platform Components and Approximate Costs
This section contains tables outlining the key components of our AWS infrastructure, including a brief description of each component's role, its purpose within our infrastructure, and an estimate of its monthly cost.
:::note
The costs mentioned below are estimates. For the most accurate and up-to-date pricing, please refer to the [AWS official documentation](https://aws.amazon.com/pricing/?aws-products-pricing.sort-by=item.additionalFields.productNameLowercase&aws-products-pricing.sort-order=asc&awsf.Free%20Tier%20Type=*all&awsf.tech-category=*all).
:::
The table below outlines key AWS infrastructure components for KubeRocketCI, detailing each component's role, purpose, and estimated monthly cost:
| Component | Description | Purpose Within Infrastructure |
|-----------------------------------------------|-----------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------|
| Application Load Balancer (ALB) | Distributes incoming application traffic across multiple targets. | Ensures high availability and fault tolerance for our applications. |
| Virtual Private Cloud (VPC) | Provides an isolated section of the AWS cloud where resources can be launched. | Segregates our infrastructure for enhanced security and management. |
| 3x Network Address Translation (NAT) Gateways | Enables instances in a private subnet to connect to the internet or other AWS services. | Provides internet access to EC2 instances without exposing them to the public internet. |
| Elastic Container Registry (ECR) | A fully managed container registry. | Stores, manages, and deploys container images. |
| Elastic Kubernetes Service (EKS) | A managed Kubernetes service. | Simplifies running Kubernetes applications on AWS. |
| Elastic Block Store (EBS) | Provides persistent block storage volumes for use with EC2 instances. | Offers highly available and durable storage for our applications. |
| Elastic Compute Cloud (EC2) | Provides scalable computing capacity. | Hosts our applications, supporting varied compute workloads. |
The table below presents an itemized estimate of monthly costs for KubeRocketCI's AWS infrastructure components, including ALB, VPC, EC2, and more:
| Component | Approximate Monthly Cost |
|---------------------------------------------------------------------------------------------------------|--------------------------------|
| Application Load Balancer (ALB) | **$30.00** |
| Virtual Private Cloud (VPC) - 3x Network Address Translation Gateways - 3x Public IPv4 Address | **$113.88** **$10.95** |
| Elastic Container Registry (ECR) | **$5.00** |
| Elastic Kubernetes Service (EKS) - 1x EKS Clusters | **$73.00** |
| Elastic Block Store (EBS) | **$14.28** |
| Elastic Compute Cloud (EC2) - 2x c5.2xlarge (Spot) - 2x c5.2xlarge (On-Demand) | **$219.11** **$576.00** |
## AWS Pricing Calculator
To further assist in your planning and budgeting efforts, we have pre-configured the AWS Pricing Calculator with inputs matching our infrastructure setup. This tool allows you to explore and adjust the cost estimation based on your specific needs, giving you a personalized overview of potential expenses.
Access the AWS Pricing Calculator with our pre-configured setup here: [AWS Pricing Calculator](https://calculator.aws/#/estimate?id=42ed1a892c891ebcd905734b437f722122983f61)
## Related Articles
* [KubeRocketCI Deployment on AWS](aws-deployment-diagram.md)
* [KubeRocketCI Reference Architecture on AWS](aws-reference-architecture.md)
---
## KubeRocketCI Reference Architecture on AWS
# KubeRocketCI Reference Architecture on AWS
The reference architecture of the KubeRocketCI on AWS is designed to provide a robust and scalable CI/CD system for developing and deploying software in a repeatable and automated manner. The architecture leverages AWS Managed Services to enable developers to quickly deploy and manage infrastructure and applications. KubeRocketCI recommends to follow the best practices and patterns from the Well-Architected Framework, the AWS Architecture Center, and EKS Best Practices Guide.
## Architecture Details
The AWS Cloud comprises three accounts: Production, Shared, and Development.
:::note
AWS Account management is out of scope for this document.
:::
Each account serves specific purposes:
* The **Production** account is used to host production workloads. The Production account serves as the final destination for deploying business applications. It maintains a separate ECR registry to store Docker images for production-level applications. The environment is designed to be highly resilient and scalable, leveraging the KubeRocketCI's CI/CD pipeline to ensure consistent and automated deployments. With proper access control and separation from development environments, the Production account provides a stable and secure environment for running mission-critical applications.
* The **Development** account is dedicated to development workload and lower environments. This account hosts the KubeRocketCI itself, running on AWS EKS. It provides developers an isolated environment to build, test, and deploy their applications in lower environments, ensuring separation from production workloads. Developers can connect to the AWS Cloud using a VPN, enforcing secure access.
* The **Shared** holds shared services that are accessible to all accounts within the organization. These services include SonarQube, Nexus, and Keycloak, which are deployed in Kubernetes Clusters managed by AWS Elastic Kubernetes Service (EKS). The shared services leverage AWS RDS, AWS EFS, and AWS ALB/NLB. The deployment of the shared services is automated using Kubernetes cluster-addons approach with GitOps and Argo CD.

## Infrastructure as Code
Infrastructure as Code (IaC) is a key principle in the KubeRocketCI architecture. Terraform is the IaC tool to provision and manage all services in each account. AWS S3 and AWS DynamoDB serve as the backend for Terraform state, ensuring consistency and reliability in the deployment process. This approach enables the architecture to be version-controlled and allows for easy replication and reproducibility of environments.
## Container Registry
The architecture utilizes AWS Elastic Container Registry (ECR) as a Docker Registry for container image management. ECR offers a secure, scalable, and reliable solution for storing and managing container images. It integrates seamlessly with other AWS services and provides a highly available and durable storage solution for containers in the CI/CD pipeline.
## IAM Roles for Service Accounts (IRSA)
The KubeRocketCI implements IAM Roles for Service Accounts (IRSA) to provide secure access to AWS services from Kubernetes Clusters. This feature enables fine-grained access control with individual Kubernetes pods assuming specific IAM roles for authenticated access to AWS resources. IRSA eliminates the need for managing and distributing access keys within the cluster, significantly enhancing security and reducing operational complexity.
## SSL Certificates
The architecture uses the AWS Certificate Manager (ACM) to secure communication between services to provide SSL certificates. ACM eliminates the need to manually manage SSL/TLS certificates, automating the renewal and deployment process. The KubeRocketCI ensures secure and encrypted traffic within its environment by leveraging ACM.
## AWS WAF
The architecture's external Application Load Balancer (ALB) endpoint is protected by the AWS Web Application Firewall (WAF). WAF protects against common web exploits and ensures the security and availability of the applications hosted within the KubeRocketCI. It offers regular rule updates and easy integration with other AWS services.
## Parameter Store and Secrets Manager
The architecture leverages the AWS Systems Manager Parameter Store and Secrets Manager to securely store and manage all secrets and parameters utilized within the EKS clusters—parameter Store stores general configuration information, such as database connection strings and API keys. In contrast, Secrets Manager securely stores sensitive information, such as passwords and access tokens. By centralizing secrets management, the architecture ensures proper access control and reduces the risk of unauthorized access.
## Observability and Monitoring
For observability and monitoring, the KubeRocketCI leverages a suite of AWS Managed Services designed to provide comprehensive insights into the performance and health of applications and infrastructure:
**AWS CloudWatch** is utilized for monitoring and observability, offering detailed insights into application and infrastructure performance. It enables real-time monitoring of logs, metrics, and events, facilitating proactive issue resolution and performance optimization.
**AWS OpenSearch Service** (successor to Amazon Elasticsearch Service) provides powerful search and analytics capabilities. It allows for the analysis of log data and metrics, supporting enhanced application monitoring and user experience optimization.
**AWS Managed Grafana** offers a scalable, secure, and fully managed Grafana service, enabling developers to create and share dashboards for visualizing real-time data.
**AWS Prometheus Service**, a managed Prometheus-compatible monitoring service, is used for monitoring Kubernetes and container environments. It supports powerful queries and provides detailed insights into container and microservices architectures.
## Summary
The reference architecture of the KubeRocketCI on AWS provides a comprehensive and scalable environment for building and deploying software applications. With a strong focus on automation, security, and best practices, this architecture enables developers to leverage the full potential of AWS services while following industry-standard DevOps practices.
---
## Working With Documentation
# Working With Documentation
This section outlines the necessary steps to start developing the KubeRocketCI documentation using Docusaurus.
Docusaurus is a modern static website generator that simplifies creating, deploying, and maintaining open source project websites.
:::note
For more details on Docusaurus, please refer to the Docusaurus [official website](https://docusaurus.io/).
:::
Adjusting the documentation to use npm instead of Yarn for working with Docusaurus involves minor changes. Below is the revised version of the documentation section, now specifying npm commands:
## Prerequisites
Before you begin, ensure you have the following installed:
- [Node.js](https://nodejs.org/en/) (version >= 18.0)
- [npm](https://www.npmjs.com/) (usually comes with Node.js)
## Local Development
1. Fork the [KubeRocketCI documentation repository](https://github.com/KubeRocketCI/docs) to your personal account.
2. Clone the forked documentation repository to your local machine.
3. Install the dependencies:
```bash
npm install
```
4. Start a local development server:
```bash
npm start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. To quit the session, press `ctrl + c` or `cmd + c`.
5. Navigate to `localhost:3000` (or the URL provided in the terminal after running the `npm start` command) in your web browser to view the documentation site.
6. Make the necessary changes to the documentation. The files are located in the `docs` directory. Changes will automatically refresh in the browser.
7. Commit your changes and create a pull request.
## Build
To build the static content of the site into the `build` directory, run:
```bash
npm run build
```
The content generated in the `build` directory can be served using any static content hosting service.
## Deployment
To deploy the documentation site, you can use the following command, which builds the site and pushes it to the `gh-pages` branch:
Using SSH:
```bash
USE_SSH=true npm run deploy
```
Not using SSH:
```bash
GIT_USER= npm run deploy
```
Ensure you replace `` with your actual GitHub username if you are not using SSH.
---
## KubeRocketCI Contribution
# KubeRocketCI Contribution
This page contains the details on the project rules and working process for KubeRocketCI team and contributors. Explore the main points about working with GitHub, following the main commit flow, as well as the details about commit types and message below.
## Project Rules
Before starting the development, please check the project rules:
1. It is highly recommended to become familiar with the GitHub flow. For details, please refer to the [GitHub official documentation](https://docs.github.com/en/get-started/using-github/github-flow) and pay attention to the main points:
a. Creating pull requests in GitHub.
b. Resolution of Merge Conflict.
c. Comments resolution.
d. One GitHub task should have one Pull Request (PR) if it doesn't change multiple operators. If there are many changes within one PR, amend the commit.
2. Only the Assignee is responsible for the PR merger and Jira task status.
3. Every PR should be merged in a timely manner.
4. Log time to Jira ticket.
## Working Process
With KubeRocketCI, the main workflow is based on the getting a Jira task and creating a Pull Request according to the rules described below.
:::info Workflow
Get Jira task → implement, verify by yourself the results → create Pull Request (PR) → send for review → resolve comments/add changes, ask colleagues for the final review → track the PR merge → verify by yourself the results → change the status in the Jira ticket to CODE COMPLETE or RESOLVED → share necessary links with a QA specialist in the QA Verification channel → QA specialist closes the Jira task after his verification → Jira task should be CLOSED.
:::
### Commit Flow
1. Get a task in the Jira/GitHub dashboard. Please be aware of the following points:
a. Every task has a reporter who can provide more details in case something is not clear.
b. The responsible person for the task and code implementation is the assignee who tracks the following:
- Actual Jira task status.
- Time logging.
- Add comments, attach necessary files.
- In comments, add link that refers to the merged PR (optional, if not related to many repositories).
- Code review and the final merge.
- MS Teams chats - ping other colleagues, answer questions, etc.
- Verification by a QA specialist.
- Bug fixing.
c. Pay attention to the task Status that differs in different entities, the workflow will help to see the whole task processing:

d. There are several entities that are used on the KubeRocketCI project: Story, Improvement, Task, Bug.
a. Every task has a reporter who can provide more details in case something is not clear.
b. The responsible person for the task and code implementation is the assignee who tracks the following:
- Actual GitHub task status.
- Add comments, attach necessary files.
- In comments, add link that refers to the merged PR (optional, if not related to many repositories).
- Code review and the final merge.
- MS Teams chats - ping other colleagues, answer questions, etc.
- Verification by a QA specialist.
- Bug fixing.
c. If the task is created on your own, make sure it is populated completely. See an example below:

2. Implement feature, improvement, fix and check the results on your own. If it is impossible to check the results of your work before the merge, verify all later.
3. When committing, use the pattern: commit type: Commit message (#GitHub ticket number).
a. commit type:
`feat`: (new feature for the user, not a new feature for build script)
`fix`: (bug fix for the user, not a fix to a build script)
`docs`: (changes to the documentation)
`style`: (formatting, missing semicolons, etc; no production code change)
`refactor`: (refactoring production code, eg. renaming a variable)
`test`: (adding missing tests, refactoring tests; no production code change)
`chore`: (updating grunt tasks etc; no production code change)
`!`: (added to other commit types to mark breaking changes) For example:
feat!: Add ingress links column into Applications table on stage page (#77)
BREAKING CHANGE: Ingress links column has been added into the Applications table on the stage details page
b. Commit message:
* brief, for example:
`fix: Remove secretKey duplication from registry secrets (#63)`
or
* descriptive, for example:
```bash
feat: Provide the ability to configure hadolint check (#88)
* Add configuration files .hadolint.yaml and .hadolint.yml to stash
```
:::note
It is mandatory to start a commit message from a capital letter.
:::
c. GitHub tickets are typically identified using a number preceded by the **#** sign and enclosed in parentheses.
:::note
Make sure there is a descriptive commit message for a breaking change Pull Request. For example:
```bash
feat!: Add ingress links column into Applications table on stage page (#77)
BREAKING CHANGE: Ingress links column has been added into the Applications
table on the stage details page
```
:::
4. Create a Pull Request, for details, please refer to the [Code Review Process](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/about-pull-request-reviews):

:::caution
If a Pull Request contains both new functionality and breaking changes, make sure the functionality description is placed before the breaking changes. For example:
```bash
feat!: Update CRD version to the v1beta1
* Implement Developers group creation process
* Align group permissions
BREAKING CHANGES: Update CRD version to the v1beta1
```
:::
## Related Articles
* [Conventional Commits](https://www.conventionalcommits.org/)
* [Karma](http://karma-runner.github.io/1.0/dev/git-commit-msg.html)
---
## KubeRocketCI Developer Guide: Architecture, Components, and Contribution Workflow
# KubeRocketCI Developer Guide: Architecture, Components, and Contribution Workflow
The KubeRocketCI Developer Guide serves as a comprehensive technical resource specifically designed for developers. It offers detailed insights into expanding the functionalities of KubeRocketCI. This section focuses on explaining the development approach and fundamental architectural blueprints that form the basis of the platform's ecosystem.
Within these pages, you'll find architectural diagrams, component schemas, and deployment strategies essential for grasping the structural elements of the platform. These technical illustrations serve as references, providing a detailed understanding of component interactions and deployment methodologies. Understanding the architecture of the KubeRocketCI and integrating third-party solutions into its established framework enables the creation of efficient, scalable, and customizable solutions within the KubeRocketCI.
The KubeRocketCI platform consists of several key components. These components are interconnected, and their relationships are illustrated in the diagram below:

Each component represents one of the following:
- A Helm chart with a Docker image.
- A standalone Helm chart.
- A standalone Docker image.
All components are regularly updated and released as part of the platform's development cycle.
Some components, such as keycloak-operator, nexus-operator, sonar-operator, and tekton-custom-task, are provided separately through the [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository. These components are optional and can be installed independently of the main platform.
## Release Channels
As a publicly available product, the KubeRocketCI relies on various channels to share information, gather feedback, and distribute new releases effectively. This section outlines the diverse channels through which users can engage with our platform and stay informed about the latest developments and enhancements.
### Marketplaces
Our product is presented on AWS and Civo marketplaces. It's essential to ensure that the product information on these platforms is up-to-date and accurately reflects the latest version of our software:
- [AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-u7xcz6pvwwwoa)
- [CIVO Marketplace](https://www.civo.com/marketplace/edp)
### OperatorHub
Our product operators are showcased on OperatorHub, enabling seamless integration and management capabilities:
- [Keycloak Operator](https://operatorhub.io/operator/edp-keycloak-operator)
- [Nexus Operator](https://operatorhub.io/operator/nexus-operator)
- [Sonar Operator](https://operatorhub.io/operator/sonar-operator)
## GitHub Repositories
Our platform components, optional enhancements, add-ons, and deployment resources are hosted on GitHub repositories. Explore the following repositories to access the source code of components.
### Platform Components
Each platform component is available in its corresponding GitHub project:
- [CD Pipeline Operator](https://github.com/epam/edp-cd-pipeline-operator/releases)
- [Codebase Operator](https://github.com/epam/edp-codebase-operator/releases)
- [EDP Gerrit](https://github.com/epam/edp-gerrit)
- [EDP Install](https://github.com/epam/edp-install/releases)
- [Gerrit Operator](https://github.com/epam/edp-gerrit-operator/releases)
- [KubeRocketCI Portal](https://github.com/epam/edp-headlamp/releases)
- [Tekton](https://github.com/epam/edp-tekton/releases)
- [GitFusion](https://github.com/KubeRocketCI/gitfusion)
- [KubeRocketCI Cache](https://github.com/KubeRocketCI/krci-cache)
- [Tekton Custom Tasks](https://github.com/KubeRocketCI/tekton-custom-task)
### Optional Components
These optional components enhance the platform's installation and configuration experience:
- [Keycloak Operator](https://github.com/epam/edp-keycloak-operator/releases)
- [Nexus Operator](https://github.com/epam/edp-nexus-operator/releases)
- [Sonar Operator](https://github.com/epam/edp-sonar-operator/releases)
### Add-ons Repository
The Add-ons repository offers a streamlined deployment process. It includes additional components that can be integrated separately into the cluster:
- [Cluster Add-Ons](https://github.com/epam/edp-cluster-add-ons)
### Platform Test Data
Access test data from the 'Create' onboarding strategy:
- [EPMD-EDP Project](https://github.com/epmd-edp)
### Helm Charts
Helm chart artifacts are available in repository:
- [Helm Charts](https://github.com/epam/edp-helm-charts)
## DockerHub
Our DockerHub repository hosts Docker images for various platform components:
- [CD Pipeline Operator](https://hub.docker.com/r/epamedp/cd-pipeline-operator/)
- [Codebase Operator](https://hub.docker.com/r/epamedp/codebase-operator/)
- [EDP Gerrit](https://hub.docker.com/r/epamedp/edp-gerrit)
- [Gerrit Operator](https://hub.docker.com/r/epamedp/gerrit-operator)
- [Keycloak Operator](https://hub.docker.com/r/epamedp/keycloak-operator/)
- [KubeRocketCI Portal](https://hub.docker.com/r/epamedp/edp-headlamp/)
- [Nexus Operator](https://hub.docker.com/r/epamedp/nexus-operator/)
- [Sonar Operator](https://hub.docker.com/r/epamedp/sonar-operator/)
- [Tekton](https://hub.docker.com/r/epamedp/edp-tekton/)
- [Tekton Cache](https://hub.docker.com/r/epamedp/tekton-cache/)
- [Tekton Custom Task](https://hub.docker.com/r/epamedp/tekton-custom-task/)
- [GitFusion](https://hub.docker.com/r/epamedp/gitfusion)
## Social Media
To maintain an active presence on social media channels and share valuable content about our software releases, we continuously publish materials across the following media:
- [SolutionsHub](https://solutionshub.epam.com/solution/kuberocketci)
- [Medium](https://medium.com/kuberocketci)
- [YouTube](https://www.youtube.com/@theplatformteam)
## Related Guides
* [Kubernetes Deployment](./kubernetes-deployment.md)
---
## Kubernetes Deployment
# Kubernetes Deployment
This section provides a comprehensive overview of the KubeRocketCI deployment approach on a Kubernetes cluster. KubeRocketCI is designed and functions based on a set of key guiding principles:
* **Operator Pattern Approach:** [Approach](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/) is used for deployment and configuration, ensuring that the platform aligns with Kubernetes native methodologies (see schema below).
* **Loosely Coupling:** KubeRocketCI comprises several loosely coupled operators responsible for different platform parts. These operators can be deployed independently, enabling the most straightforward platform customization and delivery approach.

The following deployment diagram illustrates the platform's core components, which provide the minimum functional capabilities required for the platform operation: build, push, deploy, and run applications. The platform relies on several mandatory dependencies:
* **Ingress:** An ingress controller responsible for routing traffic to the platform.
* **Tekton Stack:** Includes Tekton pipelines, triggers, dashboard, chains, etc.
* **ArgoCD:** Responsible for GitOps deployment.

* **Codebase Operator:** Responsible for managing git repositories, versioning, and branching. It also implements Jira integration controller.
* **CD Pipeline Operator:** Manages Continuous Delivery (CD) pipelines and CD stages (which is an abstraction of Kubernetes Namespace). Operator acts as the bridge between the artifact and deployment tools, like Argo CD. It defines the CD pipeline structure, artifacts promotion logic and triggers the pipeline execution.
* **Tekton Pipelines:** Manages Tekton pipelines and processes events (EventListener, Interceptor) from Version Control Systems. The pipelines are integrated with external tools like SonarQube, Nexus, etc.
* **KubeRocketCI:** This is the User Interface (UI) component, built on top of Headlamp.
**Business applications** are deployed on the platform using the CD Pipeline Operator and Argo CD. By default, the CD Pipeline Operator uses Argo CD as a deployment tool. However, it can be replaced with any other tool, like FluxCD, Spinnaker, etc. The target environment for the application deployment is a Kubernetes cluster where KubeRocketCI is deployed, but it can be any other Kubernetes cluster.
---
## Operator Development
# Operator Development
This page is intended for developers with the aim to share details on how to set up the local environment and start coding in Go language for KubeRocketCI.
## Prerequisites
* [Git](https://github.com/git-guides/install-git) is installed;
* One of our [repositories](https://github.com/epam/edp-install/blob/master/README.md#edp-repositories-description) where you would like to contribute is cloned locally;
* [Docker](https://docs.docker.com/engine/install/) is installed;
* [Kubectl](https://kubernetes.io/docs/setup/) is set up;
* Local Kubernetes cluster ([Kind](https://kind.sigs.k8s.io/) is recommended) is installed;
* [Helm](https://helm.sh/docs/intro/install/) is installed;
* Any IDE ([GoLand](https://www.jetbrains.com/go/) is used here as an example) is installed;
* [GoLang](https://go.dev/dl/) stable version is installed.
:::note
Make sure GOPATH and GOROOT environment variables are added in PATH.
:::
## Environment Setup
Set up your environment by following the steps below.
### Set Up Your IDE
We recommend using GoLand and enabling the Kubernetes plugin. Before installing plugins, make sure to save your work because IDE may require restarting.
#### Set Up Your Operator
To set up the cloned operator, follow the three steps below:
1. Configure Go Build Option. Open folder in GoLand, click the  button and select the `Go Build` option:

2. Fill in the variables in Configuration tab:
* In the `Files` field, indicate the path to the main.go file;
* In the `Working directory` field, indicate the path to the operator;
* In the `Environment field`, specify the namespace to watch by setting `WATCH_NAMESPACE` variable. It should equal `default` but it can be any other if required by the cluster specifications.
* In the `Environment field`, also specify the platform type by setting `PLATFORM_TYPE`. It should equal either `kubernetes` or `openshift`.

3. Check cluster connectivity and variables. Local development implies working within local Kubernetes clusters. [Kind](https://kind.sigs.k8s.io/) (Kubernetes in Docker) is recommended so set this or another environment first before running code.
## Pre-commit Activities
Before making commit and sending pull request, take care of precautionary measures to avoid crashing some other parts of the code.
### Testing and Linting
Testing and linting must be used before every single commit with no exceptions. The instructions for the commands below are written [here](https://github.com/epam/edp-keycloak-operator/blob/master/Makefile).
It is mandatory to run test and lint to make sure the code passes the tests and meets acceptance criteria. Most operators are covered by tests so just run them by issuing the commands "make test" and "make lint":
```bash
make test
```
The command "make test" should give the output similar to the following:

```bash
make lint
```
The command "make lint" should give the output similar to the following:

#### Observe Auto-Generated Docs, API and Manifests
The commands below are especially essential when making changes to API. The code is unsatisfactory if these commands fail.
* Generate documentation in the .MD file format so the developer can read it:
```bash
make api-docs
```
The command "make api-docs" should give the output similar to the following:

* There are also manifests within the operator that generate zz_generated.deepcopy.go file in /api/v1 directory. This file is necessary for the platform to work but it's time-consuming to fill it by yourself so there is a mechanism that does it automatically. Update it using the following command and check if it looks properly:
```bash
make generate
```
The command "make generate" should give the output similar to the following:

* Refresh custom resource definitions for Kubernetes, thus allowing the cluster to know what resources it deals with.
```bash
make manifests
```
The command "make manifests" should give the output similar to the following:

At the end of the procedure, you can push your code confidently to your branch and create a pull request.
That's it, you're all set! Good luck in coding!
## Related Articles
* [KubeRocketCI Project Rules. Working Process](./edp-workflow.md)
---
## Reference Architecture
# Reference Architecture
The KubeRocketCI Reference Architecture serves as a blueprint for software delivery, outlining the best practices, tools, and technologies leveraged by the platform to ensure efficient and high-quality software development. It provides a comprehensive guide to navigate the complexities of software delivery, from code to deployment.
KubeRocketCI operates on Kubernetes, a leading open-source system for automating deployment, scaling, and management of containerized applications. It consolidates a variety of open-source tools, ensuring a flexible and adaptable system that can seamlessly run on any public cloud or on-premises infrastructure. This versatility allows for a wide range of deployment options, **catering to diverse business needs** and **operational requirements**.
## Key Principles
The KubeRocketCI is built on a set of key principles that guide its design and functionality:
* **Managed Infrastructure and Container Orchestration:** KubeRocketCI is based on a platform that leverages managed infrastructure and container orchestration, primarily through Kubernetes or OpenShift.
* **Security:** KubeRocketCI places a high emphasis on security, covering aspects such as authentication, authorization, and Single Sign-On (SSO) for platform services.
* **Development and Testing Toolset:** KubeRocketCI provides a comprehensive set of tools for development and testing, ensuring a robust and reliable software delivery process.
* **Well-Established Engineering Process:** KubeRocketCI reflects EPAM’s well-established engineering practices (EngX) in its CI/CD pipelines and delivery analytics.
* **Open-Source and Cloud-Agnostic:** As an open-source, cloud-agnostic solution, KubeRocketCI can be run on any preferred Kubernetes or OpenShift clusters.
* **DevSecOps Excellence:** KubeRocketCI empowers DevSecOps by making security a mandatory quality gate.
* **Automated Testing:** KubeRocketCI ensures seamless and predictable regression testing through automated test analysis.
## Architecture Overview
KubeRocketCI encompasses a comprehensive CI/CD ecosystem integrating essential tools such as the **Tekton** and **Argo CD**, augmented by additional functionalities. Within this robust framework, KubeRocketCI seamlessly integrates **SonarQube** for continuous code quality assessment, enabling thorough analysis and ensuring adherence to coding standards. Additionally, incorporating **Static Application Security Testing (SAST)** toolset fortifies platform's security posture by proactively identifying vulnerabilities within the codebase. KubeRocketCI leverages dedicated artifact storage solutions to manage and version application artifacts securely, ensuring streamlined deployment processes and traceability throughout the software development lifecycle. See the reference architecture diagram below:

1. Developers access the platform by authenticating with their corporate credentials. The platform utilizes OpenID Connect (OIDC) for authentication and authorization across all tools and Kubernetes clusters. Using OIDC, KubeRocketCI establishes a unified and secure authentication mechanism, ensuring seamless access control and user authentication for all integrated tools. This standardized approach upholds strict security protocols, ensuring consistency in authentication and authorization policies across the platform ecosystem. To integrate existing Identity Providers (IdPs), Keycloak serves as an identity broker on the platform. KubeRocketCI offers the keycloak-operator to streamline Keycloak integration within the platform.
2. Developers engage with the platform via the KubeRocketCI, an intuitive interface offering a comprehensive overview of the platform’s capabilities. This centralized hub facilitates seamless navigation and access to various platform tools and components. Within the KubeRocketCI, developers can generate new components (codebases). The platform integrates with version control systems, optimizing source code management, fostering collaboration, and streamlining code review processes. To create new codebases, developers utilize Application Templates, ensuring a standardized approach to application development. The platform accommodates a range of application templates such as Java, Node.js, .NET, Python, and more. Additionally, developers can design custom templates via the KubeRocketCI Marketplace to cater to their specific requirements.
3. Tekton is a potent, adaptable, and cloud-native framework designed for crafting CI/CD systems. It offers a collection of shared, reusable components that empower developers to construct, test, and deploy applications across various cloud providers or on-premises systems. As a foundational element within the KubeRocketCI CI/CD ecosystem, Tekton seamlessly integrates with other tools and services, providing a robust and adaptable framework for constructing CI/CD pipelines. Tekton Pipelines allow developers to efficiently build, test, and deploy applications, while Tekton Triggers initiate pipelines based on specific events.
4. The codebase operator is a crucial part of the platform ecosystem. It manages codebases, their creation, deletion, and scaffolding, as well as their associated resources. It provides versioning, branching, and release capabilities and enables seamless integration with Git servers and Jira.
5. The platform has various cloud-agnostic tools that offer different functionalities, such as artifact storage, static security analysis, and code quality assessment. These tools are accessible through pipelines and codebase controllers. Additionally, the platform supports integration with managed services from cloud providers to deliver its core functionality—for instance, AWS Parameter Store stores secrets and AWS ECR - container images. AzureDevops Artifacts is an option to store artifacts leveraging Azure Cloud capabilities. SonarCloud, a cloud-based version of SonarQube, can be integrated to conduct static code analysis.
6. The CD Pipeline Operator oversees CD pipelines and their related resources. It offers a collection of shared, reusable components for constructing CD pipelines. Integrated with Tekton and Argo CD, the CD Pipeline Operator harnesses their capabilities, ensuring a robust and dependable software delivery process. With a Kubernetes API interface, the CD Pipeline Operator facilitates the management of CD pipelines. It enables artifact promotion logic and the triggering of CD pipelines based on specific events, further enhancing the efficiency and adaptability of the software delivery workflow.
7. Argo CD is a pivotal deployment tool adopted within the platform, embracing the GitOps delivery approach. It serves as the foundation for deploying both operational and business workloads. KubeRocketCI recommends running a dedicated Argo CD instance to manage operational workloads, employing the [Kubernetes add-ons approach](https://github.com/epam/edp-cluster-add-ons) for streamlined management.
8. Production workloads operate in isolation within dedicated Kubernetes clusters to uphold stringent standards and ensure the utmost security and resource allocation. This approach guarantees the highest isolation and operational integrity levels for critical production systems, aligning with industry best practices. KubeRocketCI strongly recommends utilizing a pull model for production deployment. In this model, production deployment is initiated by the Argo CD instance explicitly deployed for the production environment.
## Technology Stack
The Platform is meticulously engineered to uphold best practices in workload distribution across various environments, including development, testing (manual/automation), user acceptance (UAT), staging, and production. While lower environments like development and testing may feasibly share clusters for workload efficiency, KubeRocketCI strongly advocates and enforces the necessity of **segregating production workloads into dedicated clusters**. This segregation ensures the highest isolation, security, and resource allocation levels for mission-critical production systems, adhering to industry standards and ensuring optimal operational integrity.
KubeRocketCI harnesses the robust capabilities of Kubernetes in conjunction with a suite of powerful tools tailored for monitoring, logging, and tracing. It integrates the **Prometheus** stack within ecosystem, leveraging its metrics collection, storage, and querying capabilities to enable comprehensive monitoring of system performance and health. KubeRocketCI runs **OpenSearch** for centralized logging, enabling efficient log aggregation, analysis, and management across the platform. Incorporating **OpenTelemetry** enables standardized and seamless observability data collection, facilitating deep insights into platform behavior and performance. Additionally, it allows for connection with external aggregators and tools that support the OpenTelemetry protocol (OTLP).

KubeRocketCI integrates with GitLab, GitHub, Bitbucket, and Gerrit for version control. These systems are foundational components enabling efficient source code management, collaboration, and code review processes.
Platform ensures robust security measures by leveraging OpenID Connect (OIDC) for authentication and authorization across all platform tools and Kubernetes clusters. By employing OIDC, KubeRocketCI establishes a unified and secure authentication mechanism, enabling seamless access control and user authentication for all tools integrated into the platform. This standardized approach ensures stringent security protocols, maintaining authentication consistency and authorization policies across the platform ecosystem.
## Related Articles
* [Reference CI/CD Pipeline](./reference-cicd-pipeline.md)
---
## Reference CI/CD Pipeline
# Reference CI/CD Pipeline
This document provides an in-depth overview of the Continuous Integration and Continuous Delivery (CI/CD) pipeline reference architecture implemented within the KubeRocketCI. The pipeline is designed to facilitate efficient and automated software deployment across diverse environments, leveraging a suite of tools and methodologies for enhanced reliability, scalability, and security.
## CI/CD Pipeline Architecture
The CI/CD pipeline within KubeRocketCI orchestrates the software delivery process, encompassing several sequential stages to ensure robustness and reliability.

The CI/CD Pipeline follows a modular and scalable architecture that leverages various tools to ensure the reliability and efficiency of the software delivery process. The architecture can be divided into stages, each responsible for specific tasks. Explore the key components involved in the pipeline and their functionalities:
1. **Source Code:** The pipeline starts with the source code, representing the application's codebase. Developers commit their changes to the source code repository, triggering the pipeline.
2. **Validate Commit Message:** The commit message validation component checks the format and content of the commit message. It ensures the commit message follows the correct format and includes a valid Tracking Issue key. It helps maintain a standardized commit message format throughout the application development.
3. **Build:** The Build component compiles the source code, runs unit tests, and generates the application artifact. It consumes the artifact from the Artifact Repository (Nexus), ensuring consistent and reliable builds.
4. **SAST with SonarQube:** The Static Analysis Security Testing (SAST) component utilizes SonarQube to analyze the source code for potential security vulnerabilities, code smells, and quality issues. This step helps identify and address security or code quality issues early in development.
5. **SCA:** The Software Composition Analysis (SCA) component performs dependency analysis using cdxgen, Dependency-Track, Semgrep, and DefectDojo. It checks for known vulnerabilities or license compliance issues in the application's dependencies. By identifying and resolving these issues, it ensures the security and stability of the software.
6. **Publish:** The Publish component publishes the application artifact to the Artifact Repository. It posts Docker images to the Docker Registry and stores binary artifacts in the Nexus Repository. This process ensures that the artifacts are securely stored and easily accessed for future deployments.
7. **Deploy:** The Deploy component uses Argo CD or Tekton to deploy applications to target environments in Kubernetes, leveraging Helm charts to ensure seamless deployment. Deploy to Test/Quality Assurance/Performance Environments: The final stages of the pipeline involve deploying the application to different environments for testing and quality assurance purposes. The results of the tests are consolidated and reported to the Report Portal, facilitating efficient test reporting and analysis.
The overall architecture of the CI/CD Pipeline ensures a streamlined and automated software delivery process, from source code to deployment. It provides developers with the necessary tools and processes to ensure their applications' quality, security, and scalability. Furthermore, Tekton Chains enhances supply chain security by signing and generating in-toto metadata that verifies the integrity of artifacts and the CI/CD Pipeline.
:::note
The tools mentioned in this document are just examples and can be replaced with other tools that offer similar functionality. For instance, instead of **Harbor** for the Docker Registry, it is possible to use **AWS ECR**. Consider using **Azure Artifacts** or **JFrog Artifactory** instead of **Nexus** for the artifact repository. Instead of setting up an self-managed instance of **SonarQube**, leverage *SonarCloud*, the cloud-based version of SonarQube, as an alternative. The CI/CD Pipeline architecture is flexible and adaptable, allowing the use of different tools based on specific project requirements and platform preferences.
:::
---
## Telemetry
# Telemetry
The codebase operator for the KubeRocketCI gathers anonymous data through telemetry. This data provides a clear picture of how the platform is being used and empowers the development team to make informed decisions and strategic enhancements to meet evolving operational needs. The anonymous data collected also plays an essential role in adopting a Software Development Life Cycle (SDLC) process strategically.
## Telemetry Data
The codebase-operator collects the following data:
- The version of the platform
- The number of codebases created and their parameters: language (for example, Java, NodeJS, etc.), framework (for example, FastAPI, Flask, etc.), build tool (for example, Maven, Gradle, etc.), strategy (for example, Clone, Create, Import), and Type (for example, library, application, etc.)
- The number of CD pipelines created and their parameters: deployment type (for example, Auto, Manual), and the number of stages
- The number of Git providers connected to the platform and their types (for example GitHub, GitLab, Bitbucket, or Gerrit)
- Where Jira is enabled or not
- The type of the Docker registry connected to the platform (for example, Docker Hub, Harbor, ECR)
```go
package telemetry
type CodebaseMetrics struct {
Lang string `json:"lang"`
Framework string `json:"framework"`
BuildTool string `json:"buildTool"`
Strategy string `json:"strategy"`
Type string `json:"type"`
Versioning string `json:"versioning"`
}
type CdPipelineMetrics struct {
DeploymentType string `json:"deploymentType"`
NumberOfStages int `json:"numberOfStages"`
}
type PlatformMetrics struct {
CodebaseMetrics []CodebaseMetrics `json:"codebaseMetrics"`
CdPipelineMetrics []CdPipelineMetrics `json:"cdPipelineMetrics"`
GitProviders []string `json:"gitProviders"`
JiraEnabled bool `json:"jiraEnabled"`
RegistryType string `json:"registryType"`
Version string `json:"version"`
}
```
You can verify the code which collects the data in the [codebase-operator](https://github.com/epam/edp-codebase-operator/tree/master/pkg/telemetry) repository.
## Collecting Timeline
The codebase-operator collects the data every 24 hours and sends it to the KubeRocketCI Telemetry Service. The first data points are collected 24 hours after the codebase-operator is deployed to allow users to opt-out of telemetry.
## Disabling Telemetry
The codebase-operator collects telemetry data by default. To disable telemetry, set the `TELEMETRY_ENABLED` environment variable to `false` in the codebase-operator's deployment configuration. To achieve this, run the following command:
```bash
helm upgrade --install codebase-operator codebase-operator/codebase-operator --set "telemetryEnabled=false"
```
---
## Platform Glossary
# Glossary
To help you navigate the platform more effectively, familiarize yourself with the definitions and context of the most useful platform terms presented in the table below.
| Terms | Details |
|---|---|
| **Platform Component** - an item used in the CI/CD process |**Portal UI** - component that facilitates the management, setup, and control of business entities.|
| |**Artifactory** - component that serves as a repository for all binary artifacts. _**NOTE**: Nexus is a possible implementation of a repository._|
| |**CI/CD Server** - component that executes pipelines responsible for building, testing, and deploying code. _**NOTE**: Tekton is a possible implementation of a CI/CD server._|
| |**Code Review tool** - component that facilitates collaboration and review of code changes. _**NOTE**: GitHub/GitLab is a possible implementation of a code review tool._|
| |**Identity Server** - an authentication server that provides a centralized way to verify requests for all applications. _**NOTE**: Keycloak is a possible implementation of an identity server._|
| |**Security Realm Tenant** - a realm in the identity server (e.g., Keycloak) where user accounts and access permissions are managed. The realm is unique to the identity server instance.|
| |**Static Code Analyzer** - component that continuously inspects code quality before changes are merged into the master branch. _**NOTE**: SonarQube is a possible implementation of a static code analyzer._|
| |**VCS (Version Control System)** - a repository that tracks all changes made by developers. _**NOTE**: GitHub and GitLab are possible implementations of a version control system._|
| **KubeRocketCI Business Entity** - a part of the CI/CD process (the integration, delivery, and deployment of any codebase changes) |**Application** - a codebase type that is built as the binary artifact and deployable unit with the code that is stored in VCS. As a result, the application becomes a container and can be deployed in an Environment.|
| |**Autotests** - a codebase type that inspects a product (e.g. an application set) on a Deployment Environment. Autotests are not deployed to any container and launched from the respective code repository.|
| |**Deployment (Continuous Delivery Pipeline)** - business entity that describes the whole delivery process of the selected application set via the respective Environments. The main idea of the CD pipeline is to promote the application version between the Environments by applying the sequential verification (i.e. the second Environment will be available if the verification on the first Environment is successfully completed). _**NOTE**: The Deployment can include the essential set of applications with its specific Environments as well._|
| |**Environment** - a logical entity that facilitates the inspection of application sets. Each Environment is linked to a distinct Kubernetes namespace dedicated to containerized workloads, ensuring a one-to-one mapping between the Environment and the namespace. This structure allows for the sequential promotion of applications from one Environment to the next.|
| |**Project (also codebase)** - business entity that possesses a code.|
| |**Project Branch** - business entity that represents a specific version in a Git branch. Every Project branch has a Codebase Docker Stream entity.|
| |**Codebase Image Stream** - serves as a key component in managing the deployment lifecycle of an application version. It facilitates the identification and progression of application versions that are ready for deployment. Within the Deployment, each Environment leverages Codebase Image Streams (CBIS) to manage application versions effectively. For instance, an application named 'application1' associated with a master branch would be initially tagged in the CBIS using the format: `[codebase name]-[branch name]`, e.g., 'application1-main'. As the application version progresses through the Deployment, reaching readiness for deployment in a specific Environment, the CBIS naming convention evolves to indicate its Deployment and target Environment, following the structure: `[deployment name]-[environment name]-[project name]-verified`. This approach ensures a clear and systematic tracking of application versions from their initial identification through to their readiness for deployment in various Environments within the deploy pipeline.|
| |**Git Server** - a custom resource that is responsible for integration with Version Control System (VCS), whether it is GitHub, GitLab or Gerrit.|
| |**Infrastructure** - a Project type that is used to define and manage the underlying infrastructure of projects using the _Infrastructure as Code (IaC)_ approach, ensuring consistency and reproducibility.|
| |**Library** - a Project type that is built as the binary artifact, i.e. it`s stored in the Artifactory and can be uploaded by other applications, autotests or libraries.|
| |**Quality Gate** - a business entity that defines the minimum criteria that must be met after testing to allow an application to be promoted to the next Environment. Each Environment enforces its own quality gate, which may require either manual approval from a QA specialist or a successful run of automated tests (autotests).|
| |**Quality Gate Type** - this value defines trigger type that promotes artifacts (images) to the next Environment in a deployment. There are manual and automatic types of quality gates. The manual type means that the promoting process should be confirmed in Tekton. The automatic type promotes the images automatically in case there are no errors in the Allure Report. _**NOTE**: If any of the test types is not passed, the deploy pipeline will fail._|
| |**Trigger Type** - a value that defines a trigger type used for the CD pipeline triggering. There are manual and automatic types of triggering. The manual type means that the CD pipeline should be triggered manually. The automatic type triggers the CD pipeline automatically as soon as the Codebase Docker Stream was changed.|
| |**Automated Tests** - different types of automated tests that can be run on the Deployment for a specific Environment.|
| |**Build Pipeline** - a Tekton pipeline that builds a corresponding Project branch in the Project.|
| |**Build Stage** - a stage that takes place after the code has been submitted/merged to the repository of the main branch (_the pull request from the feature branch is merged to the main one, the Patch set is submitted in GitHub/GitLab_).|
| |**Code Review Pipeline** - a Tekton pipeline that inspects the code candidate in the Code Review tool, triggered on Pull Request created/updated event.|
| |**Code Review Stage** - a stage where code is reviewed before it goes to the main branch repository of the version control system (_the commit to the feature branch is pushed, the Patch set is created in GitHub/GitLab_).|
| |**Deploy Pipeline** - a Tekton pipeline that is responsible for the CD Pipeline Stage deployment with the full set of applications and autotests.|
| |**Environment** - a part of the Continuous Delivery where artifacts are being deployed to.|
| |**CI Pipelines** - an orchestrator for stages that is responsible for the common technical events, e.g. initialization, in Tekton pipeline.|
| |**Environment** - a namespace where the built and packed into an image applications are deployed for further testing. It is possible to deploy several applications to several Environments (Team and Integration environments) within one Deployment.|
| |**Integration Environment** - an environment type that is always deployed as soon as the new application version is built in order to launch the integration test and promote images to the next Environments. The Integration Environment can be triggered manually or in case a new image appears in the Container registry.|
|**OpenShift / Kubernetes (K8S)**|**ConfigMap** - a resource that stores configuration data and processes the strings that do not contain sensitive information.|
| |**Container** - is a lightweight, standalone, and executable package.|
| |**Container Registry** - a store for the Container that is created for the application after the Build pipeline performance.|
| |**OpenShift Web Console** - a web console that enables to view, manage, and change OpenShift / K8S resources using browser.|
| |**Operator Framework** - a deployable unit in OpenShift that is responsible for one or a set of resources and performs its life circle (adding, displaying, and provisioning).|
| |**Path** - a route component that helps to find a specified path (e.g. /api) at once and skip the other.|
| |**Pod** - the smallest deployable unit of the large microservice application that is responsible for the application launch. The pod is presented as the one launched container. When the container is collected, it will be kept in Container Registry and then saved as Pod in the OpenShift project. _**NOTE**: The Deployment Config is responsible for the Pod push, restart, and stop processes._|
| |**PV (Persistent Volume)** - a cluster resource that captures the details of the storage implementation and has an independent lifecycle of any individual pod.|
| |**PVC (Persistent Volume Claim)** - a user request for storage that can request specific size and access mode. PV resources are consumed by PVCs.|
| |**Route** - a resource in OpenShift that allows getting the external access to the pushed application.|
| |**Secret** - an object that stores and manages all the sensitive information (e.g. passwords, tokens, and SSH keys).|
| |**Service** - an external connection point with Pod that is responsible for the network. A specific Service is connected to a specific Pod using labels and redirects all the requests to Pod as well.|
| |**Site** - a route component (link name) that is created from the indicated application name and applies automatically the project name and a wildcard DNS record.|
---
## KubeRocketCI Documentation
# KubeRocketCI Documentation
**KubeRocketCI (previously known as EPAM Delivery Platform)** is an **open-source** cloud-agnostic SaaS/PaaS solution for software development, licensed under **Apache License 2.0**. It provides a pre-defined set of CI/CD patterns and tools, which allow a user to start product development quickly with established **code review**, **release**, **versioning**, **branching**, **build** processes.
## Why KubeRocketCI?
KubeRocketCI, also called **"The Rocket"**, shortens the time from project initiation to active development from several months to just hours. The platform delivers:
- **Integrated CI/CD Tools**: Pre-configured toolset including Tekton, ArgoCD, Nexus, SonarQube, and more
- **Multi-Language Support**: CI pipelines for Java, Python, C#, Go, JavaScript and others
- **Infrastructure Agnostic**: Runs on Kubernetes/OpenShift in any cloud or on-premises
- **Security Focus**: Built-in authentication, authorization, and SSO for all platform services
- **Production-Ready**: Includes observability, monitoring, and established engineering practices
## Documentation Sections
### For New Users
- [Quick Start](./quick-start/platform-installation.md) - Get up and running quickly
- [About the Platform](./about-platform.md) - Overview of KubeRocketCI
- [Basic Concepts](./basic-concepts.md) - Key terminology and concepts
### For Developers
- [User Guide](./user-guide/index.md) - Working with the KubeRocketCI portal and CI/CD flow
- [Developer Guide](./developer-guide/index.md) - Detailed information for platform developers
- [Use Cases](./use-cases/index.md) - Real-world implementation examples
### For Administrators
- [Operator Guide](./operator-guide/index.md) - Installation, configuration, and administration
- [API Reference](./api/cd-pipeline.md) - Programmatic interface details
- [Supported Versions](./supported-versions.md) - Compatibility information
### Additional Resources
- [Glossary](./glossary.md) - Terms and definitions
- [Compliance](./compliance.md) - Security and compliance information
- [FAQ](/faq/general-questions) - Frequently asked questions
## Getting Started
The fastest way to explore KubeRocketCI is to follow our [Quick Start Guide](./quick-start/platform-installation.md), which will guide you through the installation process and basic platform usage.
For a deeper understanding of the platform architecture, components, and capabilities, visit the [About the Platform](./about-platform.md) page.
---
## Install via Add-Ons
# Install via Add-Ons
This page provides an overview of Cluster Add-Ons for KubeRocketCI, including their purpose, benefits, and usage.
## What Are Add-Ons
KubeRocketCI Add-Ons is essentially a Kubernetes-based deployment pattern that allows users to easily install additional components for the platform using Argo CD applications.
Add-Ons have been introduced into KubeRocketCI starting from version 3.4.0. They empower users to seamlessly integrate the platform with various additional components, such as SonarQube, Nexus, Keycloak, Jira, and more. This eliminates the need for manual installations, as described in the [Install KubeRocketCI](../operator-guide/install-kuberocketci.md) page.
In a nutshell, Add-Ons are separate Helm charts that can be installed with just one click using the Argo CD tool.
## Add-Ons Repository Structure
All the Add-Ons for KubeRocketCI are stored in our [GitHub repository](https://github.com/epam/edp-cluster-add-ons) following the GitOps approach. In addition to default Helm and Git files, the repository contains custom resources called Applications for Argo CD and application source code. The repository adheres to the GitOps approach, allowing for easy rollback of changes when necessary. The structure of the repository is as follows:
View: edp-cluster-add-ons repo structure
```bash
edp-cluster-add-ons
├── argo-cd
│ ├── Chart.yaml
│ ├── README.md
│ ├── templates
│ │ ├── appProjectCore.yaml
│ │ ├── appProjectKRCI.yaml
│ │ ├── ...
│ └── values.yaml
├── ...
├── clusters
│ ├── core
│ │ ├── addons
│ │ │ ├── atlantis
│ │ │ │ ├── Chart.yaml
│ │ │ │ ├── README.md
│ │ │ │ ├── templates
│ │ │ │ └── values.yaml
│ │ │ ├── aws-efs-csi-driver
│ │ │ │ ├── Chart.yaml
│ │ │ │ ├── README.md
│ │ │ │ ├── templates
│ │ │ │ └── values.yaml
│ │ │ ├── ...
│ │ ├── apps
│ │ │ ├── templates
│ │ │ │ ├── atlantis.yaml
│ │ │ │ ├── aws-efs-csi-driver.yaml
│ │ │ │ ├── ...
│ │ │ ├── Chart.yaml
│ │ │ ├── README.md
│ │ │ └── values.yaml
│ │ └── bootstrap-addons.yaml
│ └── prod
├── ...
```
- **argo-cd** - The directory containing the Helm chart for deploying the main Argo CD instance and prepared project templates.
- **clusters** - A directory for organizing configurations and Helm charts specific to individual clusters. Each subdirectory corresponds to a particular cluster environment (e.g., core, prod, or dev).
- **addons** - The directory containing subdirectories with Helm charts for applications to install, such as Nexus, SonarQube, Keycloak, etc. See the full add-ons list [below](#available-add-ons-list).
- **apps** - Contains application `templates` directory used to create Argo CD application. The deployment of these applications is managed by modifying the `apps/values.yaml` file, where you can enable or disable specific applications.
- **bootstrap-addons.yaml** - The manifest file defining the app of apps application responsible for deploying all enabled application to the cluster. This manifest is applied manually.
## Enable KubeRocketCI Add-Ons
To enable Add-Ons, it is necessary to have the configured Argo CD, and connect and synchronize the forked repository. To do this, follow the guidelines below:
1. Create a fork of the [Add-Ons repository](https://github.com/epam/edp-cluster-add-ons) in your personal Git account.
2. Align **repoUrl** in [/clusters/core/apps/values.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/apps/values.yaml#L14), [/clusters/core/bootstrap-addons.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/bootstrap-addons.yaml#L16) and **repoSource** in the [/argo-cd/templates/appProjectCore.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/argo-cd/templates/appProjectCore.yaml#L36), [/argo-cd/templates/appProjectCore.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/argo-cd/templates/appProjectKRCI.yaml#L55) files of the repository, specify the SSH URL of your fork. For GitHub, replace `kuberocketci` with your ``.
3. Clone a forked add-ons repository to your local machine and install pre-configured **Argo CD** Helm chart from `/argo-cd` folder using the command below:
```bash
helm install argocd argo-cd -n argocd --create-namespace
```
4. (Optional) If you don't have an ingress controller created in your Kubernetes cluster, enable port-forwarding for the Argo CD service using the command below:
```bash
kubectl port-forward -n argocd service/argo-cd-argocd-server 65080:80
```
This will forward the Argo CD service to `http://localhost:65080` on your local machine. Open this URL in your browser to access the Argo CD interface.
5. As soon as Helm chart is deployed, open your Argo CD endpoint and navigate to **Settings** -> **Repositories**. Connect your repository where you have the values.yaml files changed by clicking the **+ CONNECT REPO** button:

6. In the appeared window, fill in the following fields and click the **CONNECT** button:
- Choose your connection method - `VIA SSH`
- Name - `addons-demo` (optional)
- Project - select project
- Repository URL - enter the `SSH URL` of your forked repository (ssh://git@github.com:22/``/edp-cluster-add-ons.git)

7. As soon as the repository is connected, the new item will appear in the repository list:

8. Apply the add-ons management application manifest and open **Application** tab:
```bash
kubectl apply -f edp-cluster-add-ons/clusters/core/bootstrap-addons.yaml -n argocd
```

9. Click the **addon-core** application to open its details:

## Install Add-Ons
Now that Add-Ons are enabled in Argo CD, they can be installed by following the steps below:
1. Choose the Add-On to install.
2. Enable the Add-Ons chosen in the [/clusters/core/apps/values.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/apps/values.yaml) file. You can also re-define Add-On parameters. Refer to the example below:
```bash
sonar:
createNamespace: true
enable: true
sonar-operator:
createNamespace: true
enable: true
```
3. Navigate to the Argo CD Add-Ons application. On the chosen Add-On, click the **⋮** button and then **Details**:

4. To install the Add-On, click the **⋮** button -> **Sync**:

5. Once the Add-On is installed, the *Sync OK* message will appear in the Add-On status bar:

6. Open the application details by clicking on the little square with an arrow underneath the Add-On name:

7. By default in all addons application `auto sync is not enabled` to install application click **Sync** button.

8. Track application resources and status in the **App details** menu:

Argo CD provides excellent observability and monitoring capabilities for its resources, which is particularly beneficial when utilizing KubeRocketCI Add-Ons.
## Available Add-Ons List
The list of the available Add-Ons:
:::info
Consult repository [README.md](https://github.com/epam/edp-cluster-add-ons?tab=readme-ov-file#available-add-ons) for the most up-to-date information.
:::
|Name|Description|Default|
|:-|:-|:-:|
|Argo CD|A GitOps continuous delivery tool that helps automate the deployment, configuration, and lifecycle management of applications in Kubernetes clusters.|false|
|AWS EFS CSI Driver|A Container Storage Interface (CSI) driver that enables the dynamic provisioning of Amazon Elastic File System (EFS) volumes in Kubernetes clusters.|false|
|Cert Manager|A native Kubernetes certificate management controller that automates the issuance and renewal of TLS certificates.|false|
|Capsule|A multi-tenancy solution for Kubernetes clusters that provides each tenant with a dedicated namespace where they can freely run their workloads with resource quotas.|false|
|Capsule tenant|A specific tenant within the Capsule multi-tenancy solution. Each tenant has its own isolated environment within the Kubernetes cluster.|false|
|DefectDojo|A security vulnerability management tool that allows tracking and managing security findings in applications.|false|
|Dependency-Track|A Software Composition Analysis (SCA) platform that helps identify and manage open-source dependencies and their associated vulnerabilities.|false|
|KubeRocketCI(EDP)|An internal platform created by EPAM to enhance software delivery processes using DevOps principles and tools.|false|
|Extensions OIDC|KubeRocketCI Helm chart to provision OIDC clients for different Add-Ons using EDP Keycloak Operator.|false|
|External Secrets|A Kubernetes Operator that fetches secrets from external secret management systems and injects them as Kubernetes Secrets.|false|
|Fluent Bit|A lightweight and efficient log processor and forwarder that collects and routes logs from various sources in Kubernetes clusters.|false|
|Harbor|A cloud-native container image registry that provides support for vulnerability scanning, policy-based image replication, and more.|false|
|Ingress nginx|An Ingress controller that provides external access to services running within a Kubernetes cluster using Nginx as the underlying server.|false|
|Jaeger Operator|An operator for deploying and managing Jaeger, an end-to-end distributed tracing system, in Kubernetes clusters.|false|
|Keycloak|An open-source Identity and Access Management (IAM) solution that enables authentication, authorization, and user management in Kubernetes clusters.|false|
|Keycloak PostgreSQL|A PostgreSQL database operator that simplifies the deployment and management of PostgreSQL instances in Kubernetes clusters.|false|
|krci-audit|An append-only admission audit trail (capture, store, and read API) recording who created, updated, or deleted KubeRocketCI resources.|false|
|MinIO Operator|An operator that simplifies the deployment and management of MinIO, a high-performance object storage server compatible with Amazon S3, in Kubernetes clusters.|false|
|Nexus|Serves as a repository manager, enabling the proxying, aggregation, and management of dependencies, as well as the storage of artifacts.|false|
|Nexus Operator|A tool designed to streamline the handling of Nexus resources and configurations, facilitating the proxying, collection, and management of dependencies within a repository manager.|false|
|OpenSearch|A community-driven, open-source search and analytics engine that provides scalable and distributed search capabilities for Kubernetes clusters.|false|
|OpenTelemetry Operator|An operator for automating the deployment and management of OpenTelemetry, a set of observability tools for capturing, analyzing, and exporting telemetry data.|false|
|PostgreSQL Operator|An operator for running and managing PostgreSQL databases in Kubernetes clusters with high availability and scalability.|false|
|Report Portal|An powered test automation dashboard that allows you to analyze test results, identify issues, and track testing progress.|false|
|Prometheus Operator|An operator that simplifies the deployment and management of Prometheus, a monitoring and alerting toolkit, in Kubernetes clusters.|false|
|Redis Operator|An operator for managing Redis, an in-memory data structure store, in Kubernetes clusters, providing high availability and horizontal scalability.|false|
|Sonar|A comprehensive open-source platform dedicated to the continuous evaluation of code quality, automatically scrutinizing code to identify bugs, code smells, and security vulnerabilities.|false|
|Sonar Operator|An operator that simplifies the management and configuration of SonarQube.|false|
|StorageClass|A Kubernetes resource that provides a way to define different classes of storage with different performance characteristics for persistent volumes.|false|
|Tekton|A flexible and cloud-native framework for building, testing, and deploying applications using Kubernetes-native workflows.|false|
|Tekton Monitoring|Prometheus ServiceMonitors and Grafana dashboards for the Tekton stack, covering pipeline throughput, task duration, queueing, and control plane health.|false|
|Tekton-cache||false|
|Vault|An open-source secrets management solution that provides secure storage, encryption, and access control for sensitive data in Kubernetes clusters.|false|
|Velero|An open source tool to safely backup and restore, perform disaster recovery, and migrate Kubernetes cluster resources and persistent volumes.|false|
---
## Install Capsule
# Install Capsule
This article explains how the KubeRocketCI leverages Capsule capabilities to enable isolation for both the [core](../install-kuberocketci.md) platform components and the business applications [workload](../../user-guide/add-cd-pipeline.md).
KubeRocketCI uses Capsule to ensure resource isolation. It is essential to define constraints through the Capsule tenant approach. This approach serves two primary objectives: limiting the resources allocated to the KubeRocketCI components and regulating the resources utilized by each deployed environment.
To ensure isolation for the core platform components, create the `krci` namespace under the Capsule tenant. Use the template provided in this instruction to create the Capsule tenant specifically for the core components.
## Integration
The following diagram outlines the general steps involved in configuring Capsule for seamless integration with KubeRocketCI. This process ensures efficient resource isolation, allowing for the deployment and management of both KubeRocketCI core platform components and business application workloads.
Follow the sequential flow of the diagram to successfully integrate Capsule with the KubeRocketCI platform:
```mermaid
graph LR;
A(Capsule Installation) --> B(Tenant Configuration) --> C(Impersonation) --> D(Create Namespace)--> E(Deploy KubeRocketCI)
```
1. **Capsule Installation** - This initial step involves setting up Capsule on your environment.
2. **Tenant Configuration** - Once Capsule is installed, the next critical step is configuring the Capsule tenant. This involves defining specific parameters and constraints to regulate the allocation of resources to KubeRocketCI components.
3. **Impersonation** - Impersonation plays a role in managing user identities and permissions within the Capsule environment. This step ensures secure and controlled access to resources.
4. **Create Namespace** - The creation of a dedicated namespace under Capsule is crucial for isolating and managing the core components of the platform. This step establishes the environment where KubeRocketCI will be deployed (`krci` by default).
5. **Deploy KubeRocketCI** - The final step involves deploying the platform within the configured Capsule environment.
## Installation
The installation procedure consists of two steps:
1. Define the namespace where KubeRocketCI will be installed in Capsule values:
```yaml title="values.yaml"
manager:
options:
# -- Boolean, enforces the Tenant owner, during Namespace creation, to name it using the selected Tenant name as prefix, separated by a dash
forceTenantPrefix: true
# enable capsule for KubeRocketCI tenant and cd-pipeline-operator
# NOTE: Capsule cannot manage cluster system namespaces
capsuleUserGroups:
- capsule.clastix.io
# enable for cd-pipeline-operator https://github.com/epam/edp-cd-pipeline-operator/blob/release/2.17/deploy-templates/values.yaml#L10
- system:serviceaccounts:krci # krci - Namespace where KubeRocketCI will be installed.
- masters # Kubernetes group that manages the KubeRocketCI tenant.
# uncomment if Argo CD manage main KubeRocketCI tenant
#- system:serviceaccounts:argocd
# uncomment if edp-oidc-admins group manage main KubeRocketCI tenant
#- edp-oidc-admins
```
2. To install the Capsule tool, use the [Cluster Add-Ons](https://github.com/epam/edp-cluster-add-ons) approach. For more details, please refer to the [Capsule](https://capsule.clastix.io/docs/general) official page.
## Configuration
After installing Capsule, the next crucial step is configuration. Follow the guidelines provided below to configure Capsule and ensure seamless integration with your system:
1. Specify the Capsule tenant configuration:
```yaml title="krci-tenant-example.yaml"
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
name: krci-tenant
spec:
...
owners:
- clusterRoles:
- admin
- capsule-namespace-manager
kind: Group
name: system:masters
#
# Uncomment if Argo CD manage KubeRocketCI tenant
#- clusterRoles:
# - admin
# - capsule-namespace-manager
# kind: ServiceAccount
# name: system:serviceaccount:argocd:argocd-application-controller
#
# Uncomment if edp-oidc-admins group manage KubeRocketCI tenant
#- clusterRoles:
# - admin
# - capsule-namespace-manager
# kind: Group
# name: edp-oidc-admins
...
```
`system:masters` Group that manages the KubeRocketCI tenant. Must be declared in the above configuration of the `capsuleUserGroups`.
The following example includes additional specifications that can be used to manage the KubeRocketCI tenant:
:::note Tenant configuration example
```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
name: krci-tenant
spec:
ingressOptions:
allowWildcardHostnames: false
allowedHostnames:
allowedRegex: ^.*example.com$ # DNSwildcard for KubeRocketCI usage
hostnameCollisionScope: Tenant
limitRanges:
items:
- limits:
# The default limits apply to each container unless otherwise specified by default
- default:
cpu: 768m
memory: 768Mi
# The default requests apply to each container unless otherwise specified by default
defaultRequest:
cpu: 256m
memory: 512Mi
type: Container
- limits:
# In case Tekton pipelines need to use volume workspaces. If use emptydir please set it to 0.
- max:
storage: 3Gi
min:
storage: 3Gi
type: PersistentVolumeClaim
# Since EDKubeRocketCIP uses one namespace, the namespace quota is set to 1
namespaceOptions:
quota: 1
networkPolicies:
items:
- ingress:
- from:
- namespaceSelector:
matchLabels:
capsule.clastix.io/tenant: krci-tenant
- podSelector: {}
- ipBlock:
cidr: 172.32.0.0/16
podSelector: {}
policyTypes:
- Ingress
# Default KubeRocketCI admins group to make admin users tenant owners
owners:
- clusterRoles:
- admin
- capsule-namespace-manager
kind: Group
name: system:masters
#
# Uncomment if Argo CD manage main KubeRocketCI tenant
#- clusterRoles:
# - admin
# - capsule-namespace-manager
# kind: ServiceAccount
# name: system:serviceaccount:argocd:argocd-application-controller
#
# Uncomment if edp-oidc-admins group manage main KubeRocketCI tenant
#- clusterRoles:
# - admin
# - capsule-namespace-manager
# kind: Group
# name: sandbox-oidc-cluster-admins
resourceQuotas:
items:
# The maximum CPU and Memory capacity for the KubeRocketCI tenant
- hard:
limits.cpu: '2'
limits.memory: 2Gi
# The maximum number of pods that can be deployed within a namespace
- hard:
pods: '15'
scope: Tenant
serviceOptions:
# Enable the capabilities to create ClusterIP service types only
allowedServices:
externalName: false
loadBalancer: false
nodePort: false
```
:::
2. To install the Capsule tenant, use the [Cluster Add-Ons](https://github.com/epam/edp-cluster-add-ons) approach.
3. [Create namespace](https://capsule.clastix.io/docs/general/tutorial/#create-namespaces) for the KubeRocketCI tenant:
1. Log in as a `system:masters` member and create a namespace for platform deployment under the Capsule tenant using the following command:
```bash
kubectl create namespace krci
```
2. To ensure that the `krci` namespace is successfully created under the Capsule tenant, you can verify the status of the Capsule tenant using the following command:
```bash
kubectl get tenant krci-tenant -o yaml
```
Expected output:
```yaml
...
status:
namespaces:
- krci
size: 1
state: Active
```
4. Enable Capsule in the values.yaml file to make it possible to manage deployable environments:
```yaml title="values.yaml"
cd-pipeline-operator:
tenancyEngine: "capsule"
```
By following these instructions, Capsule policies are utilized to manage the KubeRocketCI core components and deployable environments. By adhering to these guidelines, you should successfully install KubeRocketCI with Capsule enabled as the `tenancyEngine`.
## Related Articles
* [Install KubeRocketCI With Values File](../install-kuberocketci.md)
* [Cluster Add-Ons Overview](../add-ons-overview.md)
---
## Custom Certificates
# Custom Certificates
Familiarize yourself with the detailed instructions on adding certificates to KubeRocketCI resources as well as with the respective setup for Keycloak.
KubeRocketCI components that support custom certificates can be found in the table below:
| Helm Chart | Sub Resources |
| - | - |
| gerrit-operator | edp-gerrit |
| sonar-operator | sonar-operator, edp-sonar |
| keycloak-operator | keycloak-operator |
| nexus-operator | oauth2-proxy |
| edp-install | oauth2-proxy |
| edp-headlamp | edp-headlamp |
## Prerequisites
- The certificate in the `*.crt` format is used
- Kubectl version 1.34.0+ is installed. Please refer to the [Kubernetes official website](https://kubernetes.io/releases/download/) for details.
- [Helm](https://helm.sh) version 3.19.0+ is installed. Please refer to the [Helm page](https://github.com/helm/helm/releases) on GitHub for details.
- [Java](https://www.oracle.com/in/java/technologies/downloads/) with the `keytool` command inside
- [jq](https://stedolan.github.io/jq/) is installed.
## Enable the SPI Truststore of Keycloak
To import custom certificates to Keycloak, follow the steps below:
1. Generate the `cacerts` local keystore and import the certificate there using the keytool tool:
```bash
keytool -importcert -file CA.crt \
-alias CA.crt -keystore ./cacerts \
-storepass changeit -trustcacerts \
-noprompt
```
2. Create the `custom-keycloak-keystore` keystore secret from the `cacerts` file in the `security` namespace:
```bash
kubectl -n security create secret generic custom-keycloak-keystore \
--from-file=./cacerts
```
3. Create the `spi-truststore-data` SPI truststore secret in the `security` namespace:
```bash
kubectl -n security create secret generic spi-truststore-data \
--from-literal=KC_SPI_TRUSTSTORE_FILE_FILE=/opt/keycloak/spi-certs/cacerts \
--from-literal=KC_SPI_TRUSTSTORE_FILE_PASSWORD=changeit
```
4. Update the Keycloak `values.yaml` file from the [Install Keycloak](../auth/keycloak.md) page.
values.yaml
```yaml
...
extraVolumeMounts: |
...
# Use the Keycloak truststore for SPI connection over HTTPS/TLS
- name: spi-certificates
mountPath: /opt/keycloak/spi-certs
readOnly: true
...
extraVolumes: |
...
# Use the Keycloak truststore for SPI connection over HTTPS/TLS
- name: spi-certificates
secret:
secretName: custom-keycloak-keystore
defaultMode: 420
...
...
extraEnvFrom: |
- secretRef:
name: spi-truststore-data
...
```
## Enable Custom Certificates in KubeRocketCI Components
Creating custom certificates is a necessary but not sufficient condition for applying, therefore, certificates should be enabled as well.
1. Create the `custom-ca-certificates` secret in the platform namespace (e.g `krci`).
```bash
kubectl -n krci create secret generic custom-ca-certificates \
--from-file=CA.crt
```
2. Add the certificate by mounting the `custom-ca-certificates` secret to the operator pod as a volume.
Example of specifying custom certificates for the `keycloak-operator`:
```yaml
...
keycloak-operator:
enabled: true
# -- Additional volumes to be added to the pod
extraVolumes:
- name: custom-ca
secret:
defaultMode: 420
secretName: custom-ca-certificates
# -- Additional volumeMounts to be added to the container
extraVolumeMounts:
- name: custom-ca
mountPath: /etc/ssl/certs/CA.crt
readOnly: true
subPath: CA.crt
...
```
:::warning
Before moving ahead, be aware that starting from version 3.3.0, our development team has officially deprecated the Jenkins deploy scenario. This means that as of version 3.3.0 and in all subsequent versions (3.3.x and above), the Jenkins deploy scenario is no longer supported.
For users running versions 3.3.x and below, the Jenkins deploy scenario remains available. However, we encourage you to plan for the transition to a supported deployment method to ensure continued compatibility and access to the latest features and enhancements. To perform migration, please familiarize yourself with the [Migrate CI Pipelines From Jenkins to Tekton](../upgrade/migrate-ci-pipelines-from-jenkins-to-tekton.md).
For those who still use EDP v3.3.x and below, the information below remains valid and applicable.
:::
3. For Sonar, Jenkins and Gerrit, change the flag in the `caCerts.enabled` field to `true`. Also, change the name of the secret in the `caCerts.secret` field to `custom-ca-certificates`.
Example of specifying custom certificates for `Gerrit` via the `gerrit-operator` helm chart values:
```yaml
...
gerrit-operator:
enabled: true
gerrit:
caCerts:
# -- Flag for enabling additional CA certificates
enabled: true
# -- Change init CA certificates container image
image: adoptopenjdk/openjdk11:alpine
# -- Name of the secret containing additional CA certificates
secret: custom-ca-certificates
...
```
## Integrate Custom Certificates Into Jenkins Agents
This section describes how to add custom certificates to Jenkins agents to use them from Java applications.
:::info
For example, `curl` doesn't use keystore files specified in this part of the documentation.
:::
Jenkins agents keep keystore files in two places:
- `/etc/ssl/certs/java` folder with the `cacerts` file
- `/opt/java/openjdk/lib/security` folder with the `blocked.certs`, `cacerts`, `default.policy` and `public_suffix_list.dat` files.
1. Copy the files in `/etc/ssl/certs/java` and `/opt/java/openjdk/lib/security` directories from Jenkins agent pod to the local `tmp` folder.
There is a `copy_certs.sh` script below that can manage this. It copies the files in `/etc/ssl/certs/java` and `/opt/java/openjdk/lib/security` directories from Jenkins agent pod to the local `tmp` folder
and imports the custom certificate into the keystore files, after which it creates the
`jenkins-agent-opt-java-openjdk-lib-security-cacerts` and `jenkins-agent-etc-ssl-certs-java-cacerts` secrets from updated keystore files in KubeRocketCI namespace.
Also, the `jenkins-agent-opt-java-openjdk-lib-security-cacerts` secret contains three additional files: `blocked.certs`, `default.policy` and `public_suffix_list.dat` which managed by the `copy_certs.sh` script as well. Expand the drop-down button below to see the contents of the `copy_certs.sh` script.
copy_certs.sh
```bash
# Fill in the variables `ns` and `ca_file`
ns="krci"
ca_file="/tmp/CA.crt"
images=$(kubectl get -n "${ns}" cm jenkins-slaves -ojson | jq -r ".data[]" | grep image\> | sed 's/\s*<.*>\(.*\)<.*>/\1/')
image=$(for i in ${images[@]}; do echo $i; done | grep maven-java8)
pod_name=$(echo "${image}" | tr '.:/' '-')
overrides="{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"name\":\"${pod_name}\", \"namespace\": \"${ns}\"},
\"spec\":{\"containers\":[{\"name\":\"${pod_name}\",\"image\":\"${image}\",
\"command\":[\"sh\",\"-c\",\"while true;do sleep 30;done;\"]}]}}"
kubectl run -n "${ns}" "${pod_name}" --image "${image}" --overrides="${overrides}"
kubectl wait --for=condition=ready pod "${pod_name}" -n "${ns}"
cacerts_location=$(kubectl exec -n "${ns}" "${pod_name}" \
-- find / -name cacerts -exec ls -la "{}" \; 2>/dev/null | grep -v ^l | awk '{print $9}')
for cacerts in ${cacerts_location[@]}; do echo $(dirname "${cacerts}"); kubectl exec -n "${ns}" "${pod_name}" -- ls $(dirname "${cacerts}"); done
for cacerts in ${cacerts_location[@]}; do \
echo $(dirname "${cacerts}"); \
mkdir -p "/tmp$(dirname "${cacerts}")"; \
from_files=''; \
for file in $(kubectl exec -n "${ns}" "${pod_name}" -- ls $(dirname "${cacerts}")); do \
kubectl exec -n "${ns}" "${pod_name}" -- cat "$(dirname "${cacerts}")/${file}" > "/tmp$(dirname "${cacerts}")/${file}"; \
from_files="${from_files} --from-file=/tmp$(dirname "${cacerts}")/${file}"
done ; \
keytool -import -storepass changeit -alias kubernetes -file ${ca_file} -noprompt -keystore "/tmp${cacerts}"; \
kubectl -n "${ns}" create secret generic "jenkins-agent${cacerts//\//-}" $from_files \
done
kubectl delete -n "${ns}" pod "${pod_name}" --force --grace-period=0
```
Before using the `copy_certs.sh` script, keep in mind the following:
- assign actual values to the variables `ns` and `ca_file`
- the script collects all the images from the `jenkins-slaves` ConfigMap and uses the image of
the `maven-java8` agent as the base image of the temporary pod to get the keystore files;
- custom certificate is imported using the `keytool` application
- the `jenkins-agent-opt-java-openjdk-lib-security-cacerts` and `jenkins-agent-etc-ssl-certs-java-cacerts` secrets will be created in the `krci` namespace.
2. Run the `copy_certs.sh` script from the previous point after the requirements are met.
3. Update manually the `jenkins-slaves` ConfigMap.
Add this block with the mount of secrets to the `` block of each Jenkins agent:
```xml
...
/etc/ssl/certs/javajenkins-agent-etc-ssl-certs-java-cacerts/opt/java/openjdk/lib/securityjenkins-agent-opt-java-openjdk-lib-security-cacerts
...
```
As an example, the template of `gradle-java11-template` is shown below:
```xml
...
/etc/ssl/certs/javajenkins-agent-etc-ssl-certs-java-cacerts/opt/java/openjdk/lib/securityjenkins-agent-opt-java-openjdk-lib-security-cacerts
...
```
4. Reload the Jenkins pod:
```bash
ns="krci"
kubectl rollout restart -n "${ns}" deployment/jenkins
```
## Related Articles
* [Install KubeRocketCI](../install-kuberocketci.md)
* [Install Keycloak](../auth/keycloak.md)
---
## Advanced Installation Overview: Third-Party Tools
# Advanced Installation Overview: Third-Party Tools
This page provides a concise overview of the advanced components available in KubeRocketCI. While these third-party tools are not obligatory, they greatly enhance the capabilities of the platform, enabling the creation of a robust CI/CD environment.
## Third-Party Components
Find below the list of the key components used by KubeRocketCI:
|Component|Requirement Level|Description|
|:-|:-:|:-|
|[Tekton](../install-tekton.md)|Mandatory|A cloud-native solution for building CI/CD pipelines.|
|[Argo CD](../install-argocd.md)|Mandatory|A declarative, GitOps continuous delivery tool for Kubernetes.|
|[NGINX Ingress Controller](../install-ingress-nginx.md)[^1]| Mandatory|Manages external access to HTTP services in a Kubernetes cluster.|
|[Keycloak](../auth/keycloak.md)|Optional|An open-source identity and access management solution.|
|[DefectDojo](../devsecops/defectdojo.md)|Optional|An open-source application vulnerability management tool.|
|[ReportPortal](../project-management-and-reporting/install-reportportal.md)|Optional|An AI-powered test automation dashboard for analyzing test results.|
|[Capsule](capsule.md)[^2]|Optional|A lightweight tool for managing Kubernetes namespaces.|
|[External Secrets](../secrets-management/install-external-secrets-operator.md)|Optional|Manages external secret storage like AWS Secrets Manager, integrating with Kubernetes.|
|[Nexus](../artifacts-management/nexus-sonatype.md)|Optional|A repository manager supporting various formats including Docker, npm, and Helm charts.|
|[Harbor](../artifacts-management/harbor-installation.md)|Optional|An open-source trusted cloud native registry project that stores, signs, and scans content.|
Although we have dedicated instructions for all of these third-party tools, we recommend installing them via [add-ons approach](../add-ons-overview.md).
[^1]:
OpenShift cluster uses Routes to provide access to pods from external resources.
[^2]:
These tools need to be installed in advance before deploying KubeRocketCI.
---
## Install Harbor
# Install Harbor
One of the storage options for application images within KubeRocketCI is Harbor, utilized during the application build process.
Inspect the prerequisites and the main steps to perform for enabling [Harbor](https://goharbor.io/docs/2.8.0/) on the platform.
## Prerequisites
- Kubectl version 1.34.0+ is installed. Please refer to the [Kubernetes official website](https://kubernetes.io/releases/download/) for details.
- [Helm](https://helm.sh) version 3.19.0+ is installed. Please refer to the [Helm page](https://github.com/helm/helm/releases) on GitHub for details.
## Installation
To install Harbor with Helm, follow the steps below:
1. Create a namespace for Harbor:
```bash
kubectl create namespace harbor
```
2. Create a secret for administrator user and registry:
1. Manually
```bash
kubectl create secret generic harbor \
--from-literal=HARBOR_ADMIN_PASSWORD= \
--from-literal=REGISTRY_HTPASSWD= \
--from-literal=REGISTRY_PASSWD= \
--from-literal=secretKey= \
--namespace harbor
```
2. Using `External Secret Operator` (ESO)
Create Secret data with ESO
```yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: harbor
namespace: harbor
spec:
refreshInterval: 1h
secretStoreRef:
kind: SecretStore
name: aws-parameterstore
data:
- secretKey: HARBOR_ADMIN_PASSWORD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /control-plane/deploy-secrets
property: harbor.HARBOR_ADMIN_PASSWORD
- secretKey: secretKey
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /control-plane/deploy-secrets
property: harbor.secretKey
- secretKey: REGISTRY_HTPASSWD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /control-plane/deploy-secrets
property: harbor.REGISTRY_HTPASSWD
- secretKey: REGISTRY_PASSWD
remoteRef:
conversionStrategy: Default
decodingStrategy: None
key: /control-plane/deploy-secrets
property: harbor.REGISTRY_PASSWD
```
:::note
The `HARBOR_ADMIN_PASSWORD` is the initial password of Harbor admin.
The `secretKey` is the secret key that is used for encryption. Must be 16 characters long.
The `REGISTRY_PASSWD` is Harbor registry password.
The `REGISTRY_HTPASSWD` is login and password in htpasswd string format. This value is the string in the password
file generated by the `htpasswd` command where the username is `harbor_registry_user` and the encryption type
is `bcrypt`.
See the example below:
```bash
htpasswd -bBc passwordfile harbor_registry_user harbor_registry_password
```
The username must be `harbor_registry_user`.
The password must be the value from `REGISTRY_PASSWD`.
:::
3. Add the Helm Harbor Charts for the local client.
```bash
helm repo add harbor https://helm.goharbor.io
```
4. Check the parameters in the Harbor installation chart. For details, please refer to
the [values.yaml](https://github.com/goharbor/harbor-helm/blob/master/values.yaml) file.
5. Install Harbor in the _harbor_ namespace with the Helm tool.
```bash
helm install harbor harbor/harbor
--version 1.17.2 \
--namespace harbor \
--values values.yaml
```
See the details on the parameters below:
:::note Example values.yaml
```yaml
# we use Harbor secret to consolidate all the Harbor secrets
existingSecretAdminPassword: harbor
existingSecretAdminPasswordKey: HARBOR_ADMIN_PASSWORD
existingSecretSecretKey: harbor
core:
# The XSRF key. Will be generated automatically if it isn't specified
xsrfKey: ""
jobservice:
# Secret is used when job service communicates with other components.
# If a secret key is not specified, Helm will generate one.
# Must be a string of 16 chars.
secret: ""
registry:
# Secret is used to secure the upload state from client
# and registry storage backend.
# If a secret key is not specified, Helm will generate one.
# Must be a string of 16 chars.
secret: ""
credentials:
username: harbor_registry_user
existingSecret: harbor
fullnameOverride: harbor
# If Harbor is deployed behind the proxy, set it as the URL of proxy
externalURL: https://core.harbor.domain
ipFamily:
ipv6:
enabled: false
expose:
tls:
enabled: false
ingress:
hosts:
core: core.harbor.domain
notary: notary.harbor.domain
updateStrategy:
type: Recreate
persistence:
persistentVolumeClaim:
registry:
size: 30Gi
jobservice:
jobLog:
size: 1Gi
database:
size: 2Gi
redis:
size: 1Gi
trivy:
size: 5Gi
database:
internal:
# The initial superuser password for internal database
password: "changeit"
```
:::
6. To check if the installation is successful, run the command below:
```bash
helm status -n harbor
```
You can also check ingress endpoints to get Harbor endpoint to enter Harbor UI:
```bash
kubectl describe ingress -n harbor
```
## Related Articles
* [Install KubeRocketCI](../install-kuberocketci.md)
* [Integrate Harbor With KubeRocketCI Pipelines](../artifacts-management/harbor-integration.md)
---
## Integrate Harbor With Tekton Pipelines
# Integrate Harbor With Tekton Pipelines
[Harbor](https://goharbor.io/) is an advanced, open-source cloud-native registry that securely manages container images and Helm charts, and also supports a wide range of OCI artifacts. It enforces policies and role-based access control, while ensuring all managed content, including container images and other artifacts, are scanned and certified free from vulnerabilities. For those looking to integrate Harbor into their workflow, the documentation provides comprehensive steps on [creating projects](https://goharbor.io/docs/2.0.0/working-with-projects/create-projects/) and establishing robot accounts. These accounts facilitate automated and secure interactions with the registry, crucial for CI pipelines and enhancing overall security and efficiency in artifact management.
## Overview
Harbor integration with Tekton enables the centralized storage of container images within the cluster,
eliminating the need for external services. By leveraging Harbor as the container registry, users can manage
and store their automation results and reports in one place.
## Integration Procedure
The integration process involves two steps:
1. Creating a project to store application images.
2. Creating two service accounts (robot account) with different permissions to push (read/write) and pull (read-only) project images.
### Create New Project
The process of creating new projects is the following:
1. Log in to the Harbor console using your credentials.
2. Navigate to the **Projects** menu, click the **New Project** button:

3. On the **New Project** menu, enter a project name that matches your platform namespace in the **Project Name** field. Keep other fields as default and click **OK** to continue:

### Set Up Robot Account
To facilitate seamless interaction between KubeRocketCI and a Harbor project, it is crucial to establish a robot account. This process involves:
1. Navigate to your newly created project, select **Robot Accounts** menu and choose **New Robot Account**:

2. In the pop-up window, fill in the fields as follows:
- **Name** - `edp-push`
- **Expiration time** - set the value which is aligned with your organization policy
- **Description** - `read/write permissions`
- **Permissions** - `Pull Repository` and `Push Repository`.
To proceed, click the **ADD** button:

3. In the appeared window, copy the robot account credentials or click the **Export to file** button to save the secret and account name locally:

4. Provision the **kaniko-docker-config** secrets using kubectl, KubeRocketCI portal or with the externalSecrets operator:
The `auth` string can be generated by this command:
```bash
echo -n "robot\$edp-project+edp:secret" | base64
```
Navigate to **Portal** -> **Configuration** -> **Artifacts storage** -> **Registry**. Update or click **+ Add registry** fill in the required fields and click `Save`.

```yaml
apiVersion: v1
kind: Secret
metadata:
name: kaniko-docker-config
namespace: krci
labels:
app.edp.epam.com/secret-type: registry
app.edp.epam.com/integration-secret: "true"
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths" : {
"harbor-registry.com":
{
"username":"registry-username",
"password":"registry-password",
"auth": "secret-string"
}
}
}
```
```json
"kaniko-docker-config":
{"auths" : "harbor-registry.com":
{
"username":"registry-username",
"password":"registry-password",
"auth": "secret-string"
}
}
```
Navigate to **Portal** -> **Configuration** -> **Artifacts storage** -> **Registry**. Here, you will observe the `Managed by ExternalSecret` message:

:::note
More details of External Secrets Operator Integration can be found in the [External Secrets Operator Integration](../secrets-management/external-secrets-operator-integration.md) page.
:::
5. Repeat steps 2-3 with values below:
- **Name** - `edp-pull`
- **Expiration time** - set the value which is aligned with your organization policy
- **Description** - `read-only permissions`
- **Permissions** - `Pull Repository`.
6. Provision the **regcred** secrets using kubectl, KubeRocketCI portal or with the externalSecrets operator:
The `auth` string can be generated by this command:
```bash
echo -n "robot\$edp-project+edp-push:secret" | base64
```
Navigate to **Portal** -> **Configuration** -> **Artifacts storage** -> **Registry**. Update or click **+ Add registry** fill in the required fields and click `Save`.

```yaml
apiVersion: v1
kind: Secret
metadata:
name: regcred
namespace: krci
labels:
app.edp.epam.com/secret-type: registry
app.edp.epam.com/integration-secret: "true"
type: kubernetes.io/dockerconfigjson
stringData:
.dockerconfigjson: |
{
"auths" : {
"harbor-registry.com":
{
"username":"registry-username",
"password":"registry-password",
"auth": "secret-string"
}
}
}
```
```json
"regcred":
{"auths" : "harbor-registry.com":
{
"username":"registry-username",
"password":"registry-password",
"auth": "secret-string"
}
}
```
Navigate to **Portal** -> **Configuration** -> **Artifacts storage** -> **Registry**. Here, you will observe the `Managed by ExternalSecret` message:

:::note
More details of External Secrets Operator Integration can be found in the [External Secrets Operator Integration](../secrets-management/external-secrets-operator-integration.md) page.
:::
7. In the [values.yaml](https://github.com/epam/edp-install/blob/master/deploy-templates/values.yaml) file for the **edp-install** Helm chart, set the following values for the specified fields:
If the `kaniko-docker-config` secret has been created manually:
```yaml title="values.yaml"
...
kaniko:
existingDockerConfig: "kaniko-docker-config"
global:
dockerRegistry:
url: harbor-registry.com
type: "harbor"
...
```
If the `kaniko-docker-config` secret has been created via External Secrets Operator:
```yaml title="values.yaml"
...
kaniko:
existingDockerConfig: "kaniko-docker-config"
externalSecrets:
enabled: true
global:
dockerRegistry:
url: harbor-registry.com
type: "harbor"
...
```
8. (Optional) If you've already deployed the edp-install Helm chart, you can update it using the following command:
```bash
helm update --install krci epamedp/edp-install \
--values values.yaml \
--namespace krci
```
As a result, application images built in UI Portal will be stored in Harbor project and will be deployed from the harbor registry.
Harbor projects can be added and retained with a retention policy generated through the script in [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/harbor-ha/hack/harbor).
## Related Articles
* [Install KubeRocketCI](../install-kuberocketci.md)
* [Install Harbor](../artifacts-management/harbor-installation.md)
* [Adjust Jira Integration](../project-management-and-reporting/jira-integration.md)
* [Custom SonarQube Integration](../code-quality/sonarqube.md)
---
## Harbor OIDC Configuration
# Harbor OIDC Configuration
This guide outlines the steps for integrating [OIDC (OpenID Connect) authorization](https://openid.net/connect/) with Harbor, facilitating Single Sign-On (SSO) capabilities. By adopting OIDC, Harbor gains a unified authentication mechanism, simplifying user access management and enhancing security. This approach centralizes user permissions and access control, streamlining administration through a singular configuration interface.
## Prerequisites
Before the beginning, ensure your installation meets the following criteria:
- [Keycloak](../auth/keycloak.md) is installed
- [KubeRocketCI](../install-kuberocketci.md) is installed.
## Configure Keycloak
This section details the procedure to configure Harbor with Keycloak for secure authentication using the following steps:
1. Generate the Keycloak Client Secret:
Start by creating a secret named `keycloak-client-harbor-secret` for Keycloak. This can be accomplished either through the commands provided below or by employing the External Secrets Operator. The secret acts as a secure token for establishing communication between Keycloak and Harbor.
Generate the secret using OpenSSL and store it in a Kubernetes secret within the platform namespace (e.g, `krci`):
```bash
KEYCLOAK_CLIENT_HARBOR_SECRET=$(openssl rand -base64 32 | head -c 32)
kubectl -n krci create secret generic keycloak-client-harbor-secret \
--from-literal=cookie-secret=${KEYCLOAK_CLIENT_HARBOR_SECRET}
```
2. Deploy the KeycloakClient Custom Resource:
Proceed to create the `KeycloakClient` custom resource by applying the `harborkeycloakclient.yaml` configuration in the appropriate namespace. This step involves utilizing the previously generated `keycloak-client-harbor-secret`. Upon successful deployment, Keycloak will register Harbor as a client, with the Kubernetes secret serving as the client password.
Apply the `harborkeycloakclient.yaml` to establish the resource:
```yaml
apiVersion: v1.edp.epam.com/v1
kind: KeycloakClient
metadata:
name: harbor
spec:
advancedProtocolMappers: true
clientId: harbor
directAccess: true
public: false
secret: keycloak-client-harbor-secret
defaultClientScopes:
- profile
- email
- roles
targetRealm: control-plane
webUrl:
protocolMappers:
- name: roles
protocol: openid-connect
protocolMapper: oidc-usermodel-realm-role-mapper
config:
access.token.claim: true
claim.name: roles
id.token.claim: true
userinfo.token.claim: true
multivalued: true
```
Ensure to replace `` with your actual Harbor URL. This configuration links Harbor to Keycloak, enabling OIDC-based Single Sign-On (SSO) for a streamlined authentication process.
## Configure Harbor
The next stage is to configure Harbor. Proceed with following the steps below:
1. Log in to Harbor UI with an account that has Harbor system administrator privileges. To get the administrator password, execute the command below:
```bash
kubectl get secret harbor -n harbor -o jsonpath='{.data.HARBOR_ADMIN_PASSWORD}' | base64 --decode
```
2. Navigate to **Administration** -> **Configuration** -> **Authentication**. Configure OIDC using the parameters below:
```ini
auth_mode: oidc_auth
oidc_name: keycloak
oidc_endpoint: /auth/realms/control-plane
oidc_client_id: harbor
oidc_client_secret:
oidc_groups_claim: roles
oidc_admin_group: administrator
oidc_scope: openid,email,profile,roles
verify_certificate: true
oidc_auto_onboard: true
oidc_user_claim: preferred_username
```

As a result, users will be prompted to authenticate themselves when logging in to Harbor UI.
## Related Articles
* [EKS OIDC With Keycloak](../auth/configure-keycloak-oidc-eks.md)
* [External Secrets Operator Integration](../secrets-management/external-secrets-operator-integration.md)
* [Integrate Harbor With KubeRocketCI Pipelines](harbor-integration.md)
---
## Nexus Image Registry
# Nexus Image Registry
This documentation guide provides comprehensive instructions for integrating **Nexus Repository Manager** as a docker image registry with KubeRocketCI.
## Installation
To install Nexus in environment, it's recommended to use the resources provided in the [Cluster Add-Ons](https://github.com/epam/edp-cluster-add-ons) repository. This approach involves installing both the Nexus repository manager and the [nexus-operator](https://github.com/epam/edp-nexus-operator). Leveraging the Cluster Add-Ons simplifies the deployment and management process, providing a streamlined method to integrate Nexus into infrastructure.
1. Navigate to the forked cluster Add-Ons repository and align the [nexus values.yaml](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/nexus/values.yaml) and [nexus-operator values.yaml](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/nexus-operator/values.yaml) files. Follow the instructions to deploy Nexus, ensuring it's correctly configured to serve as artifact repository.
2. Update the configuration to enable **nexus** and **nexus-operator** in [Add-Ons](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/apps/values.yaml) repository:
```yaml title="clusters/core/apps/values.yaml"
nexus:
createNamespace: true
enable: true
nexus-operator:
createNamespace: true
enable: true
```
3. Sync resources and wait till the all **nexus** and **nexus-operator** resources are created:

4. **Sign in** into **Nexus Repository Manager** using the default credentials **Username**: `admin` and **Password**: `admin123` and update the default password for better security:

## Configuration
With [Add-Ons approach](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core) `nexus-operator` create the necessary roles, the **Service Account** `ci.user`, blob stores, repository, scripts, cleanup policies automatically. Below is a comprehensive guide on how to create all resources manually.
## Configuration Nexus Repository Manager using nexus-operator
1. Create a Kubernetes Secret that the **nexus-operator** will use to connect to the **Nexus Repository Manager** and create all resources:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: nexus-admin-password
namespace: nexus
type: Opaque
data:
user: YWRtaW4= # base64-encoded value of "admin"
password: cGFzcw== # base64-encoded value of "pass"
```
```json
"nexus-admin-password":
{
"user": "XXXXXXX",
"password": "XXXXXXX"
}
```
2. Create a secret using `manifests` or with `External Secrets Operator` to enable the **edp-nexus-operator** to connect to the **Nexus Repository Manager** for provisioning:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: ci-nexus
namespace: nexus
type: Opaque
stringData:
password:
```
```json
"ci-nexus":
{
"password": "XXXXXXX"
}
```
## Configuration Nexus Repository Manager without nexus-operator
Without using the **nexus-operator**, manual updates are required for the Helm chart values of the **Nexus Repository Manager**, as well as the creation of blob stores, repositories, roles, and the **Service Account** `ci.user`.
1. Update **Nexus Repository Manager** helm chart values:
```yaml
nexus-repository-manager:
nexus:
docker:
enabled: true
registries:
- host: nexus-ci-container.example.com
port: 5000
```
2. Create blob store. Open the Nexus UI and navigate to **Server administration and configuration** -> **Repository** -> **Blob Stores** and click **Create Blob Store**, fill the following fields and click **Save** button:
- **Type**: `File`
- **Name**: `krci-container`

3. Create repository. Open the Nexus UI and navigate to **Server administration and configuration** -> **Repository** -> **Repositories**, click **+ Create repository**, select **docker (hosted)**, fill the following fields and click **Save** button:
- **Name**: `A unique identifier for this repository`
- **HTTP**: `5000`
- **Enable Docker V1 API**: `check`
- **Blob store name**: `krci-container`
- **Strict Content Type Validation**: `check`

4. Open the Nexus UI and navigate to **Server administration and configuration** -> **Security** -> **Roles**. Click the **Create Role** button, fill the following fields and click **Save** button:
- **Type**: `Nexus role`
- **Role ID**: `krci-admin`
- **Role Name**: `krci-admin`
- **Role Descriptions**: `Read and write access to all repos and scripts`
- **Applied Privileges**: `nx-apikey-all`, `nx-repository-view-*-*-add`, `nx-repository-view-*-*-browse`,`nx-repository-view-*-*-edit`, `nx-repository-view-*-*-read`, `nx-script-*-add`, `nx-script-*-delete`, `nx-script-*-read`, `nx-script-*-run`

5. Create repository Service Account `ci.user`. Open the Nexus UI and navigate to **Server administration and configuration** -> **Security** -> **User**. Click the `Create local user` button to create a new user:

6. Type the `ci.user` username, fill the following fields and click the **Create local user** button to create the ***Service Account**, fill the following fields and click **Save** button:
- **ID**: `ci.user`
- **First name**: `ci.user`
- **Last name**: `CI`
- **Email**: `ci.user@krci.com`
- **Password**: ``
- **Status**: `Active`
- **Roles**: `krci-admin`

## Integration Nexus Repository Manager with KubeRocketCI
1. Open **KubeRocketCI** -> **Configuration** -> **Artifacts storage** -> **Registry**. Click **+ Add registry** fill in the fields below, and then click **SAVE** button:
- **Registry Provider**: `Nexus`
- **Registry Endpoint**: `nexus-ci-container.example.com`
- **Repository**: `krci` # The name of folder in nexus repository
- **Push account User**: `ci.user`
- **Push account Password/Token**: ``
- **Use the Push Accounts credentials**: `check`

2. After build application open **Nexus Repository Manager** -> **Browse server contents** -> **Browse** and open container registry:

## Related Articles
* [Install via Add-Ons](../add-ons-overview.md)
* [Manage Container Registries](../../user-guide/manage-container-registries.md)
* [Nexus Sonatype Integration](nexus-sonatype.md)
* [Change Container Registry](../../user-guide/change-container-registry.md)
---
## Sonatype Nexus Repository OSS Integration
# Sonatype Nexus Repository OSS Integration
This documentation guide provides comprehensive instructions for integrating Sonatype Nexus Repository OSS (Nexus) with KubeRocketCI.
## Prerequisites
Before proceeding, ensure the following prerequisites are met:
- Kubectl version 1.34.0+ is installed. Please refer to the [Kubernetes official website](https://kubernetes.io/releases/download/) for details.
- [Helm](https://helm.sh) version 3.19.0+ is installed. Please refer to the [Helm page](https://github.com/helm/helm/releases) on GitHub for details.
## Installation
To install Nexus in environment, it's recommended to use the resources provided in the [Cluster Add-Ons](https://github.com/epam/edp-cluster-add-ons) repository. This approach involves installing both the Nexus repository manager and the [nexus-operator](https://github.com/epam/edp-nexus-operator). Leveraging the Cluster Add-Ons simplifies the deployment and management process, providing a streamlined method to integrate Nexus into infrastructure:
1. **Nexus Repository Manager**: First, navigate to the forked cluster Add-Ons repository and align the [nexus values.yaml](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/nexus/values.yaml) and [nexus-operator values.yaml](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/nexus-operator/values.yaml) files. Follow the instructions to deploy Nexus, ensuring it's correctly configured to serve as artifact repository.
2. Update the configuration to enable **nexus** and **nexus-operator** in [Add-Ons](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/apps/values.yaml) repository:
```yaml title="clusters/core/apps/values.yaml"
nexus:
createNamespace: true
enable: true
nexus-operator:
createNamespace: true
enable: true
```
3. Sync resources and wait till the all **nexus** and **nexus-operator** resources is created:

4. **Sign In** into **Nexus Repository Manager** using the default credentials **Username**: `admin` and **Password**: `admin123` and update the default password for better security:

## Configuration
With [Add-ons approach](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core) `nexus-operator` create the necessary roles, **Service Account** `ci.user`, blob stores, repository, scripts, cleanup policies automatically.
KubeRocketCI organizes artifacts within Nexus according to the following hierarchy:
```bash
├── krci-dotnet-group
│ ├── krci-dotnet-proxy
│ ├── krci-dotnet-releases
│ ├── krci-dotnet-snapshots
│ └── krci-dotnet-hosted
krci-maven-group
│ ├── krci-maven-proxy
│ ├── krci-maven-releases
│ ├── krci-maven-snapshots
krci-npm-group
│ ├── krci-npm-proxy
│ ├── krci-npm-releases
│ ├── krci-npm-snapshots
│ └── krci-npm-hosted
krci-python-group
│ ├── krci-python-proxy
│ ├── krci-python-releases
│ ├── krci-python-snapshots
krci-yum-group
├── krci-yum-releases
├── krci-yum-snapshots
└── krci-container-hosted
```
Below is a comprehensive guide on how to create all the resources manually.
### Configure Nexus Repository Manager With nexus-operator
1. Create a Kubernetes Secret that the **nexus-operator** will use to connect to the **Nexus Repository Manager** and create all resources:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: nexus-admin-password
namespace: nexus
type: Opaque
data:
user: YWRtaW4= # base64-encoded value of "admin"
password: cGFzcw== # base64-encoded value of "pass"
```
```json
"nexus-admin-password":
{
"user": "XXXXXXX",
"password": "XXXXXXX"
}
```
2. Create a secret using `manifests` or with `External Secrets Operator` to enable the **edp-nexus-operator** to connect to the **Nexus Repository Manager** for provisioning:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: ci-nexus
namespace: nexus
type: Opaque
stringData:
password:
```
```json
"ci-nexus":
{
"password": "XXXXXXX"
}
```
### Configure Nexus Repository Manager Without nexus-operator
Without using the **nexus-operator**, manual updates are required for the Helm chart values of the **Nexus Repository Manager**, as well as the creation of blob stores, repositories, roles, and the **Service Account** `ci.user`:
1. Create blob store. Open the Nexus UI and navigate to **Server administration and configuration** -> **Repository** -> **Blob Stores** and click **Create Blob Store**, fill the following fields and click **Save** button:
- **Type**: `File`
- **Name**: `krci-maven`
- **Type**: `File`
- **Name**: `krci-npm`
- **Type**: `File`
- **Name**: `krci-dotnet`
- **Type**: `File`
- **Name**: `krci-python`
- **Type**: `File`
- **Name**: `krci-yum`
2. KubeRocketCI operates using a specific repository naming convention, where all repository names adhere to predefined standards. To align with this, navigate to **Server administration and configuration** -> **Repository** -> **Repositories** within Nexus. Here, repository creation is limited to those that match the required programming language, ensuring consistency and compliance with the KubeRocketCI framework.

a) Click Create a repository by selecting `maven2(proxy)` fill the following fields and click **Create repository**:
- **Name** `krci-maven-proxy`
- **Remote storage URL** `https://repo1.maven.org/maven2/`
- **Blob store** `krci-maven`
- **HTTP request settings** `check`
- **Use-agent customization** `user-agent-suffix`
- **Connection retries** `10`
- **Connection timeout** `1440`
b) Click Create a repository by selecting `maven2(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-maven-snapshots`
- **Version policy** `snapshots`
- **Blob store** `krci-maven`
c) Click Create a repository by selecting `maven2(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-maven-releases`
- **Version policy** `release`
- **Blob store** `krci-maven`
d) Click Create a repository by selecting `maven2(group)` fill the following fields and click **Create repository**:
- **Name** `krci-maven-group`
- **Version policy** `release`
- **Member repositories** `krci-maven-proxy`, `krci-maven-snapshots`, `krci-maven-releases`
a) Click Create a repository by selecting `npm(proxy)` fill the following fields **Create repository**:
- **Name** `krci-npm-proxy`
- **Remote storage URL** `https://registry.npmjs.org`
- **Blob store** `krci-npm`
- **HTTP request settings** `check`
- **Use-agent customization** `user-agent-suffix`
- **Connection retries** `10`
- **Connection timeout** `1440`
b) Click Create a repository by selecting `npm(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-npm-snapshots`
- **Blob store** `krci-npm`
c) Click Create a repository by selecting `npm(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-npm-releases`
- **Blob store** `krci-npm`
d) Click Create a repository by selecting `npm(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-npm-hosted`
- **Blob store** `krci-npm`
e) Click Create a repository by selecting `npm(group)` fill the following fields and click **Create repository**:
- **Name** `krci-npm-group`
- **Member repositories** `krci-npm-proxy`, `krci-npm-snapshots`, `krci-npm-releases`, `krci-npm-hosted`
a) Click Create a repository by selecting `nuget(proxy)` fill the following fields and click **Create repository**:
- **Name** `krci-dotnet-proxy`
- **Protocol version NuGet V3** `check`
- **Remote storage URL** `https://api.nuget.org/v3/index.json`
- **Blob store** `krci-dotnet`
- **HTTP request settings** `check`
- **Use-agent customization** `user-agent-suffix`
- **Connection retries** `10`
- **Connection timeout** `1440`
b) Click Create a repository by selecting `nuget(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-dotnet-snapshots`
- **Blob store** `krci-dotnet`
c) Click Create a repository by selecting `nuget(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-dotnet-releases`
- **Blob store** `krci-dotnet`
d) Click Create a repository by selecting `nuget(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-dotnet-hosted`
- **Blob store** `krci-dotnet`
e) Click Create a repository by selecting `nuget(group)` fill the following fields and click **Create repository**:
- **Name** `krci-dotnet-group`
- **Member repositories** `krci-dotnet-proxy`, `krci-dotnet-snapshots`, `krci-dotnet-releases`, `krci-dotnet-hosted`
a) Click Create a repository by selecting `pypi(proxy)` fill the following fields and click **Create repository**:
- **Name** `krci-python-proxy`
- **Remote storage URL** `https://pypi.org`
- **Blob store** `krci-python`
- **HTTP request settings** `check`
- **Use-agent customization** `user-agent-suffix`
- **Connection retries** `10`
- **Connection timeout** `1440`
b) Click Create a repository by selecting `pypi(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-python-snapshots`
- **Blob store** `krci-python`
c) Click Create a repository by selecting `pypi(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-python-releases`
- **Blob store** `krci-python`
d) Click Create a repository by selecting `pypi(group)` fill the following fields and click **Create repository**:
- **Name** `krci-python-group`
- **Member repositories** `krci-python-proxy`, `krci-python-snapshots`, `krci-python-releases`
a) Click Create a repository by selecting `yum(proxy)` fill the following fields and click **Create repository**:
- **Name** `krci-yum-proxy`
- **Remote storage URL** `http://fedora.ip-connect.info/linux/development/rawhide/Everything/x86_64/os/`
- **Blob store** `krci-yum`
- **HTTP request settings** `check`
- **Use-agent customization** `user-agent-suffix`
- **Connection retries** `10`
- **Connection timeout** `1440`
b) Click Create a repository by selecting `yum(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-yum-snapshots`
- **Repo data Depth** `3`
- **Blob store** `krci-yum`
c) Click Create a repository by selecting `yum(hosted)` fill the following fields and click **Create repository**:
- **Name** `krci-yum-releases`
- **Repo data Depth** `3`
- **Blob store** `krci-yum`
3. Open the Nexus UI and navigate to **Server administration and configuration** -> **Security** -> **Roles**. Click the **Create Role** button, fill the following fields and click **Save** button:
- **Type**: `Nexus role`
- **Role ID**: `krci-admin`
- **Role Name**: `krci-admin`
- **Role Descriptions**: `Read and write access to all repos and scripts`
- **Applied Privileges**: `nx-apikey-all`, `nx-repository-view-*-*-add`, `nx-repository-view-*-*-browse`,`nx-repository-view-*-*-edit`, `nx-repository-view-*-*-read`, `nx-script-*-add`, `nx-script-*-delete`, `nx-script-*-read`, `nx-script-*-run`

4. Create repository Service Account `ci.user`. Open the Nexus UI and navigate to **Server administration and configuration** -> **Security** -> **User**. Click the `Create local user` button to create a new user:

5. Type the `ci.user` username, fill the following fields and click the **Create local user** button to create the ***Service Account**, fill the following fields and click **Save** button::
- **ID**: `ci.user`
- **First name**: `ci.user`
- **Last name**: `CI`
- **Email**: `ci.user@krci.com`
- **Password**: ``
- **Status**: `Active`
- **Roles**: `krci-admin`

## Integrate Nexus Repository Manager With KubeRocketCI
For provision secret using manifest, KubeRocketCI portal or with the externalSecrets operator:
Go to **Portal** -> **Configuration** -> **Artifacts storage** -> **Nexus**. Update or click **+ Add integration**. Fill the following fields and click the `Save` button:
- **Quick link URL** `https://nexus.example.com`
- **URL** `http://nexus.nexus:8081`
- **User** `nexus-user-id`
- **Password** `nexus-user-password`

```yaml
apiVersion: v1
kind: Secret
metadata:
name: ci-nexus
namespace: krci
labels:
app.edp.epam.com/secret-type: nexus
app.edp.epam.com/integration-secret: "true"
type: Opaque
stringData:
url: https://nexus.example.com
username:
password:
```
```json
"ci-nexus":
{
"url": "https://nexus.example.com",
"username": "XXXXXXX",
"password": "XXXXXXX"
},
```
Go to **KubeRocketCI Portal** -> **Configuration** -> **Artifacts storage** -> **Nexus** and see `Managed by External Secret` message:

More detail of External Secrets Operator Integration can found on [the following page](../secrets-management/external-secrets-operator-integration.md)
## Related Articles
* [Install KubeRocketCI](../install-kuberocketci.md)
* [Install External Secrets Operator](../secrets-management/install-external-secrets-operator.md)
* [External Secrets Operator Integration](../secrets-management/external-secrets-operator-integration.md)
* [Cluster Add-Ons Overview](../add-ons-overview.md)
---
## Package Registry
# Package Registry
This page describes the supported package registry providers and provides detailed instruction on how to adjust configurations to work properly with these package registry providers.
## Supported Package Registry Providers
Currently, KubeRocketCI support the following package registries:
- Sonatype Nexus Repository OSS
- GitLab
- GitHub
- Azure DevOps
The table below displays the supported registries and the languages they correspond to:
|Language|Framework|Build Tool|Proxy Registry|Snapshots/Releases Registry|
|------------|:-------------------------------------------------------:|:------------------:|:-----------------------------------------:|:-----------------------------------------:|
| Java|Java 17Java 21Java 25|MavenGradle| NexusGitlabGitHubAzure DevOps | NexusGitlabGitHubAzure DevOps|
| Python|Python 3.11FastAPIFlask|Python|NexusGitlabAzure DevOps|NexusGitlabAzure DevOps|
| C#|.Net 3.1.Net 6.0|.Net|No proxy is used for this language.|NexusGitlabGitHubAzure DevOps|
| JavaScript | ReactVueAngularExpressNext.jsAntora |NPMPNPM| NexusGitlabGitHubAzure DevOps | NexusGitlabGitHubAzure DevOps |
## Proxy Package Registry Configuration
By default, KubeRocketCI uses Nexus as the proxy registry for storing and caching application dependencies. This setting is fixed and cannot be modified.
## Snapshot/Release Package Registry Configuration
The edp-tekton Helm Chart allows to override the default settings for package registries through `tekton.configs` part of its [values.yaml](https://github.com/epam/edp-tekton/blob/release/0.12/charts/pipelines-library/values.yaml#L81) file.
To provide necessary credentials for accessing the package registries, the user should create the `package-registries-auth-secret` secret and set the `tekton.packageRegistriesSecret.enabled` value to `true` to mount the secret into the pipeline.
To replace the default name of the secret, the user should set the `tekton.packageRegistriesSecret.name` parameter to the desired value:
```yaml
tekton:
packageRegistriesSecret:
enabled: true
name: "package-registries-auth-secret"
configs:
# Build Tool: Maven
mavenConfigMap: "custom-maven-settings"
# Build Tool: NPM
npmConfigMap: "custom-npm-settings"
# Build Tool: Python
pythonConfigMap: "custom-python-settings"
# Build Tool: .Net
nugetConfigMap: "custom-nuget-settings"
```
### Customizing Maven Settings
A new custom configuration map should contain the `settings.xml` file, which overrides the default Maven configuration.
For example, the following configuration map contains the `settings.xml` file with the following settings:
- **Proxy registry**: Nexus.
- **Snapshots/Releases registry**: Azure DevOps registry.
- **Authentication**:
- `CI_USERNAME` and `CI_PASSWORD` - these environment variables are used for authentication to Nexus.
- `CI_AZURE_DEVOPS_USERNAME` and `CI_AZURE_DEVOPS_PASSWORD` - these environment variables are used for authentication to Azure DevOps registry.
- **Secrets**:
- `CI_AZURE_DEVOPS_USERNAME` and `CI_AZURE_DEVOPS_PASSWORD` - these environment variables are taken from the `package-registries-auth-secret` secret.
:::note Example: custom-maven-settings.yaml
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: new-custom-maven-settings
data:
settings.xml: |
/workspace/source/cacheorg.sonarsource.scanner.mavennexus${env.CI_USERNAME}${env.CI_PASSWORD}azure-devops-registry${env.CI_AZURE_DEVOPS_USERNAME}${env.CI_AZURE_DEVOPS_PASSWORD}nexus*http://nexus.nexus:8081/repository/krci-maven-groupsonartrue
${env.SONAR_TOKEN}
${env.SONAR_HOST_URL}
azure-devops-registryazure-devops-registry::default::https://pkgs.dev.azure.com///_packaging//maven/v1azure-devops-registry::default::https://pkgs.dev.azure.com///_packaging//maven/v1azure-devops-registry
```
:::
### Customizing NPM Settings
A new custom configuration map should contain the `.npmrc-ci`, `.npmrc-publish-snapshots` and `.npmrc-publish-releases` files,
which override the default npm configuration.
For example, the following configuration map contains the `.npmrc-ci`, `.npmrc-publish-snapshots` and `.npmrc-publish-releases` files
with the following settings:
- **Proxy registry**: Nexus.
- **Snapshots/Releases registry**: Azure DevOps registry.
- **Authentication**:
- 'upBase64' (`"${CI_USERNAME}:${CI_PASSWORD}"` string in base64) - this environment variable is used for authentication to Nexus.
- `CI_AZURE_DEVOPS_USERNAME` and `CI_AZURE_DEVOPS_PASSWORD_IN_BASE64` - these environment variables are used for authentication to Azure DevOps registry.
- **Secrets**:
- `CI_AZURE_DEVOPS_USERNAME` and `CI_AZURE_DEVOPS_PASSWORD_IN_BASE64` - these environment variables are taken from the `package-registries-auth-secret` secret.
:::note Example: custom-npm-settings.yaml
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: custom-npm-settings
data:
.npmrc-ci: |
registry=${NEXUS_HOST_URL}/repository/krci-npm-group
_auth=${upBase64}
cache=${NPM_CACHE_DIR}
.npmrc-publish-snapshots: |
registry=https://pkgs.dev.azure.com///_packaging//npm/registry
username=${CI_AZURE_DEVOPS_USERNAME}
_password=${CI_AZURE_DEVOPS_PASSWORD_IN_BASE64}
email=${CI_AZURE_DEVOPS_USERNAME}
cache=${NPM_CACHE_DIR}
.npmrc-publish-releases: |
registry=https://pkgs.dev.azure.com///_packaging//npm/registry
_auth=${upBase64}
cache=${NPM_CACHE_DIR}
```
:::
### Customizing Python Configurations
For customizing python settings, a new configuration map can be prepared to replace the default pythonConfigMap.
This custom configuration map should contain the PIP_TRUSTED_HOST, PIP_INDEX, PIP_INDEX_URL, REPOSITORY_URL_SNAPSHOTS and REPOSITORY_URL_RELEASES environment variables, which overrides the default python configuration.
For example, the following configuration map contains the following settings:
- **Proxy registry**: Azure DevOps registry.
- **Snapshots/Releases registry**: Azure DevOps registry.
- **Authentication**:
- 'upBase64' (`"${CI_USERNAME}:${CI_PASSWORD}"` string in base64) - this environment variable is used for authentication to Azure DevOps registry.
:::note Example: custom-python-settings.yaml
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: custom-python-settings
data:
PIP_INDEX_PATH: "///_packaging//pypi"
PIP_INDEX_URL_PATH: "///_packaging//pypi/simple"
REPOSITORY_SNAPSHOTS_PATH: "///_packaging//pypi/upload"
REPOSITORY_RELEASES_PATH: "///_packaging//pypi/upload"
```
:::
### Customizing NuGet Settings
A new custom configuration map should contain the `nuget.config` file, which overrides the default NuGet configuration.
For example, the following configuration map contains the `nuget.config` file with the following settings:
- **Snapshots/Releases registry**: Azure DevOps registry.
- **Authentication**:
- `CI_AZURE_DEVOPS_USERNAME` and `CI_AZURE_DEVOPS_PASSWORD` - these environment variables are used for authentication to Azure DevOps registry.
- **Secrets**:
- `CI_AZURE_DEVOPS_USERNAME` and `CI_AZURE_DEVOPS_PASSWORD` - these environment variables are taken from the `package-registries-auth-secret` secret.
:::note Example: custom-nuget-settings.yaml
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: custom-nuget-settings
data:
nuget.config: |
```
:::
## Related Articles
* [Manage Container Registries](../../user-guide/manage-container-registries.md)
* [Nexus Sonatype Integration](nexus-sonatype.md)
* [Manage Git Servers](../../user-guide/git-server-overview.md)
---
## Keycloak as OIDC Provider for AWS EKS
# EKS OIDC With Keycloak
Configure Keycloak as the OIDC identity provider for an AWS EKS cluster so users can log in to `kubectl` with their existing Keycloak/SSO credentials instead of static IAM users. This guide walks through creating the Keycloak client and groups, associating Keycloak as an EKS OIDC provider (via Terraform or the AWS Console), and mapping Keycloak groups to Kubernetes RBAC roles — following the KubeRocketCI add-ons approach.
For provisioning the underlying Keycloak realm/client/group resources through the Keycloak operator's Custom Resources, see [Provision Keycloak Resources for EKS OIDC](eks-oidc-integration.md).
## Prerequisites
### Required
1. The [kubelogin](https://github.com/int128/kubelogin) plugin, installed and configured to connect OIDC with a cluster. For Windows, it is recommended to download the kubelogin as a binary and add it to your PATH. Use the [latest kubelogin release](https://github.com/int128/kubelogin/releases).
2. A running [Keycloak instance](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/keycloak).
3. The [Keycloak operator](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/keycloak-operator) is deployed.
4. The Keycloak Realm's OIDC discovery URL and jwks_uri endpoints are publicly accessible.
Optional prerequisites
- A recent Terraform 1.x release, if associating the EKS OIDC provider via Terraform instead of the AWS Console.
- [EDP Cluster Add-ons](../add-ons-overview.md) Solution is applied.
- [External Secrets Operator](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/external-secrets), if managing Keycloak credentials as synced secrets rather than manually.
## Solution Overview
By the end of this guide, Keycloak groups will be mapped to Kubernetes RBAC roles, letting users authenticate to the EKS cluster with `kubectl` using their Keycloak credentials instead of static IAM users.
This architecture encompasses three primary resource types: AWS (EKS), Keycloak, and Kubernetes.
Within this setup, the Keycloak resources, once established, remain static, facilitating the assignment of claims based on user group memberships. This stability contrasts with the dynamic nature of other resources, which may be created, modified, or deleted as necessary.
Of particular importance within the Kubernetes ecosystem are the `RoleBindings` and `ClusterRoles/Roles`. These elements define a permissions framework, where Roles specify the permissions available, and RoleBindings serve to associate those Roles with specific Keycloak groups. This association ensures that members of a group are granted only the permissions that are pertinent to their role.

## Keycloak Configuration
The initial step involves setting up the Keycloak operator (configure connections to the Keycloak instance) and along creation its associated resources, including realms, clients, roles, and groups.
1. Create user with [necessary](keycloak.md#configuration) privileges to Keycloak:
Store user credentials in AWS Parameter Store:
```json title="AWS Parameter Store"
{
"keycloak": {
"username": "",
"password": ""
}
}
```
Deactivate the External Secret Operator within the primary [kuberocketci-rbac](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/kuberocketci-rbac/values.yaml#L27) chart:
```yaml title="values.yaml"
# Configure components of the External Secrets Operator (ESO).
eso:
# -- Install components of the ESO.
enabled: false
```
Create secret with user credentials:
```bash
kubectl create secret generic keycloak \
--from-literal=username= \
--from-literal=password=
```
2. Begin by installing the [**kuberocketci-rbac**](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/kuberocketci-rbac) add-on. This can be accomplished through the use of the add-ons method, as detailed in the [addons approach](../add-ons-overview.md). Utilize the following values in the `values.yaml` file:
```yaml title="values.yaml"
keycloakUrl: "https://example.com"
# -- This block enable the creation of Keycloak operator resources for the
# EKS OIDC configuration, such as client, client scope, and realm groups.
kubernetes:
enabled: true
```
3. Activate the [**kuberocketci-rbac**](https://github.com/epam/edp-cluster-add-ons/blob/main/chart/values.yaml#L58) add-on within the application settings:
```yaml title="values.yaml"
kuberocketci-rbac:
createNamespace: true
enable: true
```
This add-on sets up a broker realm to manage traffic redirection between external Identity Providers (IdP) and internal clients. Additionally, it creates a shared realm that encompasses all clients, including EKS, Sonar, Nexus, and Portal.
The [KubeRocketCI RBAC add-on](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/kuberocketci-rbac) creates Keycloak groups that are used in the KubeRocketCI platform to manage access to resources. For more details refer to the [KubeRocketCI Groups](platform-auth-model.md#groups) documentation.
## AWS Configuration
Below are the guidelines for configuring identity provider in Kubernetes cluster:
For integrating OpenID Connect (OIDC) with Amazon EKS through terraform, it's essential to update the EKS module within your terraform repository. The relevant repository can be found at KubeRocketCI's [terraform-aws-platform](https://github.com/KubeRocketCI/terraform-aws-platform/tree/master/eks). Adjust the module by incorporating the following configuration in the `eks/template.tfvars` file:
```json title="eks/template.tfvars"
# OIDC Identity provider configuration
cluster_identity_providers = {
keycloak = {
client_id = "eks"
issuer_url = "https://example.com/auth/realms/shared"
groups_claim = "groups"
username_claim = "preferred_username"
username_prefix = "-"
}
}
```
This configuration snippet specifies the Keycloak as the OIDC Identity Provider for your EKS cluster. It includes the client ID (`eks`), the issuer URL (pointing to the Keycloak realm), and the claim used for groups (`groups`). This setup ensures that authentication and authorization mechanisms for accessing the EKS cluster are correctly configured to use Keycloak as the identity provider.
`username_claim` and `username_prefix` control how the authenticated user shows up as a Kubernetes username (in RBAC, `kubectl` output, and audit logs). Leaving them unset makes Kubernetes fall back to the `sub` claim (an opaque Keycloak user ID) prefixed with the issuer URL — see the [Access Validation](#access-validation) section below. Setting `username_claim` to `preferred_username` (or `email`) yields a human-readable username instead. Prefer `preferred_username` over `email`: Kubernetes' OIDC authenticator rejects tokens with `email_verified: false`, which is common for users brokered from a SAML upstream IdP (e.g. Azure AD) since SAML has no `email_verified` equivalent. `username_prefix = "-"` disables prefixing entirely; RBAC in this setup is unaffected either way, since group membership (not username) drives authorization.
The objective is to configure an Identity Provider within your Kubernetes cluster. The process involves several steps within the AWS Management Console:
1. Begin by opening the AWS Management Console.
2. Navigate to the Elastic Kubernetes Service (EKS) section.
3. Select your specific **Cluster name**.
4. Go to the **Access** tab, then find and select the **OIDC identity providers** section.
5. Click on **Associate identity provider**.
When associating the identity provider, ensure you input the following details:
```text
Issuer URL: https://example.com/auth/realms/shared
Client ID: eks
Groups Claim: groups
Username Claim: preferred_username
Username Prefix: -
```
## Kubeconfig
Template for kubeconfig:
```yaml
apiVersion: v1
preferences: {}
kind: Config
clusters:
- cluster:
server: https://.eks.amazonaws.com
certificate-authority-data:
name: eks
contexts:
- context:
cluster: eks
user:
name: eks
current-context: eks
users:
- name:
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl
args:
- oidc-login
- get-token
- -v1
- --oidc-issuer-url=https:///auth/realms/shared
- --oidc-client-id=eks
- --oidc-client-secret=
```
Flag `-v1` can be used for debug, in a common case it's not needed and can be deleted.
To find the client secret:
1. Open Keycloak
2. Choose **Shared realm**
3. Find **eks** keycloak client
4. Open Credentials tab
5. Copy Secret
## Access Validation
To validate access to the Kubernetes cluster by using the default **cluster-admin** role. Assign the user the **oidc-cluster-admins** Keycloak group.
To add a user to a Keycloak group, follow these steps:
1. Open Keycloak
2. Choose **Shared** realm
3. Open user screen with search field
4. Find a user and open the configuration
5. Open Groups tab
6. In Available Groups, choose an **oidc-cluster-admins** group
7. Click the **Join** button
8. The group should appear in the User's Group Membership list
As a result, the required access mapping is implemented using the following resources:
| Keycloak Group Name | Kubernetes ClusterRole | Kubernetes ClusterRoleBinding |
|----------------------|-------------------------|-------------------------------|
| [oidc-cluster-admins](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/kuberocketci-rbac/templates/kubernetes/keycloak-realmgroups-cluster-admins.yaml) | cluster-admin (built-in) | [cluster-admin](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/kuberocketci-rbac/templates/kubernetes/clusterrolebinding-admin.yaml) |
In this configuration, the Keycloak **oidc-cluster-admins** group is mapped to the Kubernetes **cluster-admin** role. This setup grants members of the **oidc-cluster-admins** group the necessary permissions to perform administrator management in the Kubernetes cluster. You can further customize access by associating different Keycloak groups with specific Kubernetes roles.
KubeRocketCI follows the same approach for managing access to its resources. For more information, refer to the [KubeRocketCI Groups](platform-auth-model.md#groups) documentation.
Follow the steps below to test the configuration:
- Run kubectl command, it is important to specify the correct kubeconfig:
```bash
KUBECONFIG= kubectl get ingresses -n
```
- After the first run and redirection to the Keycloak login page, log in using credentials (login:password) or using SSO Provider.
In case of the successful login, you will receive the following notification that can be closed:

- As the result, a respective response from the Kubernetes will appear in the console
in case a user is configured correctly and is a member of the correct group and Roles/RoleBindings.
- If something is not set up correctly, the following output error will be displayed:
```bash
Error from server (Forbidden): ingresses.networking.k8s.io is forbidden:
User ""
cannot list resource "ingresses" in API group "networking.k8s.io" in the namespace ""
```
:::note
The `User` field reflects whatever `username_claim`/`username_prefix` are configured in [AWS Configuration](#aws-configuration) above. Without `username_claim` set, it instead shows `https:///auth/realms/shared#` (the `sub` claim prefixed with the issuer URL) — harder to attribute to a real user in `kubectl` output and audit logs.
:::
## Session Update
To update the session, clear cache.
The default location for the login cache:
```bash
rm -rf ~/.kube/cache
```
## Access Cluster via Lens
To access the Kubernetes cluster via [Lens](https://k8slens.dev/), follow the steps below to configure it:
- Add a new kubeconfig to the location where Lens has access. The default location of the kubeconfig is **~/.kube/config** but it can be changed by navigating to **File** -> **Preferences** -> **Kubernetes** -> **Kubeconfig Syncs**.
- (Optional) Using Windows, it is recommended to reboot the system after adding a new kubeconfig.
- Authenticate on the Keycloak login page to be able to access the cluster.
:::note
Lens does not add namespaces of the project automatically, so it is necessary to add them manually, simply go to **Settings** -> **Namespaces** and add the namespaces of a project.
:::
## Changing the Lifespan of an Access Token
By default, the Keycloak token has a lifespan of 5 minutes. To modify this duration refer to the guidelines outlined in this [document](ui-portal-oidc.md#changing-the-lifespan-of-an-access-token).
For application-level OIDC via OAuth2-Proxy rather than cluster `kubectl` access, see [Tekton Dashboard Authentication](./oauth2-proxy.md). Using Microsoft Entra instead of Keycloak? See [AWS EKS OIDC With Microsoft Entra](../microsoft-entra/aws-eks-portal-authentication.md).
## Related Articles
* [Headlamp OIDC Configuration](ui-portal-oidc.md)
* [Provision Keycloak Resources for EKS OIDC](eks-oidc-integration.md)
---
## Provision Keycloak Resources for EKS OIDC
# AWS EKS OIDC Integration
This page shows how to provision the Keycloak realm, client, group, and user resources needed for EKS OIDC by installing the [edp-keycloak-operator](https://github.com/epam/edp-keycloak-operator) via Helm and applying its Custom Resources — `Keycloak`, `KeycloakRealm`, `KeycloakRealmGroup`, `KeycloakClientScope`, `KeycloakClient`, and `KeycloakRealmUser`. It covers only the Keycloak-side resource provisioning; for the end-to-end setup of EKS cluster access — associating Keycloak as the EKS OIDC provider and mapping groups to Kubernetes RBAC roles — see [Keycloak as OIDC Provider for AWS EKS](./configure-keycloak-oidc-eks.md).
## Prerequisites
- [EKS Configuration](./configure-keycloak-oidc-eks.md) is performed
- A recent Helm 3.x release is installed
- [Keycloak](../../operator-guide/auth/keycloak.md) is installed
## Install Keycloak Operator
:::info
Alternately, the edp-keycloak-operator can be installed using a GitOps approach via the [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/kuberocketci-rbac) repository. For detailed installation instructions, please refer to the [Install via Add-ons](../add-ons-overview.md) guide.
:::
To install the Keycloak operator, follow the steps below:
1. Add the `epamedp` Helm chart to a local client:
```bash
helm repo add epamedp https://epam.github.io/edp-helm-charts/stable
helm repo update
```
2. Install the Keycloak operator:
```bash
helm install keycloak-operator epamedp/keycloak-operator --namespace security --set name=keycloak-operator
```
## Connect Keycloak Operator to Keycloak
:::info
It is also possible to install Keycloak resources using the [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/eks) repository. For details, please refer to the [Install via Add-Ons](../add-ons-overview.md) page.
:::
The next stage after installing Keycloak is to integrate it with the Keycloak operator. It can be implemented with the following steps:
1. Create the **keycloak** secret that contains username and password defined on the [configuration step](../../operator-guide/auth/keycloak.md#configuration):
```bash
kubectl -n security create secret generic keycloak \
--from-literal=username= \
--from-literal=password=
```
2. Create the Keycloak Custom Resource with the Keycloak instance URL and the secret created in the previous step:
```yaml
apiVersion: v1.edp.epam.com/v1
kind: Keycloak
metadata:
name: main
namespace: security
spec:
secret: keycloak # Secret name
url: https://keycloak.example.com # Keycloak URL
```
3. Create the KeycloakRealm Custom Resource:
```yaml
apiVersion: v1.edp.epam.com/v1
kind: KeycloakRealm
metadata:
name: control-plane
namespace: security
spec:
realmName: control-plane
keycloakOwner: main
```
4. Create the `KeycloakRealmGroup` Custom Resource for both administrators and developers:
- administrators:
```yaml
apiVersion: v1.edp.epam.com/v1
kind: KeycloakRealmGroup
metadata:
name: administrators
namespace: security
spec:
realm: control-plane
name: eks-oidc-administrator
```
- developers:
```yaml
apiVersion: v1.edp.epam.com/v1
kind: KeycloakRealmGroup
metadata:
name: developers
namespace: security
spec:
realm: control-plane
name: eks-oidc-developers
```
5. Create the `KeycloakClientScope` Custom Resource:
```yaml
apiVersion: v1.edp.epam.com/v1
kind: KeycloakClientScope
metadata:
name: groups-keycloak-eks
namespace: security
spec:
name: groups
realm: control-plane
description: "Group Membership"
protocol: openid-connect
protocolMappers:
- name: groups
protocol: openid-connect
protocolMapper: "oidc-group-membership-mapper"
config:
"access.token.claim": "true"
"claim.name": "groups"
"full.path": "false"
"id.token.claim": "true"
"userinfo.token.claim": "true"
```
6. Create the `KeycloakClient` Custom Resource:
```yaml
apiVersion: v1.edp.epam.com/v1
kind: KeycloakClient
metadata:
name: eks
namespace: security
spec:
advancedProtocolMappers: true
clientId: eks
directAccess: true
public: false
defaultClientScopes:
- groups
targetRealm: control-plane
webUrl: "http://localhost:8000"
```
7. Create the KeycloakRealmUser Custom Resource for both administrator and developer roles:
- administrator:
``` yaml
apiVersion: v1.edp.epam.com/v1
kind: KeycloakRealmUser
metadata:
name: keycloakrealmuser-admin
namespace: security
spec:
realm: control-plane
username: "administrator"
firstName: "John"
lastName: "Snow"
email: "administrator@example.com"
enabled: true
emailVerified: true
password: "12345678"
keepResource: true
requiredUserActions:
- UPDATE_PASSWORD
groups:
- eks-oidc-administrator
```
- developer:
``` yaml
apiVersion: v1.edp.epam.com/v1
kind: KeycloakRealmUser
metadata:
name: keycloakrealmuser-developer
namespace: security
spec:
realm: control-plane
username: "developers"
firstName: "John"
lastName: "Snow"
email: "developers@example.com"
enabled: true
emailVerified: true
password: "12345678"
keepResource: true
requiredUserActions:
- UPDATE_PASSWORD
groups:
- eks-oidc-developers
```
8. To connect the created Keycloak resources with permissions, it is necessary to bind the created Keycloak groups to Kubernetes roles, e.g., assigning the Keycloak group `administrators` the Kubernetes Cluster role `cluster-admin`.
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: oidc-cluster-admins
subjects:
- kind: Group
apiGroup: rbac.authorization.k8s.io
name: administrators
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
```
9. As a result, Keycloak is integrated with the AWS Elastic Kubernetes Service. This integration allows users to easily log in to the EKS cluster using their kubeconfig files and `kubelogin`, while managing permissions through Keycloak. This seamless integration enhances the user experience and streamlines the management of access control within the KubeRocketCI platform.
## Related Articles
* [Keycloak Installation](keycloak.md)
* [EKS OIDC With Keycloak](configure-keycloak-oidc-eks.md)
---
## Install Keycloak
# Install Keycloak
Inspect the prerequisites and the main steps to perform for installing Keycloak.
:::info
The installation process below is given for a Kubernetes cluster. The steps that differ for an OpenShift cluster are
indicated in the warnings blocks.
:::
## Prerequisites
- Kubectl version 1.34.0+ is installed. Please refer to the [Kubernetes official website](https://kubernetes.io/releases/download/) for details.
- [Helm](https://helm.sh) version 3.19.0+ is installed. Please refer to the [Helm page](https://github.com/helm/helm/releases) on GitHub for details.
:::info
Out team recommends a Keycloakx helm chart from the [codecentric](https://github.com/codecentric/helm-charts/tree/master/charts/keycloakx) repository, but other repositories can be used as well (e.g. [Bitnami](https://github.com/bitnami/charts/tree/master/bitnami/keycloak/)).
Before installing Keycloak, it is necessary to install a [PostgreSQL database](https://www.postgresql.org/download/).
:::
:::info
It is also possible to install Keycloak using the cluster add-ons. For details, please refer to the [Install via Add-Ons](../add-ons-overview.md) page.
:::
## PostgreSQL Installation
To install PostgreSQL, follow the steps below:
1. Check that a security namespace is created. If not, run the following command to create it:
```bash
kubectl create namespace security
```
:::warning
On the OpenShift platform, apply the `SecurityContextConstraints` resource. Change the namespace in the `users` section if required.
View: keycloak-scc.yaml
```yaml
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegeEscalation: true
allowPrivilegedContainer: false
allowedCapabilities: null
apiVersion: security.openshift.io/v1
allowedFlexVolumes: []
defaultAddCapabilities: []
fsGroup:
type: MustRunAs
ranges:
- min: 999
max: 65543
groups: []
kind: SecurityContextConstraints
metadata:
annotations:
"helm.sh/hook": "pre-install"
name: keycloak
priority: 1
readOnlyRootFilesystem: false
requiredDropCapabilities:
- KILL
- MKNOD
- SETUID
- SETGID
runAsUser:
type: MustRunAsRange
uidRangeMin: 1
uidRangeMax: 65543
seLinuxContext:
type: MustRunAs
supplementalGroups:
type: RunAsAny
users:
- system:serviceaccount:security:keycloakx
volumes:
- configMap
- downwardAPI
- emptyDir
- persistentVolumeClaim
- projected
- secret
```
View: postgresql-keycloak-scc.yaml
```yaml
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegeEscalation: true
allowPrivilegedContainer: false
allowedCapabilities: null
apiVersion: security.openshift.io/v1
allowedFlexVolumes: []
defaultAddCapabilities: []
fsGroup:
type: MustRunAs
ranges:
- min: 999
max: 65543
groups: []
kind: SecurityContextConstraints
metadata:
annotations:
"helm.sh/hook": "pre-install"
name: postgresql-keycloak
priority: 1
readOnlyRootFilesystem: false
requiredDropCapabilities:
- KILL
- MKNOD
- SETUID
- SETGID
runAsUser:
type: MustRunAsRange
uidRangeMin: 1
uidRangeMax: 65543
seLinuxContext:
type: MustRunAs
supplementalGroups:
type: RunAsAny
users:
- system:serviceaccount:security:default
volumes:
- configMap
- downwardAPI
- emptyDir
- persistentVolumeClaim
- projected
- secret
```
:::
2. Create PostgreSQL admin secret:
```bash
kubectl -n security create secret generic keycloak-postgresql \
--from-literal=password= \
--from-literal=postgres-password=
```
3. Add a helm chart repository:
```bash
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
```
4. Install PostgreSQL v15.2.0 using [bitnami/postgresql](https://artifacthub.io/packages/helm/bitnami/postgresql) Helm chart v12.1.15:
:::info
The PostgreSQL can be deployed in production ready mode. For example, it may include multiple replicas, persistent storage, autoscaling, and monitoring.
For details, please refer to the [official Chart documentation](https://github.com/bitnami/charts/tree/master/bitnami/postgresql).
:::
```bash
helm install postgresql bitnami/postgresql \
--version 12.1.15 \
--values values.yaml \
--namespace security
```
Check out the _values.yaml_ file sample of the PostgreSQL customization:
View: values.yaml
```yaml
# PostgreSQL read only replica parameters
readReplicas:
# Number of PostgreSQL read only replicas
replicaCount: 1
image:
tag: 15.2.0-debian-11-r0
global:
postgresql:
auth:
username: admin
existingSecret: keycloak-postgresql
database: keycloak
primary:
persistence:
enabled: true
size: 3Gi
```
## Keycloak Installation
To install Keycloak, follow the steps below:
1. Use `security` namespace from the PostgreSQL installation.
2. Add a chart repository:
```bash
helm repo add codecentric https://codecentric.github.io/helm-charts
helm repo update
```
3. Create Keycloak admin secret:
```bash
kubectl -n security create secret generic keycloak-admin-creds \
--from-literal=username= \
--from-literal=password=
```
4. Install Keycloak 20.0.3 using [codecentric/keycloakx](https://artifacthub.io/packages/helm/codecentric/keycloakx) Helm chart:
:::info
Keycloak can be deployed in production ready mode. For example, it may include multiple replicas, autoscaling, and monitoring.
For details, please refer to the [official Chart documentation](https://github.com/codecentric/helm-charts/tree/master/charts/keycloakx).
:::
```bash
helm install keycloakx codecentric/keycloakx \
--version 2.3.0 \
--values values.yaml \
--namespace security
```
Check out the _values.yaml_ file sample of the Keycloak customization:
View: values.yaml
```yaml
replicas: 1
# Deploy the latest version
image:
tag: "24.0.4"
# The following parameter is unrecommended to expose. Exposed health checks lead to an unnecessary attack vector.
health:
enabled: false
# The following parameter is unrecommended to expose. Exposed metrics lead to an unnecessary attack vector.
metrics:
enabled: false
command:
- "/opt/keycloak/bin/kc.sh"
- "--verbose"
- "start"
extraEnv: |
- name: KC_HOSTNAME
value: "keycloak."
- name: KC_SPI_HOSTNAME_DEFAULT_ADMIN
value: "keycloak."
- name: KC_HTTP_ENABLED
value: "true"
- name: KC_HOSTNAME_STRICT
value: "false"
- name: KC_HOSTNAME_STRICT_HTTPS
value: "false"
- name: KC_SPI_EVENTS_LISTENER_JBOSS_LOGGING_SUCCESS_LEVEL
value: "info"
- name: KEYCLOAK_ADMIN
valueFrom:
secretKeyRef:
name: keycloak-admin-creds
key: username
- name: KEYCLOAK_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: keycloak-admin-creds
key: password
- name: JAVA_OPTS_APPEND
value: >-
-XX:+UseContainerSupport
-XX:MaxRAMPercentage=50.0
-Djava.awt.headless=true
-Djgroups.dns.query={{ include "keycloak.fullname" . }}-headless
-Dkeycloak.connectionsHttpClient.default.expect-continue-enabled=true
-Dkeycloak.connectionsHttpClient.default.reuse-connections=false
- name: HTTP_ADDRESS_FORWARDING
value: "true"
- name: PROXY_ADDRESS_FORWARDING
value: "true"
# This block should be uncommented if you install Keycloak on Kubernetes
ingress:
enabled: true
annotations:
nginx.ingress.kubernetes.io/proxy-buffer-size: 256k
# Defines the class of the Ingress Controller.
# It allows you to choose which Ingress controller in cluster should be used to expose the Keycloak service to the outside world.
ingressClassName: "nginx"
# Exposes Keycloak paths according to the rules from documentation.
# Ref: https://www.keycloak.org/server/reverseproxy#_exposed_path_recommendations
console:
enabled: false
rules:
- host: keycloak.
paths:
- path: '{{ tpl .Values.http.relativePath $ | trimSuffix "/" }}/'
pathType: Prefix
proxy:
enabled: true
mode: "edge"
# This block should be uncommented if you set Keycloak to OpenShift and change the host field
# route:
# enabled: false
# # Path for the Route
# path: '/'
# # Host name for the Route
# host: "keycloak."
# # TLS configuration
# tls:
# enabled: true
resources:
limits:
memory: "2048Mi"
requests:
cpu: "50m"
memory: "512Mi"
# Check database readiness at startup
dbchecker:
enabled: true
database:
vendor: postgres
existingSecret: keycloak-postgresql
hostname: postgresql
port: 5432
username: admin
database: keycloak
```
## Configure Keycloak with the EDP Keycloak Operator {#configuration}
For configuring Keycloak within your environment, it's recommended to utilize the [edp-keycloak-operator](https://github.com/epam/edp-keycloak-operator).
This operator simplifies the integration process by automating the deployment and management of Keycloak instances.
It ensures that Keycloak is correctly configured to serve as an identity provider, facilitating secure access management across your applications.
By leveraging the edp-keycloak-operator, you can efficiently manage realms, users, and client configurations, making it an essential tool for robust access control in Kubernetes environments.
To create a Keycloak user in the Master realm who can manage other realms, follow these steps:
1. Create the `edp_` user and set the password in the `Master` realm.
:::note
This user should be used by Keycloak Operator to access Keycloak. Please refer to the [Install KubeRocketCI](../install-kuberocketci.md) page for details.
:::
2. In the `Role Mapping` tab, assign the proper roles to the user:
- Realm Roles:
- create-realm,
- offline_access,
- uma_authorization
- Client Roles `openshift-realm`:
- impersonation,
- manage-authorization,
- manage-clients,
- manage-users

:::note
`openshift-realm` is the realm name used as the `broker` realm, which is utilized for integrating third-party Identity Providers. You can find more information about this integration in the [kuberocketci-rbac](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/kuberocketci-rbac) repository of the KubeRocketCI platform.
:::
## Related Articles
* [Install KubeRocketCI](../install-kuberocketci.md)
* [Install Harbor](../artifacts-management/harbor-installation.md)
* [Install via Add-Ons](../add-ons-overview.md)
---
## KubeRocketCI CLI Keycloak Client
# KubeRocketCI CLI Keycloak Client
The [KubeRocketCI CLI](https://github.com/KubeRocketCI/cli) authenticates users through the browser (OAuth 2.0 authorization code flow with PKCE). This page describes how to register a **public** OpenID Connect client in Keycloak so operators can run `krci auth login` against your KubeRocketCI Portal.
:::info
Create the client in the **same realm** the Portal already uses. To confirm the realm, inspect the OIDC settings returned by the Portal, for example the endpoint `GET /rest/v1/config/oidc` on your Portal base URL (replace the host with yours):
```http
GET https://portal.example.com/rest/v1/config/oidc
```
Create the client only in the **Platform realm** you identified above. Application clients belong there, not in Keycloak’s built-in administrative realms.
:::
## Configure via KeycloakClient (GitOps)
If your cluster is managed with [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) and the **Keycloak Operator** is installed, you can provision the `krci-cli` client as a `KeycloakClient` custom resource instead of using the Admin Console.
The reference manifest ships with the `kuberocketci-rbac` add-on:
[`clusters/core/addons/kuberocketci-rbac/templates/broker/keycloak-client-krci-cli.yaml`](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/kuberocketci-rbac/templates/broker/keycloak-client-krci-cli.yaml)
It creates a public OpenID Connect client in the Platform **broker** realm (`realmRef.kind: KeycloakRealm`). This matches the realm the Portal typically uses (confirm via `GET /rest/v1/config/oidc` on your Portal URL).
The manifest configures:
- **Client ID**: `krci-cli`
- **Redirect URIs**: `http://127.0.0.1/*`, `http://localhost/*`
- **Default scopes**: `profile`, `email`, `roles`, `groups`
- **Audience mapper**: `kubernetes` (for clusters with an OIDC-enabled API server)
:::note
Other Keycloak clients in add-ons may reference `ClusterKeycloakRealm` (for example realm `main` / `shared`). The CLI client is intentionally created in the **broker** realm, alongside the Portal OIDC issuer.
:::
Enable the add-on in your fork, sync the Argo CD application, then verify reconciliation:
```bash
kubectl get keycloakclient krci-cli -n security
```
Expected status: `OK`.
:::warning
When the client is reconciled from Git by the Keycloak Operator, changes made in the Keycloak Admin Console may be overwritten. Update the manifest in your add-ons repository to persist configuration changes.
:::
If add-ons are not used, or you manage a standalone Keycloak instance, follow the manual steps below in the same realm your Portal uses.
## Configure Manually in Keycloak Admin Console
For a manual setup, use the Keycloak Admin Console to select the same realm as the Portal, create the public `krci-cli` client, review client scopes and token settings, add the Kubernetes audience mapper, and then verify login from your workstation.
### Select Realm
In the Keycloak Admin Console, use the realm drop-down in the top-left corner and select the realm your Portal uses.
### Create Client
The next step is to create a Keycloak client itself:
1. In the left sidebar, open **Clients**, then click **Create client**.
2. On **General settings**, set the fields as follows:
| Field | Value |
|-------|--------|
| Client type | OpenID Connect |
| Client ID | `krci-cli` |
| Name | KubeRocketCI CLI (display only) |
| Description | Public OIDC client for the KubeRocketCI CLI (PKCE) |
| Always display in console | Off |
3. Click **Next**.
4. On **Capability config**, set the toggles:
| Toggle | Value | Note |
|--------|-------|------|
| Client authentication | Off | Public client (no client secret) |
| Authorization | Off | — |
| Standard flow | On | Authorization code flow |
| Direct access grants | Off | — |
| Implicit flow | Off | — |
| Service accounts roles | Off | — |
| OAuth 2.0 Device Authorization Grant | Off | Browser-based login |
| OIDC CIBA Grant | Off | — |
5. Click **Next**.
6. On **Login settings**, configure URLs:
| Field | Value |
|-------|--------|
| Root URL | *(empty)* |
| Home URL | *(empty)* |
| Valid redirect URIs | `http://127.0.0.1/*` and `http://localhost/*` (add **both**) |
| Valid post logout redirect URIs | *(empty)* |
| Web origins | `+` (allow all origins configured for this client) |
:::note
The CLI binds a callback listener on `localhost` with a **random port** on each login, so wildcard redirect URIs are required.
:::
7. Click **Save**. You are taken to the client **Settings** page.
The screenshots below illustrate **Access settings** (client ID, redirect URIs, web origins) and **Capability config** / **Login settings** on a typical Keycloak deployment.


### Enforce PKCE (S256)
To enforce PKCE, do these steps:
1. Open the **Advanced** tab for the `krci-cli` client.
2. Under **Advanced settings**, set **Proof Key for Code Exchange Code Challenge Method** to **S256**.
3. Click **Save** for that section.
This ensures Keycloak only accepts logins that send a PKCE code challenge, which matches how the CLI performs authorization.
### Configure Token Lifetimes
On the client **Advanced** tab, you can leave **Access Token Lifespan** and session timeouts **inherited from the realm** (for example five to fifteen minutes for access tokens), or set client-specific values.
At realm level (**Realm settings** → **Tokens**), confirm **OAuth 2.0 Refresh Token Rotation** matches your security policy. The CLI refreshes tokens using the standard OAuth2 token endpoint.
### Configure Client Scopes
To configure client scopes (openid, profile, email, roles, groups), follow the steps below:
1. Open the **Client scopes** tab for `krci-cli`.
2. Under **Default** client scopes, ensure typical OpenID scopes are present, including **`openid`**, **`profile`**, **`email`**, and **`roles`** (exact names can vary slightly by Keycloak version).
3. If your Platform expects **group** membership in tokens, add a **groups** scope (or your realm’s equivalent, for example a custom **groups** / **groups-core** scope) as a **Default** scope:
- Click **Add client scope** → choose the groups scope → **Add** → **Default**.
If the realm has no suitable groups scope yet:
1. Go to **Client scopes** in the left sidebar → **Create client scope**.
2. Set **Name** (for example `groups`), **Type** Default, **Protocol** OpenID Connect, then save.
3. Open that scope → **Mappers** → **Configure a new mapper** → **Group Membership** with settings such as:
- **Token Claim Name**: `groups`
- **Full group path**: Off
- **Add to ID token** / **Add to access token** / **Add to userinfo**: On (as required by your cluster and Portal)
4. Return to the `krci-cli` client → **Client scopes** → add the new scope as **Default**.

### Configure Audience Mapper for Kubernetes API
The same ID token can be validated by the Kubernetes API server (when OIDC is enabled on the cluster). Add an **Audience** mapper on the **dedicated** client scope Keycloak creates for this client (name pattern `krci-cli-dedicated`):
1. On `krci-cli` → **Client scopes** tab, click the dedicated scope **`krci-cli-dedicated`**.
2. Open the **Mappers** tab → **Configure a new mapper** → **Audience**.
3. Configure the mapper so the issued token’s `aud` claim includes **both** the CLI client ID and the value your API server uses for **`--oidc-client-id`** (often `kubernetes`):
| Field | Suggested value |
|-------|------------------|
| Name | `k8s-audience` (or any descriptive name) |
| Included Client Audience | *(optional)* depends on whether you model audience as another client |
| Included Custom Audience | `kubernetes` *(or the exact `--oidc-client-id` value on the API server)* |
| Add to ID token | On |
| Add to access token | On |
| Add to lightweight access token | Off |
4. Save the mapper.
:::warning
If you also change the API server to expect `aud: kubernetes`, ensure the **Portal** client’s tokens carry a compatible audience as well, or Portal logins and API calls may fail. Align this step with your [EKS / cluster OIDC configuration](configure-keycloak-oidc-eks.md).
:::
The following screenshots show the **Mappers** list on the dedicated scope and an example **Audience** mapper form. Field names and whether you use **Included Client Audience** vs **Included Custom Audience** depend on your Keycloak version and how cluster OIDC is configured.


## Verify Configuration
To ensure everything is configured properly, carefully read the checklist below:
1. **Clients** → `krci-cli` → **Settings**: Client ID, **Standard flow** enabled, redirect URIs include `http://127.0.0.1/*` and `http://localhost/*`.
2. **Advanced**: PKCE code challenge method **S256**.
3. **Client scopes**: Default scopes include `openid`, profile-related scopes, email, roles, and your groups scope as required.
4. **Client scopes** → `krci-cli-dedicated` → **Mappers**: audience mapper present and aligned with cluster `--oidc-client-id`.
## Test From Workstation
Run the command below in a terminal (replace the Portal URL with yours):
```bash
krci auth login --portal-url https://portal.example.com
```
Expected behavior:
1. A browser window opens on the Keycloak login page.
2. After successful login (and consent, if enabled), the browser redirects to `http://localhost:/callback?code=...`.
3. The terminal prints a success message with the signed-in identity.
Decode the ID token (for example with [jwt.io](https://www.jwt.io/) or your own tooling) and confirm claims similar to:
```json
{
"iss": "https://keycloak.example.com/realms/your-realm",
"aud": ["krci-cli", "kubernetes"],
"azp": "krci-cli",
"email": "user@example.com",
"groups": ["admin", "developers"]
}
```
If `aud` does not include your Kubernetes OIDC client ID, revisit **Configure Audience Mapper for Kubernetes API**. If `groups` (or your chosen claim) is missing, revisit **Configure Client Scopes**.
## Related Articles
* [Install Keycloak](keycloak.md)
* [EKS OIDC With Keycloak](configure-keycloak-oidc-eks.md)
* [OIDC Integration With EKS](eks-oidc-integration.md)
* [Headlamp OIDC Configuration](ui-portal-oidc.md)
---
## Kubernetes Namespace Management
# Kubernetes Namespace Management
KubeRocketCI [deploys](../../user-guide/add-cd-pipeline.md) applications to namespaces. By default, the platform automatically creates these namespaces. This page provides information on an alternative approach to namespace management.
## Overview
Namespaces are created by the platform when user creates CD Pipelines. The operator creates them according to the specific format: `--`.
The [cd-pipeline-operator](https://github.com/epam/edp-cd-pipeline-operator) should have the permissions to automatically create namespaces when deploying applications and delete them when uninstalling applications.
## Disable Automatic Namespace Creation
In certain scenarios, the automatic generation of namespaces might be restricted. For instance, project-specific security protocols might necessitate disabling this feature. This can be achieved by adjusting the `manageNamespace` parameter within the [values.yaml](https://github.com/epam/edp-cd-pipeline-operator/blob/release/2.20/deploy-templates/values.yaml#L96) file.
By default, `manageNamespace` is enabled (true), but it can be toggled off (false). Consequently, users might encounter issues when attempting to deploy applications through the KubeRocketCI portal due to permission constraints:

The error highlighted above indicates the necessity for users to manually create a namespace following the `--` naming convention prior to stage creation. Moreover, the cd-pipeline-operator requires administrative rights to manage the namespace effectively. For instructions on manually creating a namespace, proceed with the steps outlined below:
1. Create the namespace by running the command below:
```bash
kubectl create namespace --
```
:::note
The `--` format for namespaces is set by default but is not mandatory. You can set your custom namespace when creating an Environment.
:::
2. Create the administrator RoleBinding resource by applying the file below with the `kubectl apply -f grant_admin_permissions.yaml` command:
:::note grant_admin_permissions.yaml
```yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: edp-cd-pipeline-operator-admin
namespace: --
subjects:
- kind: ServiceAccount
name: edp-cd-pipeline-operator
namespace: krci
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
```
:::
3. Restart the cd-pipeline-operator deployment, to speedup reconciliation.
## CD Pipeline Operator RBAC Model
The `manageNamespace` parameter also defines the resources that will be created depending on the cluster deployed whether it is OpenShift or Kubernetes. This scheme displays the nesting of operator input parameters:

:::note
When deploying application on the OpenShift cluster, the `registry-view` RoleBinding is created in the main namespace.
:::
## Related Articles
* [KubeRocketCI Access Model](platform-auth-model.md)
* [EKS OIDC With Keycloak](configure-keycloak-oidc-eks.md)
---
## Tekton Dashboard Authentication
# Tekton Dashboard Authentication
[OAuth2-Proxy](https://oauth2-proxy.github.io/oauth2-proxy/) is a versatile tool that serves as a reverse proxy, utilizing the OAuth 2.0 protocol with various providers like Google, GitHub, and Keycloak to provide both authentication and authorization. This guide instructs readers on how to protect their applications' endpoints using OAuth2-Proxy. By following these steps, users can enhance the security of their endpoints without modifying their current application code. In the context of KubeRocketCI, it has integration with the Keycloak OIDC provider, enabling it to connect with any component that lacks built-in authentication.
## Prerequisites
- [Keycloak](keycloak.md) with OIDC authentication is installed.
- [Keycloak operator](../add-ons-overview.md) is installed.
## Integration OAuth2-Proxy
To streamline the installation of OAuth2-Proxy in your environment, it is advised to utilize the resources available in the [Cluster Add-Ons](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/oauth2-proxy) and their [applications](https://github.com/epam/edp-cluster-add-ons/blob/main/chart/values.yaml#L120).
## Enable OAuth2-Proxy on Tekton Dashboard
The example below illustrates how to use OAuth2-Proxy in practice when using the Tekton dashboard:
Edit the Tekton dashboard Ingress annotation by adding `auth-signin` and `auth-url` of oauth2-proxy by `kubectl` command:
```bash
kubectl annotate ingress \
nginx.ingress.kubernetes.io/auth-signin='https:///oauth2/start?rd=https://$host$request_uri' \
nginx.ingress.kubernetes.io/auth-url='http://oauth2-proxy.oauth2-proxy.svc.cluster.local:80/oauth2/auth'
```
1. Generate a cookie-secret for proxy with the following command:
```bash
tekton_dashboard_cookie_secret=$(openssl rand -base64 32 | head -c 32)
```
2. Create `tekton-dashboard-proxy-cookie-secret` in the krci namespace:
```bash
kubectl -n krci create secret generic tekton-dashboard-proxy-cookie-secret \
--from-literal=cookie-secret=${tekton_dashboard_cookie_secret}
```
3. Run `helm upgrade` to update edp-install release:
```bash
helm upgrade --version --set 'edp-tekton.dashboard.openshift_proxy.enabled=true' edp-install --namespace krci
```
## Related Articles
* [Keycloak Installation](keycloak.md)
* [Keycloak OIDC Installation](configure-keycloak-oidc-eks.md)
* [Tekton Installation](../install-tekton.md)
---
## Authentication and Authorization: Overview
# Authentication and Authorization: Overview
KubeRocketCI uses [Keycloak](https://keycloak.org) as central access management solution, handling user permissions across various platform tools, including Kubernetes. Kubernetes clusters leverage Keycloak for RBAC implementation via [OIDC](https://kubernetes.io/docs/reference/access-authn-authz/authentication/). This consistent approach allows administrators to manage access uniformly.
Within Kubernetes, [Custom Resources (CRs)](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) are used to refine and enforce access controls by [configuring Keycloak](https://operatorhub.io/operator/edp-keycloak-operator), translating Kubernetes configurations into Keycloak access policies.
## Keycloak Components Overview
Keycloak is a critical component in KubeRocketCI for managing authentication and authorization. It uses realms, roles and groups to control access across the platform.
The diagram below illustrates the Keycloak resources within the KubeRocketCI system. It shows how tools and their Keycloak configurations are managed within the `shared` and `broker` realms. The `broker` realm serves as a central "authentication proxy" (broker), connecting to external Identity Providers (IdPs) such as Google, Facebook, and Active Directory (AD) through OIDC and/or SAML protocols. The `shared` realm consolidates platform tools such as Argo CD, Nexus Repository, SonarQube, Report-portal, Harbor, and others as OIDC (OpenID Connect) clients.
Each component can have its own unique configurations, including Keycloak roles, groups, or client scopes.
```mermaid
graph TD;
style integrated_services fill:#FFF2CC,stroke:#333,stroke-width:1px
style broker_realm fill:#FFF2CC,stroke:#333,stroke-width:1px
style IdP fill:#E1D5E7,stroke:#333,stroke-width:2px,dashed
subgraph integrated_services ["shared realm"]
direction TB
Report-Portal["Report-portal---Keycloak Client Keycloak Client Scope"]
Sonar["Sonar---Keycloak ClientKeycloak Realm Role Batch"]
Vault-kms["Vault-kms --- Keycloak Client"]
Vault-okd["Vault-okd --- Keycloak Client"]
ArgoCD["Argo CD --- Keycloak Client Keycloak Realm Group"]
EKS["EKS --- Keycloak Client Keycloak Client Scope Keycloak Realm Groups"]
Harbor["Harbor --- Keycloak Client"]
Harbor-ha["Harbor-ha --- Keycloak Client"]
Harbor-ha-okd["Harbor-ha-okd --- Keycloak Client"]
AWX-operator["AWX Operator --- Keycloak Client"]
Nexus["Nexus --- Keycloak Client"]
OpenSearch["OpenSearch --- Keycloak Client Keycloak Client Scope"]
Prometheus-operator["Prometheus-operator --- Keycloak Client (Grafana)"]
Dependency-Track["Dependency-Track --- Keycloak Client"]
DefectDojo["DefectDojo --- Keycloak Client"]
Portal["KubeRocketCI portal --- KeycloakClient Keycloak Client Secret"]
%% Define the new 4x4 grid layout
Report-Portal ~~~ Nexus ~~~ EKS ~~~ Portal
Sonar ~~~ Harbor ~~~ OpenSearch ~~~ ArgoCD
Vault-kms ~~~ Harbor-ha ~~~ Prometheus-operator ~~~ AWX-operator
Vault-okd ~~~ Harbor-ha-okd ~~~ Dependency-Track ~~~ DefectDojo
end
subgraph broker_realm ["broker realm"]
shared["shared --- Keycloak Client"]
end
integrated_services --> shared["shared --- Keycloak Client"]
broker_realm --> IdP["IdP (Google, Facebook, AD)"]
```
## Keycloak Roles and Groups
The diagram below provides an overview of the access control mechanisms for various tools integrated with Keycloak.
It illustrates two primary methods of managing user access: [Keycloak roles](#roles) and [Keycloak groups](#groups).
```mermaid
graph TD;
style component_access_control fill:#F5F5F5,stroke:#333,stroke-width:1px
style keycloak_roles fill:#F5F5F5,stroke:#333,stroke-width:1px
style keycloak_groups fill:#F5F5F5,stroke:#333,stroke-width:1px
style mock_object fill:#FFF2CC,stroke:#FFF2CC,stroke-width:1px
style AWX-operator fill:#F8CECC,stroke:#333,stroke-width:1px
style DefectDojo fill:#F8CECC,stroke:#333,stroke-width:1px
style ReportPortal fill:#F8CECC,stroke:#333,stroke-width:1px
style Vault fill:#F8CECC,stroke:#333,stroke-width:1px
style Gerrit fill:#F8CECC,stroke:#333,stroke-width:1px
style keycloak_roles_components fill:#FFF2CC,stroke:#333,stroke-width:1px
style keycloak_groups_components fill:#FFF2CC,stroke:#333,stroke-width:1px
subgraph keycloak_roles_components [" "]
direction TB
Dependency-Track["Dependency-Track --- administrator developer"]
Harbor["Harbor --- administrator"]
TektonDashboard["Tekton Dashboard --- administrator developer"]
OpenSearch["OpenSearch --- administrator developer"]
Grafana["Grafana --- administrator developer"]
Sonar["Sonar --- sonar-administrators sonar-developers"]
Nexus["Nexus --- administrator developer --- Specific roles are assigned through the CR NexusUser"]
AWX-operator["AWX Operator --- Specific roles are assigned through the UI"]
DefectDojo["DefectDojo --- Specific roles are assigned through the UI"]
ReportPortal["Report-portal --- Specific roles are assigned through the UI"]
Vault["Vault --- Role 'reader' by default"]
Dependency-Track ~~~ OpenSearch ~~~ Sonar ~~~ DefectDojo
Harbor ~~~ Grafana ~~~ ReportPortal ~~~ Vault
TektonDashboard ~~~ Nexus ~~~ AWX-operator ~~~ mock_object[" "]
end
subgraph keycloak_groups_components [" "]
direction TB
ArgoCD["Argo CD --- ArgoCDAdmins ArgoCDDevelopers"]
PortalUI["KubeRocketCI portal --- ${platform}-oidc-admins ${platform}-oidc-developers ${platform}-oidc-viewers"]
Gerrit["Gerrit --- Specific roles are assigned through the CR GerritGroupMember"]
ArgoCD ~~~ Gerrit
PortalUI ~~~ Gerrit
end
keycloak_roles --> keycloak_roles_components
keycloak_groups --> keycloak_groups_components
component_access_control["Component Access Control"] --> keycloak_roles["Keycloak Roles"]
component_access_control["Component Access Control"] --> keycloak_groups["Keycloak Groups"]
```
Components, highlighted in red, require additional configuration directly within the tool's UI.
:::info
`${platform}` is a placeholder for the platform name (namespace), where the KubeRocketCI is deployed.
:::
For detailed instructions on setting up OIDC integration for various components, please refer to the following articles:
1. **AWX** - [Community Documentation](https://ansible.readthedocs.io/projects/awx/en/latest/)
2. **DefectDojo** - [DefectDojo Permissions](https://docs.defectdojo.com/en/customize_dojo/user_management/configure_sso/#keycloak)
3. **Nexus** - [Nexus authentication process](#nexus-repository-manager)
4. **Report Portal** - [Report Portal Keycloak Integration](../project-management-and-reporting/reportportal-keycloak.md)
5. **Vault** - [OIDC provider configuration](https://developer.hashicorp.com/vault/docs/auth/jwt/oidc-providers/keycloak)
6. **Tekton** - [Tekton Dashboard Authentication](oauth2-proxy.md)
7. **Gerrit** - [Gerrit Authentication](#gerrit)
### Roles
The `shared` Keycloak realm defines two composite roles:
- **Administrator Role**:
- Designed for users who need administrative access to the tools used on the platform.
- This composite role includes the `administrator` and `sonar-administrators` roles.
- Users assigned the `administrator` composite role will inherit both roles.
- **Developer Role**:
- Designed for users who need access to the development tools used on the platform.
- This composite role includes the `developer` and `sonar-developers` roles.
- Users assigned the `developer` composite role will inherit both roles.
These composite roles simplify the assignment of administrative and development permissions within the KubeRocketCI.
The table below provides an overview of the `shared` realm roles and their types:
| Realm Role Name | Regular Role | Composite role |
| -------------------- | :----------------: | :----------------: |
| administrator | | :white_check_mark: |
| developer | | :white_check_mark: |
| sonar-administrators | :white_check_mark: | |
| sonar-developers | :white_check_mark: | |
### Groups
KubeRocketCI uses the `shared` realm for group management. The [groups](https://github.com/epam/edp-install/tree/master/deploy-templates/templates/rbac) are designed to control access to various components such as Argo CD, the KubeRocketCI portal, and the EKS cluster.
| Group Name | Purpose |
| ----------------------------- | ------------------------------------------------------------------- |
| `ArgoCDAdmins` | Administrator access to Argo CD instance |
| `ArgoCD-${platform}-users` | Access to the Argo CD project mapped to the `${platform}` tenant |
| `oidc-cluster-admins` | Full administrator (cluster-admin) access to the kubernetes cluster |
| `${platform}-oidc-admins` | Administrator access to KubeRocketCI |
| `${platform}-oidc-developers` | Developer access to KubeRocketCI |
| `${platform}-oidc-viewers` | Read-only access to view resources in KubeRocketCI |
These groups simplify the management of permissions and ensure that users have the appropriate level of access based on their roles and responsibilities.
## SonarQube OIDC
Access to SonarQube is managed through configurations in Keycloak (Keycloak Operator) and SonarQube (Sonar Operator). This section provides a detailed walkthrough for configuring access control.
### Keycloak Configuration
SonarQube access is managed using Keycloak roles within the `shared` realm:
- **sonar-developers**: Grants developer access to SonarQube.
- **sonar-administrators**: Grants administrative access to SonarQube.
To grant access, the appropriate role must be assigned to the user in Keycloak.
:::note Example
A user who needs developer access to SonarQube should be assigned the `sonar-developers` role or the `developer` composite role in Keycloak.
:::
### SonarQube Configuration
[KubeRocketCI Sonar Operator](https://github.com/epam/edp-sonar-operator) provides a [SonarQube Permission Template](https://docs.sonarsource.com/sonarqube-server/latest/instance-administration/system-functions/security/) to manage user access and permissions for SonarQube projects.
The template is stored in the SonarQube [custom resource](https://github.com/epam/edp-sonar-operator/blob/master/deploy-templates/_crd_examples/permission_template.yaml) of the operator. An example of a custom resource is shown below.
:::note Sonar Permission Template
```yaml
apiVersion: v2.edp.epam.com/v1
kind: SonarPermissionTemplate
metadata:
name: edp-default
spec:
name: edp-default
description: "KubeRocketCI permission templates (DO NOT REMOVE)"
projectKeyPattern: ".+"
default: true
groupsPermissions:
view-group:
- user
sonar-developers:
- user
- securityhotspotadmin
- issueadmin
- codeviewer
sonar-administrators:
- admin
- user
sonarRef:
name: sonar
```
:::
The SonarQube Permission Template defines three groups: `view-group`, `sonar-administrators`, and `sonar-developers`:
- **view-group**: Users who have read-only access to the project. They can view project's data and metrics but cannot modify or interact with it.
- **sonar-administrators**: Users with full control over the SonarQube project. They can create, modify, delete projects, manage user access, and configure SonarQube settings.
- **sonar-developers**: Users actively working on the SonarQube project. They have read and write access, can modify project data and metrics, and configure project-specific settings.
These groups provide different levels of access based on the user's role and responsibilities.
:::info
If a user is not assigned to any group, they will be placed in the `sonar-users` group by default. This group does not have any permissions in the `edp-default` Permission Template.
:::
### Group Permissions
The following table describes the permissions assigned to each group:
| Group Name | Sonar Permissions |
| -------------------- | -------------------------------------------------- |
| view-group | user |
| sonar-administrators | admin, user |
| sonar-developers | codeviewer, issueadmin, securityhotspotadmin, user |
| sonar-users | - |
## Nexus Repository Manager
KubeRocketCI leverages oauth2-proxy to authenticate users in Nexus Repository Manager OSS.
The user's access level is determined by the roles assigned in Keycloak.
:::info
Only users with either the `administrator` or `developer` role in Keycloak can access Nexus.
:::
The platform manages two distinct roles: `edp-admin`, `edp-viewer`.
:::note Example of edp-admin NexusRole and NexusUser
```yaml
apiVersion: edp.epam.com/v1alpha1
kind: NexusRole
metadata:
name: edp-admin
spec:
id: edp-admin
nexusRef:
name: nexus
kind: Nexus
name: edp-admin
description: Read and write access to all repos and scripts
privileges:
- nx-apikey-all
- nx-repository-view-*-*-add
- nx-repository-view-*-*-browse
- nx-repository-view-*-*-edit
- nx-repository-view-*-*-read
- nx-script-*-add
- nx-script-*-delete
- nx-script-*-run
- nx-search-read
```
```yaml
apiVersion: edp.epam.com/v1alpha1
kind: NexusUser
metadata:
name: ci-user
namespace: nexus
spec:
email: ci.user@edp.com
firstName: ci.user
id: ci.user
lastName: CI
nexusRef:
kind: Nexus
name: nexus
roles:
- edp-admin
secret: $ci-nexus:password
status: active
```
:::
## KubeRocketCI Portal and Kubernetes Cluster
Both the KubeRocketCI Portal and the Kubernetes cluster use Keycloak groups for access control. Users must be added to the appropriate group in Keycloak to gain access. These groups are configured in the `broker` realm.
:::warning
For the Kubernetes cluster to manage access control correctly, Keycloak must be configured as an OpenID Connect (OIDC) provider. Ensure that your Keycloak setup is properly [configured for OIDC](./configure-keycloak-oidc-eks.md) before proceeding.
:::
:::info
The `broker` realm keeps Kubernetes OIDC client.
:::
### Keycloak Groups
Each Keycloak group corresponds to a specific level of access within the Kubernetes cluster and the KubeRocketCI portal. The table below summarizes the groups and their associated permissions.
| Group Name | View | Build | Deploy | Full Namespace Access |
|-------------------------------|:------------------:|:------------------:|:------------------:|:---------------------:|
| `${platform}-oidc-admins` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `${platform}-oidc-developers` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: |
| `${platform}-oidc-viewers` | :white_check_mark: | :x: | :x: | :x: |
#### View Permissions
In the KubeRocketCI portal, the following **View** permissions are granted to users based on their group membership:
| Group Name | View Projects | View Branches | View Pipelines | View Deployments | View Environments | View Widgets | View Security | View Observability |
|-------------------------------|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|
| `${platform}-oidc-admins` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `${platform}-oidc-developers` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `${platform}-oidc-viewers` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
#### Permissions for the Configuration sections and Kubernetes resources
Permissions for **Configuration** sections in the KubeRocketCI portal:
| Group Name | View QuickLinks | Create QuickLinks | Edit QuickLinks | Delete QuickLinks | View GitOps | Create GitOps | Delete GitOps | View Clusters | Create Clusters | Edit Clusters | Delete Clusters | View GitServers | Create GitServers | Edit GitServers | Delete GitServers | View Integrations | Create Integrations | Edit Integrations | Delete Integrations |
|-------------------------------|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:-------------------:|:------------------:|:-------------------:|
| `${platform}-oidc-admins` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `${platform}-oidc-developers` | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
| `${platform}-oidc-viewers` | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
Permissions for the most common Kubernetes resources:
| Group Name | View Pods | Create Pods | Edit Pods | Delete Pods | View Deployments | Create Deployments | Edit Deployments | Delete Deployments | View Ingresses | Create Ingresses | Edit Ingresses | Delete Ingresses | View Services | Create Services | Edit Services | Delete Services | View Config Maps | Create Config Maps | Edit Config Maps | Delete Config Maps | View Cron Jobs | Create Cron Jobs | Edit Cron Jobs | Delete Cron Jobs | View Secrets | Create Secrets | Edit Secrets | Delete Secrets | View Roles | Create Roles | Edit Roles | Delete Roles | View Role Bindings | Create Role Bindings | Edit Role Bindings | Delete Role Bindings |
|-------------------------------|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:--------------------:|:------------------:|:--------------------:|
| `${platform}-oidc-admins` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `${platform}-oidc-developers` | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
| `${platform}-oidc-viewers` | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
#### Build Permissions
The following **Build** permissions are granted to users based on their group membership:
| Group Name | Create Project | Edit Project | Delete Project | Create Branch | Edit Branch | Delete Branch | Build Project |
|-------------------------------|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|
| `${platform}-oidc-admins` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `${platform}-oidc-developers` | :x: | :x: | :x: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `${platform}-oidc-viewers` | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
#### Deploy Permissions
The following **Deploy** permissions are granted to users based on their group membership:
| Group Name | Create PipelineRun | Create Deployment Flow | Edit Deployment Flow | Delete Deployment Flow | Create Environment | Edit Environment | Delete Environment | Clean Environment | Deploy Environment | Approve/Reject ApprovalTasks |
|-------------------------------|:---------------------:|:----------------------:|:--------------------:|:----------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:------------------:|:----------------------------:|
| `${platform}-oidc-admins` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `${platform}-oidc-developers` | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| `${platform}-oidc-viewers` | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: | :x: |
### Cluster RBAC Resources
The platform defines five RoleBindings that grant the necessary permissions to the corresponding Keycloak groups mentioned above.
| RoleBinding Name | Role Name | Groups |
| ---------------- | ---------------- | ---------------------------------------------------------- |
| tenant-admin | cluster-admin | `${platform}-oidc-admins` |
| tenant-developer | tenant-developer | `${platform}-oidc-developers` |
| tenant-viewer | view | `${platform}-oidc-viewers` , `${platform}-oidc-developers` |
Platform includes RBAC settings for the full cluster administration privileges.
| Cluster Role Binding Name | Cluster Role Name | Group |
| ------------------------- | ----------------- | --------------------- |
| cluster-admin | cluster-admin | `oidc-cluster-admins` |
:::note
KubeRocketCI provides an [aggregated](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles) ClusterRole `edp-aggregate-view-${platform}` with the permissions to view the KubeRocketCI [custom resources](../../api/overview.md).
:::
:::info
The `tenant-admin` RoleBinding is created in a namespace by the `cd-pipeline-operator`. The `tenant-admin` RoleBinding assigns the `admin` role to the `${platform}-oidc-admins` and `${platform}-oidc-developers` groups.
:::
### Grant User Access to the Created Namespaces
To provide users with admin or developer privileges for project namespaces, they need to be added to the `${platform}-oidc-admins` and `${platform}-oidc-developers` groups in Keycloak.
## Argo CD
In Argo CD, groups are specified when creating an AppProject to restrict access to deployed applications. To gain access to deployed applications within a project, users must be added to the corresponding Argo CD group in Keycloak. This ensures that only authorized users can access and modify applications within the project.
:::info
By default, only the `ArgoCDAdmins` group is automatically created in Keycloak.
:::
## Gerrit
Users should authenticate to Gerrit using their Keycloak credentials.
After logging into Gerrit, users are not automatically assigned to any groups. To add a user to a group, a `GerritGroupMember` custom resource must be created. This custom resource specifies the user's email address and the name of the group to which they should be added.
Below is an example of a `GerritGroupMember` custom resource:
:::note Gerrit Group Member
```yaml
apiVersion: v2.edp.epam.com/v1
kind: GerritGroupMember
metadata:
name: user-admins
spec:
accountId: user@user.com
groupId: Administrators
```
:::
Once the `GerritGroupMember` resource is created, the user will inherit the permissions and access levels associated with the specified group.
## Related Articles
* [KubeRocketCI Portal Overview](../../user-guide/index.md)
* [EKS OIDC With Keycloak](configure-keycloak-oidc-eks.md)
* [Argo CD Integration](../cd/argocd-integration.md)
* [Audit Trails Setup](../monitoring-and-observability/audit-trails-setup.md)
---
## Portal OIDC Configuration
# Portal OIDC Configuration
This page provides instructions for configuring the [OIDC authorization](https://openid.net/connect/) for the [KubeRocketCI portal](../../user-guide/index.md), enabling the use of Single Sign-On (SSO) for authorization in the Portal. This configuration allows for centralized control of user access and rights from a single configuration point.
## Prerequisites
Ensure the following values are set first before starting the Portal OIDC configuration:
1. `realm_id` = **shared**
2. `client_id` = **eks**
3. `keycloak_client_key`= **keycloak_client_secret_key** (received from: `Shared realm` -> `clients` -> `eks` -> `Credentials` -> `Client secret`)
:::note
The values indicated above are the result of the Keycloak configuration as an OIDC identity provider.
To obtain these values, please refer to the guidelines on the [Keycloak OIDC EKS Configuration](configure-keycloak-oidc-eks.md) page.
:::
## Configure Keycloak
To proceed with the Keycloak configuration, perform the following:
1. Add the URL of the Headlamp to the `valid_redirect_uris` variable in [Keycloak](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/kuberocketci-rbac/templates/kubernetes/keycloak-client.yaml#L17):
:::note keycloak_openid_client
```yaml
redirectUris:
- "https://portal./*"
- "http://localhost:8000/*"
```
:::
Make sure to define the following Keycloak client values as indicated:

2. Configure the Keycloak client key in Kubernetes using the Kubernetes secrets or the [External Secrets Operator](../secrets-management/external-secrets-operator-integration.md):
```yaml
apiVersion: v1
kind: Secret
metadata:
name: keycloak-client-headlamp-secret
namespace: krci
type: Opaque
stringData:
clientSecret:
```
3. Assign user to one or more groups in Keycloak.
## Integrate Portal With Kubernetes
Portal is integrated in Kubernetes in three steps:
1. Update the [values.yaml](../install-kuberocketci.md) file by enabling OIDC:
:::note values.yaml
```yaml
edp-headlamp:
config:
oidc:
enabled: true
```
:::
2. Navigate to KubeRocketCI portal and log in by clicking the `Sign In` button:

3. Upon logging in, ensure the namespace for KubeRocketCI is specified by clicking the **Manage Namespaces** button:

As a result, it is possible to control access and rights from the Keycloak endpoint.
## Configure User Profile Picture
To enhance account personalization, a profile picture can be configured in the Portal using Keycloak. This requires setting up the Keycloak client scope with the necessary user attributes.
Follow the steps below to configure the user profile picture in Keycloak:
1. Open the Keycloak admin console and navigate to the **Broker** realm. In the left sidebar menu, select **Client scopes** and choose the **profile** scope:

2. Navigate to the **Mappers** tab and ensure that the **picture** attribute is created. If the attribute is not present, click **Add mapper** button. In the dropdown menu, select **By configuration**:
:::note
If the **picture** user attribute is already present, skip to step 5.
:::

3. In the **Configure a new mapper** dialog, choose the **User Attribute** type:

4. Fill in the following fields to configure the user attribute:
- **Name**: `picture`
- **User Attribute**: `picture`
- **Token Claim Name**: `picture`
- **Claim JSON Type**: `String`

Click **Save** to apply the changes.
5. After configuring the user attribute, navigate to the **Users** tab in the left sidebar menu and select the user you want to set a profile picture for:

6. In the user profile, click **Attributes** and add the **picture** attribute with the URL of the desired profile picture:
:::note
The profile picture URL should refer to an image accessible via a public URL.
:::

Click **Save** to apply the changes.
7. After configuring the user profile picture in Keycloak, the profile picture will be displayed in the KubeRocketCI portal:

## Configure Default Namespace
After logging into the Portal, it is necessary to manually configure account settings like **Default namespace** and **Allowed namespaces**. To simplify this process, the `default_namespace` user attribute can be added to the user profile in Keycloak. This will ensure that the account settings are automatically configured during login.
Follow the steps below to configure the `default_namespace` user attribute in Keycloak:
1. Open the Keycloak admin console and navigate to the **Broker** realm. In the left sidebar menu, select **Client scopes** and choose the **profile** scope:

2. Navigate to the **Mappers** tab and click the **Add mapper** button. In the dropdown menu, select **By configuration**:

3. In the **Configure a new mapper** dialog, choose the **User Attribute** type:

4. Fill in the following fields to configure the user attribute:
- **Name**: `default_namespace`
- **User Attribute**: `default_namespace`
- **Token Claim Name**: `default_namespace`
- **Claim JSON Type**: `String`

Click **Save** to apply the changes.
5. After configuring the user attribute, navigate to the **Users** tab in the left sidebar menu and select the user you want to set a default namespace for:

6. In the user profile, click **Attributes** and add the **default_namespace** attribute with the name of the desired default namespace:

Click **Save** to apply the changes.
7. After configuring the user attribute with the default namespace in Keycloak, the account settings, such as the **Default namespace** and **Allowed namespaces**, will be automatically configured during login:

## Changing the Lifespan of an Access Token
Change the Access Token Lifespan: go to your Keycloak and select *Openshift realm* > *Realm settings* > *Tokens* >
*Access Token Lifespan* > set a new value to the field and save this change.
By default, "Access Token Lifespan" value is 5 minutes:

## Related Articles
* [EKS OIDC With Keycloak](configure-keycloak-oidc-eks.md)
* [External Secrets Operator](../secrets-management/external-secrets-operator-integration.md)
---
## Install via AWS Marketplace
# Install via AWS Marketplace
This documentation provides detailed instructions on how to install the KubeRocketCI via the AWS Marketplace.
To initiate the installation process, navigate to our dedicated [AWS Marketplace](https://aws.amazon.com/marketplace/pp/prodview-u7xcz6pvwwwoa#pdp-overview) page and commence the deployment of KubeRocketCI.
:::warning
KubeRocketCI is aligned with industry standards for storing and managing sensitive data, ensuring optimal security. However, the use of custom solutions introduces uncertainties, thus the responsibility for the safety of your data is totally covered by the platform administrator.
:::
## Prerequisites
:::note
- A basic understanding of AWS services and navigation is preferred to facilitate smoother setup and deployment processes. If you are new to AWS, please refer to the [AWS Documentation](https://docs.aws.amazon.com/index.html) for detailed information on the services and their usage.
- Understanding of Kubernetes: Knowledge of Kubernetes concepts and architecture is recommended for effective management and operation of clusters.
:::
Please ensure that you review the [Prerequisites](prerequisites.md) page before proceeding with the deployment of the product. To perform a minimal installation, please ensure that you meet the following requirements:
- You have an available AWS Elastic Kubernetes Service (EKS) cluster for deployment. For detailed instructions on creating a new cluster, please refer to the [AWS EKS Cluster Creation Guide](https://docs.aws.amazon.com/eks/latest/userguide/create-cluster.html). Additionally, you can consult our [EKS Deployment Guide](deploy-aws-eks.md) for step-by-step instructions tailored to your specific needs.
- You have a domain name available and associated with the ingress object in the cluster.
- You have cluster administrator access.
- The [Tekton](install-tekton.md) resources are deployed.
- You have access to the cluster via a Service Account token.
## Deploy KubeRocketCI Platform
To deploy the platform, follow the steps below:
1. Deploy Tekton resources using the following commands:
```bash
kubectl create ns tekton-pipelines
kubectl create ns tekton-chains
kubectl create ns tekton-pipelines-resolvers
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
kubectl apply --filename https://storage.googleapis.com/tekton-releases/triggers/latest/interceptors.yaml
kubectl apply --filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
kubectl apply --filename https://storage.googleapis.com/tekton-releases/chains/latest/release.yaml
```
2. Define the mandatory parameters you would like to use for installation using the following command:
```bash
kubectl create ns krci
helm install edp-install \
--namespace krci ./* \
--set global.dnsWildCard=example.com
```
3. (Optional) Provide token to sign in to the Portal. Run the following command to create Service Account with cluster admin permissions:
```bash
kubectl create serviceaccount edp-admin -n krci
kubectl create clusterrolebinding edp-cluster-admin --clusterrole=cluster-admin --serviceaccount=krci:edp-admin
kubectl apply -f - <
# Argo CD Integration
KubeRocketCI uses Argo CD as a [part of the Continuous Delivery/Continuous Deployment](../../user-guide/cd-pipeline-details.md)
implementation. Argo CD follows the best GitOps practices, uses Kubernetes native approach for the Deployment Management, has rich UI and
required RBAC capabilities.
## Argo CD Deployment Approach in KubeRocketCI
Argo CD can be installed using [two different approaches](https://argo-cd.readthedocs.io/en/stable/operator-manual/installation):
- Cluster-wide scope with the cluster-admin access
- Namespaced scope with the single namespace access
Both approaches can be deployed with High Availability (HA) or Non High Availability (non HA) installation manifests.
KubeRocketCI uses the HA deployment with the cluster-admin permissions, to minimize cluster resources consumption by sharing
single Argo CD instance across multiple KubeRocketCI Tenants. Please follow [the installation instructions](../install-argocd.md) to deploy Argo CD.
## Integration
See a diagram below for the details:

- Argo CD is deployed in a separate `argocd` namespace.
- Argo CD uses a `cluster-admin` role for managing cluster-scope resources.
- The `control-plane` application is created using the App of Apps approach, and its code is managed by the `control-plane` members.
- The `control-plane` is used to onboard new Argo CD Tenants (Argo CD Projects - AppProject).
- The `KubeRocketCI Tenant Member` manages `Argo CD Applications` using `kind: Application` in the `krciTenant` namespace.
The [App Of Apps approach](https://argo-cd.readthedocs.io/en/stable/operator-manual/cluster-bootstrapping/) is used to
manage the `KubeRocketCI Tenants`. Inspect the [edp-grub](https://github.com/SergK/edp-grub) repository structure that is used to
provide the KubeRocketCI Tenants for the Argo CD Projects:
```bash
edp-grub
├── LICENSE
├── README.md
├── apps ### All Argo CD Applications are stored here
│ ├── grub-argocd.yaml # Application that provisions Argo CD Resources - Argo Projects (KubeRocketCI Tenants)
│ └── grub-keycloak.yaml # Application that provisions Keycloak Resources - Argo CD Groups (KubeRocketCI Tenants)
├── apps-configs
│ └── grub
│ ├── argocd ### Argo CD resources definition
│ │ └── edp.yaml
│ └── keycloak ### Keycloak resources definition
│ └── edp.yaml
├── bootstrap
│ └── root.yaml ### Root application in App of Apps, which provision Applications from /apps
└── examples ### Examples
└── tenant
└── edp-petclinic.yaml
```
The Root Application must be created under the `control-plane` scope.
## Argo CD Configuration
Now that Argo CD is integrated, it is time to configure it properly. To configure Argo CD for KubeRocketCI, follow the steps below:
1. Modify the `argocd-cmd-params-cm` ConfigMap in the `argocd` namespace and add the `application.namespaces` parameter to the `data` subsection:
```bash
kubectl patch configmap argocd-cmd-params-cm -n argocd --type merge -p '{"data":{"application.namespaces":"krci"}}'
```
```yaml
data:
application.namespaces: krci
```
2. Add a [credential template](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/#private-repositories)
for GitHub, GitLab, Bitbucket, or Gerrit integrations. The credential template must be created for each Git Server.
Generate an SSH key pair and add a public key to GitLab, GitHub, or Bitbucket account.
:::warning
Use an additional GitHub/GitLab User to access a repository. For example:
- GitHub, add a User to a repository with a "Read" role.
- GitLab, add a User to a repository with a "Guest" role.
:::
```bash
ssh-keygen -t ed25519 -C "email@example.com" -f argocd
```
Copy SSH private key to Argo CD namespace.
```bash
KRCI_NAMESPACE="krci"
VCS_HOST=""
ACCOUNT_NAME=""
URL="ssh://git@${VCS_HOST}:22/${ACCOUNT_NAME}"
kubectl create secret generic ${KRCI_NAMESPACE} -n argocd \
--from-file=sshPrivateKey=argocd \
--from-literal=url="${URL}"
kubectl label --overwrite secret ${KRCI_NAMESPACE} -n argocd "argocd.argoproj.io/secret-type=repo-creds"
```
Copy existing SSH private key for Gerrit to Argo CD namespace.
```bash
KRCI_NAMESPACE="krci"
GERRIT_PORT=$(kubectl get gerrit gerrit -n ${KRCI_NAMESPACE} -o jsonpath='{.spec.sshPort}')
GERRIT_ARGOCD_SSH_KEY_NAME="gerrit-ciuser-sshkey"
GERRIT_URL=$(echo "ssh://edp-ci@gerrit.${KRCI_NAMESPACE}:${GERRIT_PORT}" | base64)
kubectl get secret ${GERRIT_ARGOCD_SSH_KEY_NAME} -n ${KRCI_NAMESPACE} -o json | jq 'del(.data.username,.metadata.annotations,.metadata.creationTimestamp,.metadata.labels,.metadata.resourceVersion,.metadata.uid,.metadata.ownerReferences)' | jq '.metadata.namespace = "argocd"' | jq --arg name "${KRCI_NAMESPACE}" '.metadata.name = $name' | jq --arg url "${GERRIT_URL}" '.data.url = $url' | jq '.data.sshPrivateKey = .data.id_rsa' | jq 'del(.data.id_rsa,.data."id_rsa.pub")' | kubectl apply -f -
kubectl label --overwrite secret ${KRCI_NAMESPACE} -n argocd "argocd.argoproj.io/secret-type=repo-creds"
```
3. Add [SSH Known hosts](https://argo-cd.readthedocs.io/en/stable/user-guide/private-repositories/#unknown-ssh-hosts)
for GitHub, GitLab, Bitbucket, or Gerrit integration.
Add GitHub, GitLab, or Bitbucket host to Argo CD config map with known hosts.
```bash
KRCI_NAMESPACE="krci"
VCS_HOST=""
KNOWN_HOSTS_FILE="/tmp/ssh_known_hosts"
ARGOCD_KNOWN_HOSTS_NAME="argocd-ssh-known-hosts-cm"
rm -f ${KNOWN_HOSTS_FILE}
kubectl get cm ${ARGOCD_KNOWN_HOSTS_NAME} -n argocd -o jsonpath='{.data.ssh_known_hosts}' > ${KNOWN_HOSTS_FILE}
ssh-keyscan ${VCS_HOST} >> ${KNOWN_HOSTS_FILE}
kubectl create configmap ${ARGOCD_KNOWN_HOSTS_NAME} -n argocd --from-file ${KNOWN_HOSTS_FILE} -o yaml --dry-run=client | kubectl apply -f -
```
Add Gerrit host to Argo CD config map with known hosts
```bash
KRCI_NAMESPACE="krci"
KNOWN_HOSTS_FILE="/tmp/ssh_known_hosts"
ARGOCD_KNOWN_HOSTS_NAME="argocd-ssh-known-hosts-cm"
GERRIT_PORT=$(kubectl get gerrit gerrit -n ${KRCI_NAMESPACE} -o jsonpath='{.spec.sshPort}')
rm -f ${KNOWN_HOSTS_FILE}
kubectl get cm ${ARGOCD_KNOWN_HOSTS_NAME} -n argocd -o jsonpath='{.data.ssh_known_hosts}' > ${KNOWN_HOSTS_FILE}
kubectl exec -it deployment/gerrit -n ${KRCI_NAMESPACE} -- ssh-keyscan -p ${GERRIT_PORT} gerrit.${KRCI_NAMESPACE} >> ${KNOWN_HOSTS_FILE}
kubectl create configmap ${ARGOCD_KNOWN_HOSTS_NAME} -n argocd --from-file ${KNOWN_HOSTS_FILE} -o yaml --dry-run=client | kubectl apply -f -
```
4. Create an Argo CD Project (Tenant), for example, with the `krci` name:
```yaml title="AppProject"
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: krci
namespace: argocd
# Finalizer that ensures that project is not deleted until it is not referenced by any application
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
destinations:
# by default krci work with 'krci-*' namespace
- namespace: 'krci-*'
# allow to deploy to specific server (local in our case)
name: in-cluster
# Deny all cluster-scoped resources from being created, except for Namespace
clusterResourceWhitelist:
- group: ''
kind: Namespace
# Allow all namespaced-scoped resources to be created, except for ResourceQuota, LimitRange, NetworkPolicy
namespaceResourceBlacklist:
- group: ''
kind: ResourceQuota
- group: ''
kind: LimitRange
- group: ''
kind: NetworkPolicy
# we are ok to create any resources inside namespace
namespaceResourceWhitelist:
- group: '*'
kind: '*'
# enable access only for specific git server. The example below 'krci' - it is namespace where KubeRocketCI deployed
sourceRepos:
- ssh://git@github.com/*
# enable capability to deploy objects from namespaces
sourceNamespaces:
- krci
```
5. Check that your new **Repository**, **Known Hosts**, and **AppProject** are added to the Argo CD UI.
6. Generate Argo CD project token for deploy integration:
```bash
URL=
TOKEN=$(argocd proj role create-token krci developer -i argocd-ci -t)
cat <
Generate Argo CD project token via UI, follow the steps below:
1. Open your Argo CD endpoint.
2. In the Argo CD main menu, select **Settings**:

3. On the **Settings** page, select **Projects**:

4. On the **Projects** page, select the previously created Argo CD project:

5. On the project details page, select the **Roles** tab:

6. On the **Roles** tab, select the **developer** role:

7. On the appeared window, scroll down to the **JWT Tokens** section, specify the required fields and click **Create**:
- **Token ID**: Token name.
- **Expires in**: Defines the period for which the token is considered valid. Must be in the "[0-9]+[s,m,h,d]" format. For example, "12h", "7d".

8. Confirm the token creation:

9. Copy the data of the newly created token:

10. Navigate to **KubeRocketCI portal** -> **Configuration** -> **Deployment** -> **Argo CD** and click **+ Add integration**:

11. In the integration window, specify the required fields and click **Save**:
- **Quick Link URL**: Enter the URL of your Argo CD instance (e.g., https://argocd.example.com). A quick link will be added to the Overview section for quick access to Argo CD from the KubeRocketCI portal.
- **URL**: Enter the URL of your Argo CD instance (e.g., https://argocd.example.com).
- **Token**: Paste the JWT token data copied earlier.

12. Verify that the integration status is green:

Once Argo CD is successfully integrated, KubeRocketCI user can utilize Argo CD to deploy [CD pipelines](../../user-guide/add-cd-pipeline.md).
## Check Argo CD Integration (Optional)
This section provides the information on how to test the integration with Argo CD and is not mandatory to be followed.
1. Add an Argo CD application:
View: argocd-values.yaml
```yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: demo
spec:
project: krci
destination:
namespace: krci-demo
server: https://kubernetes.default.svc
source:
helm:
parameters:
- name: image.tag
value: master-0.1.0-1
- name: image.repository
value: image-repo
path: deploy-templates
# github/gitlab example ssh://git@github.com//.git
# gerrit example ssh://@gerrit.krci:30007/.git
repoURL: ssh://git@github.com/krci/demo.git
targetRevision: master
syncPolicy:
syncOptions:
- CreateNamespace=true
automated:
selfHeal: true
prune: true
```
2. Check that your new Application is added to the Argo CD UI under the `krci` Project scope.
## Deploy Argo CD Application to Remote Cluster (Optional)
KubeRocketCI also supports deploying Argo CD applications to a remote cluster. To deploy applications to remote clusters, follow the steps below:
1. Create `ServiceAccount` `ClusterRoleBinding` and `Secret` for that `ServiceAccount`.
2. Receive the bearer token:
```bash
BEAR_TOKEN=$(kubectl get secret -o jsonpath='{.data.token}' | base64 --decode)
```
3. Create ArgoCD secret for remote cluster in the ArgoCD namespace (Argo CD only discovers cluster secrets in its own control-plane namespace):
```yaml title="manifest"
apiVersion: v1
kind: Secret
metadata:
name: krci-remote-cluster
namespace: argocd
labels:
argocd.argoproj.io/secret-type: cluster
type: Opaque
stringData:
# Remote cluster name. Must exactly match the cluster name used in the
# Environment (Stage) and in the 'available_clusters' parameter of the
# krci-config ConfigMap: the generated Argo CD Applications reference
# the destination cluster by this name.
name: "krci-remote-cluster"
# Cluster endpoint URL
server: "https://xxxxxxxxxxxxxxxxxxxx.sk1.eu-central-1.eks.amazonaws.com"
# Remote cluster config
config: |
{
"bearerToken": "",
"tlsClientConfig": {
"insecure": false,
"caData": ""
}
}
```
4. Update an Argo CD Project (KubeRocketCI Tenant), with the `krci` name. Without this step, deployments to the remote cluster fail with `InvalidSpecError: application destination server 'krci-remote-cluster' and namespace 'krci-...' do not match any of the allowed destinations`:
```yaml title="AppProject"
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: krci
spec:
destinations:
# Add block that allow deploy in remote cluster
# by default, krci works with 'krci-*' namespaces
- namespace: 'krci-*'
# allow to deploy to specific server (remote in our case)
name: krci-remote-cluster
```
5. Add a remote cluster in the KubeRocketCI portal. Please refer to the [Add Cluster](../../user-guide/add-cluster.md) page for details.
:::note
When a cluster is added through the KubeRocketCI portal with the Bearer credentials type, the cd-pipeline-operator generates an equivalent Argo CD cluster secret in the platform namespace after the connectivity check succeeds. Its name is the cluster Secret name with the `-argocd-cluster` suffix appended: a cluster added as `dev2` is stored as Secret `dev2-cluster` and produces `dev2-cluster-argocd-cluster`. You can copy that secret into the ArgoCD namespace instead of composing the manifest above manually.
:::
## Keycloak Integration (Optional)
:::note
To proceed with the steps below, you need the [edp-keycloak-operator](https://github.com/epam/edp-keycloak-operator) to be deployed.
:::
To provide Argo CD with the Keycloak SSO authorization mechanism, follow the guidelines below:
1. Create secret `keycloak-client-argocd-secret`.
```bash
kubectl create secret generic keycloak-client-argocd-secret \
--from-literal=clientSecret=$(openssl rand -base64 32) \
--namespace=argocd
```
2. Update the `argocd-cm` ConfigMap:
```bash
kubectl patch configmap argocd-cm -n argocd --patch "$(cat </auth/realms/edp
clientID: argocd-tenant
clientSecret: $keycloak-client-argocd-secret:clientSecret
requestedScopes:
- openid
- profile
- email
- groups
EOF
)"
```
```yaml
data:
oidc.config:
url: "https://argocd.<.Values.global.dnsWildCard>"
application.instanceLabelKey: argocd.argoproj.io/instance-edp
oidc.config: |
name: Keycloak
issuer: https://<.Values.global.keycloakEndpoint>/auth/realms/edp
clientID: argocd-tenant
clientSecret: $keycloak-client-argocd-secret:clientSecret
requestedScopes:
- openid
- profile
- email
- groups
```
3. Create a Keycloak Group:
```yaml
apiVersion: v1.edp.epam.com/v1
kind: KeycloakRealmGroup
metadata:
name: argocd-krci-users
spec:
name: ArgoCD-krci-users
realm: main
```
4. Create a Keycloak Client:
```yaml
apiVersion: v1.edp.epam.com/v1
kind: KeycloakClient
metadata:
name: argocd
namespace: argocd
spec:
advancedProtocolMappers: true
attributes:
post.logout.redirect.uris: +
clientId: argocd-tenant
defaultClientScopes:
- groups
realmRef:
kind: ClusterKeycloakRealm
name: main
secret: keycloak-client-argocd-secret
webUrl: "https://argocd.<.Values.global.dnsWildCard>"
```
5. In Keycloak, add users to the `ArgoCD-krci-users` Keycloak Group.
6. Update spec in project:
```yaml title="AppProject"
spec:
description: CD pipelines for krci
roles:
- name: developer
description: Users for krci tenant
policies:
- p, proj:krci:developer, applications, create, krci/*, allow
- p, proj:krci:developer, applications, delete, krci/*, allow
- p, proj:krci:developer, applications, get, krci/*, allow
- p, proj:krci:developer, applications, override, krci/*, allow
- p, proj:krci:developer, applications, sync, krci/*, allow
- p, proj:krci:developer, applications, update, krci/*, allow
- p, proj:krci:developer, repositories, create, krci/*, allow
- p, proj:krci:developer, repositories, delete, krci/*, allow
- p, proj:krci:developer, repositories, update, krci/*, allow
- p, proj:krci:developer, repositories, get, krci/*, allow
groups:
# Keycloak Group name
- ArgoCD-krci-users
```
7. Then restart the deployment:
```bash
kubectl -n argocd rollout restart deployment argo-argocd-server
```
## Related Articles
* [Install Argo CD](../install-argocd.md)
---
## Customize Deploy Pipeline
# Customize Deploy Pipeline
When deploying applications into environments, it's important to automate both `pre-deployment` and `post-deployment` steps.
`Pre-deployment` procedures include essential tasks such as deploying databases, configuring specific software, and preparing the environment. Additionally, `post-deployment` procedures, such as testing, configuring, and removing old information from the environment, are crucial for ensuring the smooth operation of the deployed application. To facilitate these processes, the custom deployment feature is implemented in KubeRocketCI.
This page provides comprehensive guidelines on how to adjust the deployment logic to cater your needs.
## Deploy Custom Pipeline
Overall, the custom pipeline creation involves the following steps:
```mermaid
graph LR;
A(Create TriggerTemplate resource) --> B(Create Pipeline resource) --> C(Deploy custom environment)
```
1. **Create TriggerTemplate resource** - On this step, create the `TriggerTemplate` custom resource that will appear as an option in the in the environment stage creation menu.
2. **Create Pipeline** - On this step, create custom resource called `Pipeline` that complements the trigger template. This resource contains all the tasks to perform within the custom pipeline.
3. **Integration** - On this step, you simply select your custom pipeline logic when creating a stage for your environment.
To customize your deployment pipeline, follow the steps below:
1. Create the `TriggerTemplate` custom resource by adding the following label:
```bash
labels:
app.edp.epam.com/pipelinetype: deploy
```
:::note
Please refer to the `TriggerTemplate` [example](https://github.com/epam/edp-tekton/blob/release/0.12/charts/pipelines-library/templates/triggers/cd/deploy.yaml) for more details. Remember to set your pipeline name in the `spec.resourcetemplates.spec.pipelineRef.name` [parameter](https://github.com/epam/edp-tekton/blob/release/0.12/charts/pipelines-library/templates/triggers/cd/deploy.yaml#L35).
:::
2. Create the custom pipeline with your custom logic. Refer to the custom pipeline [example](https://github.com/epam/edp-tekton/blob/release/0.12/charts/pipelines-library/templates/triggers/cd/deploy.yaml) for more details.
3. Apply the created manifest files in the platform namespace (e.g., `krci`).
4. On the `Pipeline Configuration` step on the KubeRocketCI portal, select the added trigger template in the `Deploy Pipeline Template` section:

5. (Optional) In case you need to implement custom deployment in a remote cluster, do the following:
- Connect the KubeRocketCI platform with the remote cluster if it is not integrated yet. Please refer to the [Add Cluster](../../user-guide/add-cluster.md) page for more details
- Mount the secret to the `run-quality-gate` resource by changing the [volumes](https://github.com/epam/edp-tekton/blob/release/0.16/charts/pipelines-library/templates/tasks/cd/run-quality-gate.yaml#L9) and [volumeMounts](https://github.com/epam/edp-tekton/blob/release/0.16/charts/pipelines-library/templates/tasks/cd/run-quality-gate.yaml#L40) sections
- Switch the [context](https://github.com/epam/edp-tekton/blob/release/0.16/charts/pipelines-library/templates/tasks/cd/run-quality-gate.yaml#L33) by specifying the appropriate kube config file of the `run-quality-gate` resource
- On the `Create stage` step on the KubeRocketCI portal, select the appropriate cluster in the `cluster` section:

## Related Articles
* [Add Cluster](../../user-guide/add-cluster.md)
* [Deploy Application With Custom Build Tool/Framework](../../use-cases/tekton-custom-pipelines.md)
* [Add Environment](../../user-guide/add-cd-pipeline.md)
* [Customize Environment Cleanup](./customize-environment-deletion.md)
---
## Customize Environment Cleanup
# Customize Environment Cleanup
KubeRocketCI provides capabilities to fully operate the CI/CD flow, starting from building applications to deploying its new release. The operation flow is designed to be seamless for most of the users. However, there may be cases where more specialized actions are necessary. These might include custom procedures for managing the deletion of application resources.
## Create Custom Clean Pipeline
Delete pipeline is a typical Tekton pipeline but with its own instructions. The custom delete pipeline creation involves the following steps:
```mermaid
graph LR;
A(Create TriggerTemplate resource) --> B(Create Pipeline resource) --> C(Create Task resource) --> D(Apply changes to environment)
```
Clean pipeline consists of **Trigger Template**, **Pipeline**, and **Task** custom resources. To create a custom clean pipeline, follow the steps below:
1. Create and apply the **TriggerTemplate** custom resource. Refer to the example [TriggerTemplate](https://github.com/epam/edp-tekton/blob/master/charts/pipelines-library/templates/triggers/cd/clean.yaml). Ensure to set the appropriate pipeline type in the labels:
```bash
...
labels:
app.edp.epam.com/pipelinetype: clean
...
```
```bash
...
spec:
taskRunTemplate:
serviceAccountName: tekton
pipelineRef:
name: clean-custom
...
```
2. Create and apply the **Pipeline** custom resource. Refer to the example [Pipeline](https://github.com/epam/edp-tekton/blob/master/charts/pipelines-library/templates/pipelines/cd/clean.yaml). Additionally, set the concrete task to run:
```bash
tasks:
- name: clean
taskRef:
kind: Task
name: clean-custom
```
3. Create and apply the **Task** custom resource. Refer to the example [Task](https://github.com/epam/edp-tekton/blob/master/charts/pipelines-library/templates/tasks/cd/clean.yaml).
## Enable Clean Pipeline
As soon as all the three custom resources are correctly configured and applied, you can select the newly created pipeline in the KubeRocketCI portal.
### New Environments
To apply the newly created clean pipeline to your environments, follow the steps below:
1. In the deployment flow details page, click the **Create environment** button:

2. In the **Create environment** window, select the custom clean pipeline:

### Existing Environments
If you need to change the delete pipeline in an already existing environment, follow the steps below:
1. Navigate to the environment details page and click the **Edit** button:

2. In the **Edit environment** window, select the custom clean pipeline:

As soon as the clean pipeline is created and selected within an environment, you can trigger it by clicking the **Clean** button.
## Related Articles
* [Customize Deploy Pipeline](../../operator-guide/cd/customize-deploy-pipeline.md)
* [Add Deployment Flow](../../user-guide/add-cd-pipeline.md)
* [Manage Deployment Flows](../../user-guide/manage-environments.md)
---
## Deploy Application In Remote Cluster via IRSA
# Deploy Application In Remote Cluster via IRSA
KubeRocketCI enables secure deployment of applications to remote AWS EKS clusters using IAM Roles for Service Accounts (IRSA). This guide explains how to configure cross-account access between Kubernetes clusters, allowing applications to be deployed from one AWS account to another without storing long-term credentials. IRSA provides temporary, scoped credentials by allowing Kubernetes service accounts to assume specific IAM roles with precisely defined permissions, enhancing both security and operational efficiency when working with multi-account AWS environments.
## Prerequisites
Before implementing IRSA for cross-account deployments, the following requirements must be met:
- Configured two [AWS accounts](https://docs.aws.amazon.com/accounts/latest/reference/getting-started.html): Account A (where KubeRocketCI is deployed) and Account B (the target account for application deployment)
- Administrative access to both AWS accounts
- Running [EKS cluster](https://docs.aws.amazon.com/eks/latest/userguide/create-cluster.html) in Account A with configured [OIDC Identity Provider](../auth/configure-keycloak-oidc-eks.md) authentication
- Running [EKS cluster](https://docs.aws.amazon.com/eks/latest/userguide/create-cluster.html) in Account B as the target cluster for application deployment
- Installed and configured [Argo CD](../install-argocd.md).
## Architecture and Working Principles
KubeRocketCI uses IRSA to establish secure connections between AWS accounts without storing long-term credentials. The architecture follows these key principles:
1. **Service Account Federation** - Kubernetes service accounts in Account A are federated with AWS IAM through OIDC
2. **Role Chaining** - IAM roles in Account A assume corresponding roles in Account B
3. **Temporary Credentials** - All access is provided through short-lived, automatically rotated tokens
The cross-account deployment process involves two main components:
**CD Pipeline Operator Flow:**
- The [cd-pipeline-operator](https://github.com/epam/edp-cd-pipeline-operator) in Account A uses a service account linked to the `AWSIRSA_{cluster_name}_CDPipelineOperator` IAM role
- When new environments or clusters are configured in KubeRocketCI, the `AWSIRSA_{cluster_name}_CDPipelineOperator` role in Account A assumes the `AWSIRSA_{cluster_name}_CDPipelineAgent` role in Account B
- The agent role creates the necessary Kubernetes resources (namespaces, service accounts, secrets) in the target cluster
**Argo CD Flow:**
- Argo CD controllers in Account A use service accounts linked to the `AWSIRSA_{cluster_name}_ArgoCDMaster` IAM role
- During deployment, this role assumes the `AWSIRSA_{cluster_name}_ArgoCDAgentAccess` role in Account B
- The agent role accesses the target EKS cluster to deploy and manage applications
The diagram below illustrates the IRSA access model for cross-account deployments:
```mermaid
flowchart TD
subgraph subGraph0["AWS Account A"]
SA["cd-pipeline-operator"]
ROLE_A["IAM Role CDPipelineOperator"]
end
subgraph subGraph1["AWS Account B"]
ROLE_B["IAM Role CDPipelineAgent"]
RESOURCES["Kubernetes resources"]
end
subgraph subGraph2["CD Pipeline Operator Flow"]
subGraph0
subGraph1
end
subgraph subGraph3["AWS Account A"]
ARGOCD["Argo CD Controllers"]
ROLE_MASTER["IAM Role ArgoCDMaster"]
end
subgraph subGraph4["AWS Account B"]
ROLE_AGENT["IAM Role ArgoCDAgentAccess"]
APP_RESOURCES["Applications & Resources"]
end
subgraph subGraph5["Argo CD Flow"]
subGraph3
subGraph4
end
SA -- IRSA --> ROLE_A
ROLE_A -- AssumeRole --> ROLE_B
ROLE_B -- Create/Configure --> RESOURCES
ARGOCD -- IRSA --> ROLE_MASTER
ROLE_MASTER -- AssumeRole --> ROLE_AGENT
ROLE_AGENT -- Deploy/Manage --> APP_RESOURCES
```
## Create IAM Roles
To enable cross-account deployments using IRSA, it is necessary to create specific IAM roles in both AWS accounts.
There are two approaches to create the required IAM roles:
- **Using the AWS Management Console**: This approach is based on creating roles through the AWS web-based interface.
- **Using Terraform & AWS Management Console**: This hybrid approach is based on using the [terraform-aws-platform](https://github.com/KubeRocketCI/terraform-aws-platform) repository to create the required IAM roles in Account A, while using the AWS Management Console to create the roles in Account B.
### Using AWS Management Console
To create the required IAM roles in Account A using the AWS Management Console, follow the steps below:
1. Log in to the AWS Management Console for Account A.
2. Navigate to the **IAM** service and select **Roles**.
3. Create the `AWSIRSA_{cluster_name}_CDPipelineOperator` IAM role with the following settings:
Trust Policy
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks..amazonaws.com/id/:sub": [
"system:serviceaccount:krci:edp-cd-pipeline-operator"
],
"oidc.eks..amazonaws.com/id/:aud": "sts.amazonaws.com"
}
}
}
]
}
```
Permissions Policy
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": "arn:aws:iam:::role/AWSIRSA_{cluster_name}_CDPipelineAgent"
}
]
}
```
4. Create the `AWSIRSA_{cluster_name}_ArgoCDMaster` IAM role with the following settings:
Trust Policy
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"oidc.eks..amazonaws.com/id/:sub": [
"system:serviceaccount:argocd:argocd-application-controller",
"system:serviceaccount:argocd:argocd-applicationset-controller",
"system:serviceaccount:argocd:argocd-server"
],
"oidc.eks..amazonaws.com/id/:aud": "sts.amazonaws.com"
}
}
}
]
}
```
Permissions Policy
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": [
"arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDAgentAccess"
]
}
]
}
```
To create the required IAM roles in Account B using the AWS Management Console, follow the steps below:
1. Log in to the AWS Management Console for Account B.
2. Navigate to the **IAM** service and select **Roles**.
3. Create the `AWSIRSA_{cluster_name}_CDPipelineAgent` IAM role with the following settings:
Trust Policy
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam:::role/AWSIRSA_{cluster_name}_CDPipelineOperator"
},
"Action": "sts:AssumeRole"
}
]
}
```
4. Create the `AWSIRSA_{cluster_name}_ArgoCDAgentAccess` IAM role with the following settings:
Trust Policy
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"
},
"Action": "sts:AssumeRole"
}
]
}
```
### Using Terraform and AWS Management Console
In case of using the [terraform-aws-platform](https://github.com/KubeRocketCI/terraform-aws-platform) repository for creating and managing AWS EKS clusters, the required IAM roles in Account A can be created using Terraform, while the roles in Account B can be created using the AWS Management Console.
To create the required IAM roles in Account A using Terraform, follow the steps below:
1. Clone the forked [terraform-aws-platform](https://github.com/KubeRocketCI/terraform-aws-platform) repository.
2. Navigate to the `eks` directory.
3. Update the `terraform.tfvars` configuration file by specifying the following variables:
```hcl title="terraform.tfvars"
create_cd_pipeline_operator_irsa = true
create_argocd_irsa = true
cd_pipeline_operator_agent_role_arn = "arn:aws:iam:::role/AWSIRSA__CDPipelineAgent"
argocd_agent_role_arn = "arn:aws:iam:::role/AWSIRSA__ArgoCDAgentAccess"
```
4. Run the following commands to create the IAM roles:
:::note
It is highly recommended to run the `terraform plan` command before applying the changes to check the resources that will be created or modified.
:::
```bash
terraform init
terraform apply -var-file=./template.tfvars
```
To create the required IAM roles in Account B using the AWS Management Console, follow the steps below:
1. Log in to the AWS Management Console for Account B.
2. Navigate to the **IAM** service and select **Roles**.
3. Create the `AWSIRSA_{cluster_name}_CDPipelineAgent` IAM role with the following settings:
Trust Policy
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam:::role/AWSIRSA_{cluster_name}_CDPipelineOperator"
},
"Action": "sts:AssumeRole"
}
]
}
```
4. Create the `AWSIRSA_{cluster_name}_ArgoCDAgentAccess` IAM role with the following settings:
Trust Policy
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"
},
"Action": "sts:AssumeRole"
}
]
}
```
## Annotate Service Accounts
To enable the cross-account access for the cd-pipeline-operator and Argo CD, it is necessary to annotate the Kubernetes service accounts in the AWS Account A with the corresponding IAM role ARNs. This allows the service accounts to assume the roles and access resources in the target AWS Account B.
### CD Pipeline Operator Service Account
On the AWS Account A, where the KubeRocketCI is deployed, annotate the `edp-cd-pipeline-operator` service account with the `AWSIRSA_{cluster_name}_CDPipelineOperator` IAM role ARN.
There are several ways to annotate the service account:
Update the `cd-pipeline-operator` configuration in [edp-install](https://github.com/epam/edp-install/blob/master/deploy-templates/values.yaml) repository to automatically add annotations to service account:
```yaml title="deploy-templates/values.yaml"
cd-pipeline-operator:
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam:::role/AWSIRSA_{cluster_name}_CDPipelineOperator"
```
```bash title="ServiceAccount: edp-cd-pipeline-operator"
kubectl patch serviceaccount edp-cd-pipeline-operator -n krci \
-p '{"metadata": {"annotations": {"eks.amazonaws.com/role-arn": "arn:aws:iam:::role/AWSIRSA_{cluster_name}_CDPipelineOperator"}}}'
```
After applying annotations to service accounts, it is necessary to restart the corresponding deployments to ensure new pods are created with the updated IAM roles configuration. Use the following command:
```bash
kubectl rollout restart deployment cd-pipeline-operator -n krci
```
```yaml title="ServiceAccount: edp-cd-pipeline-operator"
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam:::role/AWSIRSA_{cluster_name}_CDPipelineOperator"
name: edp-cd-pipeline-operator
namespace: krci
```
After applying annotations to service accounts, it is necessary to restart the corresponding deployments to ensure new pods are created with the updated IAM roles configuration. Use the following command:
```bash
kubectl rollout restart deployment cd-pipeline-operator -n krci
```
### Argo CD Service Accounts
On the AWS Account A, where the Argo CD is deployed, annotate the `argocd-application-controller`, `argocd-applicationset-controller`, and `argocd-server` service accounts with the `AWSIRSA_{cluster_name}_ArgoCDMaster` IAM role ARN.
There are several ways to annotate the service accounts:
Update the Argo CD configuration in [Add-Ons](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/argo-cd/values.yaml) repository to automatically add annotations to service accounts:
```yaml title="clusters/core/addons/argo-cd/values.yaml"
argo-cd:
controller:
serviceAccount:
# -- Annotations applied to created service account
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"
server:
serviceAccount:
# -- Annotations applied to created service account
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"
applicationSet:
serviceAccount:
# -- Annotations applied to created service account
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"
```
```bash title="ServiceAccount: argocd-application-controller"
kubectl patch serviceaccount argocd-application-controller -n argocd \
-p '{"metadata": {"annotations": {"eks.amazonaws.com/role-arn": "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"}}}'
```
```bash title="ServiceAccount: argocd-applicationset-controller"
kubectl patch serviceaccount argocd-applicationset-controller -n argocd \
-p '{"metadata": {"annotations": {"eks.amazonaws.com/role-arn": "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"}}}'
```
```bash title="ServiceAccount: argocd-server"
kubectl patch serviceaccount argocd-server -n argocd \
-p '{"metadata": {"annotations": {"eks.amazonaws.com/role-arn": "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"}}}'
```
After applying annotations to service accounts, it is necessary to restart the corresponding workloads to ensure new pods are created with the updated IAM roles configuration. To do this, use the following commands:
```bash
kubectl delete pod -l app.kubernetes.io/name=argocd-application-controller -n argocd
kubectl delete pod -l app.kubernetes.io/name=argocd-applicationset-controller -n argocd
kubectl delete pod -l app.kubernetes.io/name=argocd-server -n argocd
```
```yaml title="ServiceAccount: argocd service accounts"
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"
name: argocd-application-controller
namespace: argocd
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"
name: argocd-applicationset-controller
namespace: argocd
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDMaster"
name: argocd-server
namespace: argocd
```
After applying annotations to service accounts, it is necessary to restart the corresponding workloads to ensure new pods are created with the updated IAM roles configuration. To do this, use the following commands:
```bash
kubectl delete pod -l app.kubernetes.io/name=argocd-application-controller -n argocd
kubectl delete pod -l app.kubernetes.io/name=argocd-applicationset-controller -n argocd
kubectl delete pod -l app.kubernetes.io/name=argocd-server -n argocd
```
## Update Argo CD AppProject
:::note
API server endpoint can be found in the EKS cluster details in the AWS Management Console.
:::
To allow Argo CD to deploy applications in the target cluster in Account B, it is necessary to update the **AppProject** configuration to include the target cluster as a destination.
```yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: krci
namespace: argocd
spec:
destinations:
- namespace: krci-*
server: https://.gr7..eks.amazonaws.com
```
## Configure IAM Roles Access to EKS Cluster
To allow the IAM roles created in Account B to access the EKS cluster, it is necessary to configure the access permissions for the roles in the cluster. This can be done by creating the [Access Entry](https://docs.aws.amazon.com/eks/latest/userguide/eks-access-entries.html) objects for the `AWSIRSA_{cluster_name}_CDPipelineAgent` and `AWSIRSA_{cluster_name}_ArgoCDAgentAccess` IAM roles.
To configure the access permissions for the IAM roles for the EKS cluster in Account B, follow the steps below:
### CD Pipeline Operator Access Entry
To create the Access Entry for the `AWSIRSA_{cluster_name}_CDPipelineAgent` IAM role, follow the steps below:
1. Log in to the AWS Management Console for Account B.
2. Navigate to the **EKS** service and select the target cluster.
3. In the **Access** tab, click on **Create access entry**.

4. On the **Configure IAM access entry** page, specify the following settings:
- **IAM principal ARN**: `arn:aws:iam:::role/AWSIRSA_{cluster_name}_CDPipelineAgent`
- **Type**: `Standard`
- **Kubernetes groups**: `cd-pipeline-operator` (required if Capsule Tenant is used)

Click **Next** to proceed.
5. On the **Add access policy** page, select the **AmazonEKSClusterAdminPolicy** policy and click **Add policy** button.
:::note
If Capsule Tenant is used, it is not necessary to add the `AmazonEKSClusterAdminPolicy` policy, as the access will be managed by Capsule.
:::

Click **Next** to proceed.
6. On the **Review and create** page, review the settings and click **Create access entry** to create the Access Entry.
### Argo CD Access Entry
To create the Access Entry for the `AWSIRSA_{cluster_name}_ArgoCDAgentAccess` IAM role, follow the steps below:
1. Log in to the AWS Management Console for Account B.
2. Navigate to the **EKS** service and select the target cluster.
3. In the **Access** tab, click on **Create access entry**.

4. On the **Configure IAM access entry** page, specify the following settings:
- **IAM principal ARN**: `arn:aws:iam:::role/AWSIRSA_{cluster_name}_ArgoCDAgentAccess`
- **Type**: `Standard`

Click **Next** to proceed.
5. On the **Add access policy** page, select the **AmazonEKSClusterAdminPolicy** policy and click **Add policy** button.

Click **Next** to proceed.
6. On the **Review and create** page, review the settings and click **Create access entry** to create the Access Entry.
## Configure Capsule Tenant (Optional)
If [Capsule](https://projectcapsule.dev/) is used for multi-tenancy in the EKS cluster in Account B, it is necessary to configure the Capsule Tenant for the `cd-pipeline-operator` group. This allows the `AWSIRSA_{cluster_name}_ArgoCDAgentAccess` IAM role to have the necessary permissions to manage resources within the Capsule Tenant.
To configure the Capsule Tenant for the `cd-pipeline-operator` group, align the following Capsule resources in the EKS cluster in Account B:
Capsule Configuration
```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: CapsuleConfiguration
metadata:
name: default
spec:
userGroups:
- capsule.clastix.io
- cd-pipeline-operator
```
Capsule Tenant
```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
name: krci
spec:
owners:
- clusterRoles:
- admin
- capsule-namespace-deleter
kind: Group
name: cd-pipeline-operator
```
## Next Steps
After completing the IRSA configuration on both AWS accounts, it is possible to deploy applications to the remote EKS cluster in Account B using KubeRocketCI. To proceed with the adding the remote cluster and deploying applications, refer to the [Add Cluster](../../user-guide/add-cluster.md) guide.
## Related Articles
* [Argo CD Integration](argocd-integration.md)
* [Add Cluster](../../user-guide/add-cluster.md)
* [Add Application](../../user-guide/add-application.md)
* [Add CD Pipeline](../../user-guide/add-cd-pipeline.md)
---
## Deploy Application In Remote Cluster via Token
# Deploy Application In Remote Cluster via Token
This section enables the creation of the necessary resources to configure access to a remote cluster using a static token.
## Using Kubernetes RBAC
To configure application deployment in remote cluster using Kubernetes RBAC, follow the steps below:
1. Create a ServiceAccount:
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: krci-deployer
namespace:
```
2. Bind the ServiceAccount to the cluster-admin role using ClusterRoleBinding:
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: krci-deployer-cluster-admin-binding
subjects:
- kind: ServiceAccount
name: krci-deployer
namespace:
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
```
3. Create a Secret with a token for the ServiceAccount:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: krci-deployer
namespace:
annotations:
kubernetes.io/service-account.name: krci-deployer
type: kubernetes.io/service-account-token
```
## Using Capsule
To configure application deployment in remote cluster using the Capsule tool, follow the steps below:
1. Create a ServiceAccount for deployment:
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: krci-deployer
namespace:
```
2. Create a Secret with a token for the ServiceAccount:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: krci-deployer
namespace:
annotations:
kubernetes.io/service-account.name: krci-deployer
type: kubernetes.io/service-account-token
```
3. Configure Capsule to recognize the ServiceAccount’s group:
```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: CapsuleConfiguration
metadata:
name: default
spec:
userGroups:
- capsule.clastix.io
- system:serviceaccounts:
```
4. Create a Tenant and assign ownership to the ServiceAccount through Capsule:
```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
name: krci-deployer
spec:
owners:
- clusterRoles:
- admin
- capsule-namespace-deleter
kind: ServiceAccount
name: system:serviceaccount::krci-deployer
```
## Get Kubernetes Token
To obtain the token generated by following this documentation, run the command below:
```bash
kubectl get secret -n krci-deployer -o jsonpath='{.data.token}' | base64 -d
```
## Next Steps
By completing all the steps in this documentation, you will obtain a token for integration with the Kubernetes cluster.
The next step is to configure the cluster integration with KubeRocketCI, as described in the documentation [Add Cluster](../../user-guide/add-cluster.md).
## Related Articles
* [Argo CD Integration](argocd-integration.md)
* [Add Cluster](../../user-guide/add-cluster.md)
* [Add Application](../../user-guide/add-application.md)
* [Add CD Pipeline](../../user-guide/add-cd-pipeline.md)
---
## Deploy RPM Packages
# Deploy RPM Packages
KubeRocketCI can use two types of deployment packages: Helm chart and RPM packages. While the Helm chart is the default deployment package in KubeRocketCI, using RPM packages is beneficial for specific Linux distributions, such as Oracle, Fedora, openSUSE, and others where these packages are supported and widespread. To learn more about RPM packages, refer to the official [documentation](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/7/html/rpm_packaging_guide/getting-started-with-rpm-packaging#introduction-to-rpm-packaging_getting-started-with-rpm-packaging).
In KubeRocketCI, RPM support allows to collect applications, store them as Nexus artifacts, and deploy them using the [Ansible](https://docs.ansible.com/ansible/latest/index.html) tool. KubeRocketCI is support two approach to work with RPM packages:
- **Default approach**: This approach involves configuring deployments using a GitOps repository and Kubernetes secrets.
- **AWX approach**: This approach involves deploying applications using the [AWX](https://ansible.readthedocs.io/projects/awx/en/latest/) tool.
### Features of Each Approach
#### Built-in Pipeline
- **Full GitOps Configuration**: All resources, including roles, inventories, hosts, tasks, and instance keys, are fully managed via GitOps.
- **Quick Start**: Enables a fast setup process without the need for third-party utilities.
- **Scalable**: Easily scales to accommodate an increasing number of tasks.
- **Customizable Task Execution**: Offers flexible configuration of task execution sequences.
- **No UI**: Operates entirely without a graphical user interface, relying on code-based configurations.
#### AWX Operator
- **User-Friendly Interface**: Features a convenient UI for managing configurations and tasks.
- **Partial Code-Based Configurations**: Retrieves some configurations (such as Ansible tasks) directly from the repository.
- **UI-Based Configuration**: All configurations are performed within the graphical user interface.
## Default Approach
The first method to delivery RPM packages is using KubeRocketCI RPM deploy pipeline.
### Integration Flow
Default approach involves the following steps:
```mermaid
graph LR;
A(Onboard GitOps repository) --> B(Create secret for GitOps repository) --> C(Create secret for Ansible host's) --> D(Create application) --> E(Select deploy pipeline)
```
Here is a breakdown of the scheme above:
1. **Onboard GitOps repository**: GitOps repository is used to store pre-deploy information (such as dependencies) and Ansible configuration.
2. **Create secret for GitOps repository**: A secret providing access to the GitOps repository.
3. **Create secret for Ansible host's**: This is a secret used by Ansible to manage the instances where the application will be deployed.
4. **Create application**: [Add application](../../user-guide/add-application.md) to KubeRocketCI as an RPM package.
5. **Select deploy pipeline**: Choose a specific deploy pipeline when creating/editing an environment to deploy RPM packages.
By completing these steps, will be able to add, build, and deploy RPM applications.
To set up RPM integration, follow the steps below:
1. Open the KubeRocketCI portal. Navigate to **Configuration** -> **Deployment** -> **GitOps**.
2. Specify the GitOps repository in the `username/repository_name` format.
3. Create and apply the secret for the GitOps repository by running the command below. Specify SSH key path, Git account, and repository name:
```bash
kubectl apply -f - <
data:
id_rsa: $(cat /path/to/repo_id_rsa | base64 | tr -d '\n')
url: $(echo -n "git@github.com:edp-robot/ansible-gitops.git" | base64 | tr -d '\n')
type: Opaque
EOF
```
4. Create and apply the secret for the hosts by running the command below. Don't forget to specify SSH key path:
```bash
kubectl apply -f - <
data:
id_rsa: $(cat /path/to/instance_id_rsa | base64 | tr -d '\n')
type: Opaque
EOF
```
5. When [creating codebases](../../user-guide/add-application.md), in the **Deployment option** field, select the **rpm-package** option:

6. When [creating](../../user-guide/manage-environments.md#add-a-new-environment) or [editing](../../user-guide/manage-environments.md#edit-environment) environments, in the **Deploy pipeline template** field, select **deploy-ansible**:
:::note
The **pre-deploy.yml** file will take affect only if the **Values override** option is enabled when deploying application.
:::

### GitOps Repository Structure
Below is a structure of a GitOps repository designed for deploying RPM packages:
View: repository structure
```bash
nexus.repo
inventory.ini
pre-deploy.yml
├── web
│ ├── dev
│ │ ├── nano
│ │ │ ├── 01_playbook.yml
│ │ │ └── 02_playbook.yml
│ │ └── atop
│ │ ├── 01_playbook.yml
│ │ └── 02_playbook.yml
│ ├── qa
│ │ ├── nano
│ │ │ ├── 01_playbook.yml
│ │ │ └── 02_playbook.yml
│ │ └── atop
│ │ ├── 01_playbook.yml
│ │ └── 02_playbook.yml
│ └── prod
│ ├── nano
│ │ ├── 01_playbook.yml
│ │ └── 02_playbook.yml
│ └── atop
│ ├── 01_playbook.yml
│ └── 02_playbook.yml
└── db
├── dev
│ ├── nano
│ │ ├── 01_playbook.yml
│ │ └── 02_playbook.yml
│ └── atop
│ ├── 01_playbook.yml
│ ├── 02_playbook.yml
│ └── 03_playbook.yml
├── qa
│ ├── nano
│ │ ├── 01_playbook.yml
│ │ ├── 02_playbook.yml
│ └── atop
│ ├── 01_playbook.yml
│ ├── 02_playbook.yml
│ └── 03_playbook.yml
└── prod
├── mysql
│ ├── 01_playbook.yml
│ └── 02_playbook.yml
└── cc
├── 01_playbook.yml
├── 02_playbook.yml
└── 03_playbook.yml
```
The main configuration files description:
- **nexus.repo**: Contains the configuration for connecting to Nexus, to pull artifacts to the instance.
- **inventory.ini**: Contains groups with instances, user credentials, and additional settings for connecting to the instances.
- **pre-deploy.yml**: Contains general playbooks that contain a set of tasks that must be done before starting work, such as copying and connecting Nexus config, installing additional packages depending on the group.
The rest of the files are example of deployment configurations. The KubeRocketCI deploy pipeline uses naming pattern to comparisons deployment flows/environment with file structure in GitOps repository.
```bash
///01_.yml
```
For example, the **web/qa/nano/01_copy-file.yml** file related to:
- Application: **nano**
- Deployment Flow: **web**
- Environment: **qa**
The file name must begin with its serial number (e.g., 01, 02, 03, ...), followed by an underscore.
## AWX Approach
The second approach to manage RPM packages is AWX-based. It features user interface and considered more simple.
### AWX Integration Flow
Default approach involves the following steps:
```mermaid
graph LR;
A(Onboard Ansible Git repository) --> B(Install AWX) --> C(Configure AWX)--> D(Create application) --> E(Select deploy pipeline)
```
Here is a breakdown of the scheme above:
1. **Onboard Ansible Git repository**: Create an Ansible Git repository that contains playbooks that will be used in deploy pipelines.
2. **Install AWX**: Set Up AWX application. We recommend using [cluster add-ons](../add-ons-overview.md) to install it.
3. **Configure AWX**: Once AWX tool is installed, open its UI to create AWX Project, Inventory, Templates, etc.
4. **Create application**: [Add application](../../user-guide/add-application.md) to KubeRocketCI as an RPM package.
5. **Select deploy pipeline**: Choose a specific deploy pipeline when creating/editing an environment to deploy RPM packages.
### AWX Integration
AWX Integration implies creating a Git repository, installing AWX and configuring it via UI.
### AWX Integration Prerequisites
Ensure that External Secrets Operator is [installed](../secrets-management/install-external-secrets-operator.md) and [configured](../secrets-management/external-secrets-operator-integration.md) properly.
### AWX Integration Procedure
To set up RPM integration using AWX tool, follow the steps below. Completing these steps enables the addition, building, and deployment of RPM applications:
1. Onboard Ansible Git repository where will store Ansible configuration files. Below is a structure of an Ansible Git repository designed for deploying RPM packages:
View: repository structure
```bash
package-install.yaml
└── roles
├── pre-deploy
│ ├── tasks
│ │ └── role.yaml
│ ├── files
│ │ └── nexus.repo
├── package-install
│ └── tasks
│ └── role.yaml
└── test-app-dev-web
└── tasks
└── role.yaml
```
Here is a breakdown of the scheme above:
- **package-install.yaml**: This is the main file that refers to playbooks located in the **roles** directory.
- **roles**: This directory contains all the Ansible roles that will be executed in deploy pipeline.
- **pre-deploy**: This is the first role the **package-install.yaml** file refers to. It connects to Nexus storage to interact with the application. Need to specify the required parameters in the **\/roles/pre-deploy/files/nexus.repo** file.
- **package-install**: This role contains the playbooks that install all the dependencies to AWS EC2 instances.
- **test-app-dev-web**: This role contains the application playbooks, named according to the **\-\-\** convention. It will be executed only if the **Values override** parameter is set to **true** in the Deployment Flow during the component deployment process.
2. Install AWX via [cluster add-ons](https://github.com/epam/edp-cluster-add-ons):
a. Create private repository based on the [cluster add-ons](https://github.com/epam/edp-cluster-add-ons) fork.
b. In the AWX Operator **[values.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/awx-operator/values.yaml)** file, specify hostname, secretName. OIDC mechanism is optional.
c. In the Argo CD application **[values.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/apps/values.yaml)** file, enable the AWX operator:
```bash
awx-operator:
createNamespace: true
enable: true
```
d. Synchronize state in Argo CD. Refer to the [README.md](https://github.com/epam/edp-cluster-add-ons/blob/main/README.md) file for more details.
3. Configure AWX via UI:
a. Once AWX operator is deployed, navigate to its UI using the hostname specified earlier:

b. (Optional) Configure OIDC. Navigate to **Settings** -> **Generic OIDC settings** and specify the required fields:
- **OIDC Key**: Enter **awx**
- **OIDC Secret**: This is the client secret data
- **URL**: Specify the Keycloak realm URL.

c. Navigate to **Resources** -> **Credentials** and create two credentials:
**For Git repository**: These credentials of the **Source Control** type must contain the SSH key with access to the Ansible Git repo:

**For AWS instances**: These credentials with access to the **Hosts** must contain the SSH key:

d. Navigate to **Resources** -> **Project** and create a new project. The `Source Control URL` specifies the repository containing the [Ansible project](#awx-integration-flow).

e. Navigate to **Resources** -> **Inventories** and create an inventory using the **Add inventory** option:

f. Navigate to **Resources** -> **Hosts** and add hosts' IP addresses:

g. Navigate to **Resources** -> **Templates**. Create job template called **package-install** as follows:
:::note
Don't forget to select the **Prompt on launch** checkbox for **inventory**, **limit**, and **variables** fields.
:::

4. Create application with the **rpm-package** deployment option. Refer to the [Add Application](../../user-guide/add-application.md) page for more details:

5. When [creating environments](../../user-guide/manage-environments.md#add-a-new-environment), in the **Deploy pipeline template** field, select **deploy-ansible-awx**:

6. (Optional) When deploying application, enable the **Values override** option to apply configuration from the Ansible Git repository to be executed specifically for this component:

## Related Articles
* [Customize Deploy Pipeline](../../operator-guide/cd/customize-deploy-pipeline.md)
* [Add Deployment Flow](../../user-guide/add-cd-pipeline.md)
* [Manage Deployment Flows](../../user-guide/manage-environments.md)
* [Add Application](../../user-guide/add-application.md)
---
## CI Pipeline for Terraform
# CI Pipeline for Terraform
KubeRocketCI ensures the implemented Terraform support by adding a separate component type called **Infrastructure**. The [Infrastructure](../../user-guide/components.md#types) codebase type allows to work with Terraform code that is processed by means of stages in the **Code-Review** and **Build** pipelines.
## Pipeline Stages for Terraform
Under the hood, Infrastructure codebase type, namely Terraform, looks quite similar to other codebase types. The distinguishing characteristic of the `Infrastructure` codebase type is that there is a stage called **terraform-check** in both of **Code Review** and **Build** pipelines. This stage runs the pre-commit activities which in their turn run the following commands and tools:
1. [Terraform fmt](https://developer.hashicorp.com/terraform/cli/commands/fmt) - the first step of the stage is basically the `terraform fmt` command. The `terraform fmt` command automatically updates the formatting of Terraform configuration files to follow the standard conventions and make the code more readable and consistent.
2. [Lock provider versions](https://developer.hashicorp.com/terraform/tutorials/configuration-language/provider-versioning) - locks the versions of the Terraform providers used in the project. This ensures that the project uses specific versions of the providers and prevents unexpected changes from impacting the infrastructure due to newer provider versions.
3. [Terraform validate](https://developer.hashicorp.com/terraform/cli/commands/validate) - checks the syntax and validity of the Terraform configuration files. It scans the configuration files for all possible issues.
4. [Terraform docs](https://github.com/terraform-docs/terraform-docs) - generates human-readable documentation for the Terraform project.
5. [Tflint](https://github.com/terraform-linters/tflint) - additional validation step using the `tflint` linter to provide more in-depth checks in addition to what the `terraform validate` command does.
6. [Checkov](https://github.com/bridgecrewio/checkov) - runs the `checkov` command against the Terraform codebase to identify any security misconfigurations or compliance issues.
7. [Tfsec](https://github.com/aquasecurity/tfsec) - another security-focused validation step using the `tfsec` command. Tfsec is a security scanner for Terraform templates that detects potential security issues and insecure configurations in the Terraform code.
:::note
The commands and their attributes are displayed in the [**.pre-commit-config.yaml**](https://github.com/epmd-edp/hcl-terraform-terraform/blob/master/.pre-commit-config.yaml) file.
:::
To learn more about how to operate with **Infrastructure** codebase type, read the [Add Infrastructure](../../user-guide/add-infrastructure.md) and [Manage Infrastructures](../../user-guide/infrastructure.md) pages.
## Related Articles
* [User Guide Overview](../../user-guide/index.md)
* [Add Infrastructure](../../user-guide/add-infrastructure.md)
* [Manage Infrastructures](../../user-guide/infrastructure.md)
---
## Microsoft Teams Notification
# Microsoft Teams Notification
This section describes how to set up and add notification status to Tekton pipelines by sending pipeline status to the Microsoft Teams channel.
## Create Incoming WebHook
To create a link to Incoming Webhook for the Microsoft Teams channel, follow the steps below:
1. Open the channel which will be receiving notifications and click the `•••` button from the upper-right corner. Select **Connectors** in the dropdown menu:

2. In the search field, type **Incoming Webhook** and click **Configure**:

3. Provide a name and upload an image for the webhook if necessary. Click **Create**:

4. Copy and save the unique `WebHookURL` presented in the dialog. Click `Done`:

5. Create a secret with the `` within the krci namespace.
```yaml
kubectl -n krci create secret generic microsoft-teams-webhook-url-secret \
--from-literal=url=
```
6. Add the notification task to the pipeline and add the code below in `final-block` in the pipeline and save:
```yaml
{{ include "send-to-microsoft-teams-build" . | nindent 4 }}
```
## Customize Notification Message
To make notification message informative, relevant text should be added to the message. Here are the steps to implement it:
1. Create a new pipeline with a unique name or modify your custom pipeline created before.
2. Add the task below in the `finally` block with a unique name. Edit the `params.message` value if necessary:
:::note Task send-to-microsoft-teams
```yaml
- name: microsoft-teams-pipeline-status-notification-failed
params:
- name: webhook-url-secret
value: microsoft-teams-webhook-url-secret
- name: webhook-url-secret-key
value: url
- name: message
value: >-
Build Failed project: $(params.CODEBASE_NAME) branch: $(params.git-source-revision) pipeline: $(context.pipelineRun.name) commit message: $(params.COMMIT_MESSAGE)
taskRef:
kind: Task
name: send-to-microsoft-teams
when:
- input: $(tasks.status)
operator: in
values:
- Failed
- PipelineRunTimeout
```
:::
After customization, the following message is supposed to appear in the channel when failing pipelines:

## Related Articles
* [Install KubeRocketCI](../install-kuberocketci.md)
* [Install Tekton](../install-tekton.md)
---
## Tekton Long-Term Log Storage
# Tekton Long-Term Log Storage
Tekton Results aims to help users logically group CI/CD workload history and separate out long term result storage away from the Pipeline controller. This allows you to:
- Provide custom Results metadata about your CI/CD workflows not available in the Tekton TaskRun/PipelineRun CRDs (for example: post-run actions).
- Group related workloads together (e.g. bundle related TaskRuns and PipelineRuns into a single unit).
- Make long-term result history independent of the Pipeline CRD controller, letting you free up etcd resources for Run execution.
- Store logs produced by the TaskRuns/PipelineRuns so that completed Runs can be cleaned to save resources.
## Long-Term Log Access Workflow
The following diagram illustrates the workflow for accessing long-term logs for pipelines in the KubeRocketCI Portal:
```mermaid
sequenceDiagram
actor U as User
participant KR as KubeRocketCI Portal
participant PC as Pipeline Controller
participant RW as Result Watcher
participant RA as Result API
U->>KR: Trigger or create a PipelineRun/TaskRun
KR->>PC: Start pipeline execution
RW-->>PC: Watch PipelineRun/TaskRun
Note over PC,RW: Wait for PipelineRun/TaskRun Completion
RW->>RA: Update results database
U->>KR: View pipeline logs
KR-->>RA: Get long-term logs
KR->>U: Return long-term logs
```
## Install Tekton Results
Tekton Results is deployed as part of the Tekton Pipelines installation. For installing Tekton Pipelines, we recommend using the [add-ons approach](https://github.com/epam/edp-cluster-add-ons/blob/4456631feb6510ff875b5b839534968c3846da7a/clusters/core/apps/values.yaml#L286C1-L289C30). Here's an example of how to configure values.yaml before installation:
```yaml
tekton:
createNamespace: true
enable: true
namespace: tekton-pipelines
```
## Configuration
:::note
We use Postgres operator to connect to Tekton results, but you can use any other external databases supported. Please align configuration accordingly to Tekton result [documentation](https://github.com/tektoncd/results/blob/v0.20.0/docs/external-database.md).
:::
To configure long-term log storage for pipelines in the KubeRocketCI Portal, follow the steps below:
1. Storage sizes in the [results-pg.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/tekton/results-pg.yaml) file define the allocated volumes for the Tekton Results PostgreSQL cluster:
- **Database instance storage**
- Path: `spec.instances.dataVolumeClaimSpec.resources.requests.storage`
- Default: `2Gi`
- Description: Specifies the size of the main PostgreSQL data volume.
- **Backup repository storage**
- Path: `spec.backups.pgbackrest.repos.volume.volumeClaimSpec.resources.requests.storage`
- Default: `2Gi`
- Description: Specifies the size of the pgBackRest backup repository volume.
2. Storage and retention settings in the [results.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/tekton/results.yaml) file define how Tekton Results result records are retained in the database and how related storage is configured:
- **Log storage size**
- Path: `PersistentVolumeClaim.spec.resources.requests.storage`
- Default: `5Gi`
- Description: Specifies the allocated disk size for storing pipeline logs.
- **Retention period**
- Path: `ConfigMap.data.defaultRetention` in `tekton-results-config-results-retention-policy`
- Default: `"30"` days
- Description: Defines how long log files are retained before being automatically removed.
- **Cleanup schedule**
- Path: `ConfigMap.data.runAt` in `tekton-results-config-results-retention-policy`
- Default: `"0 18 * * *0*"`
- Description: Specifies the cron expression that determines when automated log cleanup runs (daily at 6:00 PM UTC).
:::warning
The retention policy agent removes only database records from PostgreSQL. It does not delete associated log files stored on persistent volumes, S3, or GCS backends. As a result, log data may remain on disk and consume storage even after the corresponding records are expired.
:::
3. To remove physical log files from PVCs (not just database records), use the settings in the [results-clean-old-logs-cronjob.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/tekton/results-clean-old-logs-cronjob.yaml) file:
- **Cleanup schedule**
- Path: `spec.schedule`
- Default: `"0 18 * * *"`
- Description: Specifies the cron expression that determines when the CronJob runs (daily at 6:00 PM UTC).
- **Physical log retention (days)**
- Path: `spec.jobTemplate.spec.template.spec.containers.command` (the `-mtime +N` value in the `find` command)
- Default: `30` days
- Description: Physical log files in `/tekton-results/logs/` older than this many days are deleted from the PVC. The value is the number in `-mtime +N` (e.g. `+30` keeps files for 30 days).
:::note
In this example, the PGO (PostgreSQL Operator) is used for the Tekton Results database.
:::
## Database Performance Indexes
Tekton Results creates its schema through GORM auto-migration, which adds no indexes beyond the primary keys. As the
history grows, the queries behind the KubeRocketCI Portal pipeline run history fall back to sequential scans and the
history views become progressively slower to load. Create the indexes below to keep those queries on index scans.
:::note
`CREATE INDEX CONCURRENTLY` builds the index without locking the table for writes, so these statements are safe to run
against a live database. They cannot run inside a transaction block, which is why each statement is applied separately.
:::
1. Find the primary PostgreSQL pod:
```bash
PG_POD=$(kubectl get pods -n tekton-pipelines \
-l postgres-operator.crunchydata.com/cluster=results,postgres-operator.crunchydata.com/role=master \
-o jsonpath='{.items[0].metadata.name}')
```
2. Create the index covering list queries that filter by parent and type and sort by time:
```bash
kubectl exec -it -n tekton-pipelines "$PG_POD" -c database -- \
psql -U postgres -d results -c \
"CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_records_parent_type_created ON records (parent, type, created_time DESC);"
```
3. Create the index covering JSONB containment queries (`@>`) used for codebase and name filtering:
```bash
kubectl exec -it -n tekton-pipelines "$PG_POD" -c database -- \
psql -U postgres -d results -c \
"CREATE INDEX CONCURRENTLY IF NOT EXISTS results_annotations ON results USING GIN (annotations jsonb_path_ops);"
```
4. Create the index covering summary annotation filtering, which the DORA metrics views rely on:
```bash
kubectl exec -it -n tekton-pipelines "$PG_POD" -c database -- \
psql -U postgres -d results -c \
"CREATE INDEX CONCURRENTLY IF NOT EXISTS record_summary_annotations ON results USING GIN (recordsummary_annotations jsonb_path_ops);"
```
5. Verify that the indexes exist:
```bash
kubectl exec -it -n tekton-pipelines "$PG_POD" -c database -- \
psql -U postgres -d results -c "\di+"
```
6. Confirm that queries use them. The plan should report an `Index Scan` or `Bitmap Index Scan` on
`idx_records_parent_type_created` rather than a `Seq Scan`:
```bash
kubectl exec -it -n tekton-pipelines "$PG_POD" -c database -- \
psql -U postgres -d results -c "
EXPLAIN ANALYZE
SELECT * FROM records
WHERE parent LIKE 'tekton-pipelines/results/%'
AND type = 'tekton.dev/v1.PipelineRun'
ORDER BY created_time DESC
LIMIT 10;
"
```
To remove the indexes, drop them by name:
```bash
kubectl exec -it -n tekton-pipelines "$PG_POD" -c database -- \
psql -U postgres -d results -c "
DROP INDEX IF EXISTS idx_records_parent_type_created;
DROP INDEX IF EXISTS results_annotations;
DROP INDEX IF EXISTS record_summary_annotations;
"
```
## Related Articles
* [Add Application](../../user-guide/add-application.md)
* [Install Tekton](../install-tekton.md)
* [Install KubeRocketCI](../install-kuberocketci.md)
---
## Tekton Pipeline Monitoring with Prometheus and Grafana
# Tekton Pipeline Monitoring with Prometheus and Grafana
Tekton already exposes Prometheus metrics for pipeline runs, task runs, webhooks and its own
control plane. This page explains how to collect them and read them in Grafana using the
`tekton-monitoring` add-on, which ships the scrape configuration and the dashboards together so
neither has to be assembled by hand.
## Prerequisites
Ensure the following requirements are met before moving ahead:
- The [tekton](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/tekton)
add-on is deployed, so Tekton Pipelines, Triggers and Results are running.
- The **prometheus-operator** custom resource definitions are installed, since the add-on creates
`ServiceMonitor` resources.
- [kube-prometheus-stack](https://prometheus-community.github.io/helm-charts) is installed with
its Grafana sidecar enabled. The sidecar discovers dashboards in every namespace, so the
add-on can ship them from `tekton-pipelines`.
- The legacy integration is not in use. If Tekton metrics were configured before this add-on was
introduced, follow [Migrate From the Legacy Integration](#migrate-from-the-legacy-integration)
first.
## Set the Prometheus Release Label
Prometheus picks up `ServiceMonitor` resources by release label: `kube-prometheus-stack` sets
`serviceMonitorSelectorNilUsesHelmValues: true` by default, which limits Prometheus to monitors
carrying its own release label. Set this value first, so the monitors are collected as soon as
the add-on is deployed.
Run `helm list -n monitoring` to get the release name of your `kube-prometheus-stack`
installation, then set it in `clusters/core/addons/tekton-monitoring/values.yaml`:
```yaml values.yaml
serviceMonitor:
additionalLabels:
release: kube-prometheus
```
If your Prometheus sets `serviceMonitorSelectorNilUsesHelmValues: false`, the label is not
required and the value can be cleared.
## Enable the Add-On
The add-on is disabled by default. Enable it in `clusters/core/apps/values.yaml`:
```yaml values.yaml
tekton-monitoring:
createNamespace: false
enable: true
namespace: tekton-pipelines
```
Commit the change and let Argo CD synchronize the `tekton-monitoring` application. Because the
add-on deploys into the namespace owned by the `tekton` add-on, it never creates that namespace
itself.
Once the application is synchronized, the Tekton targets appear under **Status → Targets** in
Prometheus, and the six dashboards appear in Grafana under titles starting with `Tekton /`.
## What the Add-On Deploys
### Metrics Collection
Six `ServiceMonitor` resources point Prometheus at the endpoints Tekton already exposes:
| ServiceMonitor | Component | What it provides |
|:-|:-|:-|
| `tekton-pipelines-controller` | Pipelines controller | Pipeline and task run counts, durations, throttling, reconciler and workqueue health |
| `tekton-events-controller` | Events controller | CloudEvents emission |
| `tekton-triggers-controller` | Triggers controller | Reconciliation of `EventListener` and `Trigger` resources |
| `tekton-results-api` | Results API | gRPC server metrics |
| `tekton-results-watcher` | Results watcher | Archival and pruning of completed runs |
| `tekton-eventlisteners` | All EventListeners | Webhook volume, latency and triggered resources |
The EventListener monitor is deliberately cluster-wide: KubeRocketCI creates an `EventListener`
in each delivery namespace rather than in `tekton-pipelines`, and every one of them is labelled
by the EventListener controller, so a single monitor covers them all.
### Dashboards
Six dashboards are delivered as ConfigMaps and picked up by the Grafana sidecar:
| Dashboard | Answers |
|:-|:-|
| Pipeline Overview | How many pipelines ran, how many failed, and how long they took |
| Task Analytics | Which tasks are slowest and which fail most often |
| Queue and Scheduling | Whether runs are waiting on quota, node capacity or resolution |
| EventListener Traffic | Whether webhooks arrive and convert into pipeline runs |
| Platform Health | Whether the Tekton control plane itself is healthy |
| Resource Consumption | How much CPU and memory pipelines consume |
## Required Tekton Metrics Settings
Two panels depend on metric labels that Tekton omits by default. The `tekton` add-on already sets
both keys in its `config-observability` ConfigMap, so a standard installation needs no action.
Re-apply them if that manifest is re-vendored from an upstream Tekton release, or if Tekton was
installed from another source:
| Key | Value | Without it |
|:-|:-|:-|
| `metrics.count.enable-reason` | `true` | The `reason` label is absent, so **Timeouts** reads `0` permanently and **Failure reasons** collapses into a single unnamed slice |
| `metrics.running-pipelinerun.level` | `pipeline` | The running-pipelines gauge has no `pipeline` label, so **Running now** is empty once a pipeline filter is applied |
Both keys belong in the `data` block of the ConfigMap. The `_example` block lists the same keys
but is inert documentation, so values placed there have no effect.
## Reading the Dashboards
Two conventions are worth knowing before drawing conclusions from a panel:
- **Prefer p50 and p95 over the average.** A Tekton task that fails usually hangs until its
timeout instead of failing fast, so a handful of failed runs pull the mean far above what a
healthy run costs. A large gap between **Avg** and **p50** means the task hangs when it fails,
not that it is slow.
- **Counts cover completed runs.** A run is counted when it finishes, so a pipeline still in
flight appears under **Running now** rather than in the range totals.
## Migrate From the Legacy Integration
Earlier releases integrated Tekton metrics either by applying a single `ServiceMonitor` named
`tekton-overview` by hand and importing a community Grafana dashboard, or by setting
`edp-tekton.grafana.enabled` in the `edp-install` chart. Both approaches covered only the
pipelines controller and a single dashboard. The add-on replaces them.
:::warning
Do not run the add-on and the legacy integration at the same time. The `tekton-overview`
ServiceMonitor and the add-on's `tekton-pipelines-controller` ServiceMonitor select the **same**
Kubernetes Service, so Prometheus scrapes it twice and every panel that sums across targets
roughly doubles.
:::
To migrate:
1. Set `edp-tekton.grafana.enabled` to `false`, or remove the value, and apply the change.
2. Delete a hand-applied ServiceMonitor if one exists:
`kubectl delete servicemonitor tekton-overview -n tekton-pipelines`.
3. Remove any manually imported Tekton dashboard from Grafana to avoid duplicates.
4. Enable the add-on as described above.
## Troubleshooting
| Symptom | Cause |
|:-|:-|
| All panels empty | The `release` label does not match the `kube-prometheus-stack` release name |
| Targets missing in Prometheus | The prometheus-operator CRDs are absent, or the add-on has not synchronized |
| Dashboards missing in Grafana | The Grafana sidecar is disabled or not searching all namespaces |
| **Timeouts** always `0` | `metrics.count.enable-reason` is not enabled |
| **Running now** empty when filtering by pipeline | `metrics.running-pipelinerun.level` is not set to `pipeline` |
| Counts roughly doubled | The legacy integration is still enabled alongside the add-on |
## Related Articles
* [Install Tekton](../install-tekton.md)
* [Add-Ons Overview](../add-ons-overview.md)
* [Install KubeRocketCI](../install-kuberocketci.md)
---
## Tekton Overview
# Tekton Overview
KubeRocketCI provides Continuous Integration based on [Tekton](https://tekton.dev/).
Tekton is an open-source Kubernetes native framework for managing pipelines, allowing a user to compile, build and
test applications.
Tekton is an open-source Kubernetes native solution, designed for orchestrating complex pipelines that allows users to define `pipelines as code`. It enables users to compile, build, and test applications seamlessly.
The [edp-tekton](https://github.com/epam/edp-tekton) GitHub repository provides all Tekton implementation logic on the platform.
The Helm charts are used to deploy the resources inside the Kubernetes cluster.
Tekton logic is decoupled into separate components:

The diagram above describes the following:
- `Common-library` is the Helm chart of Library type which stores the common logic shareable across all Tekton pipelines.
This library contains Helm templates that generate common Tekton resources.
- `Pipelines-library` is the Helm chart of the Application type which stores the core logic for the KubeRocketCI pipelines.
Tekton CRs like Pipelines, Tasks, EventListeners, Triggers, TriggerTemplates, and other resources are delivered with
this chart.
- `EDP Interceptor` is the custom `Tekton Interceptor` which enriches the payload from the VCSs events with the KubeRocketCI data from the `Codebase` Custom Resource (CR) specification. These data are used to define the Pipeline logic.
- `Custom-pipelines` is the Helm chart of the Application type which implements custom logic running
specifically for internal platform development, for example, CI and Release.
It also demonstrates the customization flow on the platform.
Inspect the schema below that describes the logic behind the Tekton functionality on the platform:

The platform logic consists of the following:
1. The `EventListener` exposes a dedicated Pod that runs the sink logic and receives incoming events from the
VCSs (Gerrit, GitHub, GitLab) through the Ingress. It contains triggers with filtering and routing rules for
incoming requests.
2. Upon the Event Payload arrival, the `EventListener` runs triggers to process information or validate it via
different interceptors.
3. The `EDP Interceptor` extracts information from the `codebases.v2.edp.epam.com` CR and injects the received data
into top-level 'extensions' field of the Event Payload. The Interceptor consists of running Pod and Service.
4. The `Tekton Cel Interceptor` does simple transformations of the resulting data and prepares them for the Pipeline
parameters substitution.
5. The `TriggerTemplate` creates a PipelineRun instance with the required parameters extracted from the Event Payload
by Interceptors. These parameters are mandatory for Pipelines.
6. The `PipelineRun` has a mapping to the platform Tekton Pipelines using a template approach which reduces code duplication.
Each Pipeline is designed for a specific VCS (Gerrit, GitLab, GitHub), technology stack (such as Java or Python),
and type (code-review, build).
7. A `Pipeline` consists of separate Tekton Tasks. They are arranged in a specific order of execution
in the Pipeline.
8. Each `Task` is executed as a Pod on the Kubernetes cluster.
Also, Tasks can have a different number of steps that are executed as a Container in Pod.
9. The Kubernetes native approach allows the creation of PipelineRun either with the kubectl tool or
using the [KubeRocketCI portal](../../user-guide/application.md).
To learn more about Tekton Pipelines and their types in KubeRocketCI, you can read the [KubeRocketCI: Tekton Overview](../../user-guide/tekton-pipelines.md) page. The [Pipelines Overview](../../user-guide/pipelines.md) page describes how to operate with Tekton Pipelines in the KubeRocketCI portal. To create user-defined pipelines, refer to the following guides:
- [Create and Use Custom Tekton Pipelines](../../use-cases/custom-pipelines-flow.md)
- [Customize Deploy Pipeline](../cd/customize-deploy-pipeline.md)
- [Customize Environment Cleanup](../cd/customize-environment-deletion.md)
All of these guides have step-by-step video tutorials.
## Related Articles
* [Install Tekton](../install-tekton.md)
---
## Publish SonarQube Reports to Pull Requests
# Publish SonarQube Reports to Pull Requests
Pull request decoration makes SonarQube publish its **Quality Gate status** and **analysis summary** directly onto a merge request, so reviewers see new issues, security hotspots, coverage, and duplications without leaving the Git provider. This guide enables the feature in KubeRocketCI end to end, using a self-hosted **GitLab** instance as the baseline example. The same steps apply to GitHub, Bitbucket, and Azure DevOps — only the DevOps Platform type changes.
By the end, every review pipeline in KubeRocketCI adds a Quality Gate comment and a `SonarQube` commit status to the corresponding merge request.
## How SonarQube Pull Request Decoration Works
KubeRocketCI review pipelines already run SonarQube analysis in **pull request mode** (the scanner receives the `sonar.pullrequest.key`, `sonar.pullrequest.branch`, and `sonar.pullrequest.base` parameters automatically). To turn that analysis into a merge request comment, SonarQube needs three things:
1. A **DevOps Platform integration** that tells SonarQube how to reach the Git provider and post back (URL + access token).
2. A **project binding** that maps the SonarQube project to its Git repository.
3. A reachable **Server Base URL** so the links in the decoration resolve to your SonarQube instance.
### Does SonarQube Community Edition Support Pull Request Decoration?
Yes. SonarQube **Community** editions add branch and pull request analysis through the [sonarqube-community-branch-plugin](https://github.com/mc1arke/sonarqube-community-branch-plugin), which KubeRocketCI ships preinstalled. SonarQube Developer Edition and above provide the same capability natively, so no plugin is required there.
## Prerequisites
Before proceeding, ensure the following prerequisites are in place:
- SonarQube is integrated with KubeRocketCI. See [SonarQube Integration](sonarqube.md) for the base setup.
- A codebase hosted in GitLab with review and build pipelines already running.
- A GitLab **personal (or project/group) access token** with the `api` scope. SonarQube uses this token to post comments and commit statuses on merge requests.
- Administrator access to the SonarQube UI (or an admin token for the API).
## Trust the Git Provider Certificate
SonarQube posts decorations by calling the Git provider's API over HTTPS. If your GitLab (or other provider) serves a **self-signed certificate**, the SonarQube JVM must trust its CA — otherwise the integration fails on the TLS handshake with `Could not validate GitLab url`.
The SonarQube Helm chart exposes a `caCerts` option that imports a certificate into the JVM truststore and wires it into both the web and compute-engine processes (the compute engine runs the decoration):
```yaml title="values.yaml"
caCerts:
enabled: true
configMap:
name: gitlab-ca # ConfigMap holding the provider CA certificate
key: ca.crt
path: ca.crt
```
:::note
Skip this step when your Git provider uses a certificate signed by a public, already-trusted Certificate Authority.
:::
## Configure the DevOps Platform Integration
Create a global GitLab configuration in SonarQube. Use the UI for a one-time manual setup, or the Web API to automate it.
1. Open the SonarQube UI and navigate to **Administration** -> **Configuration** -> **DevOps Platform Integrations**. Select the **GitLab** tab and click **Create configuration**:

2. Fill in the fields and click **Save configuration**:
- **Configuration name** — a short identifier used when binding projects, for example `gitlab`.
- **GitLab API URL** — the `/api/v4` endpoint of your instance, for example `https://gitlab.example.com/api/v4`.
- **Personal Access Token** — the GitLab token with the `api` scope.
3. Once saved, the configuration reports **Quality Gate status reporting** and **Import repositories** as valid:

Create the global GitLab configuration with the [`alm_settings/create_gitlab`](https://next.sonarqube.com/sonarqube/web_api/api/alm_settings) endpoint. Authenticate with an admin token (note the trailing colon, which leaves the password empty):
```bash
curl -u ":" -X POST "https://sonarqube.example.com/api/alm_settings/create_gitlab" \
--data-urlencode "key=gitlab" \
--data-urlencode "url=https://gitlab.example.com/api/v4" \
--data-urlencode "personalAccessToken="
```
Verify the configuration can reach GitLab:
```bash
curl -u ":" "https://sonarqube.example.com/api/alm_settings/validate?key=gitlab"
```
An empty response with HTTP `204` confirms the connection. A `Could not validate GitLab url` error indicates a connectivity or TLS problem — see [Troubleshooting](#troubleshooting).
## Bind the SonarQube Project to Its Repository
Link each SonarQube project to the GitLab repository it should decorate. The project key matches the KubeRocketCI codebase name.
1. Open the project in SonarQube, click **Project Settings** (top-right), and select **DevOps Platform Integration** from the left menu of **General Settings**.
2. Choose the `gitlab` configuration created earlier, provide the repository's **GitLab project ID**, and save.
:::note
The GitLab project ID is shown on the repository's home page under the project name, and in GitLab under **Settings** -> **General**.
:::
Bind the project with the [`alm_settings/set_gitlab_binding`](https://next.sonarqube.com/sonarqube/web_api/api/alm_settings) endpoint. The `repository` value is the numeric GitLab project ID:
```bash
curl -u ":" -X POST "https://sonarqube.example.com/api/alm_settings/set_gitlab_binding" \
--data-urlencode "almSetting=gitlab" \
--data-urlencode "project=" \
--data-urlencode "repository=" \
--data-urlencode "monorepo=false"
```
## Set the Server Base URL
For the links inside a decoration to resolve back to SonarQube, set the server base URL to the address reachable from the Git provider and reviewers:
```bash
curl -u ":" -X POST "https://sonarqube.example.com/api/settings/set" \
--data-urlencode "key=sonar.core.serverBaseURL" \
--data-urlencode "value=https://sonarqube.example.com"
```
The same value can be set in the UI under **Administration** -> **Configuration** -> **General** -> **Server base URL**.
## Verify Pull Request Decoration End to End
With the integration in place, exercise the full flow on a real merge request:
1. In the GitLab repository, create a feature branch and open a **merge request** against the default branch.
2. KubeRocketCI triggers the **review pipeline**, which runs SonarQube analysis in pull request mode.
3. When the analysis completes, SonarQube posts a **Quality Gate** comment and a `SonarQube` commit status on the merge request:

The comment links to the full pull request analysis in SonarQube, and the commit status appears alongside the pipeline status, giving reviewers a Quality Gate signal before the merge request is merged.
## Troubleshooting
| Symptom | Cause | Resolution |
|---------|-------|------------|
| `Could not validate GitLab url. Got an unexpected answer.` | SonarQube cannot complete the TLS handshake with a self-signed Git provider, or the URL/token is wrong. | Trust the provider CA as described in [Trust the Git Provider Certificate](#trust-the-git-provider-certificate). Confirm the API URL ends with `/api/v4` and the token has the `api` scope. |
| Decoration links point to `localhost` or fail to open | `sonar.core.serverBaseURL` is unset. | Set the server base URL as shown above. |
| No comment appears on the merge request | The analysis ran in **branch mode**, not pull request mode (most common), or the project is not bound. | Confirm pull request mode as described below, and check the project binding references the correct GitLab project ID. |
### Confirm the Analysis Ran in Pull Request Mode
When both integrations are green but no comment appears, the scanner almost always submitted a **branch** analysis instead of a **pull request** analysis. Two quick checks:
- In SonarQube, open the project's branch/pull request selector. A pull request analysis is listed under **Pull Requests** with the merge request number. If you only see entries named after commit SHAs under **Branches**, the run was a branch analysis.
- In the generated `sonar-project.properties` (or the scanner log), a decorating run sets `sonar.pullrequest.key`, `sonar.pullrequest.branch`, and `sonar.pullrequest.base`, and **no** `sonar.branch.name`. Seeing `sonar.branch.name=` instead confirms the pull request parameters were not provided.
To fix, make the review (merge request) pipeline pass the three pull request parameters and **omit** the branch parameter — `sonar.branch.name` and `sonar.pullrequest.*` are mutually exclusive:
```properties
sonar.pullrequest.key=
sonar.pullrequest.branch=
sonar.pullrequest.base=
```
:::note
In KubeRocketCI Tekton pipelines these map to the `sonarqube-general` task inputs `key-id`, `source-branch`, and `target-branch`. If the task is given only `branch`, it runs a branch analysis and no decoration is posted.
:::
## Related Articles
* [SonarQube Integration](sonarqube.md)
* [Manage Project Visibility](sonarqube-visibility.md)
* [Sonarqube Project Properties for Application](../../user-guide/application-sonarqube-project-properties.md)
* [External Secrets Operator Integration](../secrets-management/external-secrets-operator-integration.md)
---
## Manage Project Visibility
# Manage Project Visibility
This manual offers detailed guidance on configuring permissions for SonarQube projects, ensuring that only authorized personnel can access and interact with the data on the SonarQube platform. It caters to both new and existing SonarQube projects, providing a clear pathway to refine visibility settings for enhanced security.
By leveraging the OpenID Connect mechanism for login, users are automatically assigned to the `sonar-users` group, granting them access to all projects by default. This document outlines methods to alter these default permissions, enhancing the platform's security and data confidentiality. It is structured into two main sections: one focusing on [restricting access to new projects](#restrict-access-for-new-projects), and the other on [reconfiguring access settings for existing projects](#configure-access-for-existing-projects).
## Restrict Access for New Projects
In its default configuration, SonarQube does not restrict access to newly created projects, making them accessible to all instance users. To modify this behavior and set new projects to private by default, follow these instructions:
1. Open the SonarQube UI in the browser.
2. Navigate to the `Administration` tab:

:::note
Ensure you have admin rights to see the `Administration` section.
:::
3. Click the `Projects` button and select `Management`:

4. On the project management page, click pencil icon at the top-right corner::

5. Select **Private** and click **Change Default Visibility**:

## Configure Access for Existing Projects
To make all the current projects private, follow the steps below:
1. In the **Projects** tab, enter the project you want to make private.
2. In the project page, click the **Project Settings** button and select **Permissions**:

3. In the project permissions page, select **Private**:

4. Repeat the procedure for all of the projects you want to make private.
## Related Articles
* [SonarQube Integration](sonarqube.md)
* [Nexus Sonatype Integration](../artifacts-management/nexus-sonatype.md)
* [Integrate SonarQube](../../quick-start/integrate-sonarcloud.md)
---
## SonarQube Integration
# SonarQube Integration
This documentation offers detailed guidance on seamlessly integrating SonarQube into KubeRocketCI.
It covers essential steps to ensure a robust connection between SonarQube's code quality and security
analysis capabilities with the platform's continuous delivery ecosystem,
facilitating enhanced code inspection and improvement practices within your development workflow.
## Prerequisites
Before proceeding, ensure the following prerequisites are in place:
- Kubectl version 1.34.0+ is installed. Please refer to the [Kubernetes official website](https://kubernetes.io/releases/download/) for details.
- [Helm](https://helm.sh) version 3.19.0+ is installed. Please refer to the [Helm page](https://github.com/helm/helm/releases) on GitHub for details.
## Installation
To install SonarQube in environment, it's recommended to use the resources provided in the [Cluster Add-Ons](https://github.com/epam/edp-cluster-add-ons) repository. This approach involves installing both the sonarqube and the [sonar-operator](https://github.com/epam/edp-sonar-operator). Leveraging the Cluster Add-Ons simplifies the deployment and management process, providing a streamlined method to integrate SonarQube into infrastructure.
1. Navigate to the forked cluster Add-Ons repository and align the [sonar values.yaml](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/sonar/values.yaml) and [sonar-operator values.yaml](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/sonar-operator/values.yaml) files. Follow the instructions to deploy sonarqube, ensuring it's correctly configured to serve as artifact repository.
2. Update the configuration to enable **sonar** and **sonar-operator** in [Add-Ons](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/apps/values.yaml) repository:
```yaml title="clusters/core/apps/values.yaml"
sonar:
createNamespace: true
enable: true
sonar-operator:
createNamespace: true
enable: true
```
3. Sync resources and wait till the all **sonar** and **sonar-operator** resources is created:

4. **Sign In** into **sonarqube** using the default credentials **Username**: `admin` and **Password**: `admin` and update the default password for better security for that click on profile icon in the upper right corner, click on **Security**, enter a new password and click **Update** button:

### Applying GitOps approach installation changes
To update SonarQube configurations:
1. Modify the relevant configuration files in the forked add-ons repository.
2. Commit and push the changes to the forker Git repository.
3. Synchronize the changes with ArgoCD.
## Configuration
With Add-ons approach add predefined [SonarQube plugins](https://github.com/epam/edp-cluster-add-ons/blob/build/0.1.0-SNAPSHOT.236/clusters/core/addons/sonar/values.yaml#L26) and [sonar-operator](https://github.com/epam/edp-cluster-add-ons/tree/build/0.1.0-SNAPSHOT.236/clusters/core/addons/sonar-operator/templates/sonar) create the necessary groups, users, permission templates, quality profiles, quality gates automatically by deploy preconfigured custom resources. Manage these configurations centrally through a GitOps-based workflow.
## Configuration SonarQube with sonar-operator
1. Create a Kubernetes Secret that the **sonar-operator** will use to connect to the **sonarqube** and create all resources:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: sonar-admin-password
namespace: sonar
type: Opaque
data:
user: YWRtaW4= # base64-encoded value of "admin"
password: cGFzcw== # base64-encoded value of "pass"
```
```json
"sonarqube":
{
"user": "XXXXXXX",
"password": "XXXXXXX"
}
```
2. Create a secret using `manifests` or with `External Secrets Operator` to enable the **sonar-operator** to connect to the **sonarqube** for provisioning:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: ci-sonar
namespace: sonar
type: Opaque
stringData:
password:
```
```json
"sonarqube-ci-user":
{
"password": "XXXXXXX"
}
```
## SonarQube configuration overview with sonar-operator
### Plugin Management
The SonarQube instance includes pre-installed plugins to meet common project needs. Additional plugins, if required, can be installed by updating the [SonarQube values.yaml](https://github.com/epam/edp-cluster-add-ons/blob/build/0.1.0-SNAPSHOT.236/clusters/core/addons/sonar/values.yaml#L26) file in the forked add-ons repository.
### Group Permissions
Access control in SonarQube is organized through predefined groups:
- **sonar-administrators:** System administrators with full access to manage the instance.
- **sonar-developers:** Developers who can view and edit project settings (managed by the Sonar Operator).
- **sonar-users:** Default group for all authenticated users with basic project viewing rights.
- **view-group:** Grants browsing access for users requiring read-only permissions.

### Permission Templates
Permissions in SonarQube are associated with projects through permission templates:
- **edp-default:** The default template applied to all projects, ensuring consistent group-level access management across the platform.
### Quality Gates
Quality Gates are used to ensure that code quality standards are met before further development or deployment proceeds:
- **KubeRocketCI way (default):** KuberocketCI quality gates are defined in the SonarQube instance, specifically tailored for the KubeRocketCI project.
- **Sonar way (built-in):** These are predefined quality gates available directly in SonarQube, not customized for any specific project but rather standardized for general use.

### Quality Profiles
Quality Profiles define the rules used during code analysis. The Sonar Operator manages quality profiles with the following default setup:
- **KubeRocketCI way (default):** A Java quality profile based on KubeRocketCI best practices, offering tailored rule sets.
## Configuration SonarQube ci-user without sonar-operator
To establish robust authentication and precise access control, generating a SonarQube token is essential. This token is a distinct identifier, enabling effortless integration between SonarQube and KubeRocketCI. To generate the SonarQube token, proceed with the following steps:
1. Open the SonarQube UI and navigate to **Administration** -> **Security** -> **User**. Create a new user or select an existing one. Click the `Options List` icon to create a token:

2. Type the `ci-user` username, define an expiration period, and click the `Generate` button to create the token:

3. Click the `Copy` button to copy the generated ``:

## Integrate SonarQube With KubeRocketCI
For provision secret using manifest, KubeRocketCI portal or with the externalSecrets operator:
Go to the **Portal** open **Configuration** -> **Code Quality** -> **SonarQube**. Update or click **+ Add integration** fill in the `URL` and `Token` fields and click the `Save` button:

```yaml
apiVersion: v1
kind: Secret
metadata:
name: ci-sonarqube
namespace: krci
labels:
app.edp.epam.com/secret-type: sonar
app.edp.epam.com/integration-secret: "true"
type: Opaque
stringData:
url: https://sonarqube.example.com
token:
```
```json
"ci-sonarqube":
{
"url": "https://sonarqube.example.com",
"token": "XXXXXXXXXXXX"
},
```
Go to the **Portal** open **Configuration** -> **Code Quality** -> **SonarQube** and see the `Managed by External Secret` message:

More details about External Secrets Operator integration can be found in the [External Secrets Operator Integration](https://epam.github.io/edp-install/operator-guide/code-quality/external-secrets-operator-integration/) page.
## Project Analysis Flow
1. SonarQube analysis is seamlessly integrated into KubeRocketCI pipelines, triggered during both review and build pipelines:
- **Review Pipeline:** Analyzes only the changes made in a pull request.
- **Build Pipeline:** Analyzes the main branch codebase to ensure overall project quality.
2. SonarQube projects are named based on the corresponding KubeRocketCI project names, making it easy to navigate analysis results in the SonarQube UI mode details how to configure repo [project-project.settings](../../user-guide/application-sonarqube-project-properties.md):

## Related Articles
* [Publish SonarQube Reports to Pull Requests](sonarqube-pr-decoration.md)
* [Sonarqube Project Properties for Application](../../user-guide/application-sonarqube-project-properties.md)
* [Install KubeRocketCI With Values File](../install-kuberocketci.md)
* [Install External Secrets Operator](../secrets-management/install-external-secrets-operator.md)
* [External Secrets Operator Integration](../secrets-management/external-secrets-operator-integration.md)
* [Cluster Add-Ons Overview](../add-ons-overview.md)
---
## Deploy AWS EKS Cluster
# Deploy AWS EKS Cluster
This instruction offers a comprehensive guide on deploying an Amazon Elastic Kubernetes Service (EKS) cluster, ensuring a scalable and secure Kubernetes environment on AWS. For those looking to optimize their EKS cluster configurations, it is highly recommended to consult the [AWS EKS Best Practices](https://aws.github.io/aws-eks-best-practices/) guide. This resource covers a wide range of topics crucial for the successful deployment and operation of your EKS clusters, including:
- **Security**: Best practices for securing your EKS clusters, including IAM roles, network policies, and secrets management.
- **Networking**: Guidance on setting up VPCs, subnets, and load balancers to ensure efficient and secure network traffic.
- **Monitoring and Logging**: Strategies for implementing comprehensive monitoring and logging solutions using AWS CloudWatch and other tools to maintain visibility into cluster performance and operational health.
- **Performance**: Tips for optimizing cluster performance through the proper selection of EC2 instances, efficient load balancing, and autoscaling configurations.
- **Cost Optimization**: Techniques for managing and reducing costs associated with running EKS clusters, including instance selection and resource allocation strategies.
By adhering to these best practices, developers and system administrators can ensure that their AWS EKS clusters are robust, secure, and cost-effective, facilitating a smooth and efficient CI/CD pipeline for software development.
## Prerequisites
:::note
Our approach to deploying the AWS EKS Cluster is based on the widely-used [terraform-aws-eks module](https://github.com/terraform-aws-modules/terraform-aws-eks) from the Terraform AWS Modules community. This module facilitates the creation of AWS Elastic Kubernetes Service (EKS) resources with best practices in mind. We encourage users to review the module's documentation to fully understand its capabilities and how it aligns with the requirements of your specific deployment scenario.
:::
Before the EKS cluster deployment and configuration, make sure to check the prerequisites. Install the required tools listed below:
- [Git](https://git-scm.com/book/en/v2)
- [Terraform](https://www.terraform.io/)
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)
- [tfenv](https://github.com/tfutils/tfenv)
To check the correct tools installation, run the following commands:
```bash
git --version
terraform version
aws --version
tfenv --version
```
:::note
Before initiating the deployment, it is crucial to consult the [AWS Service Limits](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html) documentation. Please review and adjust these limits as necessary to ensure your deployment proceeds smoothly without hitting service constraints.
:::
## Terraform Backend
This step covers the following topics:
- Create S3 bucket with policy to store terraform states
- Create DynamoDB to support state locking and consistency checking
To create the required resources, follow the steps below:
1. Fork and clone git repo with project [terraform-aws-platform](https://github.com/KubeRocketCI/terraform-aws-platform),
rename it in the correspondence with project name:
```bash
git clone https://github.com/KubeRocketCI/terraform-aws-platform
cd terraform-aws-platform/s3-backend
```
2. Fill in the input variables for Terraform run in the `s3-backend/template.tfvars` file, refer to the [s3-backend/example.tfvars](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/s3-backend/example.tfvars) as an example:
```tf title="s3-backend/template.tfvars"
region = "eu-central-1"
tags = {
"SysName" = "Terraform-Backend"
"SysOwner" = "owner@example.com"
"Environment" = "EKS-TEST-CLUSTER"
}
```
Find the detailed description of the variables in the [s3-backend/variables.tf](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/s3-backend/variables.tf) file.
3. Initialize the backend and apply the changes:
```bash
terraform init
terraform apply -var-file=./template.tfvars
```
:::note "View: Terraform output example"
```bash
Outputs:
terraform_lock_table_dynamodb_id = "terraform_locks"
terraform_states_s3_bucket_name = "terraform-states-012345678910"
```
:::
## AWS IAM Roles
This step covers the `KRCIDeployerRole` AWS IAM role creation procedure. To create the role, follow the steps below:
1. Navigate to the IAM module directory:
```bash
cd ../iam
```
2. Fill in the input variables for Terraform run in the `iam/template.tfvars` file.
Find the detailed description of the variables in the [iam/variables.tf](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/iam/variables.tf) file:
```tf title="iam/template.tfvars"
# -- e.g eu-central-1
region = "eu-central-1"
# If you need to set role boundary
iam_permissions_boundary_policy_arn = "arn:aws:iam::012345678910:policy/role_boundary"
tags = {
"SysName" = "KubeRocketCI"
"Environment" = "core"
"Project" = "my-proj"
"ManagedBy" = "terraform"
}
```
3. Initialize and apply the changes:
```bash
terraform init
terraform apply -var-file=./template.tfvars
```
:::note "View: Terraform output example"
```bash
Outputs:
deployer_iam_role_arn = "arn:aws:iam::012345678910:role/KRCIDeployerRole"
deployer_iam_role_name = "KRCIDeployerRole"
```
:::
## AWS VPC Configuration (Optional)
This step will cover the following topics:
- Create the AWS VPC
- Create the AWS VPC Subnets for instances and AWS ALB
- Create the AWS VPC Routing
To accomplish the tasks outlined above, follow these steps:
1. Navigate to the VPC module directory:
```bash
cd ../vpc
```
2. Set up the backend for store Terraform states remotely and support state locking and consistency checking via DynamoDB.
Insert the missing fields in the file `vpc/versions.tf`:
```tf title="vpc/versions.tf"
...
backend "s3" {
bucket = "terraform-states-012345678910"
key = "eu-central-1/test/vpc/terraform.tfstate"
region = "eu-central-1"
acl = "bucket-owner-full-control"
dynamodb_table = "terraform_locks"
encrypt = true
role_arn = "arn:aws:iam:::role/KRCIDeployerRole"
}
...
```
3. Fill in the input variables for Terraform run in the `vpc/template.tfvars` file. Use the [vpc/example.tfvars](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/vpc/example.tfvars) as an example.
Please find the detailed description of the variables in the [vpc/variables.tf](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/vpc/variables.tf) file:
```tf title="vpc/template.tfvars"
region = "eu-central-1"
role_arn = "arn:aws:iam::012345678910:role/KRCIDeployerRole"
platform_name = "test"
platform_cidr = "192.168.0.0/20"
subnet_azs = ["eu-central-1a", "eu-central-1b", "eu-central-1c"]
private_cidrs = ["192.168.0.0/22", "192.168.4.0/22", "192.168.8.0/22"]
public_cidrs = ["192.168.12.0/24", "192.168.13.0/24", "192.168.14.0/24"]
tags = {
"SysName" = "Terraform-Backend"
"SysOwner" = "owner@example.com"
"Environment" = "EKS-TEST-CLUSTER"
}
```
4. Initialize the backend and apply the changes:
```bash
terraform init
terraform apply -var-file=./template.tfvars
```
:::note "View: Terraform output example"
```bash
Outputs:
private_subnets = [
"subnet-012345678910",
"subnet-012345678910",
"subnet-012345678910",
]
public_subnets = [
"subnet-012345678910",
"subnet-012345678910",
"subnet-012345678910",
]
vpc_id = "vpc-012345678910"
```
:::
## Deploy and Pre-configure AWS EKS
This step will cover the following topics:
- Create the EKS Cluster
- Create the AWS ASGs for the EKS Cluster
- Create the AWS ALB
- (Optional) Create the Kaniko AWS IAM Role
- (Optional) Create the Atlantis AWS IAM Role
To accomplish the tasks outlined above, follow these steps:
1. Navigate to the EKS module directory:
```bash
cd ../eks
```
2. Set up the backend for store Terraform states remotely and support state locking and consistency checking via DynamoDB.
Insert the missing fields in the `eks/versions.tf` file:
```tf title="eks/versions.tf"
...
backend "s3" {
bucket = "terraform-states-012345678910"
key = "eu-central-1/test/eks/terraform.tfstate"
region = "eu-central-1"
acl = "bucket-owner-full-control"
dynamodb_table = "terraform_locks"
encrypt = true
role_arn = "arn:aws:iam:::role/KRCIDeployerRole"
}
...
```
3. Fill in the input variables for Terraform run in the `eks/template.tfvars` file. Use the [eks/example.tfvars](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/eks/example.tfvars) as an example.
Please find the detailed description of the variables in the [eks/variables.tf](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/eks/variables.tf) file:
```tf title="eks/versions.tf"
region = "eu-central-1"
platform_name = "test"
platform_domain_name = "example.com"
role_arn = "arn:aws:iam::012345678910:role/KRCIDeployerRole"
role_permissions_boundary_arn = "arn:aws:iam::012345678910:policy/eo_role_boundary"
vpc_id = "vpc-012345678910"
private_subnets_id = ["subnet-012345678910", "subnet-012345678910", "subnet-012345678910"]
public_subnets_id = ["subnet-012345678910", "subnet-012345678910", "subnet-012345678910"]
tags = {
"SysName" = "Terraform-Backend"
"SysOwner" = "owner@example.com"
"Environment" = "EKS-TEST-CLUSTER"
}
```
4. (Optional) Create the Kaniko AWS IAM Role:
If AWS Elastic Container Registry (ECR) will be used as the [Container Registry](../user-guide/manage-container-registries.md) in the KubeRocketCI platform, it is necessary to create a specific IAM role for Kaniko.
To configure the Kaniko AWS IAM Role, set the `create_kaniko_iam_role` variable to `true` in the `eks/template.tfvars` configuration file:
```tf title="eks/template.tfvars"
create_kaniko_iam_role = true
```
The Kaniko AWS IAM Role will be created as part of the EKS cluster provisioning process.
Once the EKS cluster and the Kaniko AWS IAM Role are successfully created, you can use the resulting Amazon Resource Name (ARN) in the `edp-tekton.kaniko.roleArn` field within the `values.yaml` file during the [KubeRocketCI installation](install-kuberocketci.md).
5. (Optional) Create the Atlantis AWS IAM Role:
If Atlantis will be used for automating Terraform workflows in Kubernetes environments, it is necessary to create a specific IAM role for Atlantis.
To create the Atlantis AWS IAM Role, set the `create_atlantis_iam_role` variable to `true` in the `eks/template.tfvars` configuration file:
```tf title="eks/template.tfvars"
create_atlantis_iam_role = true
```
The Atlantis AWS IAM Role will be created as part of the EKS cluster provisioning process.
Once the EKS cluster and the Atlantis AWS IAM Role are successfully created, you can proceed with the [Atlantis installation](./infrastructure-providers/atlantis-installation.md) and use the resulting Amazon Resource Name (ARN) in the `atlantis.serviceAccount.annotations` field within the `values.yaml` file for the Atlantis Helm chart.
6. Initialize the backend and apply the changes:
```bash
terraform init
terraform apply -var-file=./template.tfvars
```
7. Update local Kubernetes configuration.
After the EKS cluster is successfully deployed, update the local Kubernetes configuration to interact with the cluster:
```bash
aws eks update-kubeconfig --region --name
```
8. Once AWS EKS Cluster is successfully deployed, you can navigate to our [KubeRocketCI addons](add-ons-overview.md) to install and manage cluster applications using the GitOps approach.
## Argo CD Configuration (Optional)
This section covers configuring Argo CD for further integrating with an external EKS cluster. This integration necessitates creating two AWS IAM roles:
- `AWSIRSA_Test_ArgoCDMaster` AWS IAM role - for setting up IRSA annotations for the Argo CD application
- `EDPArgoCDClusterAdmin` AWS IAM role - for working with external EKS clusters and further adding them (please refer to the [Add Cluster](../user-guide/add-cluster.md) page for details).
### Argo CD IAM Role for Shared EKS Cluster
This step covers the `AWSIRSA_Test_ArgoCDMaster` AWS IAM role creation procedure. To create the role, take the following steps:
1. Navigate to the Argo CD module directory:
```bash
cd ../argo-cd
```
2. Set up the backend for store Terraform states remotely and support state locking and consistency checking via DynamoDB.
Insert the missing fields in the `argo-cd/versions.tf` file:
```tf title="argo-cd/versions.tf"
...
backend "s3" {
bucket = "terraform-states-012345678910"
key = "eu-central-1/test/argo-cd/terraform.tfstate"
region = "eu-central-1"
acl = "bucket-owner-full-control"
dynamodb_table = "terraform_locks"
encrypt = true
role_arn = "arn:aws:iam:::role/KRCIDeployerRole"
}
...
```
3. Fill in the input variables for Terraform run in the `argo-cd/template.tfvars` file. Refer to the [argo-cd/example.tfvars](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/argo-cd/example.tfvars) as an example.
Please find the detailed description of the variables in the [argo-cd/variables.tf](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/argo-cd/variables.tf) file:
```tf title="argo-cd/template.tfvars"
argocd_master_enabled = true
argocd_master_role_name_list = [
"arn:aws:iam::012345678910:role/EDPArgoCDClusterAdmin",
]
oidc_provider_arn = "arn:aws:iam::012345678910:oidc-provider/oidc.eks.eu-central-1.amazonaws.com/id/9876543210"
platform_name = "test"
region = "eu-central-1"
role_arn = "arn:aws:iam::012345678910:role/KRCIDeployerRole"
role_permissions_boundary_arn = "arn:aws:iam::012345678910:policy/eo_role_boundary"
tags = {
"SysName" = "Terraform-Backend"
"SysOwner" = "owner@example.com"
"Environment" = "EKS-TEST-CLUSTER"
}
```
4. Initialize the backend and apply the changes:
```bash
terraform init
terraform apply
```
:::note "View: Terraform output example"
```bash
Outputs:
argocd_agent_role_iam_role_arn = ""
argocd_irsa_iam_role_arn = "arn:aws:iam::012345678910:role/AWSIRSA_Test_ArgoCDMaster"
```
:::
5. Once `AWSIRSA_Test_ArgoCDMaster` AWS IAM Role is successfully created, navigate to the [Cluster addons](add-ons-overview.md) to set up IRSA annotations for the Argo CD application:
```yaml title="add-ons/argo-cd/values.yaml"
argo-cd:
controller:
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::012345678910:role/AWSIRSA_Test_ArgoCDMaster"
server:
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::012345678910:role/AWSIRSA_Test_ArgoCDMaster"
```
### Argo CD IAM Role for External EKS Cluster
This step covers the `EDPArgoCDClusterAdmin` AWS IAM role creation procedure. To create the role, take the following steps:
1. Navigate to the Argo CD module directory:
```bash
cd ../argo-cd
```
2. Set up the backend for store Terraform states remotely and support state locking and consistency checking via DynamoDB.
Insert the missing fields in the `argo-cd/versions.tf` file:
```tf title="argo-cd/versions.tf"
...
backend "s3" {
bucket = "terraform-states-012345678910"
key = "eu-central-1/test/argo-cd/terraform.tfstate"
region = "eu-central-1"
acl = "bucket-owner-full-control"
dynamodb_table = "terraform_locks"
encrypt = true
role_arn = "arn:aws:iam:::role/KRCIDeployerRole"
}
...
```
3. Fill in the input variables for Terraform run in the `argo-cd/template.tfvars` file. Refer to the [argo-cd/example.tfvars](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/argo-cd/example.tfvars) as an example.
Please find the detailed description of the variables in the [argo-cd/variables.tf](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/argo-cd/variables.tf) file:
```tf title="argo-cd/template.tfvars"
argocd_agent_enabled = true
argocd_agent_argocd_master_role_arn = "arn:aws:iam::012345678910:role/AWSIRSA_Test_ArgoCDMaster"
platform_name = "test"
region = "eu-central-1"
role_arn = "arn:aws:iam::012345678910:role/KRCIDeployerRole"
role_permissions_boundary_arn = "arn:aws:iam::012345678910:policy/eo_role_boundary"
tags = {
"SysName" = "Terraform-Backend"
"SysOwner" = "owner@example.com"
"Environment" = "EKS-TEST-CLUSTER"
}
```
4. Initialize the backend and apply the changes:
```bash
terraform init
terraform apply
```
:::note "View: Terraform output example"
```bash
Outputs:
argocd_agent_role_iam_role_arn = "arn:aws:iam::012345678910:role/EDPArgoCDClusterAdmin"
argocd_irsa_iam_role_arn = ""
```
:::
## Next Step
After the AWS EKS cluster is installed and configured, you can proceed with installing prerequisites for KubeRocketCI, such as [Tekton](../operator-guide/install-tekton.md) and [Argo CD](install-argocd.md).
## Related Articles
* [Cluster Add-Ons Overview](add-ons-overview.md)
* [Install KubeRocketCI](install-kuberocketci.md)
---
## Install and Integrate DefectDojo
# Integrate DefectDojo
Install DefectDojo on Kubernetes with Helm and integrate it into KubeRocketCI pipelines for vulnerability management. Once installed, you can enable single sign-on by following the [DefectDojo Microsoft Entra OIDC SSO Setup](../microsoft-entra/defectdojo-oidc-authentication.md) guide.
:::info
It is also possible to install DefectDojo using the add-ons approach. For details, please refer to the [KubeRocketCI addons approach](https://github.com/epam/edp-cluster-add-ons).
:::
:::note
For details on how KubeRocketCI pipelines report findings to DefectDojo, including the data model, engagement naming, and scan types, refer to [Security Scanning Pipelines](./security-pipelines.md).
:::
## Prerequisites
- Kubectl version 1.34.0+ is installed. Please refer to the [Kubernetes official website](https://kubernetes.io/releases/download/) for details.
- [Helm](https://helm.sh) version 3.19.0+ is installed. Please refer to the [Helm page](https://github.com/helm/helm/releases) on GitHub for details.
## Installation
:::info
Please refer to the [DefectDojo Helm Chart](https://github.com/DefectDojo/django-DefectDojo/tree/master/helm/defectdojo)
and [Deploy DefectDojo into the Kubernetes cluster](https://github.com/DefectDojo/django-DefectDojo/blob/dev/readme-docs/KUBERNETES.md) sections for details.
:::
## Installation DefectDojo Cluster Add-On Approach
To install DefectDojo in environment, it's recommended to use the resources provided in the [Cluster Add-Ons](https://github.com/epam/edp-cluster-add-ons) repository. Leveraging the Cluster Add-Ons simplifies the deployment and management process, providing a streamlined method to integrate DefectDojo into infrastructure.
1. Navigate to the forked cluster Add-Ons repository and align the [defectdojo values.yaml](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/defectdojo/values.yaml) file. Follow the instructions to deploy DefectDojo.
2. Update the configuration to enable **DefectDojo** in [Add-Ons](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/apps/values.yaml) repository:
```yaml title="clusters/core/apps/values.yaml"
defectdojo:
createNamespace: true
enable: true
```
3. Sync resources and wait till the all **DefectDojo** resources is created:

## Installation DefectDojo Helm Chart Approach
1. Check that a security namespace is created. If not, run the following command to create it:
```bash
kubectl create namespace defectdojo
```
:::warning For the OpenShift users
When using the OpenShift platform, install the `SecurityContextConstraints` resource. In case of using a custom namespace for `defectdojo`, change the namespace in the `users` section.
View: defectdojo-scc.yaml
```yaml
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegeEscalation: true
allowPrivilegedContainer: false
allowedCapabilities: null
apiVersion: security.openshift.io/v1
allowedFlexVolumes: []
defaultAddCapabilities: []
fsGroup:
type: MustRunAs
ranges:
- min: 999
max: 65543
groups: []
kind: SecurityContextConstraints
metadata:
annotations:
"helm.sh/hook": "pre-install"
name: defectdojo
priority: 1
readOnlyRootFilesystem: false
requiredDropCapabilities:
- KILL
- MKNOD
- SETUID
- SETGID
runAsUser:
type: MustRunAsRange
uidRangeMin: 1
uidRangeMax: 65543
seLinuxContext:
type: MustRunAs
supplementalGroups:
type: RunAsAny
users:
- system:serviceaccount:defectdojo:defectdojo
- system:serviceaccount:defectdojo:defectdojo-rabbitmq
- system:serviceaccount:defectdojo:default
volumes:
- configMap
- downwardAPI
- emptyDir
- persistentVolumeClaim
- projected
- secret
```
:::
2. Add a chart repository:
```bash
helm repo add defectdojo 'https://raw.githubusercontent.com/DefectDojo/django-DefectDojo/helm-charts'
helm repo update
```
3. Create PostgreSQL admin secret:
```bash
kubectl -n defectdojo create secret generic defectdojo-postgresql-specific \
--from-literal=postgresql-password= \
--from-literal=postgresql-postgres-password=
```
:::note
The `postgresql_password` and `postgresql_postgres_password` passwords must be 16 characters long.
:::
4. Create Rabbitmq admin secret:
```bash
kubectl -n defectdojo create secret generic defectdojo-rabbitmq-specific \
--from-literal=rabbitmq-password= \
--from-literal=rabbitmq-erlang-cookie=
```
:::note
The `rabbitmq_password` password must be 10 characters long.
The `rabbitmq_erlang_cookie` password must be 32 characters long.
:::
5. Create DefectDojo admin secret:
```bash
kubectl -n defectdojo create secret generic defectdojo \
--from-literal=DD_ADMIN_PASSWORD= \
--from-literal=DD_SECRET_KEY= \
--from-literal=DD_CREDENTIAL_AES_256_KEY= \
--from-literal=METRICS_HTTP_AUTH_PASSWORD=
```
:::note
The `dd_admin_password` password must be 22 characters long.
The `dd_secret_key` password must be 128 characters long.
The `dd_credential_aes_256_key` password must be 128 characters long.
The `metric_http_auth_password` password must be 32 characters long.
:::
6. Install DefectDojo v.2.22.4 using [defectdojo/defectdojo](https://github.com/DefectDojo/django-DefectDojo/tree/master/helm/defectdojo) Helm chart v.1.6.69:
```bash
helm upgrade --install \
defectdojo \
--version 1.6.69 \
defectdojo/defectdojo \
--namespace defectdojo \
--values values.yaml
```
Check out the *values.yaml* file sample of the DefectDojo customization:
View: values.yaml
```yaml
tag: 2.22.4
fullnameOverride: defectdojo
host: defectdojo.
site_url: https://defectdojo.
alternativeHosts:
- defectdojo-django.defectdojo
initializer:
# should be false after initial installation was performed
run: true
django:
ingress:
enabled: true # change to 'false' for OpenShift
activateTLS: false
uwsgi:
livenessProbe:
# Enable liveness checks on uwsgi container. Those values are use on nginx readiness checks as well.
# default value is 120, so in our case 20 is just fine
initialDelaySeconds: 20
```
7. For the OpenShift platform, install a Route:
View: defectdojo-route.yaml
```yaml
kind: Route
apiVersion: route.openshift.io/v1
metadata:
name: defectdojo
namespace: defectdojo
spec:
host: defectdojo.
path: /
tls:
insecureEdgeTerminationPolicy: Redirect
termination: edge
to:
kind: Service
name: defectdojo-django
port:
targetPort: http
wildcardPolicy: None
```
## Configuration DefectDojo ci-user
To prepare DefectDojo for integration with KubeRocketCI, follow the steps below:
1. Create ci user in DefectDojo UI:
- Login to DefectDojo UI using `admin` credentials:
```bash
echo "DefectDojo admin password: $(kubectl \
get secret defectdojo \
--namespace=defectdojo \
--output jsonpath='{.data.DD_ADMIN_PASSWORD}' \
| base64 --decode)"
```
- Go to User section
- Create new user Global role `Maintainer` permission:

2. Get a token of the DefectDojo user:
- Login to the DefectDojo UI using the credentials from previous steps.
- Click on profile button select the `API v2 key`.
- Copy the API key.

## Integration DefectDojo with KubeRocketCI
Provision the secret using `KubeRocketCI portal`, `Manifest` or with the `externalSecrets` operator:
Go to the **Portal** open **Configuration** -> **SECURITY** -> **DEFECTDOJO**. Update or click **+ ADD INTEGRATION** fill fields `Quick Link URL`, `URL` and `Token` click the `save` button.

```yaml
apiVersion: v1
kind: Secret
metadata:
name: ci-defectdojo
namespace: krci
labels:
app.edp.epam.com/secret-type: defectdojo
app.edp.epam.com/integration-secret: "true"
stringData:
url: https://defectdojo.example.com
token:
```
Store defectdojo URL and Token in AWS Parameter Store with following format:
```json
"ci-defectdojo":
{
"url": "https://defectdojo.example.com",
"token": "XXXXXXXXXXXX"
}
```
Go to the **Portal** open **Configuration** -> **SECURITY** -> **DefectDojo** and see the `Managed by External Secret` message.

More details about the External Secrets Operator integration procedure can be found in the [External Secrets Operator Integration](../secrets-management/external-secrets-operator-integration.md) page.
After following the instructions provided, you should be able to integrate your DefectDojo with the KubeRocketCI using one of the available scenarios.
## Related Articles
* [Install External Secrets Operator](../secrets-management/install-external-secrets-operator.md)
* [External Secrets Operator Integration](../secrets-management/external-secrets-operator-integration.md)
* [Install Harbor](../artifacts-management/harbor-installation.md)
* [DefectDojo Microsoft Entra OIDC SSO Setup](../microsoft-entra/defectdojo-oidc-authentication.md)
---
## Integrate Dependency-Track
# Integrate Dependency-Track
This documentation guide provides comprehensive instructions for installing and integrating Dependency-Track with the KubeRocketCI.
:::note
For details on how KubeRocketCI pipelines generate SBOMs with cdxgen and upload them to Dependency-Track, refer to [Security Scanning Pipelines](./security-pipelines.md).
:::
## Prerequisites
- Kubectl version 1.34.0+ is installed. Please refer to the [Kubernetes official website](https://kubernetes.io/releases/download/) for details.
- [Helm](https://helm.sh) version 3.19.0+ is installed. Please refer to the [Helm page](https://github.com/helm/helm/releases) on GitHub for details.
## Installation
To install Dependency-Track use [KubeRocketCI addons](../add-ons-overview.md) approach.
## Configuration
1. Open **Administration** -> **Access Management** -> **Teams**. Click **Create Team** -> **Automation** and click **Create**.
2. Click **+** in **Permissions** and add:
```bash
BOM_UPLOAD
PROJECT_CREATION_UPLOAD
VIEW_PORTFOLIO
```
3. Click **+** in **API keys** to create token:

4. Provision secrets using a manifest, Portal, or with the externalSecrets operator:
Go to the **Portal** open **Configuration** -> **SECURITY** -> **DEPENDENCYTRACK**. Click **+ ADD INTEGRATION** fill fields `Quick Link URL`, `URL` and `Token` click the `save` button.

```yaml
apiVersion: v1
kind: Secret
metadata:
name: ci-dependency-track
namespace: krci
labels:
app.edp.epam.com/secret-type: dependency-track
app.edp.epam.com/integration-secret: "true"
stringData:
token:
url:
type: Opaque
```
Store Dependency-Track URL and Token in the AWS Parameter Store with the following format:
```yaml
"ci-dependency-track":
{
"token": "XXXXXXXXXXXX",
"url": "https://dependency-track.example.com"
}
```
Go to the **KubeRocketCI Portal** -> **Configuration** -> **Security** -> **DependencyTrack** see the secret managed by the `Managed by External Secret`:

More detail on External Secrets Operator Integration can be found on [the following page](../secrets-management/external-secrets-operator-integration.md)
After following the instructions provided, you should be able to integrate your Dependency-Track with the KubeRocketCI.
## Related Articles
* [Install External Secrets Operator](../secrets-management/install-external-secrets-operator.md)
* [External Secrets Operator Integration](../secrets-management/external-secrets-operator-integration.md)
* [Cluster Add-Ons Overview](../add-ons-overview.md)
* [Dependency-Track Microsoft Entra OIDC SSO](../microsoft-entra/dependency-track-authentication.md)
---
## Security and Compliance: Overview
# Security and Compliance: Overview
KubeRocketCI emphasizes the importance of incorporating security practices into the software development lifecycle through the DevSecOps approach. By integrating a diverse range of open-source and enterprise security tools tailored to specific functionalities, organizations can ensure efficient and secure software development. These tools, combined with fundamental DevSecOps principles such as collaboration, continuous security, and automation, contribute to the identification and remediation of vulnerabilities early in the process, minimizes risks, and fosters a security-first culture across the organization.
## Integrated Scanners
The following tools are built into KubeRocketCI Tekton pipelines and run automatically as part of CI/CD workflows. For detailed information on when each scanner runs, how reports are produced, and how data flows into DefectDojo and Dependency-Track, refer to the [Security Scanning Pipelines](./security-pipelines.md) page.
| Tool | Category | Runs In | Results Destination |
|:----:|----------|---------|---------------------|
| [SonarQube](https://www.sonarqube.org/) | SAST + Code Quality | Build and Review pipelines | [SonarQube server](../code-quality/sonarqube.md) |
| [Semgrep](https://github.com/semgrep/semgrep) | SAST | Security-Scan pipeline | [DefectDojo](./defectdojo.md) |
| [Gitleaks](https://github.com/gitleaks/gitleaks) | Secret Detection | Security-Scan pipeline | [DefectDojo](./defectdojo.md) |
| [CycloneDX cdxgen](https://github.com/CycloneDX/cdxgen) | SCA / SBOM Generation | Security-Scan pipeline | [Dependency-Track](./dependency-track.md) |
| [Trivy](https://github.com/aquasecurity/trivy) | Container Vulnerability Scan | Security-Scan, Image-Scan-Remote pipelines | [DefectDojo](./defectdojo.md) |
| [Anchore Grype](https://github.com/anchore/grype) | Container Vulnerability Scan | Security-Scan pipeline | [DefectDojo](./defectdojo.md) |
| [Hadolint](https://github.com/hadolint/hadolint) | Dockerfile Linting | Review pipelines | Pipeline log |
| [Helm chart-testing](https://github.com/helm/chart-testing) | Helm Chart Linting | Review pipelines | Pipeline log |
## Required Integrations
To enable the full security scanning stack, provision the following integration secrets. Each secret is optional — if missing, the corresponding scanning step is skipped gracefully, allowing incremental tool adoption.
| Secret | Keys | Integration Guide |
|:------:|------|:-----------------:|
| `ci-sonarqube` | `token`, `url` | [SonarQube Integration](../code-quality/sonarqube.md) |
| `ci-defectdojo` | `token`, `url` | [Integrate DefectDojo](./defectdojo.md) |
| `ci-dependency-track` | `token`, `url` | [Integrate Dependency-Track](./dependency-track.md) |
## Supported Solutions Catalog
Beyond the tools integrated into default pipelines, KubeRocketCI supports the integration of additional open-source and enterprise security tools for organizations with extended security requirements. The table below provides a comprehensive view of available options for each security aspect.
| Functionality | Open-Source Tools (integrated in Pipelines) | Enterprise Tools (available for Integration) |
|:--------------------------------------:|---------------------------------------------|--------------------------------------------------------|
| Hardcoded Credentials Scanner | TruffleHog, GitLeaks, Git-secrets | GitGuardian, SpectralOps, Bridgecrew |
| Static Application Security Testing | SonarQube, Semgrep CLI | Veracode, Checkmarx, Coverity |
| Software Composition Analysis | OWASP Dependency-Check, cdxgen | Black Duck Hub, Mend, Snyk |
| Container Security | Trivy, Grype, Clair | Aqua Security, Sysdig Secure, Snyk |
| Infrastructure as Code Security | Checkov, Tfsec | Bridgecrew, Prisma Cloud, Snyk |
| Dynamic Application Security Testing | OWASP Zed Attack Proxy | Fortify WebInspect, Rapid7 InsightAppSec, Checkmarx |
| Continuous Monitoring and Logging | ELK Stack, OpenSearch, Loki | Splunk, Datadog |
| Security Audits and Assessments | OpenVAS | Tenable Nessus, QualysGuard, BurpSuite Professional |
| Vulnerability Management and Reporting | DefectDojo, OWASP Dependency-Track | Metasploit |

## Tool Descriptions
### Vulnerability Management
[DefectDojo](https://www.defectdojo.com/) is a comprehensive vulnerability management and security orchestration platform facilitating the handling of uploaded security reports. Examine the prerequisites and fundamental instructions for [installing DefectDojo](./defectdojo.md) on Kubernetes or OpenShift platforms.
[OWASP Dependency-Track](https://dependencytrack.org/) is an intelligent Software Composition Analysis (SCA) platform that provides a comprehensive solution for managing vulnerabilities in third-party and open-source components. See the [integration guide](./dependency-track.md) for setup instructions.
### Source Code Security
[Semgrep CLI](https://github.com/semgrep/semgrep) is a versatile and user-friendly command-line interface for the Semgrep security scanner, enabling developers to perform Static Application Security Testing (SAST) for various programming languages. It focuses on detecting and preventing potential security vulnerabilities, code quality issues, and custom anti-patterns.
[Gitleaks](https://github.com/gitleaks/gitleaks) is a versatile SAST tool used to scan Git repositories for hardcoded secrets, such as passwords and API keys, to prevent potential data leaks and unauthorized access.
[TruffleHog](https://github.com/trufflesecurity/trufflehog) is an open-source tool designed for finding and identifying potentially sensitive and secret information in the source code and commit history of Git repositories.
[Git-secrets](https://github.com/awslabs/git-secrets) is an open-source tool that helps prevent the accidental committing of secrets, sensitive information, and other types of confidential data into Git repositories.
### Container Security
[Trivy](https://github.com/aquasecurity/trivy) is a simple and comprehensive vulnerability scanner for containers and other artifacts, providing insight into potential security issues across multiple ecosystems. Trivy can be seamlessly integrated into CI/CD pipelines or utilized as part of Harbor.
[Grype](https://github.com/anchore/grype) is a fast and reliable vulnerability scanner for container images and filesystems, maintaining an up-to-date vulnerability database for efficient and accurate scanning.
[Clair](https://github.com/quay/clair) is an open-source container security tool designed to help assess the security of container images and identify vulnerabilities within them.
### Software Composition Analysis
[Cdxgen](https://github.com/CycloneDX/cdxgen) is a lightweight and efficient tool for generating Software Bill of Materials (SBOM) using CycloneDX, a standard format for managing component inventory. It helps organizations maintain an up-to-date record of all software components, their versions, and related vulnerabilities.
[OWASP Dependency-Check](https://owasp.org/www-project-dependency-check/) is a software composition analysis tool that helps identify and report known security vulnerabilities in project dependencies.
### Infrastructure as Code Security
[Tfsec](https://github.com/aquasecurity/tfsec) is an effective Infrastructure as Code (IaC) security scanner, tailored specifically for reviewing Terraform templates. It helps identify potential security issues related to misconfigurations and non-compliant practices.
[Checkov](https://github.com/bridgecrewio/checkov) is a robust static code analysis tool designed for IaC security, supporting various IaC frameworks such as Terraform, CloudFormation, and Kubernetes. It assists in detecting and mitigating security and compliance misconfigurations.
### Dynamic Application Security Testing
[OWASP Zed Attack Proxy (ZAP)](https://www.zaproxy.org/) is a security testing tool for finding vulnerabilities in web applications during the development and testing phases.
### Monitoring and Logging
[ELK Stack](../monitoring-and-observability/kibana-ilm-rollover.md) (Fluent Bit, Elasticsearch, Kibana) is used in Kubernetes for log aggregation, supporting Logsight for Stage Verification and Incident Detection.
[Loki](https://github.com/Neo23x0/Loki) is a log aggregation system designed for cloud-native environments. It is part of the CNCF and is often used alongside Prometheus for monitoring and observability.
[OpenSearch](https://opensearch.org/) is the flexible, scalable, open-source way to build solutions for data-intensive applications.
### Security Audits
[OpenVAS](https://openvas.org/) is an open-source network vulnerability scanner and security management tool designed to identify and assess security vulnerabilities in computer systems, networks, and applications.
## Related Articles
* [Security Scanning Pipelines](./security-pipelines.md)
* [Integrate DefectDojo](./defectdojo.md)
* [Integrate Dependency-Track](./dependency-track.md)
* [SonarQube Integration](../code-quality/sonarqube.md)
---
## Security Scanning Pipelines
# Security Scanning Pipelines
KubeRocketCI provides automated security scanning at three levels of the software delivery lifecycle: source code, dependencies, and container images. Scanners are embedded into Tekton pipelines and report findings to [DefectDojo](./defectdojo.md), [Dependency-Track](./dependency-track.md), and [SonarQube](../code-quality/sonarqube.md).
| Tool | Category | Report Destination | DefectDojo Scan Type |
|:----:|----------|--------------------|-----------------------|
| [Semgrep](https://github.com/semgrep/semgrep) | SAST | DefectDojo | `Semgrep JSON Report` |
| [Gitleaks](https://github.com/gitleaks/gitleaks) | Secret Detection | DefectDojo | `Gitleaks Scan` |
| [CycloneDX cdxgen](https://github.com/CycloneDX/cdxgen) | SCA / SBOM | Dependency-Track | N/A (direct API upload) |
| [SonarQube](https://www.sonarqube.org/) | SAST + Code Quality | SonarQube server | N/A |
| [Trivy](https://github.com/aquasecurity/trivy) | Container Vulnerability Scan | DefectDojo | `Trivy Scan` |
| [Anchore Grype](https://github.com/anchore/grype) | Container Vulnerability Scan | DefectDojo | `Anchore Grype` |
| [Hadolint](https://github.com/hadolint/hadolint) | Dockerfile Linting | Pipeline log | N/A |
| [Helm chart-testing](https://github.com/helm/chart-testing) | Helm Chart Linting | Pipeline log | N/A |
## Pipeline Types
Security scanning is distributed across three pipeline types. Each serves a different stage of the development workflow.
### Build and Review Pipelines
Build and review pipelines are language-specific and run for every codebase. They include [SonarQube](../code-quality/sonarqube.md) for code quality and security analysis, [Hadolint](https://github.com/hadolint/hadolint) for Dockerfile validation, and [Helm chart-testing](https://github.com/helm/chart-testing) for chart linting.
**Build pipeline** — triggered on merge to a tracked branch:
```mermaid
flowchart LR
A[fetch-repo] --> B[get-version] --> C[get-cache] --> D[compile] --> E[test]
E --> F[sonar] --> G[build] --> H[push] --> I[container-build]
I --> J[save-cache] --> K[git-tag] --> L[update-cbis]
L -. finally .-> M[report status]
```
**Review pipeline** — triggered on PR/MR creation or update:
```mermaid
flowchart LR
A[fetch-repo] --> B[get-cache] --> C[compile] --> D[test]
D --> E[sonar] --> F[build] --> G[save-cache]
A --> H[dockerfile-lint] --> I[dockerbuild-verify]
A --> J[helm-lint]
G -. finally .-> K[set review status]
```
:::info
For details on SonarQube configuration and Quality Gate behavior, refer to the [SonarQube Integration](../code-quality/sonarqube.md) page.
:::
### Security-Scan Pipeline
A dedicated pipeline that runs comprehensive security analysis independently from build/review. Available for all supported VCS providers (GitHub, GitLab, Gerrit, Bitbucket). Triggered via webhook or manually through the KubeRocketCI portal.
After cloning the repository, two tasks execute **in parallel**:
```mermaid
flowchart LR
A[fetch-repo] --> B["security
Semgrep + Gitleaks + cdxgen"]
A --> C["image-scan-chart
Trivy + Grype"]
B --> D["DefectDojo +
Dependency-Track"]
C --> E[DefectDojo]
```
The pipeline returns two result URLs visible in the portal:
- `SCAN_REPORT_URL` — DefectDojo link to code security findings (Semgrep + Gitleaks)
- `IMAGE_SCAN_REPORT_URL` — DefectDojo link to container image findings (Trivy + Grype)
### Image-Scan-Remote Pipeline
An on-demand pipeline for scanning pre-built container images from remote registries without source code. Accepts an array of fully-qualified image references:
```yaml
params:
- name: IMAGE_NAMES
value:
- "registry.example.com/myapp/backend:1.2.3"
- "registry.example.com/myapp/frontend:1.2.3"
- name: CODEBASE_NAME
value: "myapp"
```
Uses Trivy only (no Grype) and uploads results to DefectDojo with per-image engagements.
### Scanner-to-Pipeline Matrix
| Scanner | Build Pipeline | Review Pipeline | Security-Scan Pipeline | Image-Scan-Remote |
|:-------:|:-:|:-:|:-:|:-:|
| SonarQube | Yes | Yes (PR mode) | - | - |
| Semgrep | - | - | Yes | - |
| Gitleaks | - | - | Yes | - |
| cdxgen (SBOM) | - | - | Yes | - |
| Trivy | - | - | Yes | Yes |
| Grype | - | - | Yes | - |
| Hadolint | - | Yes | - | - |
| Helm Lint | - | Yes | - | - |
## Scanner Reference
This section describes each integrated scanner: what it detects, the command it runs, and where results are reported.
### Source Code Scanners
#### Semgrep (SAST)
Semgrep performs Static Application Security Testing across the entire source tree. It runs as the first step of the `security` task in the security-scan pipeline.
**Command:**
```bash
semgrep --jobs 1 --config=auto . --json \
--output semgrep-report.json --disable-version-check
```
Key behaviors:
- Uses `--config=auto` which downloads community and recommended rules from the Semgrep registry, selecting rules based on detected languages and frameworks.
- Runs single-threaded (`--jobs 1`) for stability in container environments.
- Excludes `.docker/config.json` via a `.semgrepignore` file created at scan time.
- Produces a JSON report consumed by the DefectDojo upload step.
- Does **not** fail the pipeline on findings — results go to DefectDojo for triage.
**DefectDojo mapping:** scan type = `Semgrep JSON Report`, engagement = `code-security-{branch}`.
#### Gitleaks (Secret Detection)
Gitleaks detects hardcoded secrets, API keys, passwords, and tokens in the source code. It runs as the second step of the `security` task.
**Command:**
```bash
gitleaks detect --source . --report-format=json \
--report-path=gitleaks-report.json \
--no-git --verbose --exit-code=0 --config=gitleaks.toml
```
Key behaviors:
- `--no-git` scans file content only (not git history), which is faster and avoids needing a full git clone.
- `--exit-code=0` ensures the pipeline does not fail on findings — all results are sent to DefectDojo.
- Uses a custom `gitleaks.toml` config that excludes the `.docker/` directory.
**DefectDojo mapping:** scan type = `Gitleaks Scan`, engagement = `code-security-{branch}`.
#### CycloneDX cdxgen (SCA / SBOM)
[CycloneDX cdxgen](https://github.com/CycloneDX/cdxgen) generates a Software Bill of Materials (SBOM) from the project source and uploads it directly to [Dependency-Track](./dependency-track.md). It runs as the third step of the `security` task and is also available as a standalone `cdxgen` Tekton task.
**Command:**
```bash
/opt/cdxgen/bin/cdxgen.js \
--api-key=$API_TOKEN \
--server-url=$DEPTRACK_URL \
--project-name=$PROJECT_NAME \
--project-version=$PROJECT_BRANCH \
--print
```
Key behaviors:
- Automatically detects the project type (Maven, npm, pip, Go, etc.) and generates an appropriate SBOM.
- Uploads the SBOM directly to Dependency-Track via its API (not through DefectDojo).
- `--project-name` maps to the KubeRocketCI Codebase name (e.g., `my-java-app`).
- `--project-version` maps to the git branch being scanned (e.g., `main`, `release/1.0`).
- If the `ci-dependency-track` secret is missing or empty, the step is skipped gracefully.
After upload, Dependency-Track provides:
- Full dependency tree visualization
- Known vulnerability (CVE) matching against NVD and other feeds
- License risk analysis (GPL, Apache, MIT compliance)
- Policy evaluation (banned components, outdated versions)
- Audit workflow for triaging findings
- Project-level risk scoring
#### SonarQube (Code Quality and Security)
SonarQube scanning is embedded in every build and review pipeline. It serves a dual purpose: code quality enforcement and security vulnerability detection. SonarQube is the **only scanner that acts as a hard gate** — if the Quality Gate fails, the pipeline fails.
SonarQube provides language-specific task variants:
| Task Name | Language | Build Tool |
|-----------|----------|------------|
| `sonarqube-maven` | Java (Maven) | Maven plugin (`sonar:sonar`) |
| `sonarqube-gradle` | Java (Gradle) | Gradle plugin (`sonarqube`) |
| `sonarqube-general` | Go, Python, JS/TS | Standalone `sonar-scanner-cli` |
| `sonarqube-dotnet` | C# / .NET | `dotnet sonarscanner` |
Each task performs three phases:
1. **Project setup** — verifies SonarQube availability, auto-creates the project if missing (using the Codebase's default branch).
2. **Analysis** — runs the scanner with branch-mode parameters (build pipeline) or pull-request-mode parameters (review pipeline).
3. **Quality Gate** — with `sonar.qualitygate.wait=true`, the scanner polls SonarQube until evaluation completes. A failed Quality Gate blocks artifact publishing (build) or sets a failing PR status (review).
SonarQube detects bugs, security vulnerabilities, security hotspots, code smells, coverage gaps, and code duplications.
:::info
For installation, configuration, and integration instructions, refer to the [SonarQube Integration](../code-quality/sonarqube.md) page.
:::
### Container Image Scanners
Container image scanning discovers and reports vulnerabilities in OS packages and application libraries baked into container images. KubeRocketCI provides multiple scanning approaches depending on the context.
#### Helm-Based Image Discovery (image-scan-chart)
This is the primary approach, used in all security-scan pipelines. It renders the application's Helm chart to discover which container images are deployed, then scans each one.
**Execution flow:**
| Step | Description |
|------|-------------|
| **discover-image-repository** | Queries Kubernetes for the `CodebaseImageStream` CR to extract the image repository and latest tag |
| **helm-template-and-extract** | Runs `helm template` with image overrides from the previous step, then parses rendered manifests for all `image:` references |
| **trivy** | Scans each discovered image using [Trivy](https://github.com/aquasecurity/trivy) in client/server mode, producing a JSON report per image |
| **grype** | Scans each discovered image using [Anchore Grype](https://github.com/anchore/grype), producing a JSON report per image |
| **upload-report** | Uploads all Trivy and Grype reports to DefectDojo with per-image engagements |
Key details:
- **CodebaseImageStream lookup** normalizes the branch name (lowercase, non-alphanumeric characters replaced with `-`) to locate the correct resource.
- **Helm template** uses `--set image.repository` and `--set image.tag` overrides so rendered manifests contain real production image references.
- If no Helm chart exists at `deploy-templates/`, the scan is skipped gracefully.
- **Trivy** runs in client/server mode by default (server at `http://trivy-service.trivy-system:4954`) for performance. It falls back to standalone mode if no server is configured.
- **Grype** always runs standalone (no server mode).
- Both scanners use **soft failure** — a scan error on one image does not block other images from being scanned. Upload errors **do** fail the task.
#### Remote Registry Scanning (image-scan-remote)
For scanning images that already exist in a remote registry, without needing source code or Helm charts. This approach uses Trivy only (no Grype) and creates per-image engagements in DefectDojo.
#### Build-Time TAR Scanning (image-scan)
For scanning container images saved as TAR archives (e.g., output of `kaniko --tarPath`). Runs both Trivy and Grype. Uses a fixed DefectDojo engagement name `container-security`.
#### Standalone Trivy Check (trivy-scan)
A lightweight task that scans a single image for **HIGH and CRITICAL** vulnerabilities only:
```bash
trivy image --scanners vuln --severity HIGH,CRITICAL "${TARGET_IMAGE}"
```
Results are printed to the pipeline log. No DefectDojo integration.
### Infrastructure-as-Code Linting
These tools run during review pipelines to catch issues before merge:
- **Hadolint** — validates Dockerfile best practices: pinned base images, proper instruction ordering, and shell best practices.
- **Helm chart-testing** — validates Helm chart structure, values schema, and template rendering using `ct lint`.
Both tools block the review pipeline on failure.
## DefectDojo Reporting Model
Understanding how KubeRocketCI organizes findings in DefectDojo is essential for navigating scan results and configuring alerts.
### Data Hierarchy
```text
Product Type: "KubeRocketCI"
└─ Product: "{CODEBASE_NAME}"
├─ Engagement: "code-security-{branch}"
│ ├─ Test: "Semgrep JSON Report"
│ │ └─ Findings: [...]
│ └─ Test: "Gitleaks Scan"
│ └─ Findings: [...]
│
├─ Engagement: "image:registry.example.com/myapp:1.0.0"
│ ├─ Test: "Trivy Scan"
│ │ └─ Findings: [...]
│ └─ Test: "Anchore Grype"
│ └─ Findings: [...]
│
└─ Engagement: "image:nginx:1.25"
├─ Test: "Trivy Scan"
└─ Test: "Anchore Grype"
```
- **Product Type** — `KubeRocketCI` (configurable via `DD_PRODUCT_TYPE_NAME`). Groups all platform codebases.
- **Product** — one per KubeRocketCI Codebase. Named after the Codebase (e.g., `my-java-app`).
- **Engagement** — groups related scans. Naming depends on the scan source (see table below).
- **Test** — one per scanner execution. Holds the actual findings.
### Engagement Naming Strategy
| Scan Source | Engagement Name | Rationale |
|:----------:|----------------|-----------|
| Code security scans | `code-security` or `code-security-{branch}` | One engagement per branch for SAST and secret findings |
| Container image scans | `image:{full-image-reference}` | One engagement per image to prevent `close_old_findings` from cross-contaminating findings between different images |
| TAR image scans | `container-security` | Fixed engagement for build-time scanning |
### Upload Mechanism
All uploads use the DefectDojo **reimport-scan** API:
```text
POST {DD_HOST_URL}/api/v2/reimport-scan/
Authorization: Token {DD_TOKEN}
Content-Type: multipart/form-data
```
Standard parameters sent with every upload:
| Parameter | Value | Purpose |
|-----------|-------|---------|
| `scan_date` | Current date (`YYYY-MM-DD`) | When the scan was performed |
| `minimum_severity` | `Info` | Import all severity levels |
| `active` | `true` | Mark findings as active |
| `verified` | `false` | Findings require human verification |
| `auto_create_context` | `true` | Auto-create product, engagement, and test if missing |
| `close_old_findings` | `true` | Close findings from previous scans that are no longer present |
| `push_to_jira` | `false` | No automatic Jira integration |
| `environment` | `Development` | Environment classification |
| `product_type_name` | `KubeRocketCI` | Product type grouping |
| `product_name` | `{CODEBASE_NAME}` | Maps to the KubeRocketCI Codebase |
### Result URLs
After upload, pipeline tasks return clickable DefectDojo URLs as results:
- **Single image scanned:** `{DD_HOST_URL}/engagement/{ENGAGEMENT_ID}`
- **Multiple images scanned:** `{DD_HOST_URL}/product/{PRODUCT_ID}` (shows all engagements)
These URLs appear in the KubeRocketCI portal pipeline run details.
## Configuration
### Required Secrets
| Secret Name | Keys | Used By | Purpose |
|:-----------:|------|---------|---------|
| `ci-defectdojo` | `token`, `url` | `security`, `image-scan-chart`, `image-scan-remote`, `image-scan` tasks | DefectDojo report upload |
| `ci-dependency-track` | `token`, `url` | `security` task (cdxgen step), standalone `cdxgen` task | SBOM upload to Dependency-Track |
| `ci-sonarqube` | `token`, `url` | All `sonarqube-*` tasks | SonarQube analysis |
| `ci-nexus` | `username`, `password` | `sonarqube-maven`, `sonarqube-gradle` tasks | Maven/Gradle artifact resolution during Sonar analysis |
:::tip
All security-related secrets are optional at the task level. If a secret is missing, the corresponding step is skipped gracefully. This means you can incrementally adopt tools: start with SonarQube only, then add DefectDojo, then Dependency-Track.
:::
For secret provisioning instructions, refer to:
- [Integrate DefectDojo](./defectdojo.md)
- [Integrate Dependency-Track](./dependency-track.md)
- [SonarQube Integration](../code-quality/sonarqube.md)
### Helm Chart Settings
Security scanning pipelines are controlled by the following `values.yaml` settings in the `pipelines-library` Helm chart:
```yaml title="values.yaml"
global:
gitProviders:
- github # Determines which security-scan pipeline variants are deployed
- gitlab
pipelines:
deployableResources:
security: true # Enable/disable all security-scan pipelines and tasks
java:
java25SkipSonar: true # Skip SonarQube for Java 25
tekton:
workspaceSize: 7Gi # PVC size for pipeline workspaces
```
| Setting | Effect |
|---------|--------|
| `pipelines.deployableResources.security` | When `true`, deploys all security-scan pipelines, tasks, and triggers |
| `global.gitProviders` | Controls which VCS-specific pipeline variants are deployed (e.g., `github-security-scan`) |
| `java25SkipSonar` | When `true`, omits SonarQube from Java 25 pipelines (SonarQube does not yet support Java 25) |
### External Services
| Service | Default Endpoint | Purpose |
|---------|-----------------|---------|
| Trivy Server | `http://trivy-service.trivy-system:4954` | Centralized vulnerability database for faster container scans |
| SonarQube | From `ci-sonarqube` secret | Static analysis and Quality Gate evaluation |
| DefectDojo | From `ci-defectdojo` secret | Vulnerability management and reporting |
| Dependency-Track | From `ci-dependency-track` secret | SBOM storage, dependency vulnerability tracking, license analysis |
## End-to-End Example: Java Maven Application
This section walks through the complete security scanning lifecycle of a Java Maven application called `payment-service` on KubeRocketCI.
**Setup:**
- **Codebase:** `payment-service` (registered in KubeRocketCI)
- **Git provider:** GitHub
- **Branch:** `main`
- **Container image:** `registry.example.com/payment-service:0.1.0-SNAPSHOT.42`
- **Helm chart:** `deploy-templates/` with `image.repository` and `image.tag` values
### Phase 1: Developer Opens a Pull Request
A developer pushes a feature branch and opens a PR against `main`. GitHub fires a webhook, and the review pipeline starts.
```text
Pipeline: github-maven-java17-app-review
```
| Step | Task | What Happens |
|:----:|------|-------------|
| 1 | `fetch-repository` | Clones the PR branch |
| 2 | `init-values` | Reads Codebase/CodebaseBranch CRs for pipeline config |
| 3 | `get-cache` | Restores Maven `.m2/repository` cache |
| 4 | `compile` | Runs `mvn compile` |
| 5 | `test` | Runs `mvn verify` with JaCoCo coverage |
| 6 | **`sonar`** | **SonarQube PR analysis** (see below) |
| 7 | `build` | Runs `mvn package -DskipTests` |
| 8 | `save-cache` | Saves Maven cache for next run |
| 9 | `dockerfile-lint` | **Hadolint** validates `Dockerfile` |
| 10 | `dockerbuild-verify` | Dry-run container build (no push) |
| 11 | `helm-lint` | **chart-testing** validates `deploy-templates/` |
| finally | `set-status` | Reports pass/fail back to GitHub PR |
**SonarQube during review** — the `sonarqube-maven` task runs:
```bash
mvn -s /var/configmap/settings.xml -B \
-Dsonar.projectKey=payment-service \
-Dsonar.projectName=payment-service \
-Dsonar.pullrequest.key=42 \
-Dsonar.pullrequest.branch=feature/add-refunds \
-Dsonar.pullrequest.base=main \
-Dsonar.qualitygate.wait=true \
-DskipTests verify sonar:sonar
```
**Result in SonarQube:** PR #42 appears as a decoration on the `payment-service` project. The Quality Gate evaluates new code coverage, bugs, vulnerabilities, and security hotspots. If the Quality Gate fails, the pipeline fails at step 6 and the GitHub PR status shows a red check.
### Phase 2: PR Is Merged — Build Pipeline Runs
After the PR is approved and merged, the build pipeline triggers.
```text
Pipeline: github-maven-java17-app-build-default
```
| Step | Task | What Happens |
|:----:|------|-------------|
| 1 | `fetch-repository` | Clones `main` branch |
| 2 | `init-values` | Reads Codebase CR metadata |
| 3 | `get-version` | Generates version: `0.1.0-SNAPSHOT.42` |
| 4 | `get-cache` | Restores Maven cache |
| 5 | `update-build-number` | Stamps version into the project |
| 6 | `compile` | Runs `mvn compile` |
| 7 | `test` | Runs `mvn verify` with JaCoCo |
| 8 | **`sonar`** | **SonarQube branch analysis** |
| 9 | `build` | Runs `mvn package -DskipTests` |
| 10 | `push` | Publishes JAR/WAR to Nexus |
| 11 | `container-build` | Kaniko builds and pushes container image |
| 12 | `save-cache` | Saves Maven cache |
| 13 | `git-tag` | Tags commit with `0.1.0-SNAPSHOT.42` |
| 14 | `update-cbis` | Updates CodebaseImageStream with new image tag and digest |
| finally | `report-status` | Reports to JIRA and GitHub |
**SonarQube during build** — branch analysis updates the `main` branch in SonarQube with the latest merged code, enabling long-lived branch trend tracking.
### Phase 3: Security-Scan Pipeline Runs
The security-scan pipeline is triggered via webhook or manually from the portal.
```text
Pipeline: github-security-scan
```
Two tasks run in parallel after `fetch-repository`:
#### Task A: security (SAST + Secrets + SCA)
| Step | Tool | What Happens |
|:----:|------|-------------|
| A.1 | **Semgrep** | Scans all source files for vulnerabilities. Writes `semgrep-report.json`. |
| A.2 | **Gitleaks** | Scans file content for hardcoded secrets. Writes `gitleaks-report.json`. |
| A.3 | **cdxgen** | Analyzes `pom.xml` and transitive dependencies. Generates CycloneDX SBOM. Uploads to Dependency-Track as project `payment-service`, version `main`. |
| A.4 | **Upload** | Uploads Semgrep and Gitleaks reports to DefectDojo. |
**What appears in DefectDojo after Task A:**
```text
Product: payment-service
└─ Engagement: "code-security-main"
├─ Test: "Semgrep JSON Report"
│ ├─ Finding: SQL Injection in PaymentDao.java:45 [HIGH]
│ └─ Finding: Insecure Deserialization in WebConfig.java:112 [CRITICAL]
└─ Test: "Gitleaks Scan"
└─ Finding: AWS Access Key in application-dev.properties:7 [HIGH]
```
**What appears in Dependency-Track after Task A:**
```text
Project: payment-service (version: main)
Components: 247
Vulnerabilities:
├─ CVE-2024-22262 — spring-web 6.1.4 [HIGH]
├─ CVE-2024-22243 — spring-web 6.1.4 [MEDIUM]
└─ CVE-2023-44487 — netty-codec-http2 4.1.97 [HIGH]
License Risk:
├─ 198 components: Apache-2.0
├─ 41 components: MIT
└─ 8 components: LGPL-2.1 (review required)
```
#### Task B: image-scan-chart (Container Scanning)
| Step | What Happens |
|------|-------------|
| B.1 `discover-image-repository` | Queries CodebaseImageStream for `payment-service-main`. Finds image: `registry.example.com/payment-service`, tag: `0.1.0-SNAPSHOT.42`. |
| B.2 `helm-template-and-extract` | Renders the Helm chart with image overrides. Discovers 2 images: `registry.example.com/payment-service:0.1.0-SNAPSHOT.42` and `nginx:1.25-alpine` (sidecar). |
| B.3 `trivy` | Scans both images against Trivy server. |
| B.4 `grype` | Scans both images with Grype. |
| B.5 `upload-report` | Uploads all 4 reports (2 images x 2 scanners) to DefectDojo. |
**What appears in DefectDojo after Task B:**
```text
Product: payment-service
├─ Engagement: "code-security-main"
│ └─ (Semgrep + Gitleaks findings from Task A)
│
├─ Engagement: "image:registry.example.com/payment-service:0.1.0-SNAPSHOT.42"
│ ├─ Test: "Trivy Scan" (version: 0.1.0-SNAPSHOT.42, branch: main)
│ │ ├─ Finding: CVE-2024-32002 — git 2.43.0 [HIGH]
│ │ └─ Finding: CVE-2024-6345 — setuptools 69.0.3 [HIGH]
│ └─ Test: "Anchore Grype" (version: 0.1.0-SNAPSHOT.42, branch: main)
│ └─ Finding: CVE-2024-32002 — git 2.43.0 [High]
│
└─ Engagement: "image:nginx:1.25-alpine"
├─ Test: "Trivy Scan"
│ └─ Finding: CVE-2024-24790 — Go standard library [CRITICAL]
└─ Test: "Anchore Grype"
└─ Finding: CVE-2024-24790 — Go standard library [Critical]
```
### Phase 4: On-Demand Remote Image Scan
If the security team needs to re-scan specific images without source code (e.g., after a Trivy DB update), they trigger the `image-scan-remote` pipeline:
```yaml
params:
IMAGE_NAMES:
- "registry.example.com/payment-service:0.1.0-SNAPSHOT.42"
CODEBASE_NAME: "payment-service"
```
This runs Trivy against the remote registry and uploads results to the existing `payment-service` product in DefectDojo, updating the per-image engagement.
### Security Coverage Summary
| Scanner | What It Detects | Where Results Live | Blocks Pipeline? |
|---------|----------------|-------------------|:---:|
| **SonarQube** | Code quality, bugs, security vulnerabilities, coverage | SonarQube server | Yes (Quality Gate) |
| **Semgrep** | SAST findings (injection, deserialization, etc.) | DefectDojo | No |
| **Gitleaks** | Hardcoded secrets and credentials | DefectDojo | No |
| **cdxgen + Dependency-Track** | Vulnerable dependencies, license risks | Dependency-Track | No |
| **Trivy** | OS-level and library CVEs in container images | DefectDojo | No |
| **Grype** | OS-level and library CVEs in container images | DefectDojo | No |
| **Hadolint** | Dockerfile best practices | Pipeline log | Yes (review only) |
| **Helm Lint** | Chart structure and template errors | Pipeline log | Yes (review only) |
:::note
SonarQube is the only scanner that acts as a hard gate. All other security scanners operate in a "report and continue" mode — findings are sent to DefectDojo and Dependency-Track for triage by the security team.
:::
## Related Articles
* [Security and Compliance: Overview](./overview.md)
* [Integrate DefectDojo](./defectdojo.md)
* [Integrate Dependency-Track](./dependency-track.md)
* [SonarQube Integration](../code-quality/sonarqube.md)
* [Tekton Overview](../ci/tekton-overview.md)
---
## Install Velero
# Automated Kubernetes Backup and Restore Workflows With Velero
[Velero](https://velero.io/) is an open source tool to safely back up, recover, and migrate Kubernetes clusters and persistent volumes.
It works both on premises and in a public cloud. Velero consists of a server process running as a deployment in your
Kubernetes cluster and a command-line interface (CLI) with which DevOps teams and platform operators configure scheduled
backups, trigger ad-hoc backups, perform restores, and more.
Configuring and installing Velero involves two key steps:
- **Setting up AWS resources** – configuring IAM roles and policies.
- **Installing Velero** – deploying the Velero components into the Kubernetes cluster.
## Configuring AWS IAM Roles and Policies
Velero requires specific IAM permissions to interact with AWS resources. These permissions allow Velero to create and manage EBS snapshots and volumes, as well as read and write backup data to the designated S3 bucket. This policy ensures Velero can perform backup and restore operations within your AWS account.
To simplify the setup, we recommend using the [terraform-module/velero/kubernetes](https://registry.terraform.io/modules/terraform-module/velero/kubernetes/latest) module. This module automates the creation of the necessary IAM roles and policies for Velero. You can find Velero configuration parameters in the [terraform-aws-platform](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/eks/irsa.tf#L367) repository.
With this configuration, the following IAM role will be created:
- **AWSIRSA_\_Velero**: This role will be used by Velero to perform backup and restore operations by managing EBS snapshots and accessing the S3 backup bucket. The attached policy grants Velero the required permissions to perform backup and restore operations in AWS. It includes the following capabilities:
- **EC2 permissions** — allow Velero to create, describe, tag, and delete EBS snapshots and volumes used during backup and restore processes.
- **S3 bucket access** — allows listing the backup bucket and performing read/write operations on objects, including uploading backup data, retrieving it during restores, and deleting or tagging objects as needed.
## Install Velero
To deploy Velero in your Kubernetes cluster, we recommend using the [add-ons approach](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/velero). Here's an example of how to configure values.yaml before installation:
```yaml title="values.yaml"
velero:
# -- Velero service account settings for AWS access via IRSA. Replace the role ARN with your own IAM role.
serviceAccount:
server:
create: true
name: velero-server
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::01234567890:role/AWSIRSA_Core_Velero"
# -- Use Kubernetes secrets for AWS credentials (false = use IRSA)
credentials:
useSecret: false
configuration:
# -- Backup storage settings for Velero
backupStorageLocation:
- name: default
provider: aws
bucket: velero-core
prefix: velero
config:
region: eu-central-1
# -- Settings for volume snapshots
volumeSnapshotLocation:
- name: default
provider: aws
config:
region: eu-central-1
# -- Init container to load AWS plugin for Velero
initContainers:
- name: velero-plugin-for-aws
image: velero/velero-plugin-for-aws:v1.13.1
volumeMounts:
- mountPath: /target
name: plugins
# --------------------------------------------
# Velero Schedule: krci
# --------------------------------------------
# Description:
# Creates daily backups of the "krci" namespace
# on weekdays (Monday–Friday) at 13:00 UTC.
# Excludes PersistentVolumes and PVCs,
# does not snapshot volumes,
# stores backups in the "default" location,
# and retains them for 72 hours.
# --------------------------------------------
schedules:
krci:
disabled: true
paused: false
labels:
cluster: core
region: eu-central-1
schedule: "0 13 * * 1-5"
useOwnerReferencesInBackup: false
template:
excludedClusterScopedResources:
- persistentvolumes
excludedNamespaceScopedResources:
- persistentvolumeclaims
includedNamespaces:
- krci
snapshotVolumes: false
storageLocation: default
ttl: 72h0m0s
```
At the end of the file, you will find backup schedule settings that you can use as a template for creating your own schedules.
## Related Articles
* [Associate IAM Roles With Service Accounts](../infrastructure-providers/aws/enable-irsa.md)
---
## Restore KubeRocketCI Tenant With Velero
# Restore KubeRocketCI Tenant With Velero
You can use the Velero tool to restore a platform tenant. Explore the main steps for backup and restoring below.
1. Delete all related entities in **Keycloak**: realm and clients from **master/openshift** realms. Navigate to the entities list in the Keycloak, select the necessary ones, and click the deletion icon on the entity overview page.
If there are customized configs in Keycloak, save them before making backup.

2. To restore KubeRocketCI, install and configure the Velero tool. Please refer to the [Install Velero](install-velero-add-ons.md) documentation for details.
3. Remove all locks for operators. Delete all config maps that have `-operator-lock` names. Then restart all pods with operators, or simply run the following command:
```bash
kubectl -n krci delete cm $(kubectl -n krci get cm | grep 'operator-lock' | awk '{print $1}')
```
---
## Enable Git Resource Discovery
# Enable Git Resource Discovery
This page describes installation of the [GitFusion](https://github.com/KubeRocketCI/gitfusion) component, allowing the portal to access Git-related information without requiring direct access to the Version Control System.
GitFusion enhances the developer experience by facilitating automated discovery of Git repositories, remote branches, and organizational structures across multiple Git providers. The service operates as an intermediary layer, securing communication between the KubeRocketCI portal and Git infrastructure while enabling rich repository browsing capabilities.
## Installation
:::warning
When integrating GitFusion with Bitbucket repositories, ensure your Bitbucket API token includes the `account:read` permission scope. Detailed instructions for configuring Bitbucket API tokens with appropriate permissions are available in the [Add Git Server](../../user-guide/add-git-server.md) documentation.
:::
To enable the GitFusion integration in KubeRocketCI, follow the steps below:
1. Activate GitFusion service deployment by modifying the [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/apps/values.yaml#L87) repository. Set the `gitfusion.enable` flag to `true` in the `values.yaml` file:
```yaml title="values.yaml"
gitfusion:
enable: true
```
## Verification
Once GitFusion deployment is complete, validate the integration functionality through the following testing procedures:
### Component Discovery
1. Navigate to **KubeRocketCI portal** -> **Components**.
2. On the **Components** page, click **+ Create component** -> **Application** -> **Import**.
3. Within the **Create Application** dialog, use the **Owner** dropdown to select your Git account (configured during Git Server setup):

4. Browse available repositories using the **Repository** dropdown to select the desired application for import:

### Creating Branches
1. Return to the **KubeRocketCI portal**, access **Components**, and select a specific component by clicking its name.
2. Switch to the **Branches** tab within the component details view and click **+ Create branch**.
3. In the **Create branch** dialog, interact with the branch name field to display the list of remotely available branches:

## Related Articles
* [Add Application](../../user-guide/add-application.md)
* [Manage Branches](../../user-guide/manage-branches.md)
---
## KubeRocketCI Operator Guide: Installation, Configuration, and Administration
# KubeRocketCI Operator Guide: Installation, Configuration, and Administration
The Operator guide is intended for DevOps and provides information on KubeRocketCI installation, configuration and customization, as well as the platform support. Inspect the documentation to adjust the KubeRocketCI according to your business needs:
- **Installation** - Provides step-by-step guidelines for the platform prerequisites and platform installation process, including various methods such as [Helm Chart](./install-kuberocketci.md), [AWS Marketplace](./aws-marketplace-install.md), [Civo Marketplace](./install-via-civo.md), and via [Cluster Add-Ons](./add-ons-overview.md).
- **Authentication and Authorization** - Covers the platform's authentication models, including configurations for [Keycloak](auth/keycloak.md), [Namespace Management](auth/namespace-management.md), and [Microsoft Entra ID](microsoft-entra/oidc-authentication-overview.md).
- **Artifacts Management** - Describes artifacts management using [Nexus](artifacts-management/nexus-image-registry.md) or [Harbor](artifacts-management/harbor-installation.md).
- **Code Quality** - Provides guidelines on how to integrate platform with the mandatory [SonarQube](code-quality/sonarqube.md) component.
- **Project Management and Reporting** - Provides integration options with project management tools like [Jira](project-management-and-reporting/jira-integration.md) and [ReportPortal](project-management-and-reporting/install-reportportal.md).
- **Secrets Management** - Explains the installation and integration of the [External Secrets Operator](secrets-management/install-external-secrets-operator.md).
- **Security and Compliance** - Includes guides on integrating security and compliance tools such as [Dependency-Track](devsecops/dependency-track.md) and [DefectDojo](devsecops/defectdojo.md).
- **Monitoring and Observability** - Provides installation and configuration guides for monitoring and logging tools like [Grafana Loki](monitoring-and-observability/install-loki.md) and [Elasticsearch](monitoring-and-observability/kibana-ilm-rollover.md) stacks.
- **Continuous Integration (CI)** - Covers the setup and configuration of [Tekton](ci/tekton-overview.md).
- **Continuous Deployment (CD)** - This section contains guidelines on how to integrate a mandatory component [Argo CD](cd/argocd-integration.md). Besides, it also contains information on creating [custom pipelines](cd/customize-deploy-pipeline.md), and [deploying RPM packages](cd/deploy-rpm.md).
- **Infrastructure Providers** - Provides information on integrating with various infrastructure providers, including [AWS](deploy-aws-eks.md) and [OpenShift](infrastructure-providers/okd/deploy-okd-4.10.md).
- **Disaster Recovery** - Explains the installation and configuration of [Velero](disaster-recovery/install-velero-add-ons.md) as a solution for disaster recovery.
- **Upgrade** - Provides guides on upgrading KubeRocketCI and related components, including historical versions.
- **Troubleshooting** - Includes common troubleshooting guides for various issues that may occur during the setup and operation of KubeRocketCI.
---
## Atlantis Installation and Configuration Guide for Kubernetes: Terraform Automation
# Atlantis: Enterprise-Grade Terraform Automation for Kubernetes
Atlantis is an enterprise-ready tool for automating Terraform workflows in Kubernetes environments. It provides a robust web interface and seamlessly integrates with version control systems (VCS) to automatically run Terraform operations as part of the pull request process. This enables teams to systematically review, approve, and apply infrastructure changes in a consistent, secure, and auditable manner.
This guide covers the full process of installing and configuring Atlantis as Helm chart. It includes setting up authentication, configuring integration with supported version control systems (such as Bitbucket, GitHub, or GitLab), and preparing Atlantis to automate Terraform workflows triggered by pull/merge requests.
## Prerequisites
To install and configure Atlantis, ensure the following prerequisites are met:
- A running [AWS EKS](../deploy-aws-eks.md) cluster with the necessary [IAM](https://aws.amazon.com/iam) permissions to create IAM roles.
- A Git repository containing Terraform code with the required repository [structure](https://www.runatlantis.io/docs/requirements.html#repository-structure) is created.
- An Atlantis Git [user](https://www.runatlantis.io/docs/access-credentials.html#create-an-atlantis-user-optional) is created with a generated [Access Token](https://www.runatlantis.io/docs/access-credentials.html#generating-an-access-token).
- A forked copy of the [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository for managing the Atlantis installation is cloned to the local machine.
- [Helm](https://helm.sh) is installed and configured.
- [kubectl](https://kubernetes.io/docs/tasks/tools/) is installed and configured.
- (Optional) [Argo CD](../install-argocd.md) is installed and configured.
- (Optional) [External Secrets Operator](../secrets-management/external-secrets-operator-integration) is installed and configured.
- (Optional) [Keycloak](../auth/keycloak) and [keycloak-operator](https://github.com/epam/edp-keycloak-operator) is installed and configured.
## Configuring Atlantis
:::important
All configuration steps described in this section are based on the [Atlantis](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/atlantis) Helm chart that can be found in the [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons/tree/main) repository.
:::
This section describes how to configure Atlantis for integration with supported version control systems (VCS), including setting up authentication for Atlantis Web Server, configuring Webhooks, and creating the AWS IAM Role which is required for Atlantis to perform Terraform operations on the selected provider.
## Authentication Configuration
By default, Atlantis Web Server is deployed without any authentication mechanism, which means it is publicly accessible. This setup is not recommended, as it exposes the Atlantis UI and related operations to unauthorized access.
This section describes two approaches to configure authentication for Atlantis Web Server:
1. **Basic Authentication**: A simple method that restricts access using a static username and password, stored as a Kubernetes secret.
2. **External Authentication Proxy**: A more advanced method that delegates authentication to an external identity provider (e.g., Keycloak) using an authentication proxy tools like [oauth2-proxy](https://oauth2-proxy.github.io/oauth2-proxy/). This method provides role-based access control and centralized user management.
### Basic Authentication
:::note
For more details on configuring basic authentication, refer to the [Atlantis Security documentation](https://www.runatlantis.io/docs/security#enable-authentication-on-atlantis-web-server) page.
:::
To configure Basic Authentication for Atlantis Web Server, follow the steps below:
1. Create a Kubernetes secret containing the username and password for Basic Authentication:
There are two ways to create a secret: manually using the `kubectl` command or using the External Secrets Operator (ESO).
kubectl
Run the following command to create a secret:
```bash
kubectl create secret generic atlantis-creds -n atlantis \
--from-literal=username= \
--from-literal=password=
```
The `username` and `password` are the credentials that will be used to access the Atlantis Web Server.
External Secrets Operator
Enable ESO section in the `values.yaml` file and configure the necessary parameters. For example:
```yaml
eso:
# -- Install components of the ESO.
enabled: true
# -- Defines provider type. One of `aws`, `generic`, or `vault`.
provider: "aws"
# -- Defines the path to the secret in the provider. If provider is `vault`, this is the path must be prefixed with `secret/`.
secretPath: "/infra/core/addons/atlantis"
# -- AWS configuration (if provider is `aws`).
aws:
# -- AWS region.
region: "eu-central-1"
# -- AWS role ARN for the ExternalSecretOperator to assume.
roleArn: "arn:aws:iam::012345678910:role/AWSIRSA_Shared_ExternalSecretOperatorAccess"
```
Specify the `username` and `password` fields in the AWS Parameter Store object. For example:
```json
{
"oauth2-proxy": {
"client-id": "",
"cookie-secret": ""
},
"bitbucket_token": "",
"bitbucket_secret": "",
"username": "",
"password": "",
"clientSecret": ""
}
```
After configuring the ESO section, the External Secrets Operator will automatically create the Kubernetes secret `atlantis-creds` during installation or upgrade of the Atlantis Helm chart.
2. Update the `values.yaml` file to enable Basic Authentication by setting the `atlantis.basicAuthSecretName` field to the name of the secret created in the previous step. For example:
```yaml title="values.yaml"
atlantis:
basicAuthSecretName: atlantis-creds
```
3. Apply the changes by using the `helm upgrade` command or syncing the Argo CD application.
After configuring and enabling Basic Authentication, users will be required to provide the username and password to access the Atlantis Web Server.
### External Authentication Proxy (OAuth2 Proxy)
To configure an external authentication proxy (e.g., OAuth2 Proxy) with Keycloak for Atlantis Web Server, follow the steps below:
1. Ensure that the Keycloak and [keycloak-operator](https://github.com/epam/edp-keycloak-operator) are installed and configured.
2. Update the `values.yaml` by setting the `oidc.enabled` field to `true` for enabling KeycloakClient resource creation. For example:
```yaml title="values.yaml"
oidc:
enabled: true
```
3. Create a Kubernetes secret containing the Keycloak client credentials. The secret should include the `clientSecret` field with the value of the Keycloak client secret. For example:
:::note
The `keycloak-client-atlantis-secret` is used by keycloak-operator to create the `KeycloakClient` resource.
:::
kubectl
Run the following command to create a secret:
```bash
kubectl create secret generic keycloak-client-atlantis-secret -n atlantis \
--from-literal=clientSecret=
```
The `clientSecret` is a random generated string that is used to authenticate the Atlantis client with Keycloak. It can be generated using the following command:
```bash
openssl rand -base64 32 | head -c 32
```
External Secrets Operator
Enable ESO section in the `values.yaml` file and configure the necessary parameters. For example:
```yaml
eso:
# -- Install components of the ESO.
enabled: true
# -- Defines provider type. One of `aws`, `generic`, or `vault`.
provider: "aws"
# -- Defines the path to the secret in the provider. If provider is `vault`, this is the path must be prefixed with `secret/`.
secretPath: "/infra/core/addons/atlantis"
# -- AWS configuration (if provider is `aws`).
aws:
# -- AWS region.
region: "eu-central-1"
# -- AWS role ARN for the ExternalSecretOperator to assume.
roleArn: "arn:aws:iam::012345678910:role/AWSIRSA_Shared_ExternalSecretOperatorAccess"
```
Specify the `clientSecret` field in the AWS Parameter Store object. For example:
```json
{
"oauth2-proxy": {
"client-id": "",
"cookie-secret": ""
},
"bitbucket_token": "",
"bitbucket_secret": "",
"username": "",
"password": "",
"clientSecret": ""
}
```
The `clientSecret` is a random generated string that is used to authenticate the Atlantis client with Keycloak. It can be generated using the following command:
```bash
openssl rand -base64 32 | head -c 32
```
After configuring the ESO section, the External Secrets Operator will automatically create the Kubernetes secret `keycloak-client-atlantis-secret` during installation or upgrade of the Atlantis Helm chart.
4. Enable the `oauth2-proxy` section in the `values.yaml` file and configure the necessary parameters for the external authentication proxy. For example:
```yaml title="values.yaml"
oauth2-proxy:
enabled: true
extraArgs:
# Skip authentication for /events endpoint to allow Git webhook access
skip-auth-regex: "^/events$"
config:
configFile: |-
allowed_roles = ["administrator", "developer"]
client_id = "atlantis"
code_challenge_method="S256"
cookie_csrf_expire="5m"
cookie_csrf_per_request="true"
cookie_domains = ["atlantis.example.com"]
cookie_secure = "true"
email_domains = [ "*" ]
insecure_oidc_allow_unverified_email = "true"
oidc_issuer_url = "https://keycloak.example.com/realms/"
pass_access_token = "true"
pass_authorization_header = "true"
pass_basic_auth = "false"
provider = "keycloak-oidc"
redirect_url = "https://atlantis.example.com/oauth2/callback"
skip_jwt_bearer_tokens = "true"
upstreams = [ "http://atlantis:80" ]
whitelist_domains = [".example.com"]
silence_ping_logging = "true"
existingSecret: oauth2-proxy
ingress:
enabled: true
hosts:
- atlantis.example.com
```
5. Create a Kubernetes secret `oauth2-proxy` containing the `client-id`, `client-secret`, and `cookie-secret` values. The `client-id` and `client-secret` values should match the Keycloak client credentials. The `cookie-secret` value is a random string used to encrypt the session cookies:
kubectl
Run the following command to create a secret:
```bash
kubectl create secret generic oauth2-proxy -n atlantis \
--from-literal=client-id=atlantis \
--from-literal=client-secret= \
--from-literal=cookie-secret=
```
The `client-secret` is the random string generated in the previous step.
The `cookie-secret` is a random generated string that is used to encrypt the session cookies. It can be generated using the following command:
```bash
openssl rand -base64 32 | head -c 32
```
External Secrets Operator
Enable ESO section in the `values.yaml` file and configure the necessary parameters. For example:
```yaml
eso:
# -- Install components of the ESO.
enabled: true
# -- Defines provider type. One of `aws`, `generic`, or `vault`.
provider: "aws"
# -- Defines the path to the secret in the provider. If provider is `vault`, this is the path must be prefixed with `secret/`.
secretPath: "/infra/core/addons/atlantis"
aws:
# -- AWS region.
region: "eu-central-1"
# -- AWS role ARN for the ExternalSecretOperator to assume.
roleArn: "arn:aws:iam::012345678910:role/AWSIRSA_Shared_ExternalSecretOperatorAccess"
```
Specify the `oauth2-proxy` section in the AWS Parameter Store object. Also, make sure that the `clientSecret` field is included. For example:
```json
{
"oauth2-proxy": {
"client-id": "atlantis",
"cookie-secret": ""
},
"bitbucket_token": "",
"bitbucket_secret": "",
"username": "",
"password": "",
"clientSecret": ""
}
```
The `clientSecret` is the random string generated in the previous step.
The `oauth2-proxy.cookie-secret` is a random generated string that is used to encrypt the session cookies. It can be generated using the following command:
```bash
openssl rand -base64 32 | head -c 32
```
After configuring the ESO section, the External Secrets Operator will automatically create the Kubernetes secret `oauth2-proxy` during installation or upgrade of the Atlantis Helm chart.
6. Apply the changes by using the `helm upgrade` command or syncing the Argo CD application.
7. After configuring the external authentication proxy, users will be required to authenticate using Keycloak credentials to access the Atlantis Web Server:

## Webhook Configuration
:::note
For more details on configuring webhooks, refer to the [Atlantis Webhook documentation](https://www.runatlantis.io/docs/configuring-webhooks.html).
:::
Atlantis requires a webhook to be configured in the Git repository to trigger Terraform operations. The webhook should be set up to send events to the Atlantis Web Server URL.
For each supported VCS, follow the steps below to configure the webhook:
To configure the Atlantis webhook in GitHub, follow these steps:
- In the GitHub repository, navigate to **Settings** -> **Webhooks**.
- Click **Add webhook**.
- Set the **Payload URL** to `http:///events` or `https:///events` (if using SSL).
- Set the **Content type** to `application/json`.
- In the **Secret** field, provide the [secret](https://www.runatlantis.io/docs/webhook-secrets.html) generated for the webhook.
- Select **Let me select individual events** and choose the events you want to trigger the webhook, such as:
- **Pull request reviews**
- **Pushes**
- **Issue comments**
- **Pull requests**
- Leave the **Active** option enabled.
- Click **Add webhook** to save the configuration.

To configure the Atlantis webhook in GitLab, follow these steps:
- In the GitLab repository, navigate to **Settings** -> **Webhooks**.
- Click **Add new webhook**.
- Set the **Name** to `atlantis`.
- Set the **URL** to `http:///events` or `https:///events` (if using SSL).
- In the **Secret token** field, provide the [secret](https://www.runatlantis.io/docs/webhook-secrets.html) generated for the webhook.
- Select the events you want to trigger the webhook, such as:
- **Push events**
- **Comments**
- **Merge Request events**
- Click **Add webhook** to save the configuration.

To configure the Atlantis webhook in Bitbucket, follow these steps:
- In the Bitbucket repository, navigate to **Repository Settings**. Under the **Workflow** section, select **Webhooks**.
- Click **Add webhook**.
- Set the **Title** to `atlantis`.
- Set the **URL** to `http:///events` or `https:///events` (if using SSL).
- In the **Secret** field, provide the [secret](https://www.runatlantis.io/docs/webhook-secrets.html) generated for the webhook.
- In the **Triggers** section, uncheck all options for **Repository** and **Issue** events. For **Pull Request** events, select the following:
- **Created**
- **Updated**
- **Merged**
- **Declined**
- **Comment**
- Click **Save** to save the configuration.

After configuring the webhook, it is necessary to create the Atlantis webhook Kubernetes secret. This secret should contain the **Access Token** and **Secret** fields, which are used to authenticate the webhook requests sent from the VCS to the Atlantis Web Server.
1. Create a Kubernetes webhook secret containing the **Access Token** and **Secret** parameters.
kubectl
:::note
It is also possible to specify tokens and webhook secrets for multiple providers in the same Kubernetes secret. Atlantis will automatically use the appropriate fields based on the provider specified in the webhook configuration.
:::
Run the following command to create a secret with the Git provider credentials.
For Bitbucket, run the following command:
```bash
kubectl create secret generic atlantis-webhook \
--from-literal=bitbucket_token= \
--from-literal=bitbucket_secret=
```
The `bitbucket_token` is the generated [API Token](https://support.atlassian.com/bitbucket-cloud/docs/using-api-tokens/) for the Bitbucket user.
The `bitbucket_secret` is the generated [secret](https://www.runatlantis.io/docs/webhook-secrets.html) for the Bitbucket webhook.
For GitHub, run the following command:
```bash
kubectl create secret generic atlantis-webhook \
--from-literal=github_token= \
--from-literal=github_secret=
```
The `github_token` is the generated [Access Token](https://www.runatlantis.io/docs/access-credentials.html#generating-an-access-token) for the GitHub user.
The `github_secret` is the generated [secret](https://www.runatlantis.io/docs/webhook-secrets.html) for the GitHub webhook.
For GitLab, run the following command:
```bash
kubectl create secret generic atlantis-webhook \
--from-literal=gitlab_token= \
--from-literal=gitlab_secret=
```
The `gitlab_token` is the generated [Access Token](https://www.runatlantis.io/docs/access-credentials.html#generating-an-access-token) for the GitLab user.
The `gitlab_secret` is the generated [secret](https://www.runatlantis.io/docs/webhook-secrets.html) for the GitLab webhook.
External Secrets Operator
Enable ESO section in the `values.yaml` file and configure the necessary parameters. For example:
```yaml
eso:
# -- Install components of the ESO.
enabled: true
# -- Defines provider type. One of `aws`, `generic`, or `vault`.
provider: "aws"
# -- Defines the path to the secret in the provider. If provider is `vault`, this is the path must be prefixed with `secret/`.
secretPath: "/infra/core/addons/atlantis"
aws:
# -- AWS region.
region: "eu-central-1"
# -- AWS role ARN for the ExternalSecretOperator to assume.
roleArn: "arn:aws:iam::012345678910:role/AWSIRSA_Shared_ExternalSecretOperatorAccess"
```
Specify the Git provider token and Webhook secret in the AWS Parameter Store object.
:::note
It is also possible to specify tokens and webhook secrets for multiple providers in the same AWS Parameter Store object. The External Secrets Operator will automatically create the `atlantis-webhook` Kubernetes secret with the multiple fields based on the provided parameters.
:::
For Bitbucket:
```json
{
"oauth2-proxy": {
"client-id": "",
"cookie-secret": ""
},
"bitbucket_token": "",
"bitbucket_secret": "",
"username": "",
"password": "",
"clientSecret": ""
}
```
The `bitbucket_token` is the generated [API Token](https://support.atlassian.com/bitbucket-cloud/docs/using-api-tokens/) for the Bitbucket user.
The `bitbucket_secret` is the generated [secret](https://www.runatlantis.io/docs/webhook-secrets.html) for the Bitbucket webhook.
For GitHub:
```json
{
"oauth2-proxy": {
"client-id": "",
"cookie-secret": ""
},
"github_token": "",
"github_secret": "",
"username": "",
"password": "",
"clientSecret": ""
}
```
The `github_token` is the generated [Access Token](https://www.runatlantis.io/docs/access-credentials.html#generating-an-access-token) for the GitHub user.
The `github_secret` is the generated [secret](https://www.runatlantis.io/docs/webhook-secrets.html) for the GitHub webhook.
For GitLab:
```json
{
"oauth2-proxy": {
"client-id": "",
"cookie-secret": ""
},
"gitlab_token": "",
"gitlab_secret": "",
"username": "",
"password": "",
"clientSecret": ""
}
```
The `gitlab_token` is the generated [Access Token](https://www.runatlantis.io/docs/access-credentials.html#generating-an-access-token) for the GitLab user.
The `gitlab_secret` is the generated [secret](https://www.runatlantis.io/docs/webhook-secrets.html) for the GitLab webhook.
After configuring the ESO section, the External Secrets Operator will automatically create the Kubernetes secret `atlantis-webhook` during installation or upgrade of the Atlantis Helm chart.
2. Update the `values.yaml` file to enable the webhook secret by setting the `atlantis.vcsSecretName` field to the name of the secret created in the previous step. For example:
```yaml title="values.yaml"
atlantis:
vcsSecretName: atlantis-webhook
```
3. Apply the changes by using the `helm upgrade` command or syncing the Argo CD application.
After configuring the webhook secret, Atlantis will be able to authenticate incoming webhook requests from the VCS.
## Provider Credentials
:::note
For more details on configuring provider credentials, refer to the [Atlantis Provider Credentials documentation](https://www.runatlantis.io/docs/provider-credentials).
:::
Depending on the selected provider, Atlantis needs to be provided with the necessary permissions to perform Terraform operations. In this section, it is described how to create the required AWS IAM Role or use the built-in Atlantis IAM Role from the [terraform-aws-platform](https://github.com/KubeRocketCI/terraform-aws-platform) repository.
### Creating Atlantis IAM Role
To create the AWS IAM Role for Atlantis, follow the steps below:
1. Navigate to the AWS Management Console and open the [IAM](https://aws.amazon.com/iam/) service.
2. Under the **Access management** section, select **Roles**.
3. Click **Create role**.
4. Select **Web identity** as the trusted entity type.
5. In the **Web identity** section, select the OIDC provider for appropriate EKS cluster and the audience (`sts.amazonaws.com`).
6. Add the condition to the trust policy to allow the Atlantis service account to assume the role. The condition should include the following values:
- **Key** - `oidc.eks..amazonaws.com/id/:sub`
- **Condition** - `StringLike`
- **Value** - `system:serviceaccount::`

7. Click **Next** to proceed to the permissions page.
8. On the **Add permissions** page, attach the necessary policies for Atlantis to perform Terraform operations. Select the permissions boundary if required.

9. Click **Next** to proceed to the review page.
10. Provide a name for the role and review the configuration. Click **Create role** to create the role.

After creating the AWS IAM Role, it is necessary to attach the role to the Atlantis service account. This can be done by updating the `values.yaml` file of the Atlantis Helm chart.
1. Navigate to the `clusters/core/addons/atlantis` directory of the forked [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository.
2. Open the `values.yaml` file and update the `atlantis.serviceAccount.annotations` field to include the ARN of the created AWS IAM Role. For example:
```yaml title="values.yaml"
atlantis:
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam:::role/
```
3. Apply the changes by using the `helm upgrade` command or syncing the Argo CD application.
After configuring the AWS IAM Role, Atlantis will be able to assume the role and perform Terraform operations using the provided permissions.
### Using built-in Atlantis IAM Role
:::note
For more details about Atlantis IAM Role creation, refer to the [terraform-aws-platform](https://github.com/KubeRocketCI/terraform-aws-platform/tree/master/eks/atlantis.tf) repository.
:::
In case of using the [terraform-aws-platform](https://github.com/KubeRocketCI/terraform-aws-platform) repository to manage the AWS infrastructure, Atlantis can use the built-in **Atlantis** IAM Role created by the repository. This IAM Role is automatically created and configured with the necessary permissions to assume the **KRCIDeployerRole** IAM Role for performing Terraform operations.
To use the built-in Atlantis IAM Role, follow the steps below:
1. Navigate to the AWS Management Console and open the [IAM](https://aws.amazon.com/iam/) service.
2. Under the **Access management** section, select **Roles**. Ensure that the **Atlantis** IAM Role is created. If not, create the role using the [Deploy AWS EKS Cluster](../deploy-aws-eks.md) guide.
3. Navigate to the `clusters/core/addons/atlantis` directory of the forked [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository.
4. Open the `values.yaml` file and update the `atlantis.serviceAccount.annotations` field to include the ARN of the Atlantis IAM Role. For example:
```yaml title="values.yaml"
atlantis:
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam:::role/Atlantis
```
5. Apply the changes by using the `helm upgrade` command or syncing the Argo CD application.
After configuring the AWS IAM Role, Atlantis will be able to assume the **KRCIDeployerRole** IAM Role and perform Terraform operations using the provided permissions.
## Installing Atlantis
There are two approaches to install Atlantis using [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository:
- **Using Argo CD**: This approach implies installing Atlantis as an Argo CD Application resource.
- **Using Helm**: This approach involves installing Atlantis via common Helm commands.
### Approach 1: Using Argo CD
:::note
For more information on configuring [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository, refer to the [Install via Add-Ons](../add-ons-overview.md) page.
:::
The first approach is to deploy Atlantis using Argo CD. Follow the steps below to install Atlantis using Argo CD:
1. Clone the forked [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository.
2. Navigate to the `clusters/core/addons/atlantis` directory and configure the `values.yaml` file with the necessary values for the Atlantis installation.
3. After configuring the Atlantis Helm chart values, navigate to the `clusters/core/apps` directory. In the `values.yaml` file, update the `atlantis` section by specifying the `enable` field as `true` to enable Argo CD Application creation for the Atlantis. Modify the `createNamespace` and `namespace` fields as needed. For example:
```yaml
atlantis:
createNamespace: true
enable: true
namespace: atlantis
```
4. Commit and push the changes to the remote repository. After the changes are pushed, navigate to the Argo CD and sync the Atlantis application. Verify that the Atlantis is successfully deployed:

### Approach 2: Deploy Using Helm
The second approach is to deploy Atlantis using Helm. Follow the steps below to install Atlantis using Helm:
1. Clone the forked [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository.
2. Navigate to the `clusters/core/addons/atlantis` directory and configure the `values.yaml` file with the necessary values for the Atlantis installation.
3. After configuring the Atlantis Helm chart values, run the following command to deploy the Atlantis:
```bash
helm upgrade --install atlantis . -n atlantis --create-namespace
```
4. Verify that the Atlantis is successfully deployed.
## Related Articles
* [Install via Add-Ons](../add-ons-overview.md)
* [Install Keycloak](../auth/keycloak.md)
* [Install Argo CD](../install-argocd.md)
---
## AWS EBS CSI Driver Setup for EKS
# Amazon EBS CSI Driver
This guide shows how to install the AWS EBS CSI driver on an Amazon EKS cluster, step by step: creating the IAM OIDC trust policy, attaching the AWS-managed IAM policy, and deploying the driver as an EKS add-on so Kubernetes can manage Amazon EBS-backed Persistent Volumes.
## Prerequisites
An existing AWS Identity and Access Management (IAM) OpenID Connect (OIDC) provider for your cluster. To determine whether you already have an OIDC provider or to create a new one, see [Creating an IAM OIDC provider for your cluster](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html).
To add an Amazon EBS CSI add-on, please follow the steps below:
1. Check your cluster details (the random value in the cluster name will be required in the next step):
```bash
kubectl cluster-info
```
2. Create Kubernetes IAM Trust Policy for Amazon EBS CSI Driver. Replace `AWS_ACCOUNT_ID` with your account ID, `AWS_REGION` with your AWS Region, and `EXAMPLED539D4633E53DE1B71EXAMPLE` with the value that was returned in the previous step. Save this Trust Policy into a file `aws-ebs-csi-driver-trust-policy.json`.
aws-ebs-csi-driver-trust-policy.json
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::AWS_ACCOUNT_ID:oidc-provider/oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com",
"oidc.eks.AWS_REGION.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:ebs-csi-controller-sa"
}
}
}
]
}
```
To get the notion of the IAM Role creation, please refer to the [official documentation](https://docs.aws.amazon.com/eks/latest/userguide/csi-iam-role.html).
3. Create the IAM role, for example:
```bash
aws iam create-role \
--role-name AmazonEKS_EBS_CSI_DriverRole \
--assume-role-policy-document file://"aws-ebs-csi-driver-trust-policy.json"
```
4. Attach the required AWS Managed Policy `AmazonEBSCSIDriverPolicyV2` to the role with the following command:
```bash
aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AmazonEBSCSIDriverPolicyV2 \
--role-name AmazonEKS_EBS_CSI_DriverRole
```
5. Add the Amazon EBS CSI add-on using the AWS CLI. Replace `my-cluster` with the name of your cluster, `AWS_ACCOUNT_ID` with your account ID, and `AmazonEKS_EBS_CSI_DriverRole` with the name of the role that was created earlier:
```bash
aws eks create-addon --cluster-name my-cluster --addon-name aws-ebs-csi-driver \
--service-account-role-arn arn:aws:iam::AWS_ACCOUNT_ID:role/AmazonEKS_EBS_CSI_DriverRole
```
:::note
When the plugin is deployed, it creates the `ebs-csi-controller-sa` service account. The service account is bound to a Kubernetes `ClusterRole` with the required Kubernetes permissions.
The `ebs-csi-controller-sa` service account should already be annotated with `arn:aws:iam::AWS_ACCOUNT_ID:role/AmazonEKS_EBS_CSI_DriverRole`. To check the annotation, please run:
```bash
kubectl get sa ebs-csi-controller-sa -n kube-system -o=jsonpath='{.metadata.annotations}'
```
In case pods have errors, restart the `ebs-csi-controller` deployment:
```bash
kubectl rollout restart deployment ebs-csi-controller -n kube-system
```
:::
### Related Articles
* [Creating an IAM OIDC provider for your cluster](https://docs.aws.amazon.com/eks/latest/userguide/enable-iam-roles-for-service-accounts.html)
* [Creating the Amazon EBS CSI driver IAM role for service accounts](https://docs.aws.amazon.com/eks/latest/userguide/csi-iam-role.html)
* [Managing the Amazon EBS CSI driver as an Amazon EKS add-on](https://docs.aws.amazon.com/eks/latest/userguide/managing-ebs-csi.html)
---
## Associate IAM Roles With Service Accounts
# Associate IAM Roles With Service Accounts
This page contains information on how to associate an IAM role with the service account (IRSA).
Get acquainted with the [AWS Official Documentation](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-technical-overview.html) on the subject before proceeding.
## Common Configuration of IAM Roles With Service Accounts
To successfully associate the IAM role with the service account, follow the steps below:
1. Create an IAM role that will further be associated with the service account. This role must have the following trust policy:
**IAM Role**
```bash
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam:::oidc-provider/"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
":sub": "system:serviceaccount::"
}
}
}
]
}
```
View cluster's `` URL.
```bash
aws eks describe-cluster --name --query "cluster.identity.oidc.issuer" --output text
```
Example output:
```bash
https://oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E
```
`` in this example will be:
```bash
oidc.eks.us-west-2.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E
```
2. Annotate the created service account with the IAM role:
**Service Account**
```yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name:
namespace:
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam:::role/"
```
3. All newly launched pods with this service account will be modified and then use the associated IAM role. Find below the pod specification template:
**Pod Template**
```yaml
apiVersion: v1
kind: Pod
metadata:
name: irsa-test
namespace: default
spec:
serviceAccountName:
containers:
- name: irsa
image: public.ecr.aws/aws-cli/aws-cli:2.25.4
command: ['sh', '-c', 'aws sts "get-caller-identity" && sleep 3600']
```
4. Check the logs of the created pod from the template above.
Example output:
```json
{
"UserId": "XXXXXXXXXXXXXXXXXXXXX:botocore-session-XXXXXXXXXX",
"Account": "XXXXXXXXXXXX",
"Arn": "arn:aws:sts::XXXXXXXXXXXX:assumed-role/AWSIRSATestRole/botocore-session-XXXXXXXXXX"
}
```
As a result, it is possible to perform actions in AWS under the **AWSIRSATestRole** role.
---
## IAM Roles for Kaniko Service Accounts
# IAM Roles for Kaniko Service Accounts
:::note
Alternatively, the Kaniko IAM Role can also be created automatically during the cluster installation process.
For more details, refer to the [Deploy AWS EKS Cluster](../../deploy-aws-eks.md) page.
:::
The `build-image-kaniko` stage, used in Tekton build pipelines, manages [ECR](https://aws.amazon.com/ecr/) through IRSA that should be available on the cluster. Follow the steps below to create a required role:
1. Create AWS IAM Policy `AWSIRSA__Kaniko_policy`:
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:*",
"cloudtrail:LookupEvents"
],
"Resource": "arn:aws:ecr:::repository/*"
},
{
"Effect": "Allow",
"Action": "ecr:GetAuthorizationToken",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecr:DescribeRepositories",
"ecr:CreateRepository"
],
"Resource": "arn:aws:ecr:::repository/*"
}
]
}
```
2. Create AWS IAM Role `AWSIRSA__Kaniko` with trust relationships:
:::note
`OIDC_PROVIDER` value can be found in the AWS Management Console under the Elastic Kubernetes Service (EKS) service. Select the appropriate cluster and navigate to the **Overview** tab to find the `OpenID Connect provider URL` value.

:::
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam:::oidc-provider/"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
":sub": "system:serviceaccount:*"
}
}
}
]
}
```
3. Attach the `AWSIRSA__Kaniko_policy` policy to the `AWSIRSA__Kaniko` role.
4. Set the resulting Amazon Resource Name (ARN) of the role in the `edp-tekton.kaniko.roleArn` field within the `values.yaml` file during the [KubeRocketCI installation](../../install-kuberocketci.md).
## Related Articles
* [Associate IAM Roles With Service Accounts](enable-irsa.md)
---
## Configure AWS WAF With Terraform
# Configure AWS WAF With Terraform
This page contains accurate information on how to configure [AWS WAF](https://aws.amazon.com/waf/) using Terraform with the aim to have a secured traffic exposure and to prevent the Host Header vulnerabilities.
## Prerequisites
To follow the instruction, check the following prerequisites:
1. Deployed infrastructure includes Nginx Ingress Controller
2. Deployed services for testing
3. Separate and exposed AWS ALB
4. terraform 0.14.10
5. hashicorp/aws = 4.8.0
## Solution Overview
The solution includes two parts:
1. Prerequisites (mostly the left part of the scheme) - AWS ALB, Compute Resources (EC2, EKS, etc.).
2. WAF configuration (the right part of the scheme).
The WAF ACL resource is the main resource used for the configuration; The default web ACL option is Block.

The ACL includes three managed AWS rules that secure the exposed traffic:
- AWS-AWSManagedRulesCommonRuleSet
- AWS-AWSManagedRulesLinuxRuleSet
- AWS-AWSManagedRulesKnownBadInputsRuleSet
AWS provides a lot of rules such as baseline and use-case specific rules, for details, please refer to the [Baseline rule groups](https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-baseline.html).
There is the _PreventHostInjections_ rule that prevents the Host Header vulnerabilities. This rule includes one statement that declares that the Host Header should match Regex Pattern Set, thus only in this case it will be passed.
The Regex Pattern Set is another resource that helps to organize regexes, in fact, is a set of regexes. All regexes added to the single set are matched by the OR statement, i.e. when exposing several URLs, it is necessary to add this statement to the set and refer to it in the rule.
## WAF ACL Configuration
To create the Regex Pattern Set, inspect the following code:
```terraform
resource "aws_wafv2_regex_pattern_set" "common" {
name = "Common"
scope = "REGIONAL"
regular_expression {
regex_string = "^.*(some-url).*((.example)+)\\.com$"
}
# Add here additional regular expressions for other endpoints, they are merging with OR operator, e.g.
/*
regular_expression {
regex_string = "^.*(keycloak).*((.example)+)\\.com$"
}
*/
tags = var.tags
}
```
It includes 'regex_string', for example: url - some-url.example.com,
In addition, it is possible to add other links to the same resource using the regular_expression element.
There is the Terraform code for the aws_wafv2_web_acl resource:
```terraform
resource "aws_wafv2_web_acl" "external" {
name = "ExternalACL"
scope = "REGIONAL"
default_action {
block {}
}
rule {
name = "AWS-AWSManagedRulesCommonRuleSet"
priority = 1
override_action {
none {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesCommonRuleSet"
vendor_name = "AWS"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWS-AWSManagedRulesCommonRuleSet"
sampled_requests_enabled = true
}
}
rule {
name = "AWS-AWSManagedRulesLinuxRuleSet"
priority = 2
statement {
managed_rule_group_statement {
name = "AWSManagedRulesLinuxRuleSet"
vendor_name = "AWS"
}
}
override_action {
none {}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWS-AWSManagedRulesLinuxRuleSet"
sampled_requests_enabled = true
}
}
rule {
name = "AWS-AWSManagedRulesKnownBadInputsRuleSet"
priority = 3
override_action {
none {}
}
statement {
managed_rule_group_statement {
name = "AWSManagedRulesKnownBadInputsRuleSet"
vendor_name = "AWS"
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "AWS-AWSManagedRulesKnownBadInputsRuleSet"
sampled_requests_enabled = true
}
}
rule {
name = "PreventHostInjections"
priority = 0
statement {
regex_pattern_set_reference_statement {
arn = aws_wafv2_regex_pattern_set.common.arn
field_to_match {
single_header {
name = "host"
}
}
text_transformation {
priority = 0
type = "NONE"
}
}
}
action {
allow {}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "PreventHostInjections"
sampled_requests_enabled = true
}
}
visibility_config {
cloudwatch_metrics_enabled = true
metric_name = "ExternalACL"
sampled_requests_enabled = true
}
tags = var.tags
}
```
As mentioned previously, ACL includes three managed AWS rules (group rules), for visibility, enabling sampling, and CloudWatch in the config.
The 'PreventHostInjections' custom rule refers to the created pattern set and declares the Host Header, as well as sets the 'Action' if matched to 'Allow'.
## Associate AWS Resource
To have the created ACL working, it is necessary to associate an AWS resource with it, in this case, it is AWS ALB:
```terraform
resource "aws_wafv2_web_acl_association" "waf_alb" {
resource_arn = aws_lb..arn
web_acl_arn = aws_wafv2_web_acl.external.arn
}
```
:::note
AWS ALB can be created in the scope of this Terraform code or created previously. When creating ALB to expose links, the ALB should have a security group that allows some external traffic.
:::
When ALB is associated with the WAF ACL, direct the traffic to the ALB by the Route53 CNAME record:
```terraform
module "some_url_exposure" {
source = "terraform-aws-modules/route53/aws//modules/records"
version = "2.0.0"
zone_name = "example.com"
records = [
{
name = "some-url"
type = "CNAME"
ttl = 300
records = [aws_lb..dns_name]
}
]
}
```
In the sample above, the module is used, but it is also possible to use a Terraform resource.
---
## Deploy OKD 4.10 Cluster
# Deploy OKD 4.10 Cluster
This instruction provides detailed information on the OKD 4.10 cluster deployment in the AWS Cloud and contains the additional setup necessary for the managed infrastructure.
A full description of the cluster deployment can be found in the [official documentation](https://docs.openshift.com/container-platform/4.10/authentication/managing_cloud_provider_credentials/cco-mode-sts.html).
## Prerequisites
Before the OKD cluster deployment and configuration, make sure to check the prerequisites.
### Required Tools
1. Install the following tools listed below:
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)
- [OpenShift CLI](https://docs.openshift.com/container-platform/4.10/cli_reference/openshift_cli/getting-started-cli.html)
2. Create the AWS IAM user with [the required permissions](https://docs.okd.io/4.9/installing/installing_aws/installing-aws-account.html#installation-aws-permissions_installing-aws-account). Make sure the AWS account is active, and the user doesn't have a permission boundary. Remove any Service Control Policy (SCP) restrictions from the AWS account.
3. Generate a key pair for cluster node SSH access. Please perform the steps below:
- Generate the SSH key. Specify the path and file name, such as ~/.ssh/id_ed25519, of the new SSH key. If there is an existing key pair, ensure that the public key is in the ~/.ssh directory.
```bash
ssh-keygen -t ed25519 -N '' -f /
```
- Add the SSH private key identity to the SSH agent for a local user if it has not already been added.
```bash
eval "$(ssh-agent -s)"
```
- Add the SSH private key to the ssh-agent:
```bash
ssh-add /
```
4. Build the `ccoctl` tool:
- Clone the `cloud-credential-operator` repository.
```bash
git clone https://github.com/openshift/cloud-credential-operator.git
```
- Move to the `cloud-credential-operator` folder and build the `ccoctl` tool.
```bash
cd cloud-credential-operator && git checkout release-4.10
GO_PACKAGE='github.com/openshift/cloud-credential-operator'
go build -ldflags "-X $GO_PACKAGE/pkg/version.versionFromGit=$(git describe --long --tags --abbrev=7 --match 'v[0-9]*')" ./cmd/ccoctl
```
## Prepare for the Deployment Process
Before deploying the OKD cluster, please perform the steps below:
### Create AWS Resources
Create the AWS resources with the Cloud Credential Operator utility (the `ccoctl` tool):
1. Generate the public and private RSA key files that are used to set up the OpenID Connect identity provider for the cluster:
```bash
./ccoctl aws create-key-pair
```
2. Create an OpenID Connect identity provider and an S3 bucket on AWS:
```bash
./ccoctl aws create-identity-provider \
--name= \
--region= \
--public-key-file=./serviceaccount-signer.public
```
where:
- NAME - is the name used to tag any cloud resources created for tracking,
- AWS_REGION - is the AWS region in which cloud resources will be created.
3. Create the IAM roles for each component in the cluster:
- Extract the list of the `CredentialsRequest` objects from the OpenShift Container Platform release image:
```bash
oc adm release extract \
--credentials-requests \
--cloud=aws \
--to=./credrequests \
--quay.io/openshift-release-dev/ocp-release:4.10.25-x86_64
```
:::note
A version of the openshift-release-dev docker image can be found in the [Quay registry](https://quay.io/repository/openshift-release-dev/ocp-release?tab=tags).
:::
- Use the `ccoctl` tool to process all `CredentialsRequest` objects in the `credrequests` directory:
```bash
ccoctl aws create-iam-roles \
--name= \
--region= \
--credentials-requests-dir=./credrequests
--identity-provider-arn=arn:aws:iam:::oidc-provider/-oidc.s3..amazonaws.com
```
### Create OKD Manifests
Before deploying the OKD cluster, please perform the steps below:
1. Download the [OKD installer](https://github.com/openshift/okd/releases/tag/4.10.0-0.okd-2022-07-09-073606).
2. Extract the installation program:
```bash
tar -xvf openshift-install-linux.tar.gz
```
3. Download the installation pull secret for any private registry. This pull secret allows to authenticate with the services that are provided by the authorities, including [Quay.io](https://quay.io/), serving the container images for OKD components. For example, here is a pull secret for Docker Hub:
The pull secret for the private registry
```json
{
"auths":{
"https://index.docker.io/v1/":{
"auth":"$TOKEN"
}
}
}
```
4. Create a deployment directory and the **install-config.yaml** file:
```bash
mkdir okd-deployment
touch okd-deployment/install-config.yaml
```
To specify more details about the OKD cluster platform or to modify the values of the required parameters, customize the **install-config.yaml** file for the AWS. Please see below an example of the customized file:
install-config.yaml - OKD cluster’s platform installation configuration file
```yaml
apiVersion: v1
baseDomain:
credentialsMode: Manual
compute:
- architecture: amd64
hyperthreading: Enabled
name: worker
platform:
aws:
rootVolume:
size: 30
zones:
- eu-central-1a
type: r5.large
replicas: 3
controlPlane:
architecture: amd64
hyperthreading: Enabled
name: master
platform:
aws:
rootVolume:
size: 50
zones:
- eu-central-1a
type: m5.xlarge
replicas: 3
metadata:
creationTimestamp: null
name: 4-10-okd-sandbox
networking:
clusterNetwork:
- cidr: 10.128.0.0/14
hostPrefix: 23
machineNetwork:
- cidr: 10.0.0.0/16
networkType: OVNKubernetes
serviceNetwork:
- 172.30.0.0/16
platform:
aws:
region: eu-central-1
userTags:
user:tag: 4-10-okd-sandbox
publish: External
pullSecret:
sshKey: |
```
where:
- YOUR_DOMAIN - is a base domain,
- PULL_SECRET - is a created pull secret for a private registry,
- SSH_KEY - is a created SSH key.
5. Create the required OpenShift Container Platform installation manifests:
```bash
./openshift-install create manifests --dir okd-deployment
```
6. Copy the manifests generated by the `ccoctl` tool to the `manifests` directory created by the installation program:
```bash
cp ./manifests/* ./okd-deployment/manifests/
```
7. Copy the private key generated in the `tls` directory by the `ccoctl` tool to the installation directory:
```bash
cp -a ./tls ./okd-deployment
```
## Deploy the Cluster
To initialize the cluster deployment, run the following command:
```bash
./openshift-install create cluster --dir okd-deployment --log-level=info
```
:::note
If the cloud provider account configured on the host does not have sufficient permissions to deploy the cluster, the installation process stops, and the missing permissions are displayed.
:::
When the cluster deployment is completed, directions for accessing the cluster are displayed in the terminal, including a link to the web console and credentials for the **kubeadmin** user. The `kubeconfig` for the cluster will be located in **okd-deployment/auth/kubeconfig**.
Example output
```bash
...
INFO Install complete!
INFO To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/home/myuser/install_dir/auth/kubeconfig'
INFO Access the OpenShift web-console here: https://console-openshift-console.apps.mycluster.example.com
INFO Login to the console with the user: "kubeadmin", and password: "4vYBz-Ee6gm-ymBZj-Wt5AL"
INFO Time elapsed: 36m22s:
```
:::warning
The Ignition config files contain certificates that expire after 24 hours, which are then renewed at that time. Do not turn off the cluster for this time, or you will have to update the certificates manually. See [OpenShift Container Platform documentation](https://docs.openshift.com/container-platform/4.10/installing/installing_aws/installing-aws-customizations.html#installation-launching-installer_installing-aws-customizations) for more information.
:::
## Log Into the Cluster
To log into the cluster, export the `kubeconfig`:
```bash
export KUBECONFIG=/auth/kubeconfig
```
## Manage OKD Cluster Without the Inbound Rules
In order to manage the OKD cluster without the `0.0.0.0/0` inbound rules, please perform the steps below:
1. Create a Security Group with a list of your external IPs:
```bash
aws ec2 create-security-group --group-name --description "" --vpc-id
aws ec2 authorize-security-group-ingress \
--group-id '' \
--ip-permissions 'IpProtocol=all,PrefixListIds=[{PrefixListId=}]'
```
2. Manually attach this new Security Group to all master nodes of the cluster.
3. Create another Security Group with an Elastic IP of the Cluster VPC:
```bash
aws ec2 create-security-group --group-name custom-okd-4-10 --description "Cluster Ip to 80, 443" --vpc-id
aws ec2 authorize-security-group-ingress \
--group-id '' \
--protocol all \
--port 80 \
--cidr
aws ec2 authorize-security-group-ingress \
--group-id '' \
--protocol all \
--port 443 \
--cidr
```
4. Modify the cluster load balancer via the `router-default` svc in the `openshift-ingress` namespace, paste two Security Groups created on previous steps:
The pull secret for the private registry
```yaml
apiVersion: v1
kind: Service
metadata:
name: router-default
namespace: openshift-ingress
annotations:
service.beta.kubernetes.io/aws-load-balancer-additional-resource-tags: "tag_name=some_value"
service.beta.kubernetes.io/aws-load-balancer-security-groups: ""
...
```
## Optimize Spot Instances Usage
In order to optimize the usage of Spot Instances on the AWS, add the following line under the `providerSpec` field in the MachineSet of Worker Nodes:
```yaml
providerSpec:
value:
spotMarketOptions: {}
```
## Related Articles
* [Deploy AWS EKS Cluster](../../deploy-aws-eks.md)
* [Associate IAM Roles With Service Accounts](../aws/enable-irsa.md)
* [Deploy OKD 4.9 Cluster](deploy-okd-4.9.md)
---
## Deploy OKD 4.9 Cluster
# Deploy OKD 4.9 Cluster
This instruction provides detailed information on the OKD 4.9 cluster deployment in the AWS Cloud and contains the additional setup necessary for the managed infrastructure.
A full description of the cluster deployment can be found in the [official documentation](https://docs.okd.io/4.9/installing/installing_aws/installing-aws-customizations.html).
## Prerequisites
Before the OKD cluster deployment and configuration, make sure to check the prerequisites.
### Required Tools
1. Install the following tools listed below:
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)
- [OpenShift CLI](https://docs.openshift.com/container-platform/4.9/cli_reference/openshift_cli/getting-started-cli.html)
2. Create the AWS IAM user with [the required permissions](https://docs.okd.io/4.9/installing/installing_aws/installing-aws-account.html#installation-aws-permissions_installing-aws-account). Make sure the AWS account is active, and the user doesn't have a permission boundary. Remove any Service Control Policy (SCP) restrictions from the AWS account.
3. Generate a key pair for cluster node SSH access. Please perform the steps below:
- Generate the SSH key. Specify the path and file name, such as ~/.ssh/id_ed25519, of the new SSH key. If there is an existing key pair, ensure that the public key is in the ~/.ssh directory.
```bash
ssh-keygen -t ed25519 -N '' -f /
```
- Add the SSH private key identity to the SSH agent for a local user if it has not already been added.
```bash
eval "$(ssh-agent -s)"
```
- Add the SSH private key to the ssh-agent:
```bash
ssh-add /
```
## Prepare for the Deployment Process
Before deploying the OKD cluster, please perform the steps below:
1. Download the [OKD installer](https://github.com/openshift/okd/releases/tag/4.9.0-0.okd-2022-02-12-140851).
2. Extract the installation program:
```bash
tar -xvf openshift-install-linux.tar.gz
```
3. Download the installation pull secret for any private registry.
This pull secret allows to authenticate with the services that are provided by the included authorities, including [Quay.io](https://quay.io/) serving container images for OKD components. For example, here is a pull secret for Docker Hub:
The pull secret for the private registry
```json
{
"auths":{
"https://index.docker.io/v1/":{
"auth":"$TOKEN"
}
}
}
```
4. Create the deployment directory and the **install-config.yaml** file:
```bash
mkdir okd-deployment
touch okd-deployment/install-config.yaml
```
To specify more details about the OKD cluster platform or to modify the values of the required parameters, customize the **install-config.yaml** file for AWS. Please see an example of the customized file below:
install-config.yaml - OKD cluster’s platform installation configuration file
```yaml
apiVersion: v1
baseDomain:
compute:
- architecture: amd64
hyperthreading: Enabled
name: worker
platform:
aws:
zones:
- eu-central-1a
rootVolume:
size: 50
type: r5.large
replicas: 3
controlPlane:
architecture: amd64
hyperthreading: Enabled
name: master
platform:
aws:
rootVolume:
size: 50
zones:
- eu-central-1a
type: m5.xlarge
replicas: 3
metadata:
creationTimestamp: null
name: 4-9-okd-sandbox
platform:
aws:
region: eu-central-1
userTags:
user:tag: 4-9-okd-sandbox
publish: External
pullSecret:
sshKey: |
```
where:
- YOUR_DOMAIN - is a base domain,
- PULL_SECRET - is a created pull secret for a private registry,
- SSH_KEY - is a created SSH key.
## Deploy the Cluster
To initialize the cluster deployment, run the following command:
```bash
./openshift-install create cluster --dir --log-level=info
```
:::note
If the cloud provider account configured on the host does not have sufficient permissions to deploy the cluster, the installation process stops, and the missing permissions are displayed.
:::
When the cluster deployment is completed, directions for accessing the cluster are displayed in the terminal, including a link to the web console and credentials for the **kubeadmin** user. The `kubeconfig` for the cluster will be located in **okd-deployment/auth/kubeconfig**.
Example output
```bash
...
INFO Install complete!
INFO To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/home/myuser/install_dir/auth/kubeconfig'
INFO Access the OpenShift web-console here: https://console-openshift-console.apps.mycluster.example.com
INFO Login to the console with the user: "kubeadmin", and password: "4vYBz-Ee6gm-ymBZj-Wt5AL"
INFO Time elapsed: 36m22s:
```
:::warning
The Ignition config files contain certificates that expire after 24 hours, which are then renewed at that time. Do not turn off the cluster for this time, or you will have to update the certificates manually. See [OpenShift Container Platform documentation](https://docs.openshift.com/container-platform/4.9/installing/installing_aws/installing-aws-customizations.html#installation-launching-installer_installing-aws-customizations) for more information.
:::
## Log Into the Cluster
To log into the cluster, export the `kubeconfig`:
```bash
export KUBECONFIG=/auth/kubeconfig
```
## Related Articles
* [Deploy AWS EKS Cluster](../../deploy-aws-eks.md)
* [Deploy OKD 4.10 Cluster](deploy-okd-4.10.md)
---
## Use Cert-Manager in OpenShift
# Use Cert-Manager in OpenShift
The following material covers [Let's Encrypt](https://letsencrypt.org/) certificate automation with [cert-manager](https://github.com/cert-manager/cert-manager) using [AWS Route53](https://aws.amazon.com/route53/).
The [cert-manager](https://cert-manager.io/docs/) is a Kubernetes/OpenShift operator that allows to issue and automatically renew SSL certificates. In this tutorial, the steps to secure DNS Name will be demonstrated.
Below is an instruction on how to automatically issue and install wildcard certificates on OpenShift Ingress Controller and API Server covering all cluster Routes. To secure separate OpenShift Routes, please refer to the [OpenShift Route Support](https://github.com/cert-manager/openshift-routes) project for `cert-manager`.
## Prerequisites
- The cert-manager
- OpenShift v4.7 - v4.11
- Connection to the OpenShift Cluster
- Enabled AWS IRSA
- The latest [`oc` utility](https://github.com/openshift/okd/releases). The `kubectl` tool can also be used for most of the commands.
### Install Cert-Manager Operator
[Install](https://docs.openshift.com/container-platform/4.11/security/cert_manager_operator/cert-manager-operator-install.html) the `cert-manager` operator via OpenShift [OperatorHub](https://docs.openshift.com/container-platform/4.11/operators/understanding/olm-understanding-operatorhub.html) that uses [Operator Lifecycle Manager (OLM)](https://docs.openshift.com/container-platform/4.11/operators/understanding/olm/olm-understanding-olm.html):
1. Go to the **OpenShift Admin Console** → **OperatorHub**, search for the `cert-manager`, and click **Install**:

2. Modify the `ClusterServiceVersion` OLM resource, by selecting the **Update approval** → **Manual**. If selecting **Update approval** → **Automatic** after the automatic operator update, the parameters in the `ClusterServiceVersion` will be reset to default.
:::note
Installing an operator with **Manual approval** causes all operators installed in namespace `openshift-operators` to function as [manual approval strategy](https://docs.openshift.com/container-platform/4.11/operators/user/olm-installing-operators-in-namespace.html). In case the **Manual approval** is chosen, review the manual installation plan and approve it.
:::

3. Navigate to **Operators** → **Installed Operators** and check the operator status to be **Succeeded**:

4. In case of errors, [troubleshoot](https://docs.openshift.com/container-platform/4.11/operators/admin/olm-status.html) the Operator issues:
```bash
oc describe operator cert-manager -n openshift-operators
oc describe sub cert-manager -n openshift-operators
```
### Create AWS Role for Route53
The `cert-manager` should be configured to validate Wildcard certificates using the [DNS-based](https://cert-manager.io/docs/tutorials/acme/dns-validation/) method.
1. Check the DNS **Hosted zone ID** in AWS Route53 for your domain.

2. Create [Route53 Permissions policy](https://cert-manager.io/docs/configuration/acme/dns01/route53/#set-up-an-iam-role) in AWS for `cert-manager` to be able to create DNS TXT records for the certificate validation. In this example, `cert-manager` permissions are given for a particular DNS zone only. Replace **Hosted zone ID** *XXXXXXXX* in the *"Resource": "arn:aws:route53:::hostedzone/XXXXXXXXXXXX"*.
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "route53:GetChange",
"Resource": "arn:aws:route53:::change/*"
},
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets",
"route53:ListResourceRecordSets"
],
"Resource": "arn:aws:route53:::hostedzone/XXXXXXXXXXXX"
}
]
}
```
3. Create an AWS Role with **Custom trust policy** for the `cert-manager` service account to use the [AWS IRSA](https://cert-manager.io/docs/configuration/acme/dns01/route53/#eks-iam-role-for-service-accounts-irsa) feature and then attach the created policy. Replace the following:
- `${aws-account-id}` with the AWS account ID of the EKS cluster.
- `${aws-region}` with the region where the EKS cluster is located.
- `${eks-hash}` with the hash in the EKS API URL; this will be a random 32 character hex string, for example, 45DABD88EEE3A227AF0FA468BE4EF0B5.
- `${namespace}` with the namespace where cert-manager is running.
- `${service-account-name}` with the name of the ServiceAccount object created by cert-manager.
- By default, it is *"system:serviceaccount:openshift-operators:cert-manager"* if `cert-manager` is installed via OperatorHub.
- Attach the created **Permission policy** for Route53 to the Role.
- Optionally, add **Permissions boundary** to the Role.
```json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRoleWithWebIdentity",
"Principal": {
"Federated": "arn:aws:iam::* ${aws-account-id}:oidc-provider/oidc.eks.${aws-region}.amazonaws.com/id/${eks-hash}"
},
"Condition": {
"StringEquals": {
"oidc.eks.${aws-region}.amazonaws.com/id/${eks-hash}:sub": "system:serviceaccount:${namespace}:${service-account-name}"
}
}
}
]
}
```
4. Copy the created **Role ARN**.
### Configure Cert-Manager Integration With AWS Route53
1. [Annotate](https://cert-manager.io/docs/configuration/acme/dns01/route53/#service-annotation) the `ServiceAccount` created by `cert-manager` (required for [AWS IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html)), and restart the `cert-manager` pod.
2. Replace the `eks.amazonaws.com/role-arn` annotation value with your own Role ARN.
```bash
oc edit sa cert-manager -n openshift-operators
```
```yaml hl_lines="5"
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::XXXXXXXXXXXX:role/cert-manager
```
3. Modify the `cert-manager` `Deployment` with the correct file system permissions `fsGroup: 1001`, so that the `ServiceAccount` token can be read.
:::note
In case the `ServiceAccount` token cannot be read and the operator is installed using the OperatorHub, add `fsGroup: 1001` via OpenShift [ClusterServiceVersion](https://cert-manager.io/docs/installation/operator-lifecycle-manager/#configuration-via-clusterserviceversion-csv) OLM resource. It should be a `cert-manager` controller spec. These actions are not required for OpenShift v4.10.
:::
```bash
oc get csv
oc edit csv cert-manager.${VERSION}
```
```yaml
spec:
template:
spec:
securityContext:
fsGroup: 1001
serviceAccountName: cert-manager
```

:::info
A mutating admission controller will automatically modify all pods running with the service account:
cert-manager controller pod
```yaml
apiVersion: apps/v1
kind: Pod
# ...
spec:
# ...
serviceAccountName: cert-manager
serviceAccount: cert-manager
containers:
- name: ...
# ...
env:
- name: AWS_ROLE_ARN
value: >-
arn:aws:iam::XXXXXXXXXXX:role/cert-manager
- name: AWS_WEB_IDENTITY_TOKEN_FILE
value: /var/run/secrets/eks.amazonaws.com/serviceaccount/token
volumeMounts:
- name: aws-iam-token
readOnly: true
mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount
volumes:
- name: aws-iam-token
projected:
sources:
- serviceAccountToken:
audience: sts.amazonaws.com
expirationSeconds: 86400
path: token
defaultMode: 420
```
:::
4. If you have separate public and private DNS zones for the same domain (split-horizon DNS), modify the `cert-manager` `Deployment` in order to validate DNS TXT records via [public recursive nameservers](https://cert-manager.io/docs/configuration/acme/dns01/#setting-nameservers-for-dns01-self-check).
:::note
Otherwise, you will be getting an error during a record validation:
```bash
Waiting for DNS-01 challenge propagation: NS ns-123.awsdns-00.net.:53 returned REFUSED for `_acme-challenge`.
```
To avoid the error, add `--dns01-recursive-nameservers-only --dns01-recursive-nameservers=8.8.8.8:53,1.1.1.1:53` as ARGs to the `cert-manager` controller `Deployment`.
:::
```bash
oc get csv
oc edit csv cert-manager.${VERSION}
```
```yaml
labels:
app: cert-manager
app.kubernetes.io/component: controller
app.kubernetes.io/instance: cert-manager
app.kubernetes.io/name: cert-manager
app.kubernetes.io/version: v1.9.1
spec:
containers:
- args:
- '--v=2'
- '--cluster-resource-namespace=$(POD_NAMESPACE)'
- '--leader-election-namespace=kube-system'
- '--dns01-recursive-nameservers-only'
- '--dns01-recursive-nameservers=8.8.8.8:53,1.1.1.1:53'
```
:::note
The `Deployment` must be modified via OpenShift [ClusterServiceVersion](https://cert-manager.io/docs/installation/operator-lifecycle-manager/#configuration-via-clusterserviceversion-csv) OLM resource if the operator was installed using the OperatorHub.
The OpenShift `ClusterServiceVersion` OLM resource includes several Deployments, and the ARGs must be modified only for the `cert-manager` controller.
:::
- Save the resource. After that, OLM will try to reload the resource automatically and save it to the YAML file. If OLM resets the config file, double-check the entered values.

### Configure ClusterIssuers
`ClusterIssuer` is available on the whole cluster.
1. Create the [ClusterIssuer](https://cert-manager.io/docs/configuration/acme/) resource for Let's Encrypt Staging and Prod environments that signs a Certificate using `cert-manager`.
:::note
Let's Encrypt has a [limit](https://letsencrypt.org/docs/rate-limits/) of duplicate certificates in the Prod environment. Therefore, a `ClusterIssuer` has been created for [Let's Encrypt Staging](https://letsencrypt.org/docs/staging-environment/) environment. By default, Let's Encrypt Staging certificates will not be trusted in your browser. The certificate validation cannot be tested in the Let's Encrypt Staging environment.
:::
- Change `user@example.com` with your contact email.
- Replace `hostedZoneID` XXXXXXXXXXX with the DNS **Hosted zone ID** in AWS for your domain.
- Replace the region value `${region}`.
- The secret under `privateKeySecretRef` will be created automatically by the `cert-manager` operator.
```yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
email: user@example.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-staging-issuer-account-key
solvers:
- dns01:
route53:
region: ${region}
hostedZoneID: XXXXXXXXXXX
```
```yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: user@example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod-issuer-account-key
solvers:
- dns01:
route53:
region: ${region}
hostedZoneID: XXXXXXXXXXX
```

2. Check the `ClusterIssuer` status:

```bash
oc describe clusterissuer letsencrypt-prod
oc describe clusterissuer letsencrypt-staging
```
3. If the `ClusterIssuer` state is not ready, investigate `cert-manager` controller pod logs:
```bash
oc get pod -n openshift-operators | grep 'cert-manager'
oc logs -f cert-manager-${replica_set}-${random_string} -n openshift-operators
```
### Configure Certificates
1. In two different namespaces, create a [Certificate](https://cert-manager.io/docs/usage/certificate/) resource for the OpenShift Router (Ingress controller for OpenShift) and for the OpenShift APIServer.
- OpenShift Router supports a single wildcard certificate for Ingress/Route resources in different namespaces (so called, [default SSL certificate](https://cert-manager.io/docs/faq/sync-secrets/#serving-a-wildcard-to-ingress-resources-in-different-namespaces-default-ssl-certificate)). The Ingress controller expects the certificates in a `Secret` to be created in the `openshift-ingress` namespace; the API Server, in the `openshift-config` namespace. The `cert-manager` operator will automatically create these secrets from the `Certificate` resource.
- Replace `${DOMAIN}` with your domain name. It can be checked with `oc whoami --show-server`. Put domain names in quotes.
The certificate for OpenShift Router in the `openshift-ingress` namespace
```yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: router-certs
namespace: openshift-ingress
labels:
app: cert-manager
spec:
secretName: router-certs
secretTemplate:
labels:
app: cert-manager
duration: 2160h # 90d
renewBefore: 360h # 15d
subject:
organizations:
- Org Name
commonName: '*.${DOMAIN}'
privateKey:
algorithm: RSA
encoding: PKCS1
size: 2048
rotationPolicy: Always
usages:
- server auth
- client auth
dnsNames:
- '*.${DOMAIN}'
- '*.apps.${DOMAIN}'
issuerRef:
name: letsencrypt-staging
kind: ClusterIssuer
```
The certificate for OpenShift APIServer in the `openshift-config` namespace
```yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-certs
namespace: openshift-config
labels:
app: cert-manager
spec:
secretName: api-certs
secretTemplate:
labels:
app: cert-manager
duration: 2160h # 90d
renewBefore: 360h # 15d
subject:
organizations:
- Org Name
commonName: '*.${DOMAIN}'
privateKey:
algorithm: RSA
encoding: PKCS1
size: 2048
rotationPolicy: Always
usages:
- server auth
- client auth
dnsNames:
- '*.${DOMAIN}'
- '*.apps.${DOMAIN}'
issuerRef:
name: letsencrypt-staging
kind: ClusterIssuer
```
:::info
- `cert-manager` supports [ECDSA](https://cert-manager.io/docs/faq/#is-ecc-elliptic-curve-cryptography-supported) key pairs in the `Certificate` resource. To use it, change RSA `privateKey` to ECDSA:
```yaml
privateKey:
algorithm: ECDSA
encoding: PKCS1
size: 256
rotationPolicy: Always
```
- `rotationPolicy: Always` is highly recommended since `cert-manager` does not [rotate private keys](https://cert-manager.io/docs/usage/certificate/#the-rotationpolicy-setting) by default.
- Full `Certificate` spec is described in the `cert-manager` [API documentation](https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.CertificateSpec).
:::
2. Check that the certificates in the namespaces are ready:


3. Check the details of the certificates via CLI:
```bash
oc describe certificate api-certs -n openshift-config
oc describe certificate router-certs -n openshift-ingress
```
4. Check the cert-manager controller pod logs if the Staging Certificate condition is not ready for more than 7 minutes:
```bash
oc get pod -n openshift-operators | grep 'cert-manager'
oc logs -f cert-manager-${replica_set}-${random_string} -n openshift-operators
```
5. When the certificate is ready, its private key will be put into the OpenShift `Secret` in the namespace indicated in the `Certificate` resource:
```bash
oc describe secret api-certs -n openshift-config
oc describe secret router-certs -n openshift-ingress
```
### Modify OpenShift Router and API Server Custom Resources
1. Update the Custom Resource of your Router (Ingress controller). Patch the `defaultCertificate` object value with `{ "name": "router-certs" }`:
```bash
oc patch ingresscontroller default -n openshift-ingress-operator --type=merge --patch='{"spec": { "defaultCertificate": { "name": "router-certs" }}}' --insecure-skip-tls-verify
```
:::info
After updating the `IngressController` object, the OpenShift Ingress operator redeploys the router.
:::
2. Update the Custom Resource for the OpenShift API Server:
- Export the name of `APIServer`:
```bash
export OKD_API=$(oc whoami --show-server --insecure-skip-tls-verify | cut -f 2 -d ':' | cut -f 3 -d '/' | sed 's/-api././')
```
- Patch the `servingCertificate` object value with `{ "name": "api-certs" }`:
```bash
oc patch apiserver cluster --type merge --patch="{\"spec\": {\"servingCerts\": {\"namedCertificates\": [ { \"names\": [ \"$OKD_API\" ], \"servingCertificate\": {\"name\": \"api-certs\" }}]}}}" --insecure-skip-tls-verify
```
### Move From Let's Encrypt Staging Environment to Prod
1. Test the Staging certificate on the OpenShift Admin Console. The `--insecure` flag is used because Let's Encrypt Staging certificates are not trusted in browsers by default:
```bash
curl -v --insecure https://console-openshift-console.apps.${DOMAIN}
```
2. Change `issuerRef` to `letsencrypt-prod` in both `Certificate` resources:
```bash
oc edit certificate api-certs -n openshift-config
oc edit certificate router-certs -n openshift-ingress
```
```yaml
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
```
:::note
In case the certificate reissue is not triggered after that, try to force the certificate renewal with [cmctl](https://cert-manager.io/docs/usage/cmctl/):
```bash
cmctl renew router-certs -n openshift-ingress
cmctl renew api-certs -n openshift-config
```
If this won't work, delete the `api-certs` and `router-certs` secrets. It should trigger the Prod certificates issuance:
```bash
oc delete secret router-certs -n openshift-ingress
oc delete secret api-certs -n openshift-config
```
Please note that these actions will lead to logging your account out of the OpenShift Admin Console, since certificates will be deleted. Accept the certificate warning in the browser and log in again after that.
:::
3. Check the status of the Prod certificates:
```bash
oc describe certificate api-certs -n openshift-config
oc describe certificate router-certs -n openshift-ingress
```
```bash
cmctl status certificate api-certs -n openshift-config
cmctl status certificate router-certs -n openshift-ingress
```
4. Check the web console and make sure it has secure connection:
```bash
curl -v https://console-openshift-console.apps.${DOMAIN}
```
### Troubleshoot Certificates
Below is an example of the DNS TXT `challenge` record created by the `cert-manager` operator:

Use `nslookup` or `dig` tools to check if the DNS propagation for the TXT record is complete:
```bash
nslookup -type=txt _acme-challenge.${DOMAIN}
dig txt _acme-challenge.${DOMAIN}
```
Otherwise, use web tools like [Google Admin Toolbox](https://toolbox.googleapps.com/apps/dig/#TXT/):

If the correct TXT value is shown (the value corresponds to the current TXT value in the DNS zone), it means that the DNS propagation is complete and Let's Encrypt is able to access the record in order to validate it and issue a trusted certificate.
:::note
If the DNS validation challenge self check fails, `cert-manager` will retry the self check with a fixed 10-second retry interval. [Challenges](https://cert-manager.io/docs/concepts/acme-orders-challenges/#challenge-lifecycle) that do not ever complete the self check will continue retrying until the user intervenes by either retrying the `Order` (by deleting the `Order` resource) or amending the associated `Certificate` resource to resolve any configuration errors.
:::
As soon as the domain ownership has been verified, any `cert-manager` affected validation TXT records in the AWS Route53 DNS zone will be cleaned up.
Please find below the issues that may occur and their troubleshooting:
- When certificates are not issued for a long time, or a `cert-manager` resource is not in a Ready state, [describing](https://cert-manager.io/docs/faq/troubleshooting/) a resource may show the reason for the error.
- Basically, the `cert-manager` creates the following resources during a `Certificate` issuance: `CertificateRequest`, `Order`, and `Challenge`. [Investigate](https://cert-manager.io/docs/faq/acme/) each of them in case of errors.
- Use the [cmctl](https://cert-manager.io/docs/usage/cmctl/) tool to show the state of a `Certificate` and its associated resources.
- Check the `cert-manager` controller pod logs:
```bash
oc get pod -n openshift-operators | grep 'cert-manager'
oc logs -f cert-manager-${replica_set}-${random_string} -n openshift-operators
```
- Certificate error debugging:
a. Decode certificate chain located in the secrets:
```bash
oc get secret router-certs -n openshift-ingress -o 'go-template={{index .data "tls.crt"}}' | base64 -d | while openssl x509 -noout -text; do :; done 2>/dev/null
oc get secret api-certs -n openshift-config -o 'go-template={{index .data "tls.crt"}}' | base64 -d | while openssl x509 -noout -text; do :; done 2>/dev/null
```
```bash
cmctl inspect secret router-certs -n openshift-ingress
cmctl inspect secret api-certs -n openshift-config
```
b. Check the SSL RSA private key consistency:
```bash
oc get secret router-certs -n openshift-ingress -o 'go-template={{index .data "tls.key"}}' | base64 -d | openssl rsa -check -noout
oc get secret api-certs -n openshift-config -o 'go-template={{index .data "tls.key"}}' | base64 -d | openssl rsa -check -noout
```
c. Match the SSL certificate public key against its RSA private key. Their modulus must be identical:
```bash
diff <(oc get secret api-certs -n openshift-config -o 'go-template={{index .data "tls.crt"}}' | base64 -d | openssl x509 -noout -modulus | openssl md5) <(oc get secret api-certs -n openshift-config -o 'go-template={{index .data "tls.key"}}' | base64 -d | openssl rsa -noout -modulus | openssl md5)
diff <(oc get secret router-certs -n openshift-ingress -o 'go-template={{index .data "tls.crt"}}' | base64 -d | openssl x509 -noout -modulus | openssl md5) <(oc get secret router-certs -n openshift-ingress -o 'go-template={{index .data "tls.key"}}' | base64 -d | openssl rsa -noout -modulus | openssl md5)
```
### Remove Obsolete Certificate Authority Data From Kubeconfig
After updating the certificates, the access to the cluster via Lens or CLI will be denied because of the untrusted certificate errors:
```bash
$ oc whoami
Unable to connect to the server: x509: certificate signed by unknown authority
```
Such behavior appears because the `oc` tool references an old CA data in the kubeconfig file.
:::note
Examine the Certificate Authority data using the following command:
```bash
oc config view --minify --raw -o jsonpath='{.clusters[].cluster.certificate-authority-data}' | base64 -d | openssl x509 -text
```
This certificate has the `CA:TRUE` parameter, which means that this is a self-signed root CA certificate.
:::
To fix the error, remove the old CA data from your OpenShift kubeconfig file:
```bash
sed -i "/certificate-authority-data/d" $KUBECONFIG
```
Since this field will be absent in the kubeconfig file, system root SSL certificate will be used to validate the cluster certificate trust chain. On Ubuntu, Let's Encrypt OpenShift cluster certificates will be validated against `Internet Security Research Group` root in `/etc/ssl/certs/ca-certificates.crt`.
### Certificate Renewals
The `cert-manager` automatically [renews](https://cert-manager.io/docs/usage/certificate/#renewal) the certificates based on the X.509 certificate's duration and the `renewBefore` value.
The minimum value for the `spec.duration` is 1 hour; for `spec.renewBefore`, 5 minutes. It is also required that `spec.duration` > `spec.renewBefore`.
Use the [cmctl](https://cert-manager.io/docs/usage/cmctl/) tool to manually trigger a single instant certificate renewal:
```bash
cmctl renew router-certs -n openshift-ingress
cmctl renew api-certs -n openshift-config
```
Otherwise, manually renew all certificates in all namespaces with the `app=cert-manager` label:
```bash
cmctl renew --all-namespaces -l app=cert-manager
```
Run the `cmctl renew --help` command to get more details.
## Related Articles
* [Cert-Manager Official Documentation](https://cert-manager.io/docs/)
* [Installing the Cert-Manager Operator for Red Hat OpenShift](https://docs.openshift.com/container-platform/4.11/security/cert_manager_operator/cert-manager-operator-install.html)
* [Checking Issued Certificate Details](https://crt.sh/)
---
## KubeRocketCI Infrastructure Providers: Overview
# KubeRocketCI Infrastructure Providers: AWS, Azure, GCP, and On-Premises Overview
This section provides a technical overview and integration guidelines for Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP), and on-premises solutions through the perspective of KubeRocketCI.
It introduces cross-cutting features such as automated provisioning, scalable deployment configurations, and security best practices specific to each provider within the KubeRocketCI framework.
It aims to equip users with the necessary knowledge to deploy and manage KubeRocketCI in various environments efficiently, focusing on leveraging cloud-native technologies and optimizing infrastructure utilization.
This concise guide is essential for technical users seeking to understand and implement KubeRocketCI across different infrastructure platforms.
---
## Install Argo CD
# Install Argo CD
Review the necessary prerequisites and follow the steps to enable Argo CD within KubeRocketCI.
## Prerequisites
The following tools must be installed:
- [KubeRocketCI](./install-kuberocketci.md)
- [Kubectl version 1.34+](https://kubernetes.io/docs/tasks/tools/)
- [Helm version 3.10+](https://github.com/helm/helm/releases)
- [Keycloak](./auth/keycloak.md) (optional)
## Installation
Enabling Argo CD on the platform involves two main steps:
- Argo CD installation
- Argo CD integration with Add-Ons
Argo CD can be installed in several ways, please follow the [official documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/installation/) for more details. It is also possible to install Argo CD using the [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons/tree/main/argo-cd).
### Install With Helm
Follow the steps below to install Argo CD using Helm:
:::warning "For the OpenShift users"
When using the OpenShift platform, apply the `SecurityContextConstraints` resource. Change the namespace in the `users` section if required.
View: SecurityContextConstraints
```yaml
allowHostDirVolumePlugin: false
allowHostIPC: false
allowHostNetwork: false
allowHostPID: false
allowHostPorts: false
allowPrivilegeEscalation: true
allowPrivilegedContainer: false
allowedCapabilities: null
apiVersion: security.openshift.io/v1
allowedFlexVolumes: []
defaultAddCapabilities: []
fsGroup:
type: MustRunAs
ranges:
- min: 99
max: 65543
groups: []
kind: SecurityContextConstraints
metadata:
annotations:
"helm.sh/hook": "pre-install"
name: argo-redis-ha
priority: 1
readOnlyRootFilesystem: false
requiredDropCapabilities:
- KILL
- MKNOD
- SETUID
- SETGID
runAsUser:
type: MustRunAsRange
uidRangeMin: 1
uidRangeMax: 65543
seLinuxContext:
type: MustRunAs
supplementalGroups:
type: RunAsAny
seccompProfiles:
- '*'
users:
- system:serviceaccount:argocd:argo-redis-ha
- system:serviceaccount:argocd:argo-redis-ha-haproxy
- system:serviceaccount:argocd:argocd-notifications-controller
- system:serviceaccount:argocd:argo-argocd-repo-server
- system:serviceaccount:argocd:argocd-server
volumes:
- configMap
- downwardAPI
- emptyDir
- persistentVolumeClaim
- projected
- secret
```
:::
1. Fork the [Add-Ons](https://github.com/epam/edp-cluster-add-ons/tree/main/argo-cd) repository to personal account.
2. Run the installation:
```bash
helm dependency update argo-cd
helm install argocd argo-cd -n argocd --create-namespace
```
3. Port-forward Argo CD service using kubectl:
```bash
kubectl port-forward svc/argocd-server 8080:80 -n argocd
```
4. Login to the Argo CD server in browser using login and password:
:::info
By default, to access the console with administrative privileges, use the following credentials:
- URL: localhost:8080
- Login: admin
:::
```bash title="password"
kubectl get secret -n argocd argocd-initial-admin-secret --template={{.data.password}} | base64 -d
```
5. Integrate Argo CD with [Add-Ons](add-ons-overview.md) and Install Core Add-Ons
To ensure the environment functions correctly, it is necessary to install the following core components:
- **Nginx Ingress Controller**: Provides external endpoint management through ingress resources.
- **External Secrets Operator (ESO)**: Manages secure provisioning and access to secrets.
- **Keycloak (KK)**: Enables Single Sign-On (SSO) for authentication.
- **Keycloak Operator**: Simplifies the configuration and management of Keycloak instances.
These components can be installed using the prepared [add-ons repository](https://github.com/epam/edp-cluster-add-ons). Detailed installation instructions are available in the [add-ons installation guide](add-ons-overview.md).
To configure these components, refer to the relevant sections in `values.yaml`, which include the required parameters for enabling and customizing the add-ons.

After completing the installation of these components, proceed with the configuration of Argo CD.
6. Update Argo CD Helm chart:
:::note
After installing the necessary add-ons, such as the External Secrets Operator, it is recommended to add ESO components for all secrets that were manually created during the integration of [add-ons with Argo CD](add-ons-overview.md). An example can be found [here](https://github.com/epam/edp-cluster-add-ons/blob/main/argo-cd/templates/external-secrets/externalsecret-argocd-github.yaml).
:::info
Make sure Kubernetes resources have the required labels for Argo CD to manage them.
```yaml
metadata:
label:
app.kubernetes.io/part-of: argocd
```
:::
To enable features such as ingress, login via OIDC provider, provisioning secret using ESO need to update Argo CD with [values](https://github.com/epam/edp-cluster-add-ons/blob/main/argo-cd/values.yaml) below:
```yaml title=" kubernetes values.yaml"
argo-cd:
global:
# -- Default domain used by all components
## Used for ingresses, certificates, SSO, notifications, etc.
domain: argocd.example.com
configs:
cm:
# required when SSO is enabled
url: "https://argocd.example.com"
oidc.config: |
issuer: https://keycloak.example/auth/realms/shared
server:
ingress:
enabled: true
hosts:
- "argocd.example.com"
oidc:
enabled: true
eso:
enabled: true
```
View: openshift values.yaml
```yaml
argo-cd:
global:
# -- Default domain used by all components
## Used for ingresses, certificates, SSO, notifications, etc.
domain: argocd.example.com
configs:
cm:
# required when SSO is enabled
url: "https://argocd.example.com"
oidc.config: |
issuer: https://keycloak.example/auth/realms/shared
server:
route:
enabled: true
hostname: "argocd.example.com"
termination_type: edge
termination_policy: Redirect
oidc:
enabled: true
eso:
enabled: true
```
## Next Step
- Install third-party tools via [Add-Ons](add-ons-overview.md)
- Install [KubeRocketCI](install-kuberocketci.md)
After completing the steps outlined in this documentation, the following results should be achieved:
1. **Centralized Argo CD Instance**:
- A fully deployed and operational Argo CD instance installed using Helm.
2. **Add-Ons Repository Configured**:
- Add-ons repository integrated and configured with Argo CD for managing additional components.
3. **Core Components Deployed**:
- Essential infrastructure components, such as:
- **External Secrets Operator (ESO)** for secure secret management.
- **Keycloak** and **Keycloak Operator** for Single Sign-On (SSO).
- **Nginx Ingress Controller** for external endpoint management.
## Related Articles
* [Argo CD Integration](cd/argocd-integration.md)
* [Install via Add-Ons](add-ons-overview.md)
---
## Install NGINX Ingress Controller
# Install NGINX Ingress Controller
Inspect the prerequisites and the main steps to perform for installing [Install NGINX Ingress Controller](https://docs.nginx.com/nginx-ingress-controller/intro/overview/) on Kubernetes.
## Prerequisites
- Kubectl version 1.34+ is installed. Please refer to the [Kubernetes official website](https://kubernetes.io/releases/) for details.
- [Helm](https://helm.sh) version 3.10+ is installed. Please refer to the [Helm page](https://github.com/helm/helm/releases) on GitHub for details.
## Installation
To install the ingress-nginx chart, follow the steps below:
1. Create an ingress-nginx namespace:
```bash
kubectl create namespace ingress-nginx
```
2. Add a chart repository:
```bash
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
```
3. Install the ingress-nginx chart:
```bash
helm install ingress ingress-nginx/ingress-nginx \
--version 4.7.0 \
--values values.yaml \
--namespace ingress-nginx
```
Check out the _values.yaml_ file sample of the ingress-nginx chart customization:
View: values.yaml
```yaml
controller:
addHeaders:
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
resources:
limits:
memory: "256Mi"
requests:
cpu: "50m"
memory: "128M"
config:
ssl-redirect: 'true'
client-header-buffer-size: '64k'
http2-max-field-size: '64k'
http2-max-header-size: '64k'
large-client-header-buffers: '4 64k'
upstream-keepalive-timeout: '120'
keep-alive: '10'
use-forwarded-headers: 'true'
proxy-real-ip-cidr: '172.32.0.0/16'
proxy-buffer-size: '8k'
# To watch Ingress objects without the ingressClassName field set parameter value to true.
# https://kubernetes.github.io/ingress-nginx/#i-have-only-one-ingress-controller-in-my-cluster-what-should-i-do
watchIngressWithoutClass: true
service:
type: NodePort
nodePorts:
http: 32080
https: 32443
updateStrategy:
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
metrics:
enabled: true
defaultBackend:
enabled: true
serviceAccount:
create: true
name: nginx-ingress-service-account
```
:::info
Align value **controller.config.proxy-real-ip-cidr** with your [network settings](https://kubernetes.github.io/ingress-nginx/user-guide/miscellaneous/#source-ip-address).
:::
:::note
It is also possible to install the ingress controller via cluster add-ons. For details, please refer to the [Install via Add-Ons](add-ons-overview.md) page.
:::
## Related Articles
* [Install via Add-Ons](add-ons-overview.md)
* [Install KubeRocketCI](install-kuberocketci.md)
---
## How to Install KubeRocketCI: Advanced Setup Guide
# Install KubeRocketCI
Inspect the main steps to install KubeRocketCI. Please check the [Prerequisites Overview](prerequisites.md) page before starting the installation. Also, to authenticate each of the release artifacts, please refer to the [Verification of KubeRocketCI Artifacts](../developer-guide/artifacts-verification.md) guide.
There are multiple ways to deploy KubeRocketCI:
- Using Helm (see below)
- Using [Argo CD GitOps approach](./add-ons-overview.md)
- Using [AWS Marketplace](./aws-marketplace-install.md)
:::note
The installation process below is given for a Kubernetes cluster. The steps that differ for an OpenShift cluster are indicated in the notes.
:::
:::warning
KubeRocketCI is aligned with industry standards for storing and managing sensitive data, ensuring optimal security. However, the use of custom solutions introduces uncertainties, thus the responsibility for the safety of your data is fully covered by the platform administrator.
:::
1. (Optional) KubeRocketCI manages secrets via `External Secret Operator` to integrate with a variety of tools. For more information about the secrets being used and how they are utilized, please refer to the [External Secrets Operator Integration](./secrets-management/external-secrets-operator-integration.md) guide.
2. (Optional) Deploy and configure Keycloak to enable Single Sign-On approach. To see the details on how to configure Keycloak correctly, please refer to the [Install Keycloak](./auth/keycloak.md#configuration) page.
3. Add the Helm charts repository:
```bash
helm repo add epamedp https://epam.github.io/edp-helm-charts/stable
```
4. Choose the required Helm chart version:
```bash
helm search repo epamedp/edp-install
NAME CHART VERSION APP VERSION DESCRIPTION
epamedp/edp-install 3.14.1 3.14.1 A Helm chart for KubeRocketCI Platform
```
:::note
It is highly recommended to use the latest released version.
:::
5. KubeRocketCI can be integrated with the following version control systems:
- [GitHub](https://docs.github.com/en) (by default)
- [GitLab](https://docs.gitlab.com/)
- [Gerrit](https://gerrit-review.googlesource.com/Documentation/)
This integration implies in what system the development of the application will be or is already being carried out. The `global.gitProviders` flag in the edp-install controls this integration:
Global VCS configuration (can be multiple values):
```yaml title="values.yaml"
...
global:
gitProviders:
- gerrit
- github
- gitlab
- bitbucket
...
```
Tekton event listner configuration:
``` yaml title="values.yaml"
...
edp-tekton:
gitServers:
github:
gitProvider: github
host: github.com
webhook:
skipWebhookSSLVerification: false
eventListener:
enabled: true
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "500m"
ingress:
enabled: true
...
```
``` yaml title="values.yaml"
...
edp-tekton:
gitServers:
gitlab:
gitProvider: gitlab
host: gitlab.com
webhook:
skipWebhookSSLVerification: false
eventListener:
enabled: true
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "500m"
ingress:
enabled: true
...
```
``` yaml title="values.yaml"
...
edp-tekton:
gitServers:
bitbucket:
gitProvider: bitbucket
host: bitbucket.org
webhook:
skipWebhookSSLVerification: false
eventListener:
enabled: true
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "500m"
ingress:
enabled: true
...
```
``` yaml title="values.yaml"
...
gerrit-operator:
enabled: true
...
edp-tekton:
gitServers:
gerrit:
eventListener:
enabled: true
ingress:
enabled: false
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
gitProvider: gerrit
gitUser: edp-ci
host: gerrit.edp
nameSshKeySecret: gerrit-ciuser-sshkey
quickLink:
host: gerrit.example.com
sshPort:
webhook:
skipWebhookSSLVerification: false
...
```
Gerrit server can be deployed as a part of KubeRocketCI platform when the Gerrit is enabled.
For more details on how to integrate KubeRocketCI with GitLab or GitHub, please refer to the [Add GitServer](../user-guide/add-git-server.md) page.
6. Configure Container Registry.
KubeRocketCI supports integration with multiple container registries, providing flexibility for projects using either OpenShift or Kubernetes clusters.
The supported container registries include AWS ECR, DockerHub, Harbor, OpenShift (OCR), Nexus, and GitHub (GHCR). This integration simplifies the process
of storing and managing container images across various environments.
For more details on integrating these container registries with KubeRocketCI, refer to the following documentation: [Container Registries Integration Guide](../user-guide/change-container-registry.md) and [Manage Container Registries](../user-guide/manage-container-registries.md)
For example, to enable [Harbor](artifacts-management/harbor-integration.md) as a registry storage, use the values below:
```yaml
global:
dockerRegistry:
type: "harbor"
url: "harbor.example.com"
```
7. Install platform in the **krci** namespace with the Helm tool:
Check the parameters in the installation chart [values.yaml](https://github.com/epam/edp-install/blob/v3.14.1/deploy-templates/values.yaml) file.
```bash
helm install krci epamedp/edp-install --wait --timeout=900s \
--version 3.14.1 \
--values values.yaml \
--namespace krci \
--create-namespace
```
See the example on the parameters below:
```yaml title="Example values.yaml file"
global:
# -- platform type that can be either "kubernetes" or "openshift"
platform: "kubernetes"
# DNS wildcard for routing in the Kubernetes cluster;
dnsWildCard: "example.com"
# -- Administrators of your tenant
# -- Can be gerrit, github or gitlab. By default: github
gitProviders:
- github
dockerRegistry:
# -- Docker Registry endpoint
url: ".dkr.ecr..amazonaws.com"
type: "ecr"
space: "edp"
sso:
enabled: false
# Keycloak address with which the platform will be integrated
keycloakUrl: "https://keycloak.example.com"
admins:
- "stub_user_one@example.com"
developers:
- "stub_user_one@example.com"
- "stub_user_two@example.com"
edp-tekton:
# Tekton Kaniko configuration section
kaniko:
# -- AWS IAM role to be used for kaniko pod service account (IRSA). Format: arn:aws:iam:::role/
roleArn: arn:aws:iam:::role/
gitServers:
github:
gitProvider: github
host: github.com
webhook:
skipWebhookSSLVerification: false
eventListener:
enabled: true
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "500m"
ingress:
enabled: true
krci-portal:
ingress:
enabled: true
configEnv:
PORTAL_URL: https://krci-portal.example.com
GITFUSION_URL: http://gitfusion.:8080
DEFAULT_CLUSTER_NAMESPACE:
DEFAULT_CLUSTER_NAME: core
```
:::note
Set `global.platform=openshift` while deploying KubeRocketCI in OpenShift.
:::
:::info
The full installation with integration between tools will take at least 5 minutes.
:::
8. To check if the installation is successful, run the command below:
```bash
helm status krci -n krci
```
You can also check ingress endpoints to get the Portal endpoint to enter KubeRocketCI portal:
```bash
kubectl get ingress portal -n krci
```
9. Once KubeRocketCI is successfully installed, you can explore our [Use Cases](../use-cases/index.md) to try out the functionality of the KubeRocketCI platform.
## Related Articles
* [Quick Start](../quick-start/platform-installation.md)
* [Manage Git Providers](../user-guide/add-git-server.md)
* [Set Up Kubernetes](kubernetes-cluster-settings.md)
* [Set Up OpenShift](openshift-cluster-settings.md)
* [KubeRocketCI Installation Prerequisites Overview](prerequisites.md)
* [UI Portal OIDC Integration](auth/ui-portal-oidc.md)
* [Verification of KubeRocketCI Artifacts](../developer-guide/artifacts-verification.md)
---
## Install Tekton
# Install Tekton
EPAM KubeRocketCI uses Tekton resources, such as Tasks, Pipelines, Triggers, Interceptors, and Chains for running the CI/CD pipelines.
Here are the main steps to follow for installing the Tekton resources using the Tekton release files.
## Prerequisites
- Kubectl version 1.34+ is installed. Please refer to the [Kubernetes official website](https://kubernetes.io/releases/) for details.
- For Openshift/OKD, the latest version of the `oc` utility is required. Please refer to the [OKD page](https://github.com/okd-project/okd/releases) on GitHub for details.
## Installation on Kubernetes Cluster
To install Tekton resources, follow the steps below:
:::info
Please refer to the [Install Tekton Pipelines](https://tekton.dev/docs/installation/pipelines/) and
[Install and set up Tekton Triggers](https://tekton.dev/docs/installation/triggers/) sections for details.
:::
1. Install Tekton pipelines v1.6.2 using the release file:
:::note
Tekton Pipeline resources are used for managing and running KubeRocketCI Tekton Pipelines and Tasks.
Please refer to the [KubeRocketCI Tekton Pipelines](https://github.com/epam/edp-tekton/tree/master/charts/pipelines-library/templates/pipelines) and
[KubeRocketCI Tekton Tasks](https://github.com/epam/edp-tekton/tree/master/charts/pipelines-library/templates/tasks) pages for details.
:::
```bash
kubectl apply -f https://infra.tekton.dev/tekton-releases/pipeline/previous/v1.6.2/release.yaml
```
2. Install Tekton Triggers v0.36.0 using the release file:
:::note
Tekton Trigger resources are used for managing and running KubeRocketCI Tekton EventListeners, Triggers, TriggerBindings and TriggerTemplates.
Please refer to the [KubeRocketCI Tekton Triggers](https://github.com/epam/edp-tekton/tree/master/charts/pipelines-library/templates/triggers) page for details.
:::
```bash
kubectl apply -f https://infra.tekton.dev/tekton-releases/triggers/previous/v0.36.0/release.yaml
```
3. Install Tekton Interceptors v0.36.0 using the release file:
:::note
The Platform uses GitLab, GitHub and Cel ClusterInterceptors for processing requests from webhooks.
:::
```bash
kubectl apply -f https://infra.tekton.dev/tekton-releases/triggers/previous/v0.36.0/interceptors.yaml
```
4. Install Tekton Chains v0.28.1 using the release file:
```bash
kubectl apply -f https://infra.tekton.dev/tekton-releases/chains/previous/v0.28.1/release.yaml
```
5. Install Tekton Results v0.20.0 using the KubeRocketCI manifest:
:::warning
Unlike the components above, Tekton Results **must not** be installed from the plain upstream release file.
The Platform customizes it, and the upstream `release.yaml` bundles its own PostgreSQL instance that conflicts
with the Platform database. Use the [results.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/tekton/results.yaml)
manifest from the [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository instead.
:::
```bash
kubectl apply -f https://raw.githubusercontent.com/epam/edp-cluster-add-ons/main/clusters/core/addons/tekton/results.yaml
```
The manifest is based on the upstream `release_base.yaml` (the variant without a bundled database) and adds the
following Platform customizations:
- **External database.** Connection settings point to the PostgreSQL cluster defined in
[results-pg.yaml](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/tekton/results-pg.yaml),
which must be deployed first. See [Tekton Long-Term Storage](./ci/tekton-long-term-storage.md) for details.
- **Summary labels.** The watcher runs with `-summary_labels`, which records the codebase, branch, pipeline type,
and CD pipeline labels on archived runs. The KubeRocketCI Portal relies on these to render the pipeline run
history, so omitting the flag leaves history entries without their metadata.
- **Log storage.** The Results API serves pipeline logs from a persistent volume, and a CronJob prunes entries
older than 30 days.
## Installation on OKD cluster
To install Tekton resources, follow the steps below:
:::info
Please refer to the [Install Tekton Operator](https://tekton.dev/docs/operator/) documentation for details.
:::
:::note
Tekton Operator also deploys [Pipelines as Code CI](https://pipelinesascode.com/) that requires OpenShift v4.11 (based on Kubernetes v1.24) or higher. This feature is optional and its deployments can be scaled to zero replicas.
:::
Install Tekton Operator v0.67.0 using the release file:
```bash
kubectl apply -f https://github.com/tektoncd/operator/releases/download/v0.67.0/openshift-release.yaml
```
After the installation, the Tekton Operator will install the following components: Pipeline, Trigger, and Addons.
:::note
If there is the following error in the `openshift-operators` namespace for `openshift-pipelines-operator` and `tekton-operator-webhook` deployments:
```bash
Error: container has runAsNonRoot and image will run as root
```
Patch the deployments with the following commands:
```bash
kubectl -n openshift-operators patch deployment openshift-pipelines-operator -p '{"spec": {"template": {"spec": {"securityContext": {"runAsUser": 1000}}}}}'
kubectl -n openshift-operators patch deployment tekton-operator-webhook -p '{"spec": {"template": {"spec": {"securityContext": {"runAsUser": 1000}}}}}'
```
:::
Grant access for Tekton Service Accounts in the `openshift-pipelines` namespace to the Privileged SCC:
```bash
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:tekton-operators-proxy-webhook
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:tekton-pipelines-controller
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:tekton-pipelines-resolvers
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:tekton-pipelines-webhook
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:tekton-triggers-controller
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:tekton-triggers-core-interceptors
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:tekton-triggers-webhook
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:pipelines-as-code-controller
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:pipelines-as-code-watcher
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:pipelines-as-code-webhook
oc adm policy add-scc-to-user privileged system:serviceaccount:openshift-pipelines:default
```
## Related Articles
* [Install via Add-Ons](add-ons-overview.md)
---
## Install via Civo Marketplace
# Install via Civo Marketplace
This documentation provides detailed instructions on how to install the KubeRocketCI platform via [Civo Marketplace](https://www.civo.com/marketplace/kuberocketci).
As a prerequisite, make sure to [sign up](https://dashboard.civo.com/signup) on Civo.
## Launch Cluster
The first step of the installation procedure is to launch the cluster. Please refer to the [official instructions](https://www.civo.com/docs/kubernetes/create-a-cluster) that describe this process in detail.
To succeed, follow the steps below:
1. Log in to your personal Civo account.
2. Create a new Kubernetes cluster with the following parameters. Please refer to the [official guidelines](https://www.civo.com/docs/kubernetes/create-a-cluster) for more details:
- **Name**: `demo`
- **How many nodes**: `1`
- **Select size**: Type: `Standard`, Size: `Medium`
- **Network**: `Default`
- **Firewall**: `Create a new firewall` with the `6443` and `443` ports opened
- **Advanced options**: Kubernetes version: latest (currently 1.34.0)
- **Marketplace**: From the `CI/CD` selection choose `Argo CD` and `Tekton` for pre-installation.
3. Wait till the cluster is created.
:::note
The process of deploying the cluster typically takes about two minutes. Following this, an extra five minutes are needed for the deployment of both the Argo CD and Tekton.
:::
4. As soon as cluster is deployed, ensure all the marketplace applications are installed, too:

5. Download and apply the kubeconfig file:

6. Ensure all the pods are up and running in both the Tekton and Argo CD namespaces after 5 minutes of waiting. Restart deployments if the pods are failed to deploy:
```bash
kubectl get ns
kubectl get pods -n tekton-pipelines
kubectl get pods -n argocd
```

## Install KubeRocketCI
As soon as the cluster is deployed, it is time to install the KubeRocketCI application.
1. In the Civo portal, navigate to **Marketplace** -> **CI/CD**:

2. Select `KubeRocketCI` and choose which Version Control Systems you would prefer to integrate it with and click the **Install Apps** button:

3. Wait till the KubeRocketCI app appears in the **Installed applications** list:

4. Wait till all the pods are up and running. Use the `kubectl get pods` command to check the status of the pods:
```bash
kubectl get pods -n krci
```

5. As soon as all the pods are deployed. Navigate to the **Cluster Information** tab and copy the DNS name:

6. In the new browser tab, access the KubeRocketCI portal by typing the URL according to the `https://krci-portal.` format.
:::note
You can find the exact portal URL in the krci-portal deployment details.
:::
7. Create the edp-admin service account and generate an access token to open the KubeRocketCI:
```bash
kubectl -n krci create serviceaccount edp-admin
kubectl create clusterrolebinding edp-admin --serviceaccount=krci:edp-admin --clusterrole=cluster-admin
kubectl create token edp-admin -n krci
```
8. In the login menu, paste the generated token in the **Access token** field and click the **Sign in** button.

9. Upon logging in, open the namespaces window by clicking the **Manage Namespaces** button in the top right corner of the UI:

10. Ensure the `krci` namespace is specified in both default and allowed namespaces. If not, define them manually:
- Default namespace: `krci`
- Allowed namespaces: `krci`

:::note
Remember to press **Enter** to add the allowed namespace to the list.
:::
Well done! You've successfully installed the KubeRocketCI platform on the Civo cluster. You're now set to integrate KubeRocketCI with the necessary third-party tools.
Proceed to the [SonarQube Integration](../quick-start/integrate-sonarcloud.md) page.
## Related Articles
* [Install via AWS Marketplace](aws-marketplace-install.md)
* [KubeRocketCI Installation](install-kuberocketci.md)
* [SonarQube Integration](../quick-start/integrate-sonarcloud.md)
* [Argo CD Integration](cd/argocd-integration.md)
---
## Installation Overview
# Installation Overview
This documentation provides a concise introduction to the KubeRocketCI installation options. KubeRocketCI can be installed using different approaches. Each of them comes with its own benefits:
- [Quick Start Guide](../quick-start/platform-installation.md): This option is ideal for users looking to quickly deploy KubeRocketCI with minimal prerequisites. Watch our [video tutorial](https://www.youtube.com/watch?v=ILlY4niCWeU) for a guided installation experience.
- [Install via Add-Ons](add-ons-overview.md): Recommended for advanced KubeRocketCI users, this installation streamlines the setup of supported integrations and follows the GitOps approach. Familiarity with Argo CD is recommended.
- [Install via Helm Charts](install-kuberocketci.md): While more complex, this method offers the highest level of flexibility, allowing for customization to suit specific needs. It requires a good understanding of KubeRocketCI.
- [Install via AWS Marketplace](aws-marketplace-install.md): Optimal for users leveraging AWS infrastructure, offering a minimal setup for testing KubeRocketCI functionality.
- [Install via Civo Marketplace](install-via-civo.md): Preferred for users deploying KubeRocketCI in a Civo Kubernetes cluster. Follow our step-by-step [video tutorial](https://www.youtube.com/watch?v=QjZoPnIKDtA) for onboarding KubeRocketCI to a new Civo cluster.
## Related Articles
* [Quick Start Guide](../quick-start/platform-installation.md)
* [Quick Start Overview](../quick-start/quick-start-overview.md)
* [Install KubeRocketCI](install-kuberocketci.md)
* [Install via Add-Ons](add-ons-overview.md)
* [Install via AWS Marketplace](aws-marketplace-install.md)
* [Install via Civo Marketplace](install-via-civo.md)
* [Deploy AWS EKS Cluster](deploy-aws-eks.md)
---
## Efficient Kubernetes Autoscaling With Karpenter and KEDA: A Comprehensive Guide
# Efficient Kubernetes Autoscaling With Karpenter and KEDA: A Comprehensive Guide
In modern cloud environments, efficient resource management is essential to maintain performance while minimizing costs. This documentation provides a step-by-step guide to configuring pods and cluster autoscaling in a Kubernetes environment using Karpenter and KEDA.
Karpenter dynamically provisions and removes nodes based on real-time demand, ensuring that the cluster has just the right amount of capacity. KEDA, on the other hand, scales workloads by adjusting pod replicas based on key metrics, such as pipeline activity and user requests.
By implementing this approach, the cluster remains responsive to workload fluctuations, preventing over-provisioning and reducing unnecessary resource usage. This results in a cost-effective, scalable, and efficient infrastructure that adapts to real-time demands without manual intervention.
## Prerequisites
Before setting up AutoScaling, ensure the following requirements are met:
- [**Prometheus is installed**](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/prometheus-operator) and exporting cluster metrics.
- [**Nginx Ingress is installed**](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/ingress-nginx) and configured to export its [metrics](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/ingress-nginx/values.yaml#L38) to Prometheus.
## Karpenter
Configuring and installing Karpenter involves several key steps:
- **Setting up AWS resources** – configuring IAM roles, permissions, and networking.
- **Installing Karpenter** – deploying Karpenter controller in the Kubernetes cluster.
- **Configuring essential components** – setting up `Node Pools` and `Node Classes` to enable automatic node provisioning.
### AWS Configuration
To enable Karpenter to manage node provisioning effectively, it is essential to properly configure the necessary AWS resources. These steps include:
- **Creating IAM roles and policies** – Karpenter requires specific permissions to provision and manage EC2 instances.
- **Tagging VPC Subnets and Security Groups** – Karpenter uses these tags to determine which network subnets and security groups should be applied when provisioning new nodes.
:::info
Karpenter does not use Auto Scaling Groups (ASG) for node creation. Instead, it provisions EC2 instances directly and registers them with the Kubernetes cluster.
:::
#### IAM Role and Policies
Karpenter needs specific IAM permissions to manage EC2 instances, including the ability to create and terminate EC2 instances in your AWS account. It also requires permissions to register and manage nodes in the Kubernetes cluster.
To simplify the setup, we recommend using the [terraform-aws-karpenter](https://registry.terraform.io/modules/terraform-aws-modules/eks/aws/latest/submodules/karpenter) module. This module automates the creation of the necessary IAM roles and policies for Karpenter.
This setup assumes your cluster uses on-demand instances with 24/7 availability. If your cluster configuration differs, adjust the settings to match your needs. You can find Karpenter configuration parameters in the [terraform-aws-platform](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/eks/irsa.tf#L345) repository.
With this configuration, the following IAM roles will be created:
- **KarpenterControllerRole-\**: This role also includes `system:nodes` access to the Kubernetes cluster and will be used by the [Karpenter controller](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/karpenter/values.yaml#L33) deployed within the cluster. This role contains the `KarpenterController` custom policy.
- **KarpenterNodeRole-\**: This role will be used by Karpenter to manage EC2 instances. We will configure this role later in the Karpenter [Node Class setup](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/karpenter-np/templates/node-class.yaml#L8). This role contains the following policies:
- `AmazonEC2ContainerRegistryReadOnly`
- `AmazonEKS_CNI_Policy`
- `AmazonEKSWorkerNodePolicy`
- `AmazonSSMManagedInstanceCore`
#### Configure Network and Security Groups
Karpenter needs to know which subnets and security groups to use when provisioning new nodes. This is done by tagging your VPC subnets and security groups. Verify the tags in your required subnets and security groups. If necessary, modify your [terraform configuration](https://github.com/KubeRocketCI/terraform-aws-platform/blob/master/vpc/main.tf#L37) to add new, unique tags. These tags will be used in the Karpenter [Node Class configuration](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/karpenter-np/templates/node-class.yaml).
### Install Karpenter
To deploy Karpenter in your Kubernetes cluster, we recommend using the [add-ons approach](https://github.com/epam/edp-cluster-add-ons/tree/main/clusters/core/addons/karpenter).
For best practices, Karpenter should be deployed on nodes that are not managed by Karpenter itself. This ensures that Karpenter can manage the cluster independently of its own scaling actions. To achieve this, you should use the affinity configuration in the values.yaml file.
Additionally, Karpenter requires the `KarpenterControllerRole-` IAM role to manage the cluster's nodes. This role must be specified in the Service Account configuration. The clusterName should also be set in the settings section. Here's an example of how to configure values.yaml before installation:
```yaml title="values.yaml"
karpenter:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: karpenter.sh/nodepool
operator: DoesNotExist
# -- Karpenter IAM role to manage cluster nodes
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::0123456789:role/KarpenterControllerRole-
# -- EKS cluster name
settings:
clusterName:
```
### Deploy Karpenter Resources
Once Karpenter is installed, you need to create a Node Class and Node Pool. The Node Class defines the configuration for nodes that Karpenter will provision, while the Node Pool specifies the criteria for selecting which nodes to use. We recommend using the [add-ons approach](https://github.com/epam/edp-cluster-add-ons/blob/main/clusters/core/addons/karpenter-np/values.yaml) to deploy Karpenter resources. First, adjust the values.yaml file according to your specific requirements:
```yaml title="values.yaml"
karpenter:
# -- AMI used by nodes in the EKS cluster
amiID: ami-XXXXXXXXXXXXXXXXX
# -- EKS cluster name (must match the Karpenter configuration)
clusterName: ""
# Instance type settings
instanceType:
category: ["m"]
family: ["m7i"]
size: ["xlarge"]
type: ["on-demand"]
```
You can adjust the Node Pools and Node Class configuration based on your workload requirements. For instance, you can specify different instance types, categories, and families. More detailed information on configuring Node Pools and Node Classes can be found in the [Karpenter documentation](https://karpenter.sh/docs/).
### Verify Karpenter Functionality
To verify the functionality of Karpenter, you can create a pod and adjust the number of replicas in its configuration.
1. Create a deployment with the zero replicas:
```bash
cat <
# Kubernetes Cluster Scaling
KubeRocketCI provides a solution for dynamically scaling pods and nodes in a Kubernetes cluster. This approach ensures resources are provisioned based on demand, reducing latency and optimizing costs. By automatically adjusting capacity, the cluster remains responsive to workload fluctuations, improving performance during peak loads while minimizing resource waste during low activity.
This solution enhances reliability by preventing resource shortages, supports high availability by efficiently distributing workloads, and simplifies infrastructure management by automating scaling decisions.
## Architecture Overview
KubeRocketCI can use these tools for automatic resource scaling:
- **Karpenter** – dynamically manages node scaling in the cluster, creating new instances as the load increases and removing resources when demand decreases.
- **KEDA** – adjusts the number of pods based on workload, ensuring flexibility and optimal resource utilization.
The diagram below illustrates the AWS EKS cluster architecture, including key components, dependencies, and scaling mechanisms:
- **System Node** – contains control components such as Tekton Controller, KEDA, Ingress Controller, and Karpenter.
- **Tekton Node** – runs CI/CD pipelines.
- **Dynamic Node** – hosts operators and services that are scaled by Karpenter.
- **Auto Scaling Groups (ASG)** – manage system and Tekton Nodes.

Automatic scaling ensures efficient resource allocation, reduces latency, and optimizes costs. Read the [Efficient Kubernetes Autoscaling with Karpenter and KEDA: A Comprehensive Guide](./namespace-and-cluster-autoscaling.md) to set up automatic scaling in your cluster.
---
## Set Up Kubernetes
# Set Up Kubernetes
Make sure the cluster meets the following conditions:
1. Kubernetes cluster is installed with minimum 2 worker nodes with total capacity 8 Cores and 32Gb RAM.
2. Machine with [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) is installed with a cluster-admin access to the Kubernetes cluster.
3. Ingress controller is installed in a cluster, for example [ingress-nginx](./install-ingress-nginx.md).
4. Ingress controller is configured with the disabled HTTP/2 protocol and header size of 64k support.
Find below an example of the Config Map for the NGINX Ingress controller:
```yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
data:
client-header-buffer-size: 64k
large-client-header-buffers: 4 64k
use-http2: "false"
```
5. Load balancer (if any exists in front of the Ingress controller) is configured with session stickiness, disabled HTTP/2 protocol and header size of 32k support.
6. Keycloak instance is installed. To get accurate information on how to install Keycloak, please refer to the [Install Keycloak](auth/keycloak.md) instruction.
7. Helm 3.10 or higher is installed on the installation machine with the help of the [Installing Helm](https://v3.helm.sh/docs/intro/install/) instruction.
8. Storage classes are used with the [Retain Reclaim Policy](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#retain) and [Delete Reclaim Policy](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#delete).
9. We recommended using our storage class as [default storage class](https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/#changing-the-default-storageclass).
:::info
By default, KubeRocketCI uses the `default Storage Class` in a cluster. We recommend using the following Storage Classes.
Storage class templates with the Retain and Delete Reclaim Policies:
``` yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
annotations:
storageclass.kubernetes.io/is-default-class: 'true'
allowedTopologies: []
mountOptions: []
provisioner: ebs.csi.aws.com
reclaimPolicy: Retain
volumeBindingMode: Immediate
```
``` yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
annotations:
storageclass.kubernetes.io/is-default-class: 'true'
allowedTopologies: []
mountOptions: []
provisioner: ebs.csi.aws.com
reclaimPolicy: Delete
volumeBindingMode: Immediate
allowVolumeExpansion: true
```
``` yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3-retain
allowedTopologies: []
mountOptions: []
provisioner: ebs.csi.aws.com
reclaimPolicy: Retain
volumeBindingMode: Immediate
allowVolumeExpansion: true
```
:::
## Related Articles
* [Install Amazon EBS CSI Driver](infrastructure-providers/aws/ebs-csi-driver.md)
* [Install NGINX Ingress Controller](install-ingress-nginx.md)
* [Install Keycloak](auth/keycloak.md)
---
## Argo CD Microsoft Entra OIDC SSO Setup
# Guide: Microsoft Entra SSO Integration With Argo CD
Configure Argo CD single sign-on using Microsoft Entra as the OIDC identity provider. This guide covers registering the Microsoft Entra application, mapping Entra groups to Argo CD RBAC roles, and updating the Argo CD Helm chart — the same platform-access pattern used for the [AWS EKS cluster and KubeRocketCI Portal](./aws-eks-portal-authentication.md).
## Prerequisites for Argo CD SSO with Microsoft Entra
Before you begin, make sure the following prerequisites are met:
- Access to the [Microsoft Entra Admin Center](https://entra.microsoft.com/) with administrative privileges.
- [Microsoft Entra](https://learn.microsoft.com/en-us/entra/fundamentals/create-new-tenant) Tenant is created.
- [Argo CD](../install-argocd.md) is installed (can be installed during **Configuring Helm chart** step).
- A forked copy of the [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository is created.
- (Optional) [External Secrets Operator](../secrets-management/install-external-secrets-operator.md) is installed.
## Registering the Argo CD Application in Microsoft Entra
To configure Microsoft Entra as the Identity Provider for the Argo CD, it is necessary to create and configure an Application in the Microsoft Entra Admin Center:
1. Log in to the [Microsoft Entra Admin Center](https://entra.microsoft.com/?feature.msaljs=true#home):

2. In the left sidebar menu, select **Applications** and click **App registrations**:

3. Click on the **New registration** button:

4. Fill in the required fields, such as **Name**, **Supported account types** and **Redirect URI** (you can skip setting the **Redirect URI** if you don't deploy Argo CD yet). Click **Register** to create the application:
:::note
The **Redirect URI** should be in the format `https:///auth/callback`.
:::

5. In the created application, navigate to the **Authentication** section from the left sidebar menu. In the **Implicit grant and hybrid flows** section, select **ID tokens** for the token type. In the **Allow public client flows** section, set the value to **No**:

6. Navigate to the **Certificates & secrets** section. In the **Client secrets** tab, click on the **New client secret** button to create a new secret. Fill in the required fields and click **Add**:

7. Copy the generated client secret value and store it securely. You will need this value to configure the Argo CD Helm chart:

8. Navigate to the **Token configuration** section and click on **Add group claim** button. Choose the group type as **Security Groups** and for the ID token type, select **Group ID**:

Also, add the **preferred_username** and **email** optional claims:

9. Navigate to the **API permissions** section. Click on the **Add a permission** button. Select **Microsoft Graph** and then **Delegated permissions**. Add the following permissions:
- **email**
- **openid**
- **profile**
- **User.Read**

After adding the permissions, click on the **Grant admin consent for 'Tenant name'** button to grant the required permissions.
## Creating the Groups
To manage access to the Argo CD, it is necessary to create groups in the Microsoft Entra Admin Center and assign users to them.
1. In the Microsoft Entra Admin Center, in the left sidebar menu, select **Groups** and then **All groups**. Click on **New group** button to create a new group(s) for users who will have access to Argo CD (e.g., `ArgoCDAdmins`, `ArgoCDReadOnly`, etc.):

2. Fill in the required fields, such as **Groups type** and **Group name**. In the **Members** section, add users who will be part of the group.

3. Click on the **Create** button and repeat this process for each required group.
## Configuring the Argo CD Helm Chart for OIDC
To integrate Argo CD with configured Microsoft Entra Application, it is necessary to configure the Argo CD Helm chart. In this example, we will use the [edp-cluster-add-ons](https://github.com/epam/edp-cluster-add-ons) repository to deploy Argo CD to the Kubernetes (e.g. AWS EKS) cluster.
:::note
The Application data, such as **Application (client) ID** and **Directory (tenant) ID**, can be found in the **Overview** section of the Application in the Microsoft Entra Admin Center.

:::
:::note
The **Object ID** can be found in the **Overview** section of the group in the Microsoft Entra Admin Center.

:::
1. Navigate to the forked [Cluster Add-Ons repository](https://github.com/epam/edp-cluster-add-ons) and locate the `values.yaml` file in the `argo-cd` directory:
Update the `values.yaml` file with the following values:
```yaml title="argo-cd/values.yaml"
argo-cd:
configs:
cm:
url: "https://"
application.instanceLabelKey: argocd.argoproj.io/instance-edp
exec.enabled: true
oidc.config: |
name: Entra
issuer: https://login.microsoftonline.com//v2.0
clientID:
clientSecret: $keycloak-client-argocd-secret:clientSecret
requestedIDTokenClaims:
groups:
essential: true
value: "SecurityGroup"
requestedScopes:
- openid
- profile
- email
rbac:
scopes: '[groups, email]'
policy.csv: |
# default global admins
g, "