[{"data":1,"prerenderedAt":1286},["ShallowReactive",2],{"/blog/how-to-use-agent-based-gitops":3,"navigation-en-us":501,"banner-en-us":929,"footer-en-us":939,"blog-post-authors-en-us-Cesar Saavedra":1181,"blog-related-posts-en-us-how-to-use-agent-based-gitops":1196,"blog-promotions-en-us":1222,"next-steps-en-us":1276},{"id":4,"title":5,"authors":6,"body":8,"category":478,"date":479,"description":480,"extension":481,"externalUrl":482,"faq":482,"featured":483,"heroImage":484,"meta":485,"navigation":486,"path":487,"seo":488,"slug":492,"stem":493,"tags":494,"template":499,"updatedDate":482,"__hash__":500},"blogPosts/en-us/blog/how-to-use-agent-based-gitops.md","How to use a pull-based (agent-based) approach for GitOps",[7],"Cesar Saavedra",{"type":9,"value":10,"toc":469},"minimark",[11,27,32,35,44,49,57,66,76,79,87,105,117,127,134,150,157,167,174,188,195,201,204,211,220,234,241,244,250,260,270,290,293,301,310,317,332,339,345,352,361,368,374,384,390,399,405,413,422,430,436,445,448,452,455],[12,13,14,15,21,22,26],"p",{},"In the previous post, titled ",[16,17,20],"a",{"href":18,"rel":19},"https://about.gitlab.com/blog/gitops-done-3-ways/",[],"3 ways to approach GitOps",", we discussed the many benefits and options that GitLab supports for fulfilling the ",[16,23,25],{"href":24},"/topics/gitops/","GitOps"," requirements of customers, whose IT environments are composed of heterogeneous technologies and infrastructures. This post is a 3-part series, in which we delve deeper into these options. In this first part, we cover the pull-based or agent-based approach.",[28,29,31],"h2",{"id":30},"about-a-pull-based-or-agent-based-approach","About a pull-based or agent-based approach",[12,33,34],{},"In this approach, an agent is installed in your infrastructure components to pull changes whenever there is a drift from the desired configuration, which resides in GitLab. Although the infrastructure components could be anything from a physical server or router to a VM or a database, we will focus on a Kubernetes cluster in this section.",[12,36,37,38,43],{},"In the following example, the ",[16,39,42],{"href":40,"rel":41},"https://about.gitlab.com/solutions/gitops/",[],"reconciliation loop"," is made up of two components: an agent running on the Kubernetes cluster and a server-side service running on the GitLab instance. One of the benefits of this approach is that you don’t have to expose your Kubernetes clusters outside your firewall. Another benefit is its distributed architecture, in that agents running on the infrastructure components are in charge of correcting any drift relieving the server-side from resource consumption. This approach requires the maintenance and installation of agents on all infrastructure components you want to be part of your GitOps flows.",[45,46,48],"h3",{"id":47},"gitlab-agent-for-kubernetes-as-a-pull-based-approach","GitLab Agent for Kubernetes as a pull-based approach",[12,50,51,56],{},[16,52,55],{"href":53,"rel":54},"https://docs.gitlab.com/releases/#introducing-the-gitlab-kubernetes-agent",[],"Introduced"," as part of GitLab 13.4, the GitLab Agent for Kubernetes runs on your Kubernetes cluster and pulls changes in your infrastructure configuration from GitLab to your cluster keeping your infrastructure configuration from drifting away from its desired state.",[12,58,59,60,65],{},"GitLab Agent for Kubernetes (the feature) is currently implemented as two components (",[16,61,64],{"href":62,"rel":63},"https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md",[],"architecture doc","):",[67,68,69,73],"ul",{},[70,71,72],"li",{},"GitLab Agent for Kubernetes (agentk program): The component that users install into their cluster.",[70,74,75],{},"GitLab Agent for Kubernetes Server (kas program): The server-side counterpart, that runs \"next to GitLab.\"",[12,77,78],{},"The high-level architecture of the GitLab Agent for Kubernetes is depicted below:",[12,80,81,86],{},[82,83],"img",{"alt":84,"src":85},"GitLab K8s agent high-level architecture","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398517/blog/Content%20Images/how-to-use-agent-based-gitops/0-K8s-agent-arch.png","\nGitLab K8s agent high-level architecture.",[12,88,89,90,94,95,98,99,101,102,104],{},"The ",[91,92,93],"strong",{},"agentk"," is installed on your Kubernetes cluster and it is the component that applies updates to the infrastructure. The ",[91,96,97],{},"kas"," is installed on the GitLab instance and it manages the authentication and authorization between ",[91,100,93],{}," instances and GitLab, monitors projects for any changes and gathers latest project manifests to send to ",[91,103,93],{}," instances.",[106,107,108],"blockquote",{},[12,109,110,113,114,116],{},[91,111,112],{},"NOTE:"," on Gitlab.com, the ",[91,115,97],{}," is installed and maintained by GitLab. On self-managed instances, the customer needs to install it.",[12,118,119,120,122,123,126],{},"In the following self-managed instance example, we go through a GitOps flow that leverages the pull-based approach to GitOps.  After the ",[91,121,93],{}," component has already been installed on the K8s cluster, the user proceeds to log on to the GitLab instance and creates a project called ",[91,124,125],{},"gitops-project",":",[12,128,129,133],{},[82,130],{"alt":131,"src":132},"Creating the gitops-project","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398518/blog/Content%20Images/how-to-use-agent-based-gitops/1-create-gitops-proj.png","\nCreating the gitops-project.",[12,135,136,137,139,140,142,143,145,146,149],{},"The project ",[91,138,125],{}," will be the one that will be monitored or observed by the ",[91,141,97],{}," component. Then, under ",[91,144,125],{},", the user creates an empty manifest file called ",[91,147,148],{},"manifest.yaml",". This is the manifest file that will contain the Infrastructure as Code configuration for this project:",[12,151,152,156],{},[82,153],{"alt":154,"src":155},"Manifest file created","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398533/blog/Content%20Images/how-to-use-agent-based-gitops/2-manifest-file-created.png","\nManifest file created.",[12,158,159,160,163,164,166],{},"Next, the user creates a Kubernetes agent configuration repository project, ",[91,161,162],{},"kubernetes-agent",", which will contain information pertinent to the ",[91,165,97],{}," component.",[12,168,169,173],{},[82,170],{"alt":171,"src":172},"Creating the kubernetes-agent project","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398533/blog/Content%20Images/how-to-use-agent-based-gitops/3-create-K8s-agent-proj.png","\nCreating the kubernetes-agent project.",[12,175,176,177,179,180,183,184,187],{},"Within the ",[91,178,162],{}," project, the user creates a subdirectory ",[91,181,182],{},".gitlab/agents/agent1",", where ",[91,185,186],{},"agent1"," is the name given to this specific agent:",[12,189,190,194],{},[82,191],{"alt":192,"src":193},"Config.yaml file created","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398533/blog/Content%20Images/how-to-use-agent-based-gitops/4-config-yaml-created.png","\nConfig.yaml file created.",[12,196,197,198,200],{},"Notice that in the screenshot above, the project to be observed, ",[91,199,125],{},", was created in an earlier step.",[12,202,203],{},"The next step consists of the creation of a GitLab Rails Agent record to associate it with the Kubernetes agent configuration repository project. In the following screenshot, you see the commands that the user enters to first identify the task-runner pod, to log into it, to enter the Rails Console, and finally to create the agent record and a token for it:",[12,205,206,210],{},[82,207],{"alt":208,"src":209},"Agent record created","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398534/blog/Content%20Images/how-to-use-agent-based-gitops/5-agent-record-created.png","\nAgent record created.",[12,212,213,214,216,217,219],{},"In the above screenshot, the last command uses the agent token to create a secret on the K8s cluster for secured communication between the ",[91,215,93],{}," and the ",[91,218,97],{}," components.",[12,221,89,222,224,225,228,229,216,231,233],{},[91,223,93],{}," pod creation on the K8s cluster is the next step. For this, the user creates a ",[91,226,227],{},"resources.yml"," file, in which the secured communication protocol between the ",[91,230,93],{},[91,232,97],{}," is specified as shown in the following snippet:",[12,235,236,240],{},[82,237],{"alt":238,"src":239},"Websockets line","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398536/blog/Content%20Images/how-to-use-agent-based-gitops/6-wss-line-in-resources-yml.png","\nWebSockets communication specified in the resources.yml file.",[12,242,243],{},"In the above snippet, secured WebSockets protocol is being used. GitLab also supports gRPC.",[12,245,246,247,249],{},"Once the ",[91,248,227],{}," file is updated with the corresponding GitLab instance information, the user proceeds to create the pod:",[12,251,252,256,257,259],{},[82,253],{"alt":254,"src":255},"Agentk pod created","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398537/blog/Content%20Images/how-to-use-agent-based-gitops/7-agentk-created.png","\nCreation of the ",[91,258,93],{}," pod.",[12,261,262,263,266,267,269],{},"In the screenshot above, you can see the execution of the ",[91,264,265],{},"kubectl apply"," that created the ",[91,268,93],{}," pod in the K8s cluster.",[12,271,272,273,275,276,278,279,284,285,289],{},"Now that the ",[91,274,93],{}," and ",[91,277,97],{}," have been installed and are communicating securely with each other, the user can start performing some GitOps flows. Although the ",[16,280,283],{"href":281,"rel":282},"https://about.gitlab.com/topics/version-control/what-is-gitlab-flow/",[],"GitLab Flow"," is the recommended approach for DevOps, it is also applicable to GitOps flows; after all GitOps is all about applying the goodness of DevOps to managing ",[16,286,288],{"href":287},"/topics/gitops/infrastructure-as-code/","Infrastructure as Code",".",[12,291,292],{},"This means that the user should create an issue and then a merge request, in which all stakeholders can collaborate towards the resolution of the issue. For the sake of brevity, in this technical blog post, we will skip all these steps and show you how updates to the Infrastructure as Code configuration files are automatically applied to the infrastructure components.",[12,294,295,296,289],{},"NOTE: Fostering Collaboration is a great benefit of GitOps. For more information on this, check out this short ",[16,297,300],{"href":298,"rel":299},"https://youtu.be/onFpj_wvbLM",[],"tech video",[12,302,303,304,306,307,309],{},"For example, the user can start making updates to the ",[91,305,148],{}," file under the ",[91,308,125],{},", which is being observed by the kas component. Here you can see the user has pasted content into this file:",[12,311,312,316],{},[82,313],{"alt":314,"src":315},"Manifest.yaml file updated","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398537/blog/Content%20Images/how-to-use-agent-based-gitops/8-manifest-yaml-updated.png","\nManifest.yaml file updated.",[12,318,319,320,322,323,325,326,328,329,331],{},"Remember that this file had been created as an empty file. As soon as the user commits the changes displayed above, the ",[91,321,97],{}," component will detect the changes and communicate these to the ",[91,324,93],{}," component, which is running on the K8s cluster. The ",[91,327,93],{}," will immediately apply these changes to the infrastructure. In this example, the user has updated the infrastructure configuration file to have 2 instances of an nginx. As shown in the screenshot below, the ",[91,330,93],{}," has applied these updates by the instantiation of 2 nginx pods in the K8s cluster:",[12,333,334,338],{},[82,335],{"alt":336,"src":337},"Two nginx pods up and running","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398538/blog/Content%20Images/how-to-use-agent-based-gitops/9-two-nginx-running.png","\nGitOps flow instantiates two nginx pods.",[12,340,341,342,344],{},"If the user were to change the ",[91,343,148],{}," file one more time and increment the replicas of the nginx pod to 3:",[12,346,347,351],{},[82,348],{"alt":349,"src":350},"Manifest.yaml file updated with 3 nginx","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398518/blog/Content%20Images/how-to-use-agent-based-gitops/10-manifest-yaml-updated-again.png","\nManifest.yaml file updated with 3 nginx instances.",[12,353,354,355,357,358,360],{},"Again, as soon as the commit takes place, the ",[91,356,97],{}," component detects the update and communicates this to the ",[91,359,93],{}," component, which in turn, spins up a third nginx pod in the K8s cluster:",[12,362,363,367],{},[82,364],{"alt":365,"src":366},"Three nginx pods up and running","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398533/blog/Content%20Images/how-to-use-agent-based-gitops/11-three-nginx-running.png","\nGitOps flow instantiates a third nginx pod.",[12,369,370,371,373],{},"Lastly, the user can check the log files of the different components running on GKE, in this example. In the following screenshot, the user can see the ",[91,372,97],{}," component running on the GitLab instance:",[12,375,376,380,381,383],{},[82,377],{"alt":378,"src":379},"kas running on GKE","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398533/blog/Content%20Images/how-to-use-agent-based-gitops/12-kas-on-GKE.png","\nThe ",[91,382,97],{}," component running on GKE.",[12,385,386,387,389],{},"And then the user can drill down into the log of the ",[91,388,97],{}," component, and see how it is detecting commits on the project it is observing:",[12,391,392,380,396,398],{},[82,393],{"alt":394,"src":395},"kas log on GKE","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398534/blog/Content%20Images/how-to-use-agent-based-gitops/13-kas-log-on-GKE.png",[91,397,97],{}," log output on GKE.",[12,400,401,402,404],{},"Likewise, the user can navigate to the ",[91,403,93],{}," component of the K8s cluster:",[12,406,407,380,411,383],{},[82,408],{"alt":409,"src":410},"agentk running on GKE","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398533/blog/Content%20Images/how-to-use-agent-based-gitops/14-agentk-on-GitLab.png",[91,412,93],{},[12,414,415,416,418,419,421],{},"And, again drill down to its log to see, how the ",[91,417,93],{}," component runs synchronizations with the ",[91,420,97],{}," component:",[12,423,424,380,428,398],{},[82,425],{"alt":426,"src":427},"agentk log on GKE","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398533/blog/Content%20Images/how-to-use-agent-based-gitops/15-agentk-log-top-on-GitLab.png",[91,429,93],{},[12,431,432,433,435],{},"In the following screenshot, the user sees the log statements indicating that the ",[91,434,93],{}," is instantiating a third instance of an nginx pod:",[12,437,438,380,442,444],{},[82,439],{"alt":440,"src":441},"agentk instantiating a third nginx pod","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398533/blog/Content%20Images/how-to-use-agent-based-gitops/16-agentk-log-synced-on-GitLab.png",[91,443,93],{}," instantiating a third nginx pod.",[12,446,447],{},"The above sections described an example of the setup needed to install and run the GitLab Agent for Kubernetes as well as how projects are monitored and synchronized from GitLab to a running K8s cluster.",[28,449,451],{"id":450},"conclusion","Conclusion",[12,453,454],{},"We have gone over the setup and use of the Agent, which is an integral part of our pull-based or agent-based approach to GitOps. We also covered a GitOps flow that leveraged this agent-based approach, which is a good choice for Kubernetes shops that need to keep their clusters secured and behind their firewall. This approach comes with its drawbacks in that you need to maintain the agents, which also consume the resources of your infrastructure components. In part two of this series, we will discuss the push-based or agentless approach to GitOps.",[12,456,457,458,463,464],{},"Cover image by ",[16,459,462],{"href":460,"rel":461},"https://unsplash.com/@vincentledvina?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",[],"Vincent Ledvina"," on ",[16,465,468],{"href":466,"rel":467},"https://unsplash.com/s/photos/grand-tetons?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText",[],"Unsplash",{"title":470,"searchDepth":471,"depth":471,"links":472},"",2,[473,477],{"id":30,"depth":471,"text":31,"children":474},[475],{"id":47,"depth":476,"text":48},3,{"id":450,"depth":471,"text":451},"engineering","2021-06-23","Learn how GitLab supports agent-based approach for GitOps","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749682037/Blog/Hero%20Images/agent-based-gitops-cover-880x587.jpg",{},true,"/en-us/blog/how-to-use-agent-based-gitops",{"title":5,"description":480,"ogTitle":5,"ogDescription":480,"noIndex":483,"ogImage":484,"ogUrl":489,"ogSiteName":490,"ogType":491,"canonicalUrls":489},"https://about.gitlab.com/blog/how-to-use-agent-based-gitops","https://about.gitlab.com","article","how-to-use-agent-based-gitops","en-us/blog/how-to-use-agent-based-gitops",[25,495,496,497,498],"features","CI","DevOps","demo","BlogPost","c1qjNn4YUTKDBF1K9_t3jZp6dZStb1dhT5agQT3qqkk",{"logo":502,"freeTrial":507,"sales":512,"login":517,"items":522,"search":849,"minimal":880,"duo":899,"switchNav":908,"pricingDeployment":919},{"config":503},{"href":504,"dataGaName":505,"dataGaLocation":506},"/","gitlab logo","header",{"text":508,"config":509},"Get free trial",{"href":510,"dataGaName":511,"dataGaLocation":506},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":513,"config":514},"Request a demo",{"href":515,"dataGaName":516,"dataGaLocation":506},"/sales/?contact-topic=request-demo","sales",{"text":518,"config":519},"Sign in",{"href":520,"dataGaName":521,"dataGaLocation":506},"https://gitlab.com/users/sign_in/","sign in",[523,552,652,657,771,827],{"text":524,"config":525,"menu":527},"Platform",{"dataNavLevelOne":526},"platform",{"type":528,"columns":529},"cards",[530,536,544],{"title":524,"description":531,"link":532},"The intelligent orchestration platform for DevSecOps",{"text":533,"config":534},"Explore our Platform",{"href":535,"dataGaName":526,"dataGaLocation":506},"/platform/",{"title":537,"description":538,"link":539},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":540,"config":541},"Meet GitLab Duo",{"href":542,"dataGaName":543,"dataGaLocation":506},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":545,"description":546,"link":547},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":548,"config":549},"Learn more",{"href":550,"dataGaName":551,"dataGaLocation":506},"/why-gitlab/","why gitlab",{"text":553,"left":486,"config":554,"menu":556},"Product",{"dataNavLevelOne":555},"solutions",{"type":557,"link":558,"columns":562,"feature":631},"lists",{"text":559,"config":560},"View all Solutions",{"href":561,"dataGaName":555,"dataGaLocation":506},"/solutions/",[563,587,610],{"title":564,"description":565,"link":566,"items":571},"Automation","CI/CD and automation to accelerate deployment",{"config":567},{"icon":568,"href":569,"dataGaName":570,"dataGaLocation":506},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[572,576,579,583],{"text":573,"config":574},"CI/CD",{"href":575,"dataGaLocation":506,"dataGaName":573},"/solutions/continuous-integration/",{"text":537,"config":577},{"href":542,"dataGaLocation":506,"dataGaName":578},"gitlab duo agent platform - product menu",{"text":580,"config":581},"Source Code Management",{"href":582,"dataGaLocation":506,"dataGaName":580},"/solutions/source-code-management/",{"text":584,"config":585},"Automated Software Delivery",{"href":569,"dataGaLocation":506,"dataGaName":586},"Automated software delivery",{"title":588,"description":589,"link":590,"items":595},"Security","Deliver code faster without compromising security",{"config":591},{"href":592,"dataGaName":593,"dataGaLocation":506,"icon":594},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[596,600,605],{"text":597,"config":598},"Application Security Testing",{"href":592,"dataGaName":599,"dataGaLocation":506},"Application security testing",{"text":601,"config":602},"Software Supply Chain Security",{"href":603,"dataGaLocation":506,"dataGaName":604},"/solutions/supply-chain/","Software supply chain security",{"text":606,"config":607},"Software Compliance",{"href":608,"dataGaName":609,"dataGaLocation":506},"/solutions/software-compliance/","software compliance",{"title":611,"link":612,"items":617},"Measurement",{"config":613},{"icon":614,"href":615,"dataGaName":616,"dataGaLocation":506},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[618,622,626],{"text":619,"config":620},"Visibility & Measurement",{"href":615,"dataGaLocation":506,"dataGaName":621},"Visibility and Measurement",{"text":623,"config":624},"Value Stream Management",{"href":625,"dataGaLocation":506,"dataGaName":623},"/solutions/value-stream-management/",{"text":627,"config":628},"Analytics & Insights",{"href":629,"dataGaLocation":506,"dataGaName":630},"/solutions/analytics-and-insights/","Analytics and insights",{"title":632,"type":557,"items":633},"GitLab for",[634,640,646],{"text":635,"config":636},"Enterprise",{"icon":637,"href":638,"dataGaLocation":506,"dataGaName":639},"Building","/enterprise/","enterprise",{"text":641,"config":642},"Small Business",{"icon":643,"href":644,"dataGaLocation":506,"dataGaName":645},"Work","/small-business/","small business",{"text":647,"config":648},"Public Sector",{"icon":649,"href":650,"dataGaLocation":506,"dataGaName":651},"Organization","/solutions/public-sector/","public sector",{"text":653,"config":654},"Pricing",{"href":655,"dataGaName":656,"dataGaLocation":506,"dataNavLevelOne":656},"/pricing/","pricing",{"text":658,"config":659,"menu":661},"Resources",{"dataNavLevelOne":660},"resources",{"type":557,"link":662,"columns":666,"feature":760},{"text":663,"config":664},"View all resources",{"href":665,"dataGaName":660,"dataGaLocation":506},"/resources/",[667,700,727],{"title":668,"items":669},"Getting started",[670,675,680,685,690,695],{"text":671,"config":672},"Install",{"href":673,"dataGaName":674,"dataGaLocation":506},"/install/","install",{"text":676,"config":677},"Quick start guides",{"href":678,"dataGaName":679,"dataGaLocation":506},"/get-started/","quick setup checklists",{"text":681,"config":682},"Learn",{"href":683,"dataGaLocation":506,"dataGaName":684},"https://university.gitlab.com/","learn",{"text":686,"config":687},"Product documentation",{"href":688,"dataGaName":689,"dataGaLocation":506},"https://docs.gitlab.com/","product documentation",{"text":691,"config":692},"Best practice videos",{"href":693,"dataGaName":694,"dataGaLocation":506},"/getting-started-videos/","best practice videos",{"text":696,"config":697},"Integrations",{"href":698,"dataGaName":699,"dataGaLocation":506},"/integrations/","integrations",{"title":701,"items":702},"Discover",[703,708,713,718,722],{"text":704,"config":705},"Customer success stories",{"href":706,"dataGaName":707,"dataGaLocation":506},"/customers/","customer success stories",{"text":709,"config":710},"Blog",{"href":711,"dataGaName":712,"dataGaLocation":506},"/blog/","blog",{"text":714,"config":715},"Demo Hub",{"href":716,"dataGaName":717,"dataGaLocation":506},"/demo-hub/","demo hub",{"text":719,"config":720},"The Source",{"href":721,"dataGaName":712,"dataGaLocation":506},"/the-source/",{"text":723,"config":724},"Remote",{"href":725,"dataGaName":726,"dataGaLocation":506},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":728,"items":729},"Connect",[730,735,740,745,750,755],{"text":731,"config":732},"GitLab Services",{"href":733,"dataGaName":734,"dataGaLocation":506},"/services/","services",{"text":736,"config":737},"Contribute",{"href":738,"dataGaName":739,"dataGaLocation":506},"https://contributors.gitlab.com","contribute",{"text":741,"config":742},"Community",{"href":743,"dataGaName":744,"dataGaLocation":506},"/community/","community",{"text":746,"config":747},"Forum",{"href":748,"dataGaName":749,"dataGaLocation":506},"https://forum.gitlab.com/","forum",{"text":751,"config":752},"Events",{"href":753,"dataGaName":754,"dataGaLocation":506},"/events/","events",{"text":756,"config":757},"Partners",{"href":758,"dataGaName":759,"dataGaLocation":506},"/partners/","partners",{"config":761,"title":764,"text":765,"link":766},{"background":762,"textColor":763},"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":767,"config":768},"Read the latest",{"href":769,"dataGaName":770,"dataGaLocation":506},"/whats-new/","whats new",{"text":772,"config":773,"menu":775},"Company",{"dataNavLevelOne":774},"company",{"type":557,"columns":776},[777],{"items":778},[779,784,790,792,797,802,807,812,817,822],{"text":780,"config":781},"About",{"href":782,"dataGaName":783,"dataGaLocation":506},"/company/","about",{"text":785,"config":786,"footerGa":789},"Jobs",{"href":787,"dataGaName":788,"dataGaLocation":506},"/jobs/","jobs",{"dataGaName":788},{"text":751,"config":791},{"href":753,"dataGaName":754,"dataGaLocation":506},{"text":793,"config":794},"Leadership",{"href":795,"dataGaName":796,"dataGaLocation":506},"/company/team/e-group/","leadership",{"text":798,"config":799},"Handbook",{"href":800,"dataGaName":801,"dataGaLocation":506},"https://handbook.gitlab.com/","handbook",{"text":803,"config":804},"Investor relations",{"href":805,"dataGaName":806,"dataGaLocation":506},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":808,"config":809},"Trust Center",{"href":810,"dataGaName":811,"dataGaLocation":506},"/security/","trust center",{"text":813,"config":814},"AI Transparency Center",{"href":815,"dataGaName":816,"dataGaLocation":506},"/ai-transparency-center/","ai transparency center",{"text":818,"config":819},"Newsletter",{"href":820,"dataGaName":821,"dataGaLocation":506},"/company/contact/#contact-forms","newsletter",{"text":823,"config":824},"Press",{"href":825,"dataGaName":826,"dataGaLocation":506},"/press/","press",{"text":828,"config":829,"menu":830},"Contact us",{"dataNavLevelOne":774},{"type":557,"columns":831},[832],{"items":833},[834,839,844],{"text":835,"config":836},"Talk to sales",{"href":837,"dataGaName":838,"dataGaLocation":506},"/sales/","talk to sales",{"text":840,"config":841},"Support portal",{"href":842,"dataGaName":843,"dataGaLocation":506},"https://support.gitlab.com/hc/en-us","support portal",{"text":845,"config":846},"Customer portal",{"href":847,"dataGaName":848,"dataGaLocation":506},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":850,"login":851,"suggestions":858},"Close",{"text":852,"link":853},"To search repositories and projects, login to",{"text":854,"config":855},"gitlab.com",{"href":520,"dataGaName":856,"dataGaLocation":857},"search login","search",{"text":859,"default":860},"Suggestions",[861,863,867,869,873,877],{"text":537,"config":862},{"href":542,"dataGaName":537,"dataGaLocation":857},{"text":864,"config":865},"Code Suggestions (AI)",{"href":866,"dataGaName":864,"dataGaLocation":857},"/solutions/code-suggestions/",{"text":573,"config":868},{"href":575,"dataGaName":573,"dataGaLocation":857},{"text":870,"config":871},"GitLab on AWS",{"href":872,"dataGaName":870,"dataGaLocation":857},"/partners/technology-partners/aws/",{"text":874,"config":875},"GitLab on Google Cloud",{"href":876,"dataGaName":874,"dataGaLocation":857},"/partners/technology-partners/google-cloud-platform/",{"text":878,"config":879},"Why GitLab?",{"href":550,"dataGaName":878,"dataGaLocation":857},{"freeTrial":881,"mobileIcon":886,"desktopIcon":891,"secondaryButton":894},{"text":882,"config":883},"Start free trial",{"href":884,"dataGaName":511,"dataGaLocation":885},"https://gitlab.com/-/trials/new/","nav",{"altText":887,"config":888},"Gitlab Icon",{"src":889,"dataGaName":890,"dataGaLocation":885},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":887,"config":892},{"src":893,"dataGaName":890,"dataGaLocation":885},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":895,"config":896},"Get Started",{"href":897,"dataGaName":898,"dataGaLocation":885},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":900,"mobileIcon":904,"desktopIcon":906},{"text":901,"config":902},"Learn more about GitLab Duo",{"href":542,"dataGaName":903,"dataGaLocation":885},"gitlab duo",{"altText":887,"config":905},{"src":889,"dataGaName":890,"dataGaLocation":885},{"altText":887,"config":907},{"src":893,"dataGaName":890,"dataGaLocation":885},{"button":909,"mobileIcon":914,"desktopIcon":916},{"text":910,"config":911},"/switch",{"href":912,"dataGaName":913,"dataGaLocation":885},"#contact","switch",{"altText":887,"config":915},{"src":889,"dataGaName":890,"dataGaLocation":885},{"altText":887,"config":917},{"src":918,"dataGaName":890,"dataGaLocation":885},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":920,"mobileIcon":925,"desktopIcon":927},{"text":921,"config":922},"Back to pricing",{"href":655,"dataGaName":923,"dataGaLocation":885,"icon":924},"back to pricing","GoBack",{"altText":887,"config":926},{"src":889,"dataGaName":890,"dataGaLocation":885},{"altText":887,"config":928},{"src":893,"dataGaName":890,"dataGaLocation":885},{"title":930,"titleMobile":931,"button":932,"config":937},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":548,"config":933},{"href":934,"dataGaName":935,"dataGaLocation":936},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":938,"disabled":483},"release",{"data":940},{"text":941,"source":942,"edit":948,"contribute":953,"config":958,"items":963,"minimal":1170},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":943,"config":944},"View page source",{"href":945,"dataGaName":946,"dataGaLocation":947},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":949,"config":950},"Edit this page",{"href":951,"dataGaName":952,"dataGaLocation":947},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":954,"config":955},"Please contribute",{"href":956,"dataGaName":957,"dataGaLocation":947},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":959,"facebook":960,"youtube":961,"linkedin":962},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[964,1011,1062,1106,1138],{"title":653,"links":965,"subMenu":980},[966,970,975],{"text":967,"config":968},"View plans",{"href":655,"dataGaName":969,"dataGaLocation":947},"view plans",{"text":971,"config":972},"Why Premium?",{"href":973,"dataGaName":974,"dataGaLocation":947},"/pricing/premium/","why premium",{"text":976,"config":977},"Why Ultimate?",{"href":978,"dataGaName":979,"dataGaLocation":947},"/pricing/ultimate/","why ultimate",[981],{"title":982,"links":983},"Contact Us",[984,987,989,991,996,1001,1006],{"text":985,"config":986},"Contact sales",{"href":837,"dataGaName":516,"dataGaLocation":947},{"text":840,"config":988},{"href":842,"dataGaName":843,"dataGaLocation":947},{"text":845,"config":990},{"href":847,"dataGaName":848,"dataGaLocation":947},{"text":992,"config":993},"Status",{"href":994,"dataGaName":995,"dataGaLocation":947},"https://status.gitlab.com/","status",{"text":997,"config":998},"Terms of use",{"href":999,"dataGaName":1000,"dataGaLocation":947},"/terms/","terms of use",{"text":1002,"config":1003},"Privacy statement",{"href":1004,"dataGaName":1005,"dataGaLocation":947},"/privacy/","privacy statement",{"text":1007,"config":1008},"Cookie preferences",{"dataGaName":1009,"dataGaLocation":947,"id":1010,"isOneTrustButton":486},"cookie preferences","ot-sdk-btn",{"title":553,"links":1012,"subMenu":1021},[1013,1017],{"text":1014,"config":1015},"DevSecOps platform",{"href":535,"dataGaName":1016,"dataGaLocation":947},"devsecops platform",{"text":1018,"config":1019},"AI-Assisted Development",{"href":542,"dataGaName":1020,"dataGaLocation":947},"ai-assisted development",[1022],{"title":1023,"links":1024},"Topics",[1025,1030,1033,1037,1042,1047,1052,1057],{"text":1026,"config":1027},"CICD",{"href":1028,"dataGaName":1029,"dataGaLocation":947},"/topics/ci-cd/","cicd",{"text":25,"config":1031},{"href":24,"dataGaName":1032,"dataGaLocation":947},"gitops",{"text":497,"config":1034},{"href":1035,"dataGaName":1036,"dataGaLocation":947},"/topics/devops/","devops",{"text":1038,"config":1039},"Version Control",{"href":1040,"dataGaName":1041,"dataGaLocation":947},"/topics/version-control/","version control",{"text":1043,"config":1044},"DevSecOps",{"href":1045,"dataGaName":1046,"dataGaLocation":947},"/topics/devsecops/","devsecops",{"text":1048,"config":1049},"Cloud Native",{"href":1050,"dataGaName":1051,"dataGaLocation":947},"/topics/cloud-native/","cloud native",{"text":1053,"config":1054},"AI for Coding",{"href":1055,"dataGaName":1056,"dataGaLocation":947},"/topics/devops/ai-for-coding/","ai for coding",{"text":1058,"config":1059},"Agentic AI",{"href":1060,"dataGaName":1061,"dataGaLocation":947},"/topics/agentic-ai/","agentic ai",{"title":1063,"links":1064},"Solutions",[1065,1067,1069,1074,1078,1081,1085,1088,1090,1093,1096,1101],{"text":597,"config":1066},{"href":592,"dataGaName":597,"dataGaLocation":947},{"text":586,"config":1068},{"href":569,"dataGaName":570,"dataGaLocation":947},{"text":1070,"config":1071},"Agile development",{"href":1072,"dataGaName":1073,"dataGaLocation":947},"/solutions/agile-delivery/","agile delivery",{"text":1075,"config":1076},"SCM",{"href":582,"dataGaName":1077,"dataGaLocation":947},"source code management",{"text":1026,"config":1079},{"href":575,"dataGaName":1080,"dataGaLocation":947},"continuous integration & delivery",{"text":1082,"config":1083},"Value stream management",{"href":625,"dataGaName":1084,"dataGaLocation":947},"value stream management",{"text":25,"config":1086},{"href":1087,"dataGaName":1032,"dataGaLocation":947},"/solutions/gitops/",{"text":635,"config":1089},{"href":638,"dataGaName":639,"dataGaLocation":947},{"text":1091,"config":1092},"Small business",{"href":644,"dataGaName":645,"dataGaLocation":947},{"text":1094,"config":1095},"Public sector",{"href":650,"dataGaName":651,"dataGaLocation":947},{"text":1097,"config":1098},"Education",{"href":1099,"dataGaName":1100,"dataGaLocation":947},"/solutions/education/","education",{"text":1102,"config":1103},"Financial services",{"href":1104,"dataGaName":1105,"dataGaLocation":947},"/solutions/finance/","financial services",{"title":658,"links":1107},[1108,1110,1112,1114,1117,1119,1122,1124,1126,1128,1130,1132,1134,1136],{"text":671,"config":1109},{"href":673,"dataGaName":674,"dataGaLocation":947},{"text":676,"config":1111},{"href":678,"dataGaName":679,"dataGaLocation":947},{"text":681,"config":1113},{"href":683,"dataGaName":684,"dataGaLocation":947},{"text":686,"config":1115},{"href":688,"dataGaName":1116,"dataGaLocation":947},"docs",{"text":709,"config":1118},{"href":711,"dataGaName":712,"dataGaLocation":947},{"text":1120,"config":1121},"What's new",{"href":769,"dataGaName":770,"dataGaLocation":947},{"text":704,"config":1123},{"href":706,"dataGaName":707,"dataGaLocation":947},{"text":723,"config":1125},{"href":725,"dataGaName":726,"dataGaLocation":947},{"text":731,"config":1127},{"href":733,"dataGaName":734,"dataGaLocation":947},{"text":736,"config":1129},{"href":738,"dataGaName":739,"dataGaLocation":947},{"text":741,"config":1131},{"href":743,"dataGaName":744,"dataGaLocation":947},{"text":746,"config":1133},{"href":748,"dataGaName":749,"dataGaLocation":947},{"text":751,"config":1135},{"href":753,"dataGaName":754,"dataGaLocation":947},{"text":756,"config":1137},{"href":758,"dataGaName":759,"dataGaLocation":947},{"title":772,"links":1139},[1140,1142,1144,1146,1148,1150,1154,1159,1161,1163,1165],{"text":780,"config":1141},{"href":782,"dataGaName":774,"dataGaLocation":947},{"text":785,"config":1143},{"href":787,"dataGaName":788,"dataGaLocation":947},{"text":793,"config":1145},{"href":795,"dataGaName":796,"dataGaLocation":947},{"text":798,"config":1147},{"href":800,"dataGaName":801,"dataGaLocation":947},{"text":803,"config":1149},{"href":805,"dataGaName":806,"dataGaLocation":947},{"text":1151,"config":1152},"Sustainability",{"href":1153,"dataGaName":1151,"dataGaLocation":947},"/sustainability/",{"text":1155,"config":1156},"Diversity, inclusion and belonging (DIB)",{"href":1157,"dataGaName":1158,"dataGaLocation":947},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":808,"config":1160},{"href":810,"dataGaName":811,"dataGaLocation":947},{"text":818,"config":1162},{"href":820,"dataGaName":821,"dataGaLocation":947},{"text":823,"config":1164},{"href":825,"dataGaName":826,"dataGaLocation":947},{"text":1166,"config":1167},"Modern Slavery Transparency Statement",{"href":1168,"dataGaName":1169,"dataGaLocation":947},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1171},[1172,1175,1178],{"text":1173,"config":1174},"Terms",{"href":999,"dataGaName":1000,"dataGaLocation":947},{"text":1176,"config":1177},"Cookies",{"dataGaName":1009,"dataGaLocation":947,"id":1010,"isOneTrustButton":486},{"text":1179,"config":1180},"Privacy",{"href":1004,"dataGaName":1005,"dataGaLocation":947},[1182],{"id":1183,"title":7,"body":482,"config":1184,"content":1186,"description":482,"extension":1190,"meta":1191,"navigation":486,"path":1192,"seo":1193,"stem":1194,"__hash__":1195},"blogAuthors/en-us/blog/authors/cesar-saavedra.yml",{"template":1185},"BlogAuthor",{"name":7,"config":1187},{"headshot":1188,"ctfId":1189},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659600/Blog/Author%20Headshots/csaavedra1-headshot.jpg","csaavedra1","yml",{},"/en-us/blog/authors/cesar-saavedra",{},"en-us/blog/authors/cesar-saavedra","SMqRf-z0W5m5GROz_dXGjmuIb3YaOwm_n_RfeK16GcA",[1197,1206,1214],{"title":1198,"description":1199,"heroImage":1200,"category":478,"date":1201,"authors":1202,"slug":1205,"externalUrl":482},"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",[1203,1204],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1207,"description":1208,"heroImage":1209,"category":478,"date":1210,"authors":1211,"slug":1213,"externalUrl":482},"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",[1212],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1215,"description":1216,"heroImage":1217,"category":478,"date":1218,"authors":1219,"slug":1221,"externalUrl":482},"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",[1220],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1223},[1224,1238,1250,1262],{"id":1225,"categories":1226,"header":1228,"text":1229,"button":1230,"image":1235},"ai-modernization",[1227],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1231,"config":1232},"Get your AI maturity score",{"href":1233,"dataGaName":1234,"dataGaLocation":712},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1236},{"src":1237},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1239,"categories":1240,"header":1242,"text":1229,"button":1243,"image":1247},"devops-modernization",[1241,1046],"product","Are you just managing tools or shipping innovation?",{"text":1244,"config":1245},"Get your DevOps maturity score",{"href":1246,"dataGaName":1234,"dataGaLocation":712},"/assessments/devops-modernization-assessment/",{"config":1248},{"src":1249},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1251,"categories":1252,"header":1254,"text":1229,"button":1255,"image":1259},"security-modernization",[1253],"security","Are you trading speed for security?",{"text":1256,"config":1257},"Get your security maturity score",{"href":1258,"dataGaName":1234,"dataGaLocation":712},"/assessments/security-modernization-assessment/",{"config":1260},{"src":1261},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1263,"paths":1264,"header":1267,"text":1268,"button":1269,"image":1274},"github-azure-migration",[1265,1266],"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":1270,"config":1271},"See how GitLab compares to GitHub",{"href":1272,"dataGaName":1273,"dataGaLocation":712},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1275},{"src":1249},{"header":1277,"blurb":1278,"button":1279,"secondaryButton":1284},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1280,"config":1281},"Get your free trial",{"href":1282,"dataGaName":511,"dataGaLocation":1283},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":985,"config":1285},{"href":837,"dataGaName":516,"dataGaLocation":1283},1786803770164]