[{"data":1,"prerenderedAt":1116},["ShallowReactive",2],{"/blog/how-to-migrate-atlassians-bamboo-servers-ci-cd-infrastructure-to-gitlab-ci-part-two":3,"navigation-en-us":331,"banner-en-us":758,"footer-en-us":768,"blog-post-authors-en-us-Ivan Lychev":1012,"blog-related-posts-en-us-how-to-migrate-atlassians-bamboo-servers-ci-cd-infrastructure-to-gitlab-ci-part-two":1026,"blog-promotions-en-us":1052,"next-steps-en-us":1106},{"id":4,"title":5,"authors":6,"body":8,"category":308,"date":309,"description":310,"extension":311,"externalUrl":312,"faq":312,"featured":313,"heroImage":314,"meta":315,"navigation":316,"path":317,"seo":318,"slug":323,"stem":324,"tags":325,"template":329,"updatedDate":312,"__hash__":330},"blogPosts/en-us/blog/how-to-migrate-atlassians-bamboo-servers-ci-cd-infrastructure-to-gitlab-ci-part-two.md","How to migrate Atlassian's Bamboo server's CI/CD infrastructure to GitLab CI, part two",[7],"Ivan Lychev",{"type":9,"value":10,"toc":295},"minimark",[11,21,26,29,32,35,47,54,69,75,79,90,107,111,117,124,148,161,167,181,191,197,207,210,219,223,236,258,262,267,270,282,285,289,292],[12,13,14,15,20],"p",{},"In ",[16,17,19],"a",{"href":18},"/blog/migration-from-atlassian-bamboo-server-to-gitlab-ci/","part one of our series",", I showed you how to migrate from Atlassian’s Bamboo Server to GitLab CI/CD. In this blog post we’re going to take a deep dive into how it works from a user’s perspective.",[22,23,25],"h2",{"id":24},"get-started","Get started",[12,27,28],{},"You’ve deployed the demo so it’s time to play with it to understand how it works.",[12,30,31],{},"Let's imagine that one of the members of our project is John Doe. He is a software engineer responsible for developing some components (app1, app2, and app3) of the entire product, and he and his team would like to test those components in several combinations in myriad preview environments. So, what does that look like?",[12,33,34],{},"First of all, let’s make some commits to the app1, app2, and app3 source code and get successful builds upon those commits.",[12,36,37,38,42,43,46],{},"After that, we should create releases for those apps to be able to deploy them (as the deployment part of the apps CI config only shows when being triggered by a Git tag, i.e., a GitLab release). A release can be created by launching the last step (",[39,40,41],"code",{},"manual-create-release",") in a commit pipeline. That would give us a new release with the ugly name containing the date and commit SHA in the patch part (in accord to ",[39,44,45],{},"semver"," scheme):",[12,48,49],{},[50,51],"img",{"alt":52,"src":53},"app_gitlab_release","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782397942/blog/Content%20Images/app_gitlab_release.png",[12,55,56,57,60,61,64,65,68],{},"On the ",[39,58,59],{},"Tags"," tab for the same app you now can see a deployment part of the pipeline has been triggered by the just created GitLab release but no actual environments to deploy are displayed (the ",[39,62,63],{},"_"," item in the ",[39,66,67],{},"Deploy-nonprod"," stage is not an env):",[12,70,71],{},[50,72],{"alt":73,"src":74},"absent_envs","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782397921/blog/Content%20Images/absent_envs.png",[22,76,78],{"id":77},"create-an-environment","Create an environment",[12,80,81,82,85,86,89],{},"But before that we have to briefly switch to another team who is responsible for preparing infrastructure IaC templates. Navigate to the ",[39,83,84],{},"infra/environment-blueprints"," project and pretend you are a member of that team doing their job. Namely, imagine you have just created some initial set of IaC files (they are already kindly prepared by me and present in the repository). You’ve tested them and now you feel that they are ready to be used by the other members of the project. You indicate such a readiness of a particular version of the IaC files by giving it a GitTag. Let’s put a tag like ",[39,87,88],{},"v1.0.0"," onto the HEAD version.",[12,91,92,93,96,97,100,101,103,104,106],{},"You will see how the tags are going to be used immediately. But first let's make some changes to the IaC files (e.g., add a new resource for some of the apps) and create a second Git tag, let's say ",[39,94,95],{},"v1.1.0",". So, at this moment we have two versions of IaC templates (or ",[39,98,99],{},"blueprints",") for our infrastructure - ",[39,102,88],{}," and ",[39,105,95],{},".",[22,108,110],{"id":109},"deploy-an-app-into-the-environment","Deploy an app into the environment",[12,112,113,114,116],{},"Now we can return back to John and his team. We assume John is somehow informed that the version of the IaC templates he should use is ",[39,115,88],{},". He wants to create a new preview environment out of the IaC templates of that version and put app1 and app2 into that env.",[12,118,119,120,123],{},"(Here starts a description of how a user interoperates with the ",[39,121,122],{},"infrastructure-set"," Git repo. Notice that though the eventual idea is that it should be a Merge Request workflow – where you first get a Terraform plan within a Merge Request and can apply such a plan by merging the MR – which is widely advocated by GitLab but for the sake of simplicity here the MR workflow is not implemented and instead direct push commits into a branch are made).",[12,125,126,127,130,131,133,134,137,138,103,140,143,144,147],{},"John wants the env to be named ",[39,128,129],{},"preview-for-johns-team",". He creates a new branch in the ",[39,132,122],{}," repo with that name and puts two files into it: a ",[39,135,136],{},"version.txt"," containing text ",[39,139,88],{},[39,141,142],{},"apps.txt"," with text ",[39,145,146],{},"app1 app2"," inside (the files format and its content is utterly simplified).",[12,149,150,151,153,154,156,157,160],{},"The ",[39,152,122],{}," pipeline is triggered by the new branch and first generates a Terraform plan using the set of the Terraform files indicated by the tag specified in ",[39,155,136],{},". John reviews the plan and wants to proceed with creating the environment by starting the ",[39,158,159],{},"Terraform-apply"," stage:",[12,162,163],{},[50,164],{"alt":165,"src":166},"new_env_pipeline","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398757/blog/Content%20Images/new_env_pipeline.png",[12,168,169,170,103,175,180],{},"(To store the Terraform plan as artifact and Terraform state the embedded features of GitLab are leveraged - ",[16,171,174],{"href":172,"rel":173},"https://docs.gitlab.com/user/packages/package_registry/",[],"Package Registry",[16,176,179],{"href":177,"rel":178},"https://docs.gitlab.com/user/infrastructure/iac/terraform_state/",[],"Terraform HTTP back-end by GitLab",".)",[12,182,183,184,187,188,190],{},"Now return to the ",[39,185,186],{},"app1"," project and rerun the pipeline for the app1 release we created previously to make it regenerate a list of environments to deploy. You should see that the ",[39,189,129],{}," item has appeared in the list of the environments:",[12,192,193],{},[50,194],{"alt":195,"src":196},"new_env_in_the_deploy_pipeline","https://res.cloudinary.com/about-gitlab-com/image/upload/v1782398757/blog/Content%20Images/new_env_in_the_deploy_pipeline.png",[12,198,199,200,203,204,206],{},"Click the arrow button to deploy. Then refer to the ",[39,201,202],{},"Deployments/Environments"," section of the ",[39,205,186],{}," project to ensure a new env with the app1 release deployed into it is displayed.",[12,208,209],{},"We have successfully created a new environment and deployed one of the apps into it!",[12,211,212,213,215,216,218],{},"Notice that although the above describes how users manually deploy the applications into an environment after it has been created which doesn’t look really convenient, in a real life scenario we most likely would have some additional step in the ",[39,214,122],{}," pipeline that runs after Terraform successfully finishes creating an environment and triggers deployment pipelines for all the applications specified in the ",[39,217,142],{},". In that situation, we would need to establish which versions of the applications should be deployed in such an automated manner - for example, those might be the latest versions available for each app or the versions currently deployed to production, etc.",[22,220,222],{"id":221},"update-an-environments-infrastructure","Update an environment's infrastructure",[12,224,225,226,228,229,232,233,235],{},"John got notified that a new version of the infrastructure templates is available (you remember that ",[39,227,95],{}," tag in the ",[39,230,231],{},"environment-blueprints"," repo?). His team wants to assess how app1 would work within the new conditions. They decide to update an existing env, namely ",[39,234,129],{},", for that purpose.",[12,237,238,239,241,242,245,246,248,249,251,252,254,255,257],{},"John walks to the ",[39,240,129],{}," branch of the ",[39,243,244],{},"environment-set"," repo and changes ",[39,247,136],{},"'s content from ",[39,250,88],{}," to ",[39,253,95],{},". The branch pipeline gets triggered and first shows John a Terraform plan for a diff comparing the current state of the environment. After reviewing and accepting that diff, John proceeds with actual updating the environment by launching ",[39,256,159],{}," stage. That's it!",[22,259,261],{"id":260},"advantages-and-disadvantages","Advantages and disadvantages",[263,264,266],"h3",{"id":265},"virtues","Virtues",[12,268,269],{},"Given that this case assumes migrating from some existing CI/CD infrastructure based on Atlassian Bamboo with a lot of users who are familiar with it, the proposed solution leverages the native capabilities of GitLab so that it mostly keeps the concepts and workflows used with Bamboo. This strategy makes the process of migration more smooth for the users.",[12,271,272,273,275,276,278,279,281],{},"The solution sticks to the GitOps tenets and empowers a project with all the virtues provided by Git. For example, it's usually easy to track any changes in the infrastructure back to Git repos. (It may not be so easy for the ",[39,274,244],{}," project where we do not have the infrastructure changes captured in Git commits, but in that case a task of finding differences between two states of a particular environment can be accomplished by fetching the two versions of the ",[39,277,231],{}," repo corresponding to those states denoted in the ",[39,280,136],{}," and figuring out the differences by using any apt tool.)",[12,283,284],{},"The solution tends to support user self-service where most of the tasks of changing the infrastructure can be performed only by those familiar with the basics of Git and Terraform. As a result, it offloads the DevOps team from some part of the work and removes dependence on the Ops department which comes in really handy, especially for large-scale projects.",[263,286,288],{"id":287},"shortcomings","Shortcomings",[12,290,291],{},"Besides the mentioned deficits which stem from the necessity to utterly simplify all the aspects of this demo to make it comprehensible and possible to prepare in a sensible amount of time, this solution possesses some shortcomings that have to be resolved by using external tools to make this solution appropriate for a real life usage.",[12,293,294],{},"For example, there is no way to have a central dashboard with an aggregated view of all the environments with all the apps and their versions deployed into the envs. This would require creating some custom SPA web app which would gather information from GitLab via API.",{"title":296,"searchDepth":297,"depth":297,"links":298},"",2,[299,300,301,302,303],{"id":24,"depth":297,"text":25},{"id":77,"depth":297,"text":78},{"id":109,"depth":297,"text":110},{"id":221,"depth":297,"text":222},{"id":260,"depth":297,"text":261,"children":304},[305,307],{"id":265,"depth":306,"text":266},3,{"id":287,"depth":306,"text":288},"engineering","2022-07-11","A real-world look at how a migrated CI/CD infrastructure will work in GitLab CI.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749679081/Blog/Hero%20Images/jenkins-migration.jpg",{},true,"/en-us/blog/how-to-migrate-atlassians-bamboo-servers-ci-cd-infrastructure-to-gitlab-ci-part-two",{"title":319,"description":310,"ogTitle":319,"ogDescription":310,"noIndex":313,"ogImage":314,"ogUrl":320,"ogSiteName":321,"ogType":322,"canonicalUrls":320},"Bamboo Server to GitLab CI migration: Advanced techniques","https://about.gitlab.com/blog/how-to-migrate-atlassians-bamboo-servers-ci-cd-infrastructure-to-gitlab-ci-part-two","https://about.gitlab.com","article","how-to-migrate-atlassians-bamboo-servers-ci-cd-infrastructure-to-gitlab-ci-part-two","en-us/blog/how-to-migrate-atlassians-bamboo-servers-ci-cd-infrastructure-to-gitlab-ci-part-two",[326,327,328],"CI/CD","DevOps","tutorial","BlogPost","vJQhLFg02VzRJ9Z94J81qxNhWcA2LS5cAcAx0i7l82c",{"logo":332,"freeTrial":337,"sales":342,"login":347,"items":352,"search":678,"minimal":709,"duo":728,"switchNav":737,"pricingDeployment":748},{"config":333},{"href":334,"dataGaName":335,"dataGaLocation":336},"/","gitlab logo","header",{"text":338,"config":339},"Get free trial",{"href":340,"dataGaName":341,"dataGaLocation":336},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":343,"config":344},"Request a demo",{"href":345,"dataGaName":346,"dataGaLocation":336},"/sales/?contact-topic=request-demo","sales",{"text":348,"config":349},"Sign in",{"href":350,"dataGaName":351,"dataGaLocation":336},"https://gitlab.com/users/sign_in/","sign in",[353,382,481,486,600,656],{"text":354,"config":355,"menu":357},"Platform",{"dataNavLevelOne":356},"platform",{"type":358,"columns":359},"cards",[360,366,374],{"title":354,"description":361,"link":362},"The intelligent orchestration platform for DevSecOps",{"text":363,"config":364},"Explore our Platform",{"href":365,"dataGaName":356,"dataGaLocation":336},"/platform/",{"title":367,"description":368,"link":369},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":370,"config":371},"Meet GitLab Duo",{"href":372,"dataGaName":373,"dataGaLocation":336},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":375,"description":376,"link":377},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":378,"config":379},"Learn more",{"href":380,"dataGaName":381,"dataGaLocation":336},"/why-gitlab/","why gitlab",{"text":383,"left":316,"config":384,"menu":386},"Product",{"dataNavLevelOne":385},"solutions",{"type":387,"link":388,"columns":392,"feature":460},"lists",{"text":389,"config":390},"View all Solutions",{"href":391,"dataGaName":385,"dataGaLocation":336},"/solutions/",[393,416,439],{"title":394,"description":395,"link":396,"items":401},"Automation","CI/CD and automation to accelerate deployment",{"config":397},{"icon":398,"href":399,"dataGaName":400,"dataGaLocation":336},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[402,405,408,412],{"text":326,"config":403},{"href":404,"dataGaLocation":336,"dataGaName":326},"/solutions/continuous-integration/",{"text":367,"config":406},{"href":372,"dataGaLocation":336,"dataGaName":407},"gitlab duo agent platform - product menu",{"text":409,"config":410},"Source Code Management",{"href":411,"dataGaLocation":336,"dataGaName":409},"/solutions/source-code-management/",{"text":413,"config":414},"Automated Software Delivery",{"href":399,"dataGaLocation":336,"dataGaName":415},"Automated software delivery",{"title":417,"description":418,"link":419,"items":424},"Security","Deliver code faster without compromising security",{"config":420},{"href":421,"dataGaName":422,"dataGaLocation":336,"icon":423},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[425,429,434],{"text":426,"config":427},"Application Security Testing",{"href":421,"dataGaName":428,"dataGaLocation":336},"Application security testing",{"text":430,"config":431},"Software Supply Chain Security",{"href":432,"dataGaLocation":336,"dataGaName":433},"/solutions/supply-chain/","Software supply chain security",{"text":435,"config":436},"Software Compliance",{"href":437,"dataGaName":438,"dataGaLocation":336},"/solutions/software-compliance/","software compliance",{"title":440,"link":441,"items":446},"Measurement",{"config":442},{"icon":443,"href":444,"dataGaName":445,"dataGaLocation":336},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[447,451,455],{"text":448,"config":449},"Visibility & Measurement",{"href":444,"dataGaLocation":336,"dataGaName":450},"Visibility and Measurement",{"text":452,"config":453},"Value Stream Management",{"href":454,"dataGaLocation":336,"dataGaName":452},"/solutions/value-stream-management/",{"text":456,"config":457},"Analytics & Insights",{"href":458,"dataGaLocation":336,"dataGaName":459},"/solutions/analytics-and-insights/","Analytics and insights",{"title":461,"type":387,"items":462},"GitLab for",[463,469,475],{"text":464,"config":465},"Enterprise",{"icon":466,"href":467,"dataGaLocation":336,"dataGaName":468},"Building","/enterprise/","enterprise",{"text":470,"config":471},"Small Business",{"icon":472,"href":473,"dataGaLocation":336,"dataGaName":474},"Work","/small-business/","small business",{"text":476,"config":477},"Public Sector",{"icon":478,"href":479,"dataGaLocation":336,"dataGaName":480},"Organization","/solutions/public-sector/","public sector",{"text":482,"config":483},"Pricing",{"href":484,"dataGaName":485,"dataGaLocation":336,"dataNavLevelOne":485},"/pricing/","pricing",{"text":487,"config":488,"menu":490},"Resources",{"dataNavLevelOne":489},"resources",{"type":387,"link":491,"columns":495,"feature":589},{"text":492,"config":493},"View all resources",{"href":494,"dataGaName":489,"dataGaLocation":336},"/resources/",[496,529,556],{"title":497,"items":498},"Getting started",[499,504,509,514,519,524],{"text":500,"config":501},"Install",{"href":502,"dataGaName":503,"dataGaLocation":336},"/install/","install",{"text":505,"config":506},"Quick start guides",{"href":507,"dataGaName":508,"dataGaLocation":336},"/get-started/","quick setup checklists",{"text":510,"config":511},"Learn",{"href":512,"dataGaLocation":336,"dataGaName":513},"https://university.gitlab.com/","learn",{"text":515,"config":516},"Product documentation",{"href":517,"dataGaName":518,"dataGaLocation":336},"https://docs.gitlab.com/","product documentation",{"text":520,"config":521},"Best practice videos",{"href":522,"dataGaName":523,"dataGaLocation":336},"/getting-started-videos/","best practice videos",{"text":525,"config":526},"Integrations",{"href":527,"dataGaName":528,"dataGaLocation":336},"/integrations/","integrations",{"title":530,"items":531},"Discover",[532,537,542,547,551],{"text":533,"config":534},"Customer success stories",{"href":535,"dataGaName":536,"dataGaLocation":336},"/customers/","customer success stories",{"text":538,"config":539},"Blog",{"href":540,"dataGaName":541,"dataGaLocation":336},"/blog/","blog",{"text":543,"config":544},"Demo Hub",{"href":545,"dataGaName":546,"dataGaLocation":336},"/demo-hub/","demo hub",{"text":548,"config":549},"The Source",{"href":550,"dataGaName":541,"dataGaLocation":336},"/the-source/",{"text":552,"config":553},"Remote",{"href":554,"dataGaName":555,"dataGaLocation":336},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":557,"items":558},"Connect",[559,564,569,574,579,584],{"text":560,"config":561},"GitLab Services",{"href":562,"dataGaName":563,"dataGaLocation":336},"/services/","services",{"text":565,"config":566},"Contribute",{"href":567,"dataGaName":568,"dataGaLocation":336},"https://contributors.gitlab.com","contribute",{"text":570,"config":571},"Community",{"href":572,"dataGaName":573,"dataGaLocation":336},"/community/","community",{"text":575,"config":576},"Forum",{"href":577,"dataGaName":578,"dataGaLocation":336},"https://forum.gitlab.com/","forum",{"text":580,"config":581},"Events",{"href":582,"dataGaName":583,"dataGaLocation":336},"/events/","events",{"text":585,"config":586},"Partners",{"href":587,"dataGaName":588,"dataGaLocation":336},"/partners/","partners",{"config":590,"title":593,"text":594,"link":595},{"background":591,"textColor":592},"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":596,"config":597},"Read the latest",{"href":598,"dataGaName":599,"dataGaLocation":336},"/whats-new/","whats new",{"text":601,"config":602,"menu":604},"Company",{"dataNavLevelOne":603},"company",{"type":387,"columns":605},[606],{"items":607},[608,613,619,621,626,631,636,641,646,651],{"text":609,"config":610},"About",{"href":611,"dataGaName":612,"dataGaLocation":336},"/company/","about",{"text":614,"config":615,"footerGa":618},"Jobs",{"href":616,"dataGaName":617,"dataGaLocation":336},"/jobs/","jobs",{"dataGaName":617},{"text":580,"config":620},{"href":582,"dataGaName":583,"dataGaLocation":336},{"text":622,"config":623},"Leadership",{"href":624,"dataGaName":625,"dataGaLocation":336},"/company/team/e-group/","leadership",{"text":627,"config":628},"Handbook",{"href":629,"dataGaName":630,"dataGaLocation":336},"https://handbook.gitlab.com/","handbook",{"text":632,"config":633},"Investor relations",{"href":634,"dataGaName":635,"dataGaLocation":336},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":637,"config":638},"Trust Center",{"href":639,"dataGaName":640,"dataGaLocation":336},"/security/","trust center",{"text":642,"config":643},"AI Transparency Center",{"href":644,"dataGaName":645,"dataGaLocation":336},"/ai-transparency-center/","ai transparency center",{"text":647,"config":648},"Newsletter",{"href":649,"dataGaName":650,"dataGaLocation":336},"/company/contact/#contact-forms","newsletter",{"text":652,"config":653},"Press",{"href":654,"dataGaName":655,"dataGaLocation":336},"/press/","press",{"text":657,"config":658,"menu":659},"Contact us",{"dataNavLevelOne":603},{"type":387,"columns":660},[661],{"items":662},[663,668,673],{"text":664,"config":665},"Talk to sales",{"href":666,"dataGaName":667,"dataGaLocation":336},"/sales/","talk to sales",{"text":669,"config":670},"Support portal",{"href":671,"dataGaName":672,"dataGaLocation":336},"https://support.gitlab.com/hc/en-us","support portal",{"text":674,"config":675},"Customer portal",{"href":676,"dataGaName":677,"dataGaLocation":336},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":679,"login":680,"suggestions":687},"Close",{"text":681,"link":682},"To search repositories and projects, login to",{"text":683,"config":684},"gitlab.com",{"href":350,"dataGaName":685,"dataGaLocation":686},"search login","search",{"text":688,"default":689},"Suggestions",[690,692,696,698,702,706],{"text":367,"config":691},{"href":372,"dataGaName":367,"dataGaLocation":686},{"text":693,"config":694},"Code Suggestions (AI)",{"href":695,"dataGaName":693,"dataGaLocation":686},"/solutions/code-suggestions/",{"text":326,"config":697},{"href":404,"dataGaName":326,"dataGaLocation":686},{"text":699,"config":700},"GitLab on AWS",{"href":701,"dataGaName":699,"dataGaLocation":686},"/partners/technology-partners/aws/",{"text":703,"config":704},"GitLab on Google Cloud",{"href":705,"dataGaName":703,"dataGaLocation":686},"/partners/technology-partners/google-cloud-platform/",{"text":707,"config":708},"Why GitLab?",{"href":380,"dataGaName":707,"dataGaLocation":686},{"freeTrial":710,"mobileIcon":715,"desktopIcon":720,"secondaryButton":723},{"text":711,"config":712},"Start free trial",{"href":713,"dataGaName":341,"dataGaLocation":714},"https://gitlab.com/-/trials/new/","nav",{"altText":716,"config":717},"Gitlab Icon",{"src":718,"dataGaName":719,"dataGaLocation":714},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":716,"config":721},{"src":722,"dataGaName":719,"dataGaLocation":714},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":724,"config":725},"Get Started",{"href":726,"dataGaName":727,"dataGaLocation":714},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/get-started/","get started",{"freeTrial":729,"mobileIcon":733,"desktopIcon":735},{"text":730,"config":731},"Learn more about GitLab Duo",{"href":372,"dataGaName":732,"dataGaLocation":714},"gitlab duo",{"altText":716,"config":734},{"src":718,"dataGaName":719,"dataGaLocation":714},{"altText":716,"config":736},{"src":722,"dataGaName":719,"dataGaLocation":714},{"button":738,"mobileIcon":743,"desktopIcon":745},{"text":739,"config":740},"/switch",{"href":741,"dataGaName":742,"dataGaLocation":714},"#contact","switch",{"altText":716,"config":744},{"src":718,"dataGaName":719,"dataGaLocation":714},{"altText":716,"config":746},{"src":747,"dataGaName":719,"dataGaLocation":714},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":749,"mobileIcon":754,"desktopIcon":756},{"text":750,"config":751},"Back to pricing",{"href":484,"dataGaName":752,"dataGaLocation":714,"icon":753},"back to pricing","GoBack",{"altText":716,"config":755},{"src":718,"dataGaName":719,"dataGaLocation":714},{"altText":716,"config":757},{"src":722,"dataGaName":719,"dataGaLocation":714},{"title":759,"titleMobile":760,"button":761,"config":766},"Duo Agent Platform delivers 400% ROI, per new Forrester Consulting study.","400% ROI: Forrester TEI for GitLab Duo",{"text":378,"config":762},{"href":763,"dataGaName":764,"dataGaLocation":765},"https://about.gitlab.com/blog/gitlab-duo-agent-platform-delivers-400-percent-roi/","forrester-tei-dap-banner","global-banner",{"layout":767,"disabled":313},"release",{"data":769},{"text":770,"source":771,"edit":777,"contribute":782,"config":787,"items":792,"minimal":1001},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":772,"config":773},"View page source",{"href":774,"dataGaName":775,"dataGaLocation":776},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":778,"config":779},"Edit this page",{"href":780,"dataGaName":781,"dataGaLocation":776},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":783,"config":784},"Please contribute",{"href":785,"dataGaName":786,"dataGaLocation":776},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":788,"facebook":789,"youtube":790,"linkedin":791},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[793,840,893,937,969],{"title":482,"links":794,"subMenu":809},[795,799,804],{"text":796,"config":797},"View plans",{"href":484,"dataGaName":798,"dataGaLocation":776},"view plans",{"text":800,"config":801},"Why Premium?",{"href":802,"dataGaName":803,"dataGaLocation":776},"/pricing/premium/","why premium",{"text":805,"config":806},"Why Ultimate?",{"href":807,"dataGaName":808,"dataGaLocation":776},"/pricing/ultimate/","why ultimate",[810],{"title":811,"links":812},"Contact Us",[813,816,818,820,825,830,835],{"text":814,"config":815},"Contact sales",{"href":666,"dataGaName":346,"dataGaLocation":776},{"text":669,"config":817},{"href":671,"dataGaName":672,"dataGaLocation":776},{"text":674,"config":819},{"href":676,"dataGaName":677,"dataGaLocation":776},{"text":821,"config":822},"Status",{"href":823,"dataGaName":824,"dataGaLocation":776},"https://status.gitlab.com/","status",{"text":826,"config":827},"Terms of use",{"href":828,"dataGaName":829,"dataGaLocation":776},"/terms/","terms of use",{"text":831,"config":832},"Privacy statement",{"href":833,"dataGaName":834,"dataGaLocation":776},"/privacy/","privacy statement",{"text":836,"config":837},"Cookie preferences",{"dataGaName":838,"dataGaLocation":776,"id":839,"isOneTrustButton":316},"cookie preferences","ot-sdk-btn",{"title":383,"links":841,"subMenu":850},[842,846],{"text":843,"config":844},"DevSecOps platform",{"href":365,"dataGaName":845,"dataGaLocation":776},"devsecops platform",{"text":847,"config":848},"AI-Assisted Development",{"href":372,"dataGaName":849,"dataGaLocation":776},"ai-assisted development",[851],{"title":852,"links":853},"Topics",[854,859,864,868,873,878,883,888],{"text":855,"config":856},"CICD",{"href":857,"dataGaName":858,"dataGaLocation":776},"/topics/ci-cd/","cicd",{"text":860,"config":861},"GitOps",{"href":862,"dataGaName":863,"dataGaLocation":776},"/topics/gitops/","gitops",{"text":327,"config":865},{"href":866,"dataGaName":867,"dataGaLocation":776},"/topics/devops/","devops",{"text":869,"config":870},"Version Control",{"href":871,"dataGaName":872,"dataGaLocation":776},"/topics/version-control/","version control",{"text":874,"config":875},"DevSecOps",{"href":876,"dataGaName":877,"dataGaLocation":776},"/topics/devsecops/","devsecops",{"text":879,"config":880},"Cloud Native",{"href":881,"dataGaName":882,"dataGaLocation":776},"/topics/cloud-native/","cloud native",{"text":884,"config":885},"AI for Coding",{"href":886,"dataGaName":887,"dataGaLocation":776},"/topics/devops/ai-for-coding/","ai for coding",{"text":889,"config":890},"Agentic AI",{"href":891,"dataGaName":892,"dataGaLocation":776},"/topics/agentic-ai/","agentic ai",{"title":894,"links":895},"Solutions",[896,898,900,905,909,912,916,919,921,924,927,932],{"text":426,"config":897},{"href":421,"dataGaName":426,"dataGaLocation":776},{"text":415,"config":899},{"href":399,"dataGaName":400,"dataGaLocation":776},{"text":901,"config":902},"Agile development",{"href":903,"dataGaName":904,"dataGaLocation":776},"/solutions/agile-delivery/","agile delivery",{"text":906,"config":907},"SCM",{"href":411,"dataGaName":908,"dataGaLocation":776},"source code management",{"text":855,"config":910},{"href":404,"dataGaName":911,"dataGaLocation":776},"continuous integration & delivery",{"text":913,"config":914},"Value stream management",{"href":454,"dataGaName":915,"dataGaLocation":776},"value stream management",{"text":860,"config":917},{"href":918,"dataGaName":863,"dataGaLocation":776},"/solutions/gitops/",{"text":464,"config":920},{"href":467,"dataGaName":468,"dataGaLocation":776},{"text":922,"config":923},"Small business",{"href":473,"dataGaName":474,"dataGaLocation":776},{"text":925,"config":926},"Public sector",{"href":479,"dataGaName":480,"dataGaLocation":776},{"text":928,"config":929},"Education",{"href":930,"dataGaName":931,"dataGaLocation":776},"/solutions/education/","education",{"text":933,"config":934},"Financial services",{"href":935,"dataGaName":936,"dataGaLocation":776},"/solutions/finance/","financial services",{"title":487,"links":938},[939,941,943,945,948,950,953,955,957,959,961,963,965,967],{"text":500,"config":940},{"href":502,"dataGaName":503,"dataGaLocation":776},{"text":505,"config":942},{"href":507,"dataGaName":508,"dataGaLocation":776},{"text":510,"config":944},{"href":512,"dataGaName":513,"dataGaLocation":776},{"text":515,"config":946},{"href":517,"dataGaName":947,"dataGaLocation":776},"docs",{"text":538,"config":949},{"href":540,"dataGaName":541,"dataGaLocation":776},{"text":951,"config":952},"What's new",{"href":598,"dataGaName":599,"dataGaLocation":776},{"text":533,"config":954},{"href":535,"dataGaName":536,"dataGaLocation":776},{"text":552,"config":956},{"href":554,"dataGaName":555,"dataGaLocation":776},{"text":560,"config":958},{"href":562,"dataGaName":563,"dataGaLocation":776},{"text":565,"config":960},{"href":567,"dataGaName":568,"dataGaLocation":776},{"text":570,"config":962},{"href":572,"dataGaName":573,"dataGaLocation":776},{"text":575,"config":964},{"href":577,"dataGaName":578,"dataGaLocation":776},{"text":580,"config":966},{"href":582,"dataGaName":583,"dataGaLocation":776},{"text":585,"config":968},{"href":587,"dataGaName":588,"dataGaLocation":776},{"title":601,"links":970},[971,973,975,977,979,981,985,990,992,994,996],{"text":609,"config":972},{"href":611,"dataGaName":603,"dataGaLocation":776},{"text":614,"config":974},{"href":616,"dataGaName":617,"dataGaLocation":776},{"text":622,"config":976},{"href":624,"dataGaName":625,"dataGaLocation":776},{"text":627,"config":978},{"href":629,"dataGaName":630,"dataGaLocation":776},{"text":632,"config":980},{"href":634,"dataGaName":635,"dataGaLocation":776},{"text":982,"config":983},"Sustainability",{"href":984,"dataGaName":982,"dataGaLocation":776},"/sustainability/",{"text":986,"config":987},"Diversity, inclusion and belonging (DIB)",{"href":988,"dataGaName":989,"dataGaLocation":776},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":637,"config":991},{"href":639,"dataGaName":640,"dataGaLocation":776},{"text":647,"config":993},{"href":649,"dataGaName":650,"dataGaLocation":776},{"text":652,"config":995},{"href":654,"dataGaName":655,"dataGaLocation":776},{"text":997,"config":998},"Modern Slavery Transparency Statement",{"href":999,"dataGaName":1000,"dataGaLocation":776},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":1002},[1003,1006,1009],{"text":1004,"config":1005},"Terms",{"href":828,"dataGaName":829,"dataGaLocation":776},{"text":1007,"config":1008},"Cookies",{"dataGaName":838,"dataGaLocation":776,"id":839,"isOneTrustButton":316},{"text":1010,"config":1011},"Privacy",{"href":833,"dataGaName":834,"dataGaLocation":776},[1013],{"id":1014,"title":7,"body":312,"config":1015,"content":1017,"description":312,"extension":1020,"meta":1021,"navigation":316,"path":1022,"seo":1023,"stem":1024,"__hash__":1025},"blogAuthors/en-us/blog/authors/ivan-lychev.yml",{"template":1016},"BlogAuthor",{"name":7,"config":1018},{"headshot":296,"ctfId":1019},"iLychevAD","yml",{},"/en-us/blog/authors/ivan-lychev",{},"en-us/blog/authors/ivan-lychev","9r8u9KqOTqtu_73UkGz5wcH8ZwY-WyHEIE1ulqCYllQ",[1027,1036,1044],{"title":1028,"description":1029,"heroImage":1030,"category":308,"date":1031,"authors":1032,"slug":1035,"externalUrl":312},"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",[1033,1034],"Mathias Ewald","Martin Paloncy, Edgeless Systems","confidential-ai-for-gitlab-self-hosted",{"title":1037,"description":1038,"heroImage":1039,"category":308,"date":1040,"authors":1041,"slug":1043,"externalUrl":312},"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",[1042],"Lysanne Pinto","green-devops-carbon-measurement-cicd-pipeline",{"title":1045,"description":1046,"heroImage":1047,"category":308,"date":1048,"authors":1049,"slug":1051,"externalUrl":312},"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",[1050],"Paul Meresanu","how-to-build-ci-cd-observability-at-scale",{"promotions":1053},[1054,1068,1080,1092],{"id":1055,"categories":1056,"header":1058,"text":1059,"button":1060,"image":1065},"ai-modernization",[1057],"ai","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":1061,"config":1062},"Get your AI maturity score",{"href":1063,"dataGaName":1064,"dataGaLocation":541},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":1066},{"src":1067},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":1069,"categories":1070,"header":1072,"text":1059,"button":1073,"image":1077},"devops-modernization",[1071,877],"product","Are you just managing tools or shipping innovation?",{"text":1074,"config":1075},"Get your DevOps maturity score",{"href":1076,"dataGaName":1064,"dataGaLocation":541},"/assessments/devops-modernization-assessment/",{"config":1078},{"src":1079},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":1081,"categories":1082,"header":1084,"text":1059,"button":1085,"image":1089},"security-modernization",[1083],"security","Are you trading speed for security?",{"text":1086,"config":1087},"Get your security maturity score",{"href":1088,"dataGaName":1064,"dataGaLocation":541},"/assessments/security-modernization-assessment/",{"config":1090},{"src":1091},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":1093,"paths":1094,"header":1097,"text":1098,"button":1099,"image":1104},"github-azure-migration",[1095,1096],"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":1100,"config":1101},"See how GitLab compares to GitHub",{"href":1102,"dataGaName":1103,"dataGaLocation":541},"/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":1105},{"src":1079},{"header":1107,"blurb":1108,"button":1109,"secondaryButton":1114},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":1110,"config":1111},"Get your free trial",{"href":1112,"dataGaName":341,"dataGaLocation":1113},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":814,"config":1115},{"href":666,"dataGaName":346,"dataGaLocation":1113},1786803735002]