[{"data":1,"prerenderedAt":759},["ShallowReactive",2],{"/en-us/blog/how-to-agentless-gitops-aws":3,"navigation-en-us":37,"banner-en-us":465,"footer-en-us":482,"Cesar Saavedra":725,"next-steps-en-us":738,"footer-source-/en-us/blog/how-to-agentless-gitops-aws/":753},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":27,"_id":30,"_type":31,"title":32,"_source":33,"_file":34,"_stem":35,"_extension":36},"/en-us/blog/how-to-agentless-gitops-aws","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"How to Use Push-Based GitOps with Terraform & AWS ECS/EC2","Learn how GitLab supports agentless approach for GitOps on AWS.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663397/Blog/Hero%20Images/logoforblogpost.jpg","https://about.gitlab.com/blog/how-to-agentless-gitops-aws","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"How to use a push-based approach for GitOps with Terraform and AWS ECS and EC2\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Cesar Saavedra\"}],\n        \"datePublished\": \"2021-08-10\",\n      }",{"title":17,"description":10,"authors":18,"heroImage":11,"date":20,"body":21,"category":22,"tags":23},"How to use a push-based approach for GitOps with Terraform and AWS ECS and EC2",[19],"Cesar Saavedra","2021-08-10","In [part two of our GitOps\nseries](/blog/how-to-agentless-gitops-vars/), we described how to\nuse a push-based (or agentless) approach for [GitOps](/topics/gitops/) by\nusing GitLab scripting capabilities as well as integrating\ninfrastructure-as-code tools into GitOps pipelines. In this third blog post,\nwe’ll also dig deep into how to use a push-based approach, but this time our\nfocus will be on the integrations of Terraform, AWS ECS, and AWS EC2 in\nGitOps flows. This approach may be preferable when using infrastructure\ncomponents that aren't Kubernetes, such as VMs, physical devices, and\ncloud-provider services.\n\n\nSimilar to Ansible – an agentless IT automation solution – Terraform can be\nleveraged by the scripting capabilities of GitLab to shape your\ninfrastructure. GitLab also provides out-of-the-box integrations with\nTerraform, such as GitLab-managed Terraform state and Terraform plan reports\nin merge requests.\n\n\n## GitOps flows with GitLab and Terraform\n\n\nIn this section, we explain how to use GitLab and Terraform for a\nnon-Kubernetes GitOps flow and Kubernetes GitOps.\n\n\n### GitLab and Terraform for non-K8s infrastructure\n\n\nGitLab leverages Terraform to provision a non-Kubernetes infrastructure\ncomponent, namely a MySQL database running on AWS.\n\n\nNote: Ideally, the provisioning of a database should be an on-demand,\nself-service process that developers can just use. We use this scenario to\nillustrate a GitOps flow using a non-Kubernetes infrastructure component.\n\n\n#### How collaboration works in GitLab\n\n\nSasha, a developer, creates an issue and assigns the issue to Sidney, the\ndatabase administrator, who then creates a Merge Request (MR) to start her\nwork and invite collaboration with other stakeholders across the\norganization. Opening the MR automatically creates a feature branch for the\nGitLab project. Sidney uses Terraform to create an infrastructure-as-code\nconfiguration for the database, named `mysqlmain.tf`. The database happens\nto be an AWS RDS MySQL instance. The database Terraform configuration file\nshould look like this:\n\n\n![Terraform configuration file for MySQL\ndatabase](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/0-tf-mysqlmain-created.png){:\n.shadow.small.center.wrap-text}\n\nTerraform configuration file for MySQL database.\n\n{: .note.text-center}\n\n\nTake note of the version of the database (`engine_version`), the database\nstorage (`allocated_storage`), and the embedded database admin user\n(`username`) and password, in the image above.\n\n\nAs soon as Sidney adds the file `mysqlmain.tf` file to the feature branch, a\npipeline is automatically executed by GitLab in the MR. As part of the\nreview process, a \"Terraform plan\" is executed against the Terraform files\nand the output is attached to the MR as an artifact:\n\n\n![Terraform plan output attached to Merge\nRequest](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/1-tf-report-in-MR.png){:\n.shadow.small.center.wrap-text}\n\nTerraform plan output attached to MR.\n\n{: .note.text-center}\n\n\nIn the picture above, you can see the note \"1 Terraform report was generated\nin your pipelines\". You can click on the `View full log` button to see the\noutput file of the \"Terraform plan\" command that was run against the new\nconfiguration file, as seen below:\n\n\n![Terraform plan output detailed log\nview](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/2-tf-plan-output.png){:\n.shadow.small.center.wrap-text}\n\nTerraform plan output detailed log view.\n\n{: .note.text-center}\n\n\nThe Terraform output shows that a database will be created once this\nconfiguration file is applied to the infrastructure. The artifacts attached\nto an MR provide information that can help stakeholders review the proposed\nchanges. The Terraform output in the MR fosters collaboration between\nstakeholders, and leads to infrastructure that is more consistent,\nresilient, reliable, and stable, and helps prevent unscheduled outages.\n\n\nIn the image below, we see how reviewers can collaborate in GitLab. The\nscreenshow shows that the original requester, Sasha, notices that a database\nstorage of 5 GB is too small, so she makes an inline suggestion to increase\nthe database storage capacity to 10 GB.\n\n\n![Inline suggestion to increase database storage to\n10GB](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/3-tf-inline-suggestion-by-Sasha.png){:\n.shadow.small.center.wrap-text}\n\nInline suggestion to increase database storage to 10GB.\n\n{: .note.text-center}\n\n\nInline suggestions foster collaboration and help increase developer\nproductivity suggested changes can be added with the click of a button.\n\n\nNext, Sidney invites DevOps engineer Devon to collaborate on the MR. Devon\nnotices that the database version in the configuration file is not the\nlatest one. He proceeds to make an inline suggestion proposing a more\nup-to-date version for Sidney to review:\n\n\n![Inline suggestion to update database\nversion](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/4-tf-inline-suggestion-by-Devon.png){:\n.shadow.small.center.wrap-text}\n\nInline suggestion to update database version.\n\n{: .note.text-center}\n\n\nSidney can monitor the discussion between code reviewers on the MR by\ntracking the number of unresolved threads. So far, there are four unresolved\nthreads:\n\n\n![Number of unresolved threads displayed at the top of the\nMR](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/5-tf-unresolved-threads-for-Sidney.png){:\n.shadow.small.center.wrap-text}\n\nNumber of unresolved threads displayed at the top of the MR.\n\n{: .note.text-center}\n\n\nSidney starts resolving the threads by following the convenient thread\nnavigation provided by GitLab, which makes it easy for her to process each\nof the proposed review items. Sidney just needs to click \"Apply suggestion\"\nto accept an input from a reviewer:\n\n\n![Applying a suggestion with a single button\nclick](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/6-tf-apply-inline-suggestion-by-Sidney.png){:\n.shadow.small.center.wrap-text}\n\nApplying a suggestion with one click.\n\n{: .note.text-center}\n\n\nDevon suggested replacing the embedded database admin username and password\nwith a parameter in the inline review, so Sidney replaces the embedded\nvalues with variables. The variable values will be managed by masked\nvariables within GitLab:\n\n\n![Parameterizing variables in Terraform configuration\nfile](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/7-tf-parameterizing-vars-by-Sidney.png){:\n.shadow.small.center.wrap-text}\n\nParameterizing variables in Terraform configuration file.\n\n{: .note.text-center}\n\n\nOnce the threads are resolved and the stakeholders involved in thh MR finish\ncollaborating, it's time to merge.\n\n\nLearn more about how GitLab fosters collaboration using the principles of\nGitOps in the video below:\n\n\n\u003C!-- blank line -->\n\n\u003Cfigure class=\"video_container\">\n  \u003Ciframe src=\"https://www.youtube-nocookie.com/embed/onFpj_wvbLM\" frameborder=\"0\" allowfullscreen=\"true\"> \u003C/iframe>\n\u003C/figure>\n\n\u003C!-- blank line -->\n\n\n\nIn this next example, Sasha is the one merging the MR:\n\n\n![Merge Request with infrastructure updates being\nmerged](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/8-tf-MR-merged.png){:\n.shadow.small.center.wrap-text}\n\nMR with infrastructure updates being merged.\n\n{: .note.text-center}\n\n\nMerging automatically launches a pipeline that will apply the changes to the\ninfrastructure:\n\n\n![GitOps pipeline completed\nexecution](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/9-tf-pipeline-complete.png){:\n.shadow.small.center.wrap-text}\n\nGitOps pipeline completed execution.\n\n{: .note.text-center}\n\n\n#### CI/CD with non-K8s infrastructure\n\n\nThe CI/CD pipeline in the previous example works by validating the\ninfrastructure configuration files. Then the pipeline validates the proposed\nupdates against the current state of the infrastructure. Finally, it applies\nthe updates to the production infrastructure.\n\n\nRunning this GitOps flow results in a brand new MySQL database on AWS RDS:\n\n\n![A new MySQL database has been created via a GitOps\nflow](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/10-db-ready.png){:\n.shadow.small.center.wrap-text}\n\nA new MySQL database has been created via a GitOps flow.\n\n{: .note.text-center}\n\n\nBy checking the details of the new MySQL database you can corroborate that\nthe database storage is 10 GB and that the database version is the most\ncurrent\"\n\n\n![Resulting MySQL database configuration from the collaboration of\nstakeholders](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/11-db-version-and-10g-storage.png){:\n.shadow.small.center.wrap-text}\n\nThe MySQL database configuration built by team member collaboration.\n\n{: .note.text-center}\n\n\nIn the next section, we look at how a similar GitOps flow can be applied to\na Kubernetes cluster.\n\n\n### GitLab and Terraform for K8s infrastructure\n\n\nWe skip past all the collaboration steps to focus on a change to the EKS\ncluster Terraform configuration file. In the picture below, a user is\nchanging the minimum size of the autoscaling group of the EKS cluster from\none to two:\n\n\n![Raising autoscaling group minimum to\n2](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/12-worker-nodes-to-two.png){:\n.shadow.small.center.wrap-text}\n\nIncreasing autoscaling group minimum to two.\n\n{: .note.text-center}\n\n\nWhen the stakeholder commits the change in the MR, a CI/CD pipeline\nvalidates the configuration, performs a plan against production, and applys\nthe updates to the production infrastructure. After the pipeline finishes,\nthe user can log into the Amazon EC2 console to verify that the EKS cluster\nnow has a minimum of two nodes in its autoscaling group:\n\n\n![GitOps flow modified the number of worker nodes in K8s\ncluster](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/13-two-worker-nodes-on-AWS.png){:\n.shadow.small.center.wrap-text}\n\nGitOps flow modified the number of worker nodes in K8s cluster.\n\n{: .note.text-center}\n\n\nSee this scenario in action by watching the [GitOps\npresentation](/topics/gitops/gitops-multicloud-deployments-gitlab/) on our\nGitOps topics page.\n\n\n## GitOps flows for non-K8s (like ECS, EC2)\n\n\nGitLab also provides Auto Deploy capabilities to streamline application\ndeployment to ECS and EC2, so you can shape infrastructure as desired.\n\n\n### Deploying to Amazon ECS\n\n\nAfter creating your ECS cluster, GitLab can deliver your application and its\ninfrastructure to the cluster by including the ECS Deployment template in\nyour `gitlab-ci.yml`, using CI/CD.\n\n\n```\n\ninclude:\n\nTemplate: AWS/Deploy-ECS.gitlab-ci.yml\n\n```\n\n\nNext, create the `ECS Task Definition` file in your project that specifies\nyour app's infrastructure requirements, along with other details.\n\n\n![ECS Task Definition file\nsnippet](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/14-ECS-taskdef-file.png){:\n.shadow.small.center.wrap-text}\n\nECS Task Definition file snippet.\n\n{: .note.text-center}\n\n\nFinally, define the project variable that will drive the template:\n\n\n![Project variables required to auto-deploy to\nECS](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/15-ECS-related-vars.png){:\n.shadow.small.center.wrap-text}\n\nProject variables required to auto-deploy to ECS.\n\n{: .note.text-center}\n\n\nThe ECS deployment template does the rest, including support review\npipelines.\n\n\n![Review pipeline in GitOps\nflow](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/16-ECS-review-pipeline.png){:\n.shadow.small.center.wrap-text}\n\nReview pipeline in GitOps flow.\n\n{: .note.text-center}\n\n\nIn the review pipeline above, stakeholders can review the proposed changes\nbefore sending to production. The two screenshots below show different\naspects of the proposed changes in the log output of the `review_fargate`\njob:\n\n\n![Configuring load balancers in\nECS](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/17-review-fargate-log-begin.png){:\n.shadow.small.center.wrap-text}\n\nConfigure load balancers in ECS.\n\n{: .note.text-center}\n\n\nSee the configuration for infrastructure components like load balancers in\nthe image above. The image below shows infrastructure components like\nsubnets, security groups, and the assignment of a public IP address:\n\n\n![Configuring subnets, security groups in\nECS](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/18-review-fargate-log-middle.png){:\n.shadow.small.center.wrap-text}\n\nConfiguring subnets and security groups in ECS.\n\n{: .note.text-center}\n\n\nOnce all stakeholders are done collaborating on a proposed change to the\nproduction infrastructure, the updates are applied using a CI/CD pipeline.\nBelow is an example of this type of pipeline:\n\n\n![Applying infrastructure updates to\nproduction](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/19-ECS-prod-pipeline.png){:\n.shadow.small.center.wrap-text}\n\nApplying infrastructure updates to production.\n\n{: .note.text-center}\n\n\nRead our documentation to learn more about [how GitLab users can Auto Deploy\nto\nECS](https://docs.gitlab.com/ee/ci/cloud_deployment/#deploy-your-application-to-the-aws-elastic-container-service-ecs).\n\n\n### Deploying to Amazon EC2\n\n\nGitLab also provides a built-in template to provision infrastructure and\ndeploy your applications to EC2 as part of Auto DevOps. The template:\n\n\n- Provisions infrastructure using AWS CloudFormation\n\n- Pushes application to S3\n\n- Deploys your application from S3 to EC2\n\n\nEach of these steps requires a JSON configuration file. Below is an example\nof a portion of a CloudFormation Stack JSON file used to create your\ninfrastructure:\n\n\n![CloudFormation stack JSON\nsnippet](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/20-EC2-portion-stack-file.png){:\n.shadow.small.center.wrap-text}\n\nCloudFormation stack JSON snippet.\n\n{: .note.text-center}\n\n\nThe JSON used by the Auto Deploy template to push your application to S3\nwould look similar to this:\n\n\n![JSON to push application to\nS3](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/21-EC2-push-file.png){:\n.shadow.small.center.wrap-text}\n\nJSON to push application to S3.\n\n{: .note.text-center}\n\n\nAnd the file used for the actual deployment of your application from S3 to\nEC2 would be like the following:\n\n\n![JSON to deploy application to\nEC2](https://about.gitlab.com/images/blogimages/how-to-agentless-gitops-aws/22-EC2-deploy-file.png){:\n.shadow.small.center.wrap-text}\n\nJSON to deploy application to EC2.\n\n{: .note.text-center}\n\n\nAfter creating these files, you need to create the following variables in\nyour project - displayed here with some sample values:\n\n\n```\n\nvariables:\n  CI_AWS_CF_CREATE_STACK_FILE: 'aws/cf_create_stack.json'\n  CI_AWS_S3_PUSH_FILE: 'aws/s3_push.json'\n  CI_AWS_EC2_DEPLOYMENT_FILE: 'aws/create_deployment.json'\n  CI_AWS_CF_STACK_NAME: 'YourStackName'\n```\n\n\nThe last step is to include the template in your `.gitlab-ci.yml` file:\n\n\n```\n\ninclude:\n  - template: AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml\n```\n\n\nMore details on [how GitLab uses Auto Deploy to EC2 are available in the\ndocumentation](https://docs.gitlab.com/ee/ci/cloud_deployment/#provision-and-deploy-to-your-aws-elastic-compute-cloud-ec2).\n\n\n## Agent or agentless: GitLab has your GitOps flows covered\n\n\nWhether your situation calls for an agent-based/pull-approach to doing\nGitOps, or for an agentless/push-approach, GitLab has your back. GitLab\noffers the flexibility to choose the approach to GitOps that best fits your\nspecific projects or applications. GitLab also supports many types of\ninfrastructures – from physical components and virtual machines, Kubernetes\nand containers, as well as infrastructure-as-code tools like Terraform,\nAnsible, and AWS Cloud Formation.\n","engineering",[24,25,26],"GitOps","DevOps","demo",{"slug":28,"featured":6,"template":29},"how-to-agentless-gitops-aws","BlogPost","content:en-us:blog:how-to-agentless-gitops-aws.yml","yaml","How To Agentless Gitops Aws","content","en-us/blog/how-to-agentless-gitops-aws.yml","en-us/blog/how-to-agentless-gitops-aws","yml",{"_path":38,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"data":40,"_id":461,"_type":31,"title":462,"_source":33,"_file":463,"_stem":464,"_extension":36},"/shared/en-us/main-navigation","en-us",{"logo":41,"freeTrial":46,"sales":51,"login":56,"items":61,"search":392,"minimal":423,"duo":442,"pricingDeployment":451},{"config":42},{"href":43,"dataGaName":44,"dataGaLocation":45},"/","gitlab logo","header",{"text":47,"config":48},"Get free trial",{"href":49,"dataGaName":50,"dataGaLocation":45},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":52,"config":53},"Talk to sales",{"href":54,"dataGaName":55,"dataGaLocation":45},"/sales/","sales",{"text":57,"config":58},"Sign in",{"href":59,"dataGaName":60,"dataGaLocation":45},"https://gitlab.com/users/sign_in/","sign in",[62,106,203,208,313,373],{"text":63,"config":64,"cards":66,"footer":89},"Platform",{"dataNavLevelOne":65},"platform",[67,73,81],{"title":63,"description":68,"link":69},"The most comprehensive AI-powered DevSecOps Platform",{"text":70,"config":71},"Explore our Platform",{"href":72,"dataGaName":65,"dataGaLocation":45},"/platform/",{"title":74,"description":75,"link":76},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":77,"config":78},"Meet GitLab Duo",{"href":79,"dataGaName":80,"dataGaLocation":45},"/gitlab-duo/","gitlab duo ai",{"title":82,"description":83,"link":84},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":85,"config":86},"Learn more",{"href":87,"dataGaName":88,"dataGaLocation":45},"/why-gitlab/","why gitlab",{"title":90,"items":91},"Get started with",[92,97,102],{"text":93,"config":94},"Platform Engineering",{"href":95,"dataGaName":96,"dataGaLocation":45},"/solutions/platform-engineering/","platform engineering",{"text":98,"config":99},"Developer Experience",{"href":100,"dataGaName":101,"dataGaLocation":45},"/developer-experience/","Developer experience",{"text":103,"config":104},"MLOps",{"href":105,"dataGaName":103,"dataGaLocation":45},"/topics/devops/the-role-of-ai-in-devops/",{"text":107,"left":108,"config":109,"link":111,"lists":115,"footer":185},"Product",true,{"dataNavLevelOne":110},"solutions",{"text":112,"config":113},"View all Solutions",{"href":114,"dataGaName":110,"dataGaLocation":45},"/solutions/",[116,141,164],{"title":117,"description":118,"link":119,"items":124},"Automation","CI/CD and automation to accelerate deployment",{"config":120},{"icon":121,"href":122,"dataGaName":123,"dataGaLocation":45},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[125,129,133,137],{"text":126,"config":127},"CI/CD",{"href":128,"dataGaLocation":45,"dataGaName":126},"/solutions/continuous-integration/",{"text":130,"config":131},"AI-Assisted Development",{"href":79,"dataGaLocation":45,"dataGaName":132},"AI assisted development",{"text":134,"config":135},"Source Code Management",{"href":136,"dataGaLocation":45,"dataGaName":134},"/solutions/source-code-management/",{"text":138,"config":139},"Automated Software Delivery",{"href":122,"dataGaLocation":45,"dataGaName":140},"Automated software delivery",{"title":142,"description":143,"link":144,"items":149},"Security","Deliver code faster without compromising security",{"config":145},{"href":146,"dataGaName":147,"dataGaLocation":45,"icon":148},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[150,154,159],{"text":151,"config":152},"Application Security Testing",{"href":146,"dataGaName":153,"dataGaLocation":45},"Application security testing",{"text":155,"config":156},"Software Supply Chain Security",{"href":157,"dataGaLocation":45,"dataGaName":158},"/solutions/supply-chain/","Software supply chain security",{"text":160,"config":161},"Software Compliance",{"href":162,"dataGaName":163,"dataGaLocation":45},"/solutions/software-compliance/","software compliance",{"title":165,"link":166,"items":171},"Measurement",{"config":167},{"icon":168,"href":169,"dataGaName":170,"dataGaLocation":45},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[172,176,180],{"text":173,"config":174},"Visibility & Measurement",{"href":169,"dataGaLocation":45,"dataGaName":175},"Visibility and Measurement",{"text":177,"config":178},"Value Stream Management",{"href":179,"dataGaLocation":45,"dataGaName":177},"/solutions/value-stream-management/",{"text":181,"config":182},"Analytics & Insights",{"href":183,"dataGaLocation":45,"dataGaName":184},"/solutions/analytics-and-insights/","Analytics and insights",{"title":186,"items":187},"GitLab for",[188,193,198],{"text":189,"config":190},"Enterprise",{"href":191,"dataGaLocation":45,"dataGaName":192},"/enterprise/","enterprise",{"text":194,"config":195},"Small Business",{"href":196,"dataGaLocation":45,"dataGaName":197},"/small-business/","small business",{"text":199,"config":200},"Public Sector",{"href":201,"dataGaLocation":45,"dataGaName":202},"/solutions/public-sector/","public sector",{"text":204,"config":205},"Pricing",{"href":206,"dataGaName":207,"dataGaLocation":45,"dataNavLevelOne":207},"/pricing/","pricing",{"text":209,"config":210,"link":212,"lists":216,"feature":300},"Resources",{"dataNavLevelOne":211},"resources",{"text":213,"config":214},"View all resources",{"href":215,"dataGaName":211,"dataGaLocation":45},"/resources/",[217,250,272],{"title":218,"items":219},"Getting started",[220,225,230,235,240,245],{"text":221,"config":222},"Install",{"href":223,"dataGaName":224,"dataGaLocation":45},"/install/","install",{"text":226,"config":227},"Quick start guides",{"href":228,"dataGaName":229,"dataGaLocation":45},"/get-started/","quick setup checklists",{"text":231,"config":232},"Learn",{"href":233,"dataGaLocation":45,"dataGaName":234},"https://university.gitlab.com/","learn",{"text":236,"config":237},"Product documentation",{"href":238,"dataGaName":239,"dataGaLocation":45},"https://docs.gitlab.com/","product documentation",{"text":241,"config":242},"Best practice videos",{"href":243,"dataGaName":244,"dataGaLocation":45},"/getting-started-videos/","best practice videos",{"text":246,"config":247},"Integrations",{"href":248,"dataGaName":249,"dataGaLocation":45},"/integrations/","integrations",{"title":251,"items":252},"Discover",[253,258,262,267],{"text":254,"config":255},"Customer success stories",{"href":256,"dataGaName":257,"dataGaLocation":45},"/customers/","customer success stories",{"text":259,"config":260},"Blog",{"href":261,"dataGaName":5,"dataGaLocation":45},"/blog/",{"text":263,"config":264},"Remote",{"href":265,"dataGaName":266,"dataGaLocation":45},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":268,"config":269},"TeamOps",{"href":270,"dataGaName":271,"dataGaLocation":45},"/teamops/","teamops",{"title":273,"items":274},"Connect",[275,280,285,290,295],{"text":276,"config":277},"GitLab Services",{"href":278,"dataGaName":279,"dataGaLocation":45},"/services/","services",{"text":281,"config":282},"Community",{"href":283,"dataGaName":284,"dataGaLocation":45},"/community/","community",{"text":286,"config":287},"Forum",{"href":288,"dataGaName":289,"dataGaLocation":45},"https://forum.gitlab.com/","forum",{"text":291,"config":292},"Events",{"href":293,"dataGaName":294,"dataGaLocation":45},"/events/","events",{"text":296,"config":297},"Partners",{"href":298,"dataGaName":299,"dataGaLocation":45},"/partners/","partners",{"backgroundColor":301,"textColor":302,"text":303,"image":304,"link":308},"#2f2a6b","#fff","Insights for the future of software development",{"altText":305,"config":306},"the source promo card",{"src":307},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":309,"config":310},"Read the latest",{"href":311,"dataGaName":312,"dataGaLocation":45},"/the-source/","the source",{"text":314,"config":315,"lists":317},"Company",{"dataNavLevelOne":316},"company",[318],{"items":319},[320,325,331,333,338,343,348,353,358,363,368],{"text":321,"config":322},"About",{"href":323,"dataGaName":324,"dataGaLocation":45},"/company/","about",{"text":326,"config":327,"footerGa":330},"Jobs",{"href":328,"dataGaName":329,"dataGaLocation":45},"/jobs/","jobs",{"dataGaName":329},{"text":291,"config":332},{"href":293,"dataGaName":294,"dataGaLocation":45},{"text":334,"config":335},"Leadership",{"href":336,"dataGaName":337,"dataGaLocation":45},"/company/team/e-group/","leadership",{"text":339,"config":340},"Team",{"href":341,"dataGaName":342,"dataGaLocation":45},"/company/team/","team",{"text":344,"config":345},"Handbook",{"href":346,"dataGaName":347,"dataGaLocation":45},"https://handbook.gitlab.com/","handbook",{"text":349,"config":350},"Investor relations",{"href":351,"dataGaName":352,"dataGaLocation":45},"https://ir.gitlab.com/","investor relations",{"text":354,"config":355},"Trust Center",{"href":356,"dataGaName":357,"dataGaLocation":45},"/security/","trust center",{"text":359,"config":360},"AI Transparency Center",{"href":361,"dataGaName":362,"dataGaLocation":45},"/ai-transparency-center/","ai transparency center",{"text":364,"config":365},"Newsletter",{"href":366,"dataGaName":367,"dataGaLocation":45},"/company/contact/","newsletter",{"text":369,"config":370},"Press",{"href":371,"dataGaName":372,"dataGaLocation":45},"/press/","press",{"text":374,"config":375,"lists":376},"Contact us",{"dataNavLevelOne":316},[377],{"items":378},[379,382,387],{"text":52,"config":380},{"href":54,"dataGaName":381,"dataGaLocation":45},"talk to sales",{"text":383,"config":384},"Support portal",{"href":385,"dataGaName":386,"dataGaLocation":45},"https://support.gitlab.com","support portal",{"text":388,"config":389},"Customer portal",{"href":390,"dataGaName":391,"dataGaLocation":45},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":393,"login":394,"suggestions":401},"Close",{"text":395,"link":396},"To search repositories and projects, login to",{"text":397,"config":398},"gitlab.com",{"href":59,"dataGaName":399,"dataGaLocation":400},"search login","search",{"text":402,"default":403},"Suggestions",[404,406,410,412,416,420],{"text":74,"config":405},{"href":79,"dataGaName":74,"dataGaLocation":400},{"text":407,"config":408},"Code Suggestions (AI)",{"href":409,"dataGaName":407,"dataGaLocation":400},"/solutions/code-suggestions/",{"text":126,"config":411},{"href":128,"dataGaName":126,"dataGaLocation":400},{"text":413,"config":414},"GitLab on AWS",{"href":415,"dataGaName":413,"dataGaLocation":400},"/partners/technology-partners/aws/",{"text":417,"config":418},"GitLab on Google Cloud",{"href":419,"dataGaName":417,"dataGaLocation":400},"/partners/technology-partners/google-cloud-platform/",{"text":421,"config":422},"Why GitLab?",{"href":87,"dataGaName":421,"dataGaLocation":400},{"freeTrial":424,"mobileIcon":429,"desktopIcon":434,"secondaryButton":437},{"text":425,"config":426},"Start free trial",{"href":427,"dataGaName":50,"dataGaLocation":428},"https://gitlab.com/-/trials/new/","nav",{"altText":430,"config":431},"Gitlab Icon",{"src":432,"dataGaName":433,"dataGaLocation":428},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":430,"config":435},{"src":436,"dataGaName":433,"dataGaLocation":428},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":438,"config":439},"Get Started",{"href":440,"dataGaName":441,"dataGaLocation":428},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":443,"mobileIcon":447,"desktopIcon":449},{"text":444,"config":445},"Learn more about GitLab Duo",{"href":79,"dataGaName":446,"dataGaLocation":428},"gitlab duo",{"altText":430,"config":448},{"src":432,"dataGaName":433,"dataGaLocation":428},{"altText":430,"config":450},{"src":436,"dataGaName":433,"dataGaLocation":428},{"freeTrial":452,"mobileIcon":457,"desktopIcon":459},{"text":453,"config":454},"Back to pricing",{"href":206,"dataGaName":455,"dataGaLocation":428,"icon":456},"back to pricing","GoBack",{"altText":430,"config":458},{"src":432,"dataGaName":433,"dataGaLocation":428},{"altText":430,"config":460},{"src":436,"dataGaName":433,"dataGaLocation":428},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":466,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"title":467,"button":468,"image":473,"config":477,"_id":479,"_type":31,"_source":33,"_file":480,"_stem":481,"_extension":36},"/shared/en-us/banner","is now in public beta!",{"text":469,"config":470},"Try the Beta",{"href":471,"dataGaName":472,"dataGaLocation":45},"/gitlab-duo/agent-platform/","duo banner",{"altText":474,"config":475},"GitLab Duo Agent Platform",{"src":476},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":478},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":483,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"data":484,"_id":721,"_type":31,"title":722,"_source":33,"_file":723,"_stem":724,"_extension":36},"/shared/en-us/main-footer",{"text":485,"source":486,"edit":492,"contribute":497,"config":502,"items":507,"minimal":713},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":487,"config":488},"View page source",{"href":489,"dataGaName":490,"dataGaLocation":491},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":493,"config":494},"Edit this page",{"href":495,"dataGaName":496,"dataGaLocation":491},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":498,"config":499},"Please contribute",{"href":500,"dataGaName":501,"dataGaLocation":491},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":503,"facebook":504,"youtube":505,"linkedin":506},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[508,555,606,650,679],{"title":204,"links":509,"subMenu":524},[510,514,519],{"text":511,"config":512},"View plans",{"href":206,"dataGaName":513,"dataGaLocation":491},"view plans",{"text":515,"config":516},"Why Premium?",{"href":517,"dataGaName":518,"dataGaLocation":491},"/pricing/premium/","why premium",{"text":520,"config":521},"Why Ultimate?",{"href":522,"dataGaName":523,"dataGaLocation":491},"/pricing/ultimate/","why ultimate",[525],{"title":526,"links":527},"Contact Us",[528,531,533,535,540,545,550],{"text":529,"config":530},"Contact sales",{"href":54,"dataGaName":55,"dataGaLocation":491},{"text":383,"config":532},{"href":385,"dataGaName":386,"dataGaLocation":491},{"text":388,"config":534},{"href":390,"dataGaName":391,"dataGaLocation":491},{"text":536,"config":537},"Status",{"href":538,"dataGaName":539,"dataGaLocation":491},"https://status.gitlab.com/","status",{"text":541,"config":542},"Terms of use",{"href":543,"dataGaName":544,"dataGaLocation":491},"/terms/","terms of use",{"text":546,"config":547},"Privacy statement",{"href":548,"dataGaName":549,"dataGaLocation":491},"/privacy/","privacy statement",{"text":551,"config":552},"Cookie preferences",{"dataGaName":553,"dataGaLocation":491,"id":554,"isOneTrustButton":108},"cookie preferences","ot-sdk-btn",{"title":107,"links":556,"subMenu":564},[557,561],{"text":558,"config":559},"DevSecOps platform",{"href":72,"dataGaName":560,"dataGaLocation":491},"devsecops platform",{"text":130,"config":562},{"href":79,"dataGaName":563,"dataGaLocation":491},"ai-assisted development",[565],{"title":566,"links":567},"Topics",[568,573,577,581,586,591,596,601],{"text":569,"config":570},"CICD",{"href":571,"dataGaName":572,"dataGaLocation":491},"/topics/ci-cd/","cicd",{"text":24,"config":574},{"href":575,"dataGaName":576,"dataGaLocation":491},"/topics/gitops/","gitops",{"text":25,"config":578},{"href":579,"dataGaName":580,"dataGaLocation":491},"/topics/devops/","devops",{"text":582,"config":583},"Version Control",{"href":584,"dataGaName":585,"dataGaLocation":491},"/topics/version-control/","version control",{"text":587,"config":588},"DevSecOps",{"href":589,"dataGaName":590,"dataGaLocation":491},"/topics/devsecops/","devsecops",{"text":592,"config":593},"Cloud Native",{"href":594,"dataGaName":595,"dataGaLocation":491},"/topics/cloud-native/","cloud native",{"text":597,"config":598},"AI for Coding",{"href":599,"dataGaName":600,"dataGaLocation":491},"/topics/devops/ai-for-coding/","ai for coding",{"text":602,"config":603},"Agentic AI",{"href":604,"dataGaName":605,"dataGaLocation":491},"/topics/agentic-ai/","agentic ai",{"title":607,"links":608},"Solutions",[609,611,613,618,622,625,629,632,634,637,640,645],{"text":151,"config":610},{"href":146,"dataGaName":151,"dataGaLocation":491},{"text":140,"config":612},{"href":122,"dataGaName":123,"dataGaLocation":491},{"text":614,"config":615},"Agile development",{"href":616,"dataGaName":617,"dataGaLocation":491},"/solutions/agile-delivery/","agile delivery",{"text":619,"config":620},"SCM",{"href":136,"dataGaName":621,"dataGaLocation":491},"source code management",{"text":569,"config":623},{"href":128,"dataGaName":624,"dataGaLocation":491},"continuous integration & delivery",{"text":626,"config":627},"Value stream management",{"href":179,"dataGaName":628,"dataGaLocation":491},"value stream management",{"text":24,"config":630},{"href":631,"dataGaName":576,"dataGaLocation":491},"/solutions/gitops/",{"text":189,"config":633},{"href":191,"dataGaName":192,"dataGaLocation":491},{"text":635,"config":636},"Small business",{"href":196,"dataGaName":197,"dataGaLocation":491},{"text":638,"config":639},"Public sector",{"href":201,"dataGaName":202,"dataGaLocation":491},{"text":641,"config":642},"Education",{"href":643,"dataGaName":644,"dataGaLocation":491},"/solutions/education/","education",{"text":646,"config":647},"Financial services",{"href":648,"dataGaName":649,"dataGaLocation":491},"/solutions/finance/","financial services",{"title":209,"links":651},[652,654,656,658,661,663,665,667,669,671,673,675,677],{"text":221,"config":653},{"href":223,"dataGaName":224,"dataGaLocation":491},{"text":226,"config":655},{"href":228,"dataGaName":229,"dataGaLocation":491},{"text":231,"config":657},{"href":233,"dataGaName":234,"dataGaLocation":491},{"text":236,"config":659},{"href":238,"dataGaName":660,"dataGaLocation":491},"docs",{"text":259,"config":662},{"href":261,"dataGaName":5,"dataGaLocation":491},{"text":254,"config":664},{"href":256,"dataGaName":257,"dataGaLocation":491},{"text":263,"config":666},{"href":265,"dataGaName":266,"dataGaLocation":491},{"text":276,"config":668},{"href":278,"dataGaName":279,"dataGaLocation":491},{"text":268,"config":670},{"href":270,"dataGaName":271,"dataGaLocation":491},{"text":281,"config":672},{"href":283,"dataGaName":284,"dataGaLocation":491},{"text":286,"config":674},{"href":288,"dataGaName":289,"dataGaLocation":491},{"text":291,"config":676},{"href":293,"dataGaName":294,"dataGaLocation":491},{"text":296,"config":678},{"href":298,"dataGaName":299,"dataGaLocation":491},{"title":314,"links":680},[681,683,685,687,689,691,693,697,702,704,706,708],{"text":321,"config":682},{"href":323,"dataGaName":316,"dataGaLocation":491},{"text":326,"config":684},{"href":328,"dataGaName":329,"dataGaLocation":491},{"text":334,"config":686},{"href":336,"dataGaName":337,"dataGaLocation":491},{"text":339,"config":688},{"href":341,"dataGaName":342,"dataGaLocation":491},{"text":344,"config":690},{"href":346,"dataGaName":347,"dataGaLocation":491},{"text":349,"config":692},{"href":351,"dataGaName":352,"dataGaLocation":491},{"text":694,"config":695},"Sustainability",{"href":696,"dataGaName":694,"dataGaLocation":491},"/sustainability/",{"text":698,"config":699},"Diversity, inclusion and belonging (DIB)",{"href":700,"dataGaName":701,"dataGaLocation":491},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":354,"config":703},{"href":356,"dataGaName":357,"dataGaLocation":491},{"text":364,"config":705},{"href":366,"dataGaName":367,"dataGaLocation":491},{"text":369,"config":707},{"href":371,"dataGaName":372,"dataGaLocation":491},{"text":709,"config":710},"Modern Slavery Transparency Statement",{"href":711,"dataGaName":712,"dataGaLocation":491},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":714},[715,717,719],{"text":541,"config":716},{"href":543,"dataGaName":544,"dataGaLocation":491},{"text":546,"config":718},{"href":548,"dataGaName":549,"dataGaLocation":491},{"text":551,"config":720},{"dataGaName":553,"dataGaLocation":491,"id":554,"isOneTrustButton":108},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[726],{"_path":727,"_dir":728,"_draft":6,"_partial":6,"_locale":7,"content":729,"config":733,"_id":735,"_type":31,"title":19,"_source":33,"_file":736,"_stem":737,"_extension":36},"/en-us/blog/authors/cesar-saavedra","authors",{"name":19,"config":730},{"headshot":731,"ctfId":732},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659600/Blog/Author%20Headshots/csaavedra1-headshot.jpg","csaavedra1",{"template":734},"BlogAuthor","content:en-us:blog:authors:cesar-saavedra.yml","en-us/blog/authors/cesar-saavedra.yml","en-us/blog/authors/cesar-saavedra",{"_path":739,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"header":740,"eyebrow":741,"blurb":742,"button":743,"secondaryButton":747,"_id":749,"_type":31,"title":750,"_source":33,"_file":751,"_stem":752,"_extension":36},"/shared/en-us/next-steps","Start shipping better software faster","50%+ of the Fortune 100 trust GitLab","See what your team can do with the intelligent\n\n\nDevSecOps platform.\n",{"text":47,"config":744},{"href":745,"dataGaName":50,"dataGaLocation":746},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":52,"config":748},{"href":54,"dataGaName":55,"dataGaLocation":746},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":754,"content":755,"config":758,"_id":30,"_type":31,"title":32,"_source":33,"_file":34,"_stem":35,"_extension":36},{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},{"title":17,"description":10,"authors":756,"heroImage":11,"date":20,"body":21,"category":22,"tags":757},[19],[24,25,26],{"slug":28,"featured":6,"template":29},1761814430909]