[{"data":1,"prerenderedAt":1345},["ShallowReactive",2],{"/blog/gitops-with-gitlab-using-ci-cd":3,"navigation-en-us":560,"banner-en-us":988,"footer-en-us":998,"blog-post-authors-en-us-Viktor Nagy":1240,"blog-related-posts-en-us-gitops-with-gitlab-using-ci-cd":1255,"blog-promotions-en-us":1281,"next-steps-en-us":1335},{"id":4,"title":5,"authors":6,"body":8,"category":538,"date":539,"description":540,"extension":541,"externalUrl":542,"faq":542,"featured":543,"heroImage":544,"meta":545,"navigation":546,"path":547,"seo":548,"slug":552,"stem":553,"tags":554,"template":558,"updatedDate":542,"__hash__":559},"blogPosts/en-us/blog/gitops-with-gitlab-using-ci-cd.md","GitOps with GitLab: The CI/CD Tunnel",[7],"Viktor Nagy",{"type":9,"value":10,"toc":519},"minimark",[11,24,31,36,39,43,46,49,65,68,71,79,83,86,152,155,224,228,231,236,245,264,267,271,274,302,306,316,319,326,330,333,344,347,351,360,371,376,380,383,387,393,397,404,408,411,424,430,473,476,493,497,500,504,507,515],[12,13,14],"p",{},[15,16,17,18,23],"em",{},"It is possible to use GitLab as a best-in-class GitOps tool, and this blog post series is going to show you how. These easy-to-follow tutorials will focus on different user problems, including provisioning, managing a base infrastructure, and deploying various third-party or custom applications on top of them. You can find the entire \"Ultimate guide to GitOps with GitLab\" tutorial series ",[19,20,22],"a",{"href":21},"/blog/the-ultimate-guide-to-gitops-with-gitlab/","here",".",[12,25,26,27,23],{},"In this article, we will see how you can access a Kubernetes cluster using GitLab CI/CD and why you might want to do it even if you aim for ",[19,28,30],{"href":29},"/topics/gitops/","GitOps",[32,33,35],"h2",{"id":34},"prerequisites","Prerequisites",[12,37,38],{},"This post assumes that you have a Kubernetes cluster connected to GitLab using the GitLab Kubernetes Agent. If you don't have such a cluster, I recommend consulting the previous posts (linked above) to have a similar setup from where we will start today.",[32,40,42],{"id":41},"meet-the-cicd-tunnel","Meet the CI/CD Tunnel",[12,44,45],{},"The GitLab Kubernetes Agent is not just a GitOps tool that will enable pull-based deployments and be one more application to maintain beside the other 70 in your DevOps stack. The GitLab Kubernetes Agent aims to serve the GitLab vision of providing you a single application for the whole DevSecOps lifecycle. As a result, the Agent's goal is to provide an integrated experience with every relevant GitLab feature.",[12,47,48],{},"What GitLab features does the Agent integrate with today?",[50,51,52,56,59,62],"ul",{},[53,54,55],"li",{},"GitLab CI/CD",[53,57,58],{},"Container network security",[53,60,61],{},"Container host security",[53,63,64],{},"Container scanning",[12,66,67],{},"In this post, we will focus on the GitLab CI/CD integration. Given the power and flexibility of GitLab CI/CD, the majority of our users have been using it for years successfully and, until the Agent appeared, they often had to manually script their cluster connections and deployments into it. If the previous setup sounds familiar, I recommend checking out the Agent's CI/CD integration features, the CI/CD tunnel. The CI/CD tunnel enables a cluster connection to be used from GitLab CI/CD, thus you need only minor adjustments to your existing setup, and will receive a GitLab supported component that we are continuously expanding to provide more and more integrations on top of it.",[12,69,70],{},"The CI/CD tunnel is always enabled in the project where you register and configure the Agent, and the given connection can be shared by other groups and projects, too. This way, a single connection can be reused throughout the organization to save on resource and maintenance costs.",[12,72,73,74,78],{},"GitLab automatically injects the available Kubernetes contexts into the CI/CD runner environment's ",[75,76,77],"code",{},"KUBECONFIG",". As a result, you can activate a context and start using it without much setup.",[32,80,82],{"id":81},"how-to-configure-the-cicd-tunnel","How to configure the CI/CD tunnel",[12,84,85],{},"As already mentioned, the CI/CD tunnel is always enabled in the project where you register and configure the Agent. If you would like to use the tunnel in the same repository, no configuration is needed. If you would like to share the connection with other repositories, open your agent configuration file and add the following lines:",[87,88,93],"pre",{"className":89,"code":90,"language":91,"meta":92,"style":92},"language-yaml shiki shiki-themes github-light","ci_access:\n   projects:\n   - id: path/to/project\n   groups:\n   - id: path/to/group\n\n","yaml","",[75,94,95,108,116,132,140],{"__ignoreMap":92},[96,97,100,104],"span",{"class":98,"line":99},"line",1,[96,101,103],{"class":102},"shJU0","ci_access",[96,105,107],{"class":106},"sgsFI",":\n",[96,109,111,114],{"class":98,"line":110},2,[96,112,113],{"class":102},"   projects",[96,115,107],{"class":106},[96,117,119,122,125,128],{"class":98,"line":118},3,[96,120,121],{"class":106},"   - ",[96,123,124],{"class":102},"id",[96,126,127],{"class":106},": ",[96,129,131],{"class":130},"sYBdl","path/to/project\n",[96,133,135,138],{"class":98,"line":134},4,[96,136,137],{"class":102},"   groups",[96,139,107],{"class":106},[96,141,143,145,147,149],{"class":98,"line":142},5,[96,144,121],{"class":106},[96,146,124],{"class":102},[96,148,127],{"class":106},[96,150,151],{"class":130},"path/to/group\n",[12,153,154],{},"Change the placeholder paths here to your project or group path. Sharing a connection with a group enables access to all the projects within that group. Once you save the configuration file, you can turn your attention to your application project repository, and use the following job to list and select an agent:",[87,156,158],{"className":89,"code":157,"language":91,"meta":92,"style":92},"deploy:\n   image:\n     name: bitnami/kubectl:latest\n     entrypoint: [\"\"]\n   script:\n   - kubectl config get-contexts \n   - kubectl config use-context path/to/agent-configuration-project:your-agent-name\n\n",[75,159,160,167,174,184,198,205,216],{"__ignoreMap":92},[96,161,162,165],{"class":98,"line":99},[96,163,164],{"class":102},"deploy",[96,166,107],{"class":106},[96,168,169,172],{"class":98,"line":110},[96,170,171],{"class":102},"   image",[96,173,107],{"class":106},[96,175,176,179,181],{"class":98,"line":118},[96,177,178],{"class":102},"     name",[96,180,127],{"class":106},[96,182,183],{"class":130},"bitnami/kubectl:latest\n",[96,185,186,189,192,195],{"class":98,"line":134},[96,187,188],{"class":102},"     entrypoint",[96,190,191],{"class":106},": [",[96,193,194],{"class":130},"\"\"",[96,196,197],{"class":106},"]\n",[96,199,200,203],{"class":98,"line":142},[96,201,202],{"class":102},"   script",[96,204,107],{"class":106},[96,206,208,210,213],{"class":98,"line":207},6,[96,209,121],{"class":106},[96,211,212],{"class":130},"kubectl config get-contexts",[96,214,215],{"class":106}," \n",[96,217,219,221],{"class":98,"line":218},7,[96,220,121],{"class":106},[96,222,223],{"class":130},"kubectl config use-context path/to/agent-configuration-project:your-agent-name\n",[32,225,227],{"id":226},"how-to-install-gitlab-integrated-applications-into-your-cluster","How to install GitLab integrated applications into your cluster",[12,229,230],{},"As an application of the above, let's install some applications into the cluster. As various GitLab features require applications in your cluster to be installed and configured for GitLab, Gitlab provides a cluster management project template to help you get started. One can easily install these GitLab integrated applications into their clusters using this template. Let's see how to use it with the CI/CD tunnel and the Agent!",[232,233,235],"h3",{"id":234},"create-the-cluster-management-project","Create the cluster management project",[12,237,238,239,244],{},"First, let's create a new GitLab project using the \"Cluster Management Project\" template. Open the ",[19,240,243],{"href":241,"rel":242},"https://gitlab.com/projects/new#create_from_template",[],"create new project from template page",", search for \"GitLab Cluster Management\", and start a new project with that template.",[12,246,247,248,251,252,257,258,263],{},"You will receive a project that already contains quite a lot of things! It comes with a ready-made ",[75,249,250],{},".gitlab-ci.yml"," file and ",[19,253,256],{"href":254,"rel":255},"https://github.com/roboll/helmfile",[],"helmfile"," based setup for 11 applications that integrate with various GitLab functionalities. ",[19,259,262],{"href":260,"rel":261},"https://docs.gitlab.com/user/clusters/management_project_template/#built-in-applications",[],"Each application might require different configurations",". You can read about these in the linked documentation.",[12,265,266],{},"As part of this article, we will install NGINX Ingress and GitLab Runners using the cluster management project.",[232,268,270],{"id":269},"how-to-share-the-cicd-tunnel","How to share the CI/CD tunnel",[12,272,273],{},"This newly created project needs access to one of your clusters. Let's share an Agent's connection with this project as described above. Edit your agent configuration file and add:",[87,275,277],{"className":89,"code":276,"language":91,"meta":92,"style":92},"ci_access:\n   projects:\n   - id: path/to/your/cluster/management/project\n\n",[75,278,279,285,291],{"__ignoreMap":92},[96,280,281,283],{"class":98,"line":99},[96,282,103],{"class":102},[96,284,107],{"class":106},[96,286,287,289],{"class":98,"line":110},[96,288,113],{"class":102},[96,290,107],{"class":106},[96,292,293,295,297,299],{"class":98,"line":118},[96,294,121],{"class":106},[96,296,124],{"class":102},[96,298,127],{"class":106},[96,300,301],{"class":130},"path/to/your/cluster/management/project\n",[232,303,305],{"id":304},"pick-the-right-kubernetes-context","Pick the right Kubernetes context",[12,307,308,309,311,312,315],{},"The CI/CD tunnel is already available from within your cluster management project. We tried to make it simple to start using a cluster connection without the need to edit ",[75,310,250],{},". For simple setups, you can just set a ",[75,313,314],{},"KUBE_CONTEXT"," environment variable with the path to and name of your agent.",[12,317,318],{},"Set an environment variable under \"Settings\" / \"CI/CD\" / \"Variables\"",[12,320,321],{},[322,323],"img",{"alt":324,"src":325},"KUBE_CONTEXT variable setup","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782397707/blog/Content%20Images/2022-01-07-gitops-with-gitlab-using-ci-cd/KUBE_CONTEXT_setting.png",[232,327,329],{"id":328},"how-to-install-nginx-ingress","How to install NGINX Ingress",[12,331,332],{},"We are ready to install any of the supported applications using this agent connection! Let's start by installing NGINX Ingress as it does not require any application-specific configuration.",[12,334,335,336,339,340,343],{},"In your cluster management project, edit ",[75,337,338],{},"helmfile.yaml"," and uncomment the line that points to the ",[75,341,342],{},"ingress"," application. Commit the changes and wait for GitLab magic to happen!",[12,345,346],{},"This was really easy!",[232,348,350],{"id":349},"how-to-install-gitlab-runner","How to install GitLab Runner",[12,352,353,354,359],{},"As GitLab Runner is more integrated with GitLab, it needs a little bit of configuration. ",[19,355,358],{"href":356,"rel":357},"https://docs.gitlab.com/user/infrastructure/clusters/manage/management_project_applications/runner/#required-variables",[],"The Runner should know"," where it can find your GitLab instance and needs a token to authenticate with GitLab.",[12,361,362,363,366,367,370],{},"To make it simple for you to install a Runner fleet, you can configure these as environment variables. By default the ",[75,364,365],{},"CI_SERVER_URL"," variable is used to specify the GitLab url. You can overwrite this if needed. For the token, you should create ",[75,368,369],{},"GITLAB_RUNNER_REGISTRATION_TOKEN"," as a masked and protected environment variable with the value of your Runner registration token. Feel free to use either a project or a group registration token.",[12,372,373,374,23],{},"Finally, as with the Ingress installation, uncomment the related line in the ",[75,375,338],{},[32,377,379],{"id":378},"the-full-potential-of-the-cluster-management-project","The full potential of the cluster management project",[12,381,382],{},"The cluster management project you created is yours. Thus, you are free to change it, extend it, or get rid of it. In this section, I would like to share with you a few ideas of how you might benefit the most from it.",[232,384,386],{"id":385},"did-you-move-away-from-helm-v2-already","Did you move away from Helm v2 already?",[12,388,389,390,392],{},"The ",[75,391,250],{}," file in the cluster management project has a job that supports users to upgrade their Helm v2 installations to v3. If you never had these applications installed through a cluster management project with Helm v2, then you don't need that job. Feel free to delete it from your CI yaml.",[232,394,396],{"id":395},"extend-the-project-with-your-own-apps","Extend the project with your own apps",[12,398,399,400,403],{},"The cluster management project is self-contained as is. You can add your own helm/helmfile based application setups to it. To get started, I recommend to check out the ",[19,401,256],{"href":254,"rel":402},[]," README.",[232,405,407],{"id":406},"stay-up-to-date","Stay up to date",[12,409,410],{},"We want you to own the cluster management project, so you can upgrade the applications independently of GitLab releases. Still, you might prefer to follow GitLab releases, too, as you can expect improvements to the cluster management project template. How can you do that?",[12,412,413,414,417,418,420,421,423],{},"If you followed the ",[75,415,416],{},"kpt"," based Agent installation setup, you know that ",[75,419,416],{}," can check out a git subtree and merge local changes with upstream changes when you request an update. You can use ",[75,422,416],{}," here, too!",[12,425,426,427,429],{},"As you manage the cluster management project, you can replace selected applications with their ",[75,428,416],{}," checkouts. For example, you can start following the upstream template with:",[87,431,435],{"className":432,"code":433,"language":434,"meta":92,"style":92},"language-bash shiki shiki-themes github-light","cd applicatioins\nrm -rf prometheus\nkpt pkg get https://gitlab.com/gitlab-org/project-templates/cluster-management.git/applications/prometheus prometheus\n","bash",[75,436,437,446,458],{"__ignoreMap":92},[96,438,439,443],{"class":98,"line":99},[96,440,442],{"class":441},"sYu0t","cd",[96,444,445],{"class":130}," applicatioins\n",[96,447,448,452,455],{"class":98,"line":110},[96,449,451],{"class":450},"s7eDp","rm",[96,453,454],{"class":441}," -rf",[96,456,457],{"class":130}," prometheus\n",[96,459,460,462,465,468,471],{"class":98,"line":118},[96,461,416],{"class":450},[96,463,464],{"class":130}," pkg",[96,466,467],{"class":130}," get",[96,469,470],{"class":130}," https://gitlab.com/gitlab-org/project-templates/cluster-management.git/applications/prometheus",[96,472,457],{"class":130},[12,474,475],{},"and update to the most recent version by running:",[87,477,479],{"className":432,"code":478,"language":434,"meta":92,"style":92},"kpt pkg update applications/prometheus\n",[75,480,481],{"__ignoreMap":92},[96,482,483,485,487,490],{"class":98,"line":99},[96,484,416],{"class":450},[96,486,464],{"class":130},[96,488,489],{"class":130}," update",[96,491,492],{"class":130}," applications/prometheus\n",[32,494,496],{"id":495},"recap","Recap",[12,498,499],{},"As we have seen in this article, the GitLab Kubernetes Agent provides way more possibilities than focused GitOps tools do. Besides supporting pull-based deployments, we support GitLab users with integrating into their existing CI/CD based workflows. Moreover, a Cluster Management Project template ships with GitLab that supplements the various GitLab integrations to simplify getting started with them.",[32,501,503],{"id":502},"whats-next","What's next",[12,505,506],{},"Building on our knowledge of the CI/CD tunnel, in the next article we will look into how to use Auto DevOps with the Agent.",[12,508,509],{},[15,510,511,514],{},[19,512,513],{"href":21},"Click here"," for the next tutorial.",[516,517,518],"style",{},"html pre.shiki code .shJU0, html code.shiki .shJU0{--shiki-default:#22863A}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}",{"title":92,"searchDepth":110,"depth":110,"links":520},[521,522,523,524,531,536,537],{"id":34,"depth":110,"text":35},{"id":41,"depth":110,"text":42},{"id":81,"depth":110,"text":82},{"id":226,"depth":110,"text":227,"children":525},[526,527,528,529,530],{"id":234,"depth":118,"text":235},{"id":269,"depth":118,"text":270},{"id":304,"depth":118,"text":305},{"id":328,"depth":118,"text":329},{"id":349,"depth":118,"text":350},{"id":378,"depth":110,"text":379,"children":532},[533,534,535],{"id":385,"depth":118,"text":386},{"id":395,"depth":118,"text":396},{"id":406,"depth":118,"text":407},{"id":495,"depth":110,"text":496},{"id":502,"depth":110,"text":503},"engineering","2022-01-07","This is the fifth in a series of tutorials on how to do GitOps with GitLab.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749667236/Blog/Hero%20Images/Learn-at-GL.jpg",{},true,"/en-us/blog/gitops-with-gitlab-using-ci-cd",{"title":5,"description":540,"ogTitle":5,"ogDescription":540,"noIndex":543,"ogImage":544,"ogUrl":549,"ogSiteName":550,"ogType":551,"canonicalUrls":549},"https://about.gitlab.com/blog/gitops-with-gitlab-using-ci-cd","https://about.gitlab.com","article","gitops-with-gitlab-using-ci-cd","en-us/blog/gitops-with-gitlab-using-ci-cd",[555,556,557],"kubernetes","DevOps","workflow","BlogPost","rgu7hpRHUchdHEtjx5SuVn_7G4wIB9DFRNjZbQ1B7k8",{"logo":561,"freeTrial":566,"sales":571,"login":576,"items":581,"search":908,"minimal":939,"duo":958,"switchNav":967,"pricingDeployment":978},{"config":562},{"href":563,"dataGaName":564,"dataGaLocation":565},"/","gitlab logo","header",{"text":567,"config":568},"Get free trial",{"href":569,"dataGaName":570,"dataGaLocation":565},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":572,"config":573},"Request a demo",{"href":574,"dataGaName":575,"dataGaLocation":565},"/sales/?contact-topic=request-demo","sales",{"text":577,"config":578},"Sign in",{"href":579,"dataGaName":580,"dataGaLocation":565},"https://gitlab.com/users/sign_in/","sign in",[582,611,711,716,830,886],{"text":583,"config":584,"menu":586},"Platform",{"dataNavLevelOne":585},"platform",{"type":587,"columns":588},"cards",[589,595,603],{"title":583,"description":590,"link":591},"The intelligent orchestration platform for DevSecOps",{"text":592,"config":593},"Explore our Platform",{"href":594,"dataGaName":585,"dataGaLocation":565},"/platform/",{"title":596,"description":597,"link":598},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":599,"config":600},"Meet GitLab Duo",{"href":601,"dataGaName":602,"dataGaLocation":565},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":604,"description":605,"link":606},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":607,"config":608},"Learn more",{"href":609,"dataGaName":610,"dataGaLocation":565},"/why-gitlab/","why gitlab",{"text":612,"left":546,"config":613,"menu":615},"Product",{"dataNavLevelOne":614},"solutions",{"type":616,"link":617,"columns":621,"feature":690},"lists",{"text":618,"config":619},"View all Solutions",{"href":620,"dataGaName":614,"dataGaLocation":565},"/solutions/",[622,646,669],{"title":623,"description":624,"link":625,"items":630},"Automation","CI/CD and automation to accelerate deployment",{"config":626},{"icon":627,"href":628,"dataGaName":629,"dataGaLocation":565},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[631,635,638,642],{"text":632,"config":633},"CI/CD",{"href":634,"dataGaLocation":565,"dataGaName":632},"/solutions/continuous-integration/",{"text":596,"config":636},{"href":601,"dataGaLocation":565,"dataGaName":637},"gitlab duo agent platform - product menu",{"text":639,"config":640},"Source Code Management",{"href":641,"dataGaLocation":565,"dataGaName":639},"/solutions/source-code-management/",{"text":643,"config":644},"Automated Software Delivery",{"href":628,"dataGaLocation":565,"dataGaName":645},"Automated software delivery",{"title":647,"description":648,"link":649,"items":654},"Security","Deliver code faster without compromising security",{"config":650},{"href":651,"dataGaName":652,"dataGaLocation":565,"icon":653},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[655,659,664],{"text":656,"config":657},"Application Security Testing",{"href":651,"dataGaName":658,"dataGaLocation":565},"Application security testing",{"text":660,"config":661},"Software Supply Chain Security",{"href":662,"dataGaLocation":565,"dataGaName":663},"/solutions/supply-chain/","Software supply chain security",{"text":665,"config":666},"Software Compliance",{"href":667,"dataGaName":668,"dataGaLocation":565},"/solutions/software-compliance/","software compliance",{"title":670,"link":671,"items":676},"Measurement",{"config":672},{"icon":673,"href":674,"dataGaName":675,"dataGaLocation":565},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[677,681,685],{"text":678,"config":679},"Visibility & Measurement",{"href":674,"dataGaLocation":565,"dataGaName":680},"Visibility and Measurement",{"text":682,"config":683},"Value Stream Management",{"href":684,"dataGaLocation":565,"dataGaName":682},"/solutions/value-stream-management/",{"text":686,"config":687},"Analytics & Insights",{"href":688,"dataGaLocation":565,"dataGaName":689},"/solutions/analytics-and-insights/","Analytics and insights",{"title":691,"type":616,"items":692},"GitLab for",[693,699,705],{"text":694,"config":695},"Enterprise",{"icon":696,"href":697,"dataGaLocation":565,"dataGaName":698},"Building","/enterprise/","enterprise",{"text":700,"config":701},"Small Business",{"icon":702,"href":703,"dataGaLocation":565,"dataGaName":704},"Work","/small-business/","small business",{"text":706,"config":707},"Public Sector",{"icon":708,"href":709,"dataGaLocation":565,"dataGaName":710},"Organization","/solutions/public-sector/","public sector",{"text":712,"config":713},"Pricing",{"href":714,"dataGaName":715,"dataGaLocation":565,"dataNavLevelOne":715},"/pricing/","pricing",{"text":717,"config":718,"menu":720},"Resources",{"dataNavLevelOne":719},"resources",{"type":616,"link":721,"columns":725,"feature":819},{"text":722,"config":723},"View all resources",{"href":724,"dataGaName":719,"dataGaLocation":565},"/resources/",[726,759,786],{"title":727,"items":728},"Getting started",[729,734,739,744,749,754],{"text":730,"config":731},"Install",{"href":732,"dataGaName":733,"dataGaLocation":565},"/install/","install",{"text":735,"config":736},"Quick start guides",{"href":737,"dataGaName":738,"dataGaLocation":565},"/get-started/","quick setup checklists",{"text":740,"config":741},"Learn",{"href":742,"dataGaLocation":565,"dataGaName":743},"https://university.gitlab.com/","learn",{"text":745,"config":746},"Product documentation",{"href":747,"dataGaName":748,"dataGaLocation":565},"https://docs.gitlab.com/","product documentation",{"text":750,"config":751},"Best practice videos",{"href":752,"dataGaName":753,"dataGaLocation":565},"/getting-started-videos/","best practice videos",{"text":755,"config":756},"Integrations",{"href":757,"dataGaName":758,"dataGaLocation":565},"/integrations/","integrations",{"title":760,"items":761},"Discover",[762,767,772,777,781],{"text":763,"config":764},"Customer success stories",{"href":765,"dataGaName":766,"dataGaLocation":565},"/customers/","customer success stories",{"text":768,"config":769},"Blog",{"href":770,"dataGaName":771,"dataGaLocation":565},"/blog/","blog",{"text":773,"config":774},"Demo Hub",{"href":775,"dataGaName":776,"dataGaLocation":565},"/demo-hub/","demo hub",{"text":778,"config":779},"The Source",{"href":780,"dataGaName":771,"dataGaLocation":565},"/the-source/",{"text":782,"config":783},"Remote",{"href":784,"dataGaName":785,"dataGaLocation":565},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":787,"items":788},"Connect",[789,794,799,804,809,814],{"text":790,"config":791},"GitLab Services",{"href":792,"dataGaName":793,"dataGaLocation":565},"/services/","services",{"text":795,"config":796},"Contribute",{"href":797,"dataGaName":798,"dataGaLocation":565},"https://contributors.gitlab.com","contribute",{"text":800,"config":801},"Community",{"href":802,"dataGaName":803,"dataGaLocation":565},"/community/","community",{"text":805,"config":806},"Forum",{"href":807,"dataGaName":808,"dataGaLocation":565},"https://forum.gitlab.com/","forum",{"text":810,"config":811},"Events",{"href":812,"dataGaName":813,"dataGaLocation":565},"/events/","events",{"text":815,"config":816},"Partners",{"href":817,"dataGaName":818,"dataGaLocation":565},"/partners/","partners",{"config":820,"title":823,"text":824,"link":825},{"background":821,"textColor":822},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","What’s new in GitLab","Stay updated with our latest features and improvements.",{"text":826,"config":827},"Read the latest",{"href":828,"dataGaName":829,"dataGaLocation":565},"/whats-new/","whats new",{"text":831,"config":832,"menu":834},"Company",{"dataNavLevelOne":833},"company",{"type":616,"columns":835},[836],{"items":837},[838,843,849,851,856,861,866,871,876,881],{"text":839,"config":840},"About",{"href":841,"dataGaName":842,"dataGaLocation":565},"/company/","about",{"text":844,"config":845,"footerGa":848},"Jobs",{"href":846,"dataGaName":847,"dataGaLocation":565},"/jobs/","jobs",{"dataGaName":847},{"text":810,"config":850},{"href":812,"dataGaName":813,"dataGaLocation":565},{"text":852,"config":853},"Leadership",{"href":854,"dataGaName":855,"dataGaLocation":565},"/company/team/e-group/","leadership",{"text":857,"config":858},"Handbook",{"href":859,"dataGaName":860,"dataGaLocation":565},"https://handbook.gitlab.com/","handbook",{"text":862,"config":863},"Investor relations",{"href":864,"dataGaName":865,"dataGaLocation":565},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":867,"config":868},"Trust Center",{"href":869,"dataGaName":870,"dataGaLocation":565},"/security/","trust center",{"text":872,"config":873},"AI Transparency Center",{"href":874,"dataGaName":875,"dataGaLocation":565},"/ai-transparency-center/","ai transparency center",{"text":877,"config":878},"Newsletter",{"href":879,"dataGaName":880,"dataGaLocation":565},"/company/contact/#contact-forms","newsletter",{"text":882,"config":883},"Press",{"href":884,"dataGaName":885,"dataGaLocation":565},"/press/","press",{"text":887,"config":888,"menu":889},"Contact us",{"dataNavLevelOne":833},{"type":616,"columns":890},[891],{"items":892},[893,898,903],{"text":894,"config":895},"Talk to sales",{"href":896,"dataGaName":897,"dataGaLocation":565},"/sales/","talk to sales",{"text":899,"config":900},"Support portal",{"href":901,"dataGaName":902,"dataGaLocation":565},"https://support.gitlab.com/hc/en-us","support portal",{"text":904,"config":905},"Customer portal",{"href":906,"dataGaName":907,"dataGaLocation":565},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":909,"login":910,"suggestions":917},"Close",{"text":911,"link":912},"To search repositories and projects, login to",{"text":913,"config":914},"gitlab.com",{"href":579,"dataGaName":915,"dataGaLocation":916},"search login","search",{"text":918,"default":919},"Suggestions",[920,922,926,928,932,936],{"text":596,"config":921},{"href":601,"dataGaName":596,"dataGaLocation":916},{"text":923,"config":924},"Code Suggestions (AI)",{"href":925,"dataGaName":923,"dataGaLocation":916},"/solutions/code-suggestions/",{"text":632,"config":927},{"href":634,"dataGaName":632,"dataGaLocation":916},{"text":929,"config":930},"GitLab on AWS",{"href":931,"dataGaName":929,"dataGaLocation":916},"/partners/technology-partners/aws/",{"text":933,"config":934},"GitLab on Google Cloud",{"href":935,"dataGaName":933,"dataGaLocation":916},"/partners/technology-partners/google-cloud-platform/",{"text":937,"config":938},"Why GitLab?",{"href":609,"dataGaName":937,"dataGaLocation":916},{"freeTrial":940,"mobileIcon":945,"desktopIcon":950,"secondaryButton":953},{"text":941,"config":942},"Start free trial",{"href":943,"dataGaName":570,"dataGaLocation":944},"https://gitlab.com/-/trials/new/","nav",{"altText":946,"config":947},"Gitlab Icon",{"src":948,"dataGaName":949,"dataGaLocation":944},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":946,"config":951},{"src":952,"dataGaName":949,"dataGaLocation":944},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":954,"config":955},"Get Started",{"href":956,"dataGaName":957,"dataGaLocation":944},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":959,"mobileIcon":963,"desktopIcon":965},{"text":960,"config":961},"Learn more about GitLab Duo",{"href":601,"dataGaName":962,"dataGaLocation":944},"gitlab duo",{"altText":946,"config":964},{"src":948,"dataGaName":949,"dataGaLocation":944},{"altText":946,"config":966},{"src":952,"dataGaName":949,"dataGaLocation":944},{"button":968,"mobileIcon":973,"desktopIcon":975},{"text":969,"config":970},"/switch",{"href":971,"dataGaName":972,"dataGaLocation":944},"#contact","switch",{"altText":946,"config":974},{"src":948,"dataGaName":949,"dataGaLocation":944},{"altText":946,"config":976},{"src":977,"dataGaName":949,"dataGaLocation":944},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":979,"mobileIcon":984,"desktopIcon":986},{"text":980,"config":981},"Back to pricing",{"href":714,"dataGaName":982,"dataGaLocation":944,"icon":983},"back to pricing","GoBack",{"altText":946,"config":985},{"src":948,"dataGaName":949,"dataGaLocation":944},{"altText":946,"config":987},{"src":952,"dataGaName":949,"dataGaLocation":944},{"title":989,"titleMobile":990,"button":991,"config":996},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":607,"config":992},{"href":993,"dataGaName":994,"dataGaLocation":995},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":997,"disabled":543},"release",{"data":999},{"text":1000,"source":1001,"edit":1007,"contribute":1012,"config":1017,"items":1022,"minimal":1229},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":1002,"config":1003},"View page source",{"href":1004,"dataGaName":1005,"dataGaLocation":1006},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":1008,"config":1009},"Edit this page",{"href":1010,"dataGaName":1011,"dataGaLocation":1006},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":1013,"config":1014},"Please contribute",{"href":1015,"dataGaName":1016,"dataGaLocation":1006},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":1018,"facebook":1019,"youtube":1020,"linkedin":1021},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[1023,1070,1121,1165,1197],{"title":712,"links":1024,"subMenu":1039},[1025,1029,1034],{"text":1026,"config":1027},"View plans",{"href":714,"dataGaName":1028,"dataGaLocation":1006},"view plans",{"text":1030,"config":1031},"Why Premium?",{"href":1032,"dataGaName":1033,"dataGaLocation":1006},"/pricing/premium/","why premium",{"text":1035,"config":1036},"Why Ultimate?",{"href":1037,"dataGaName":1038,"dataGaLocation":1006},"/pricing/ultimate/","why ultimate",[1040],{"title":1041,"links":1042},"Contact Us",[1043,1046,1048,1050,1055,1060,1065],{"text":1044,"config":1045},"Contact sales",{"href":896,"dataGaName":575,"dataGaLocation":1006},{"text":899,"config":1047},{"href":901,"dataGaName":902,"dataGaLocation":1006},{"text":904,"config":1049},{"href":906,"dataGaName":907,"dataGaLocation":1006},{"text":1051,"config":1052},"Status",{"href":1053,"dataGaName":1054,"dataGaLocation":1006},"https://status.gitlab.com/","status",{"text":1056,"config":1057},"Terms of use",{"href":1058,"dataGaName":1059,"dataGaLocation":1006},"/terms/","terms of use",{"text":1061,"config":1062},"Privacy statement",{"href":1063,"dataGaName":1064,"dataGaLocation":1006},"/privacy/","privacy statement",{"text":1066,"config":1067},"Cookie preferences",{"dataGaName":1068,"dataGaLocation":1006,"id":1069,"isOneTrustButton":546},"cookie preferences","ot-sdk-btn",{"title":612,"links":1071,"subMenu":1080},[1072,1076],{"text":1073,"config":1074},"DevSecOps platform",{"href":594,"dataGaName":1075,"dataGaLocation":1006},"devsecops platform",{"text":1077,"config":1078},"AI-Assisted Development",{"href":601,"dataGaName":1079,"dataGaLocation":1006},"ai-assisted development",[1081],{"title":1082,"links":1083},"Topics",[1084,1089,1092,1096,1101,1106,1111,1116],{"text":1085,"config":1086},"CICD",{"href":1087,"dataGaName":1088,"dataGaLocation":1006},"/topics/ci-cd/","cicd",{"text":30,"config":1090},{"href":29,"dataGaName":1091,"dataGaLocation":1006},"gitops",{"text":556,"config":1093},{"href":1094,"dataGaName":1095,"dataGaLocation":1006},"/topics/devops/","devops",{"text":1097,"config":1098},"Version Control",{"href":1099,"dataGaName":1100,"dataGaLocation":1006},"/topics/version-control/","version control",{"text":1102,"config":1103},"DevSecOps",{"href":1104,"dataGaName":1105,"dataGaLocation":1006},"/topics/devsecops/","devsecops",{"text":1107,"config":1108},"Cloud Native",{"href":1109,"dataGaName":1110,"dataGaLocation":1006},"/topics/cloud-native/","cloud native",{"text":1112,"config":1113},"AI for Coding",{"href":1114,"dataGaName":1115,"dataGaLocation":1006},"/topics/devops/ai-for-coding/","ai for coding",{"text":1117,"config":1118},"Agentic AI",{"href":1119,"dataGaName":1120,"dataGaLocation":1006},"/topics/agentic-ai/","agentic ai",{"title":1122,"links":1123},"Solutions",[1124,1126,1128,1133,1137,1140,1144,1147,1149,1152,1155,1160],{"text":656,"config":1125},{"href":651,"dataGaName":656,"dataGaLocation":1006},{"text":645,"config":1127},{"href":628,"dataGaName":629,"dataGaLocation":1006},{"text":1129,"config":1130},"Agile development",{"href":1131,"dataGaName":1132,"dataGaLocation":1006},"/solutions/agile-delivery/","agile delivery",{"text":1134,"config":1135},"SCM",{"href":641,"dataGaName":1136,"dataGaLocation":1006},"source code management",{"text":1085,"config":1138},{"href":634,"dataGaName":1139,"dataGaLocation":1006},"continuous integration & delivery",{"text":1141,"config":1142},"Value stream management",{"href":684,"dataGaName":1143,"dataGaLocation":1006},"value stream management",{"text":30,"config":1145},{"href":1146,"dataGaName":1091,"dataGaLocation":1006},"/solutions/gitops/",{"text":694,"config":1148},{"href":697,"dataGaName":698,"dataGaLocation":1006},{"text":1150,"config":1151},"Small business",{"href":703,"dataGaName":704,"dataGaLocation":1006},{"text":1153,"config":1154},"Public sector",{"href":709,"dataGaName":710,"dataGaLocation":1006},{"text":1156,"config":1157},"Education",{"href":1158,"dataGaName":1159,"dataGaLocation":1006},"/solutions/education/","education",{"text":1161,"config":1162},"Financial services",{"href":1163,"dataGaName":1164,"dataGaLocation":1006},"/solutions/finance/","financial services",{"title":717,"links":1166},[1167,1169,1171,1173,1176,1178,1181,1183,1185,1187,1189,1191,1193,1195],{"text":730,"config":1168},{"href":732,"dataGaName":733,"dataGaLocation":1006},{"text":735,"config":1170},{"href":737,"dataGaName":738,"dataGaLocation":1006},{"text":740,"config":1172},{"href":742,"dataGaName":743,"dataGaLocation":1006},{"text":745,"config":1174},{"href":747,"dataGaName":1175,"dataGaLocation":1006},"docs",{"text":768,"config":1177},{"href":770,"dataGaName":771,"dataGaLocation":1006},{"text":1179,"config":1180},"What's new",{"href":828,"dataGaName":829,"dataGaLocation":1006},{"text":763,"config":1182},{"href":765,"dataGaName":766,"dataGaLocation":1006},{"text":782,"config":1184},{"href":784,"dataGaName":785,"dataGaLocation":1006},{"text":790,"config":1186},{"href":792,"dataGaName":793,"dataGaLocation":1006},{"text":795,"config":1188},{"href":797,"dataGaName":798,"dataGaLocation":1006},{"text":800,"config":1190},{"href":802,"dataGaName":803,"dataGaLocation":1006},{"text":805,"config":1192},{"href":807,"dataGaName":808,"dataGaLocation":1006},{"text":810,"config":1194},{"href":812,"dataGaName":813,"dataGaLocation":1006},{"text":815,"config":1196},{"href":817,"dataGaName":818,"dataGaLocation":1006},{"title":831,"links":1198},[1199,1201,1203,1205,1207,1209,1213,1218,1220,1222,1224],{"text":839,"config":1200},{"href":841,"dataGaName":833,"dataGaLocation":1006},{"text":844,"config":1202},{"href":846,"dataGaName":847,"dataGaLocation":1006},{"text":852,"config":1204},{"href":854,"dataGaName":855,"dataGaLocation":1006},{"text":857,"config":1206},{"href":859,"dataGaName":860,"dataGaLocation":1006},{"text":862,"config":1208},{"href":864,"dataGaName":865,"dataGaLocation":1006},{"text":1210,"config":1211},"Sustainability",{"href":1212,"dataGaName":1210,"dataGaLocation":1006},"/sustainability/",{"text":1214,"config":1215},"Diversity, inclusion and belonging (DIB)",{"href":1216,"dataGaName":1217,"dataGaLocation":1006},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":867,"config":1219},{"href":869,"dataGaName":870,"dataGaLocation":1006},{"text":877,"config":1221},{"href":879,"dataGaName":880,"dataGaLocation":1006},{"text":882,"config":1223},{"href":884,"dataGaName":885,"dataGaLocation":1006},{"text":1225,"config":1226},"Modern Slavery Transparency Statement",{"href":1227,"dataGaName":1228,"dataGaLocation":1006},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1230},[1231,1234,1237],{"text":1232,"config":1233},"Terms",{"href":1058,"dataGaName":1059,"dataGaLocation":1006},{"text":1235,"config":1236},"Cookies",{"dataGaName":1068,"dataGaLocation":1006,"id":1069,"isOneTrustButton":546},{"text":1238,"config":1239},"Privacy",{"href":1063,"dataGaName":1064,"dataGaLocation":1006},[1241],{"id":1242,"title":7,"body":542,"config":1243,"content":1245,"description":542,"extension":1249,"meta":1250,"navigation":546,"path":1251,"seo":1252,"stem":1253,"__hash__":1254},"blogAuthors/en-us/blog/authors/viktor-nagy.yml",{"template":1244},"BlogAuthor",{"name":7,"config":1246},{"headshot":1247,"ctfId":1248},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662918/Blog/Author%20Headshots/nagy-headshot.jpg","nagyvgitlab","yml",{},"/en-us/blog/authors/viktor-nagy",{},"en-us/blog/authors/viktor-nagy","rM3QZ5iaPa1fk9rDH9Dq-owlsuuFm699I03jWP1dUY4",[1256,1265,1273],{"title":1257,"description":1258,"heroImage":1259,"category":538,"date":1260,"authors":1261,"slug":1264,"externalUrl":542},"Confidential AI for GitLab Self-Hosted","Give developers AI coding agents in GitLab Duo without source code leaving a hardware-encrypted boundary — no GPUs needed.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1773866173/vte9qh8rriznvyclhkes.png","2026-08-06",[1262,1263],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1266,"description":1267,"heroImage":1268,"category":538,"date":1269,"authors":1270,"slug":1272,"externalUrl":542},"Green DevOps: Why carbon measurement belongs in your CI/CD pipeline","CI/CD pipelines have a hidden carbon cost. Here's why measuring it matters, and how you can get started with Eco CI and Carmen in GitLab.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-07-09",[1271],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1274,"description":1275,"heroImage":1276,"category":538,"date":1277,"authors":1278,"slug":1280,"externalUrl":542},"How to build CI/CD observability at scale","This practical guide to GitLab pipeline analytics helps self-managed users gain operational insights using Prometheus and Grafana.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1774465167/n5hlvrsrheadeccyr1oz.png","2026-04-28",[1279],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1282},[1283,1297,1309,1321],{"id":1284,"categories":1285,"header":1287,"text":1288,"button":1289,"image":1294},"ai-modernization",[1286],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1290,"config":1291},"Get your AI maturity score",{"href":1292,"dataGaName":1293,"dataGaLocation":771},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1295},{"src":1296},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1298,"categories":1299,"header":1301,"text":1288,"button":1302,"image":1306},"devops-modernization",[1300,1105],"product","Are you just managing tools or shipping innovation?",{"text":1303,"config":1304},"Get your DevOps maturity score",{"href":1305,"dataGaName":1293,"dataGaLocation":771},"/assessments/devops-modernization-assessment/",{"config":1307},{"src":1308},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1310,"categories":1311,"header":1313,"text":1288,"button":1314,"image":1318},"security-modernization",[1312],"security","Are you trading speed for security?",{"text":1315,"config":1316},"Get your security maturity score",{"href":1317,"dataGaName":1293,"dataGaLocation":771},"/assessments/security-modernization-assessment/",{"config":1319},{"src":1320},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1322,"paths":1323,"header":1326,"text":1327,"button":1328,"image":1333},"github-azure-migration",[1324,1325],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Is your team ready for GitHub's Azure move?","GitHub is already rebuilding around Azure. Find out what it means for you.",{"text":1329,"config":1330},"See how GitLab compares to GitHub",{"href":1331,"dataGaName":1332,"dataGaLocation":771},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1334},{"src":1308},{"header":1336,"blurb":1337,"button":1338,"secondaryButton":1343},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1339,"config":1340},"Get your free trial",{"href":1341,"dataGaName":570,"dataGaLocation":1342},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":1044,"config":1344},{"href":896,"dataGaName":575,"dataGaLocation":1342},1786803761495]