[{"data":1,"prerenderedAt":705},["ShallowReactive",2],{"/en-us/blog/serverless-js-project-template/":3,"navigation-en-us":36,"banner-en-us":452,"footer-en-us":467,"Mike Greiling":678,"next-steps-en-us":690},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"seo":8,"content":16,"config":26,"_id":29,"_type":30,"title":31,"_source":32,"_file":33,"_stem":34,"_extension":35},"/en-us/blog/serverless-js-project-template","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Starting a serverless JS project with GitLab","Introduction to the new serverless JS project template at GitLab","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749680997/Blog/Hero%20Images/clouds-cover.jpg","https://about.gitlab.com/blog/serverless-js-project-template","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Starting a serverless JS project with GitLab\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Mike Greiling\"}],\n        \"datePublished\": \"2020-01-14\",\n      }",{"title":9,"description":10,"authors":17,"heroImage":11,"date":19,"body":20,"category":21,"tags":22},[18],"Mike Greiling","2020-01-14","\n\n{::options parse_block_html=\"true\" /}\n\n\n\n\u003C!-- Content start here -->\n\nIf you've been working in web development these past few years than you've no doubt heard about [serverless](/topics/serverless/) FaaS solutions like AWS Lambda or Knative. The idea boils down to writing code as a set of discrete functions that can be triggered by events. All worries about provisioning server nodes, scaling them, managing your back-end stack, and many other operational tasks are abstracted away. Moreover, it often results in massive cost savings as compute resources are provisioned on-demand. As this paradigm is growing in maturity and popularity, many tools have been created to make the process even easier and there has never been a better time to try it out for yourself.\n\nTo demonstrate how easy it is to get started with FaaS in GitLab, we've now added a project template to get you up and running even faster. If you're interested in wading into the serverless waters without running a single command in your terminal, follow along and try it yourself! All that is needed for this example is a free GitLab account and an AWS account.\n\n### 1. Creating a project\n\nTo start off, let's create a project with our new serverless template. Open up the [new project](https://gitlab.com/projects/new) page and select the \"Create from template\" tab. Then scroll down and select the \"Serverless Framework/JS\" template.\n\n![Step 1](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-1.1.jpg){: .shadow.medium.center}\n\nGive your project a name and select \"Create project\"\n\n### 2. Configuring your AWS credentials\n\nNow that we have our GitLab project complete with a boilerplate serverless application, it's time to give it access credentials to AWS so we can deploy it.\n\nOpen up the AWS console, sign in, and navigate to the [IAM section](https://console.aws.amazon.com/iam/home). Here you can select \"Users\" in the left-hand column, and create a new user using the \"Add user\" button at the top of the list.\n\n![Step 2-1](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-2.1.jpg){: .shadow.medium.center}\n\nGive your user a name like \"gitlab-serverless\" and make sure to select the \"Programatic access\" checkbox before clicking on \"Next\".\n\n![Step 2-2](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-2.2.jpg){: .shadow.medium.center}\n\nNow we need to give this user the appropriate permissions to deploy serverless functions. On the \"Permissions\" page select \"Attach existing policies directly\" and then click the \"Create policy\" button. This will open a new window.\n\n![Step 2-3](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-2.3.jpg){: .shadow.medium.center}\n\nHere you'll need to select the \"JSON\" tab and paste the following policy statement:\n\n```json\n{\n  \"Statement\": [\n    {\n      \"Action\": [\n        \"apigateway:*\",\n        \"cloudformation:CancelUpdateStack\",\n        \"cloudformation:ContinueUpdateRollback\",\n        \"cloudformation:CreateChangeSet\",\n        \"cloudformation:CreateStack\",\n        \"cloudformation:CreateUploadBucket\",\n        \"cloudformation:DeleteStack\",\n        \"cloudformation:Describe*\",\n        \"cloudformation:EstimateTemplateCost\",\n        \"cloudformation:ExecuteChangeSet\",\n        \"cloudformation:Get*\",\n        \"cloudformation:List*\",\n        \"cloudformation:PreviewStackUpdate\",\n        \"cloudformation:UpdateStack\",\n        \"cloudformation:UpdateTerminationProtection\",\n        \"cloudformation:ValidateTemplate\",\n        \"dynamodb:CreateTable\",\n        \"dynamodb:DeleteTable\",\n        \"dynamodb:DescribeTable\",\n        \"ec2:AttachInternetGateway\",\n        \"ec2:AuthorizeSecurityGroupIngress\",\n        \"ec2:CreateInternetGateway\",\n        \"ec2:CreateNetworkAcl\",\n        \"ec2:CreateNetworkAclEntry\",\n        \"ec2:CreateRouteTable\",\n        \"ec2:CreateSecurityGroup\",\n        \"ec2:CreateSubnet\",\n        \"ec2:CreateTags\",\n        \"ec2:CreateVpc\",\n        \"ec2:DeleteInternetGateway\",\n        \"ec2:DeleteNetworkAcl\",\n        \"ec2:DeleteNetworkAclEntry\",\n        \"ec2:DeleteRouteTable\",\n        \"ec2:DeleteSecurityGroup\",\n        \"ec2:DeleteSubnet\",\n        \"ec2:DeleteVpc\",\n        \"ec2:Describe*\",\n        \"ec2:DetachInternetGateway\",\n        \"ec2:ModifyVpcAttribute\",\n        \"events:DeleteRule\",\n        \"events:DescribeRule\",\n        \"events:ListRuleNamesByTarget\",\n        \"events:ListRules\",\n        \"events:ListTargetsByRule\",\n        \"events:PutRule\",\n        \"events:PutTargets\",\n        \"events:RemoveTargets\",\n        \"iam:CreateRole\",\n        \"iam:DeleteRole\",\n        \"iam:DeleteRolePolicy\",\n        \"iam:GetRole\",\n        \"iam:PassRole\",\n        \"iam:PutRolePolicy\",\n        \"iot:CreateTopicRule\",\n        \"iot:DeleteTopicRule\",\n        \"iot:DisableTopicRule\",\n        \"iot:EnableTopicRule\",\n        \"iot:ReplaceTopicRule\",\n        \"kinesis:CreateStream\",\n        \"kinesis:DeleteStream\",\n        \"kinesis:DescribeStream\",\n        \"lambda:*\",\n        \"logs:CreateLogGroup\",\n        \"logs:DeleteLogGroup\",\n        \"logs:DescribeLogGroups\",\n        \"logs:DescribeLogStreams\",\n        \"logs:FilterLogEvents\",\n        \"logs:GetLogEvents\",\n        \"s3:CreateBucket\",\n        \"s3:DeleteBucket\",\n        \"s3:DeleteBucketPolicy\",\n        \"s3:DeleteObject\",\n        \"s3:DeleteObjectVersion\",\n        \"s3:GetObject\",\n        \"s3:GetObjectVersion\",\n        \"s3:ListAllMyBuckets\",\n        \"s3:ListBucket\",\n        \"s3:PutBucketNotification\",\n        \"s3:PutBucketPolicy\",\n        \"s3:PutBucketTagging\",\n        \"s3:PutBucketWebsite\",\n        \"s3:PutEncryptionConfiguration\",\n        \"s3:PutObject\",\n        \"sns:CreateTopic\",\n        \"sns:DeleteTopic\",\n        \"sns:GetSubscriptionAttributes\",\n        \"sns:GetTopicAttributes\",\n        \"sns:ListSubscriptions\",\n        \"sns:ListSubscriptionsByTopic\",\n        \"sns:ListTopics\",\n        \"sns:SetSubscriptionAttributes\",\n        \"sns:SetTopicAttributes\",\n        \"sns:Subscribe\",\n        \"sns:Unsubscribe\",\n        \"states:CreateStateMachine\",\n        \"states:DeleteStateMachine\"\n      ],\n      \"Effect\": \"Allow\",\n      \"Resource\": \"*\"\n    }\n  ],\n  \"Version\": \"2012-10-17\"\n}\n```\n\n> Note: This policy is an example that encompasses pretty much everything the Serverless framework _might_ need on AWS, but much of it not likely to be used. You may wish to restrict this policy to fit your needs and security requirements. At minimum, the serverless credentials will need access to the `cloudformation`, `iam`, `lambda`, `logs`, and `s3` functions specified above.\n\n![Step 2-4](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-2.4.jpg){: .shadow.medium.center}\n\nClick \"Review Policy\" and you'll need to give this policy a name. I've used \"GitLabServerlessPolicy\". Then click \"Create policy\".\n\nAfter this is done, return to your \"Add user\" tab and search for the policy you just created (you may need to hit the \"refresh\" icon on the right). Check the box next to this policy and select the \"Next\" button.\n\n![Step 2-5](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-2.5.jpg){: .shadow.medium.center}\n\nProceed to add tags or skip straight to the review. The final page should resemble the following:\n\n![Step 2-6](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-2.6.jpg){: .shadow.medium.center}\n\nAfter clicking \"Create user\" you should finally be presented with a page that shows you your access credentials for this new AWS user account. Select \"show\" next to the \"secret access key\" and copy both this and the access key ID someplace for safe keeping.\n\n### 3. Entering your AWS credentials\n\nReturning back to GitLab, we'll need to enter these two credentials into our project's [CI/CD settings](/topics/ci-cd/). Select \"Settings -> CI/CD\" in the left-hand menu.\n\n![Step 3-1](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-3.1.jpg){: .shadow.small.center}\n\nOn this page, we need to expand the Variables section and enter our AWS credentials:\n\n![Step 3-2](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-3.2.jpg){: .shadow.medium.center}\n\nUse `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` as the keys for the two values you copied from AWS in the previous step. Don't forget to click \"Save variables\".\n\n### 4. Deploying your first AWS Lambda function.\n\nNow it's time to deploy your serverless project. If you're doing this on gitlab.com you've already got access to a GitLab runner with 2,000 free CI pipeline minutes, if not you'll need to [configure a runner yourself](https://docs.gitlab.com/runner/#install-gitlab-runner).\n\nGo to \"CI/CD -> Pipelines\" in the left-hand menu and click the \"Run Pipeline\" button. For fun, let's enter an environment variable with the key `A_VARIABLE` and give it whatever value you want. This will be usable by our deployed function.\n\n![Step 4-1](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-4.1.jpg){: .shadow.medium.center}\n\nSelect \"Run Pipeline\" and you should see your jobs start running. This project template has tests which will automatically run every time you run a pipeline. Once those are complete, the \"production\" job will deploy your code to AWS Lambda and finally it will produce a landing page on [GitLab Pages](https://docs.gitlab.com/ee/user/project/pages/). After just a few minutes this process should complete and you can visit \"Settings -> Pages\" to see a link to the URL where your GitLab project has been deployed. (It may take a few minutes before this URL is accessible the first time you make a deployment).\n\n![Step 4-2](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-4.2.jpg){: .shadow.medium.center}\n\nWhen you visit this page, here's what you'll see:\n\n![Step 4 Result](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-4.3.gif){: .shadow.medium.center}\n\nYou can enter an input value and click \"run function\". This input is sent to your serverless function which then responds and the response is printed under \"Function Output:\". Note that the environment value we provided using the `A_VARIABLE` key is present as well.\n\n### 5. Making Changes\n\nNow that we have a working AWS serverless project, let's try to make our own function. How about a simple calculator?\n\nOpen up the Web IDE and let's make the following changes:\n\nWithin `src/handler.js` add the following function:\n\n```javascript\nmodule.exports.add = async function(event) {\n  const A = Number(event.queryStringParameters.A);\n  const B = Number(event.queryStringParameters.B);\n  const result = A + B;\n\n  return {\n    statusCode: 200,\n    headers: {\n      \"Access-Control-Allow-Origin\": \"*\"\n    },\n    body: result\n  };\n};\n```\n\nThen open `public/index.html` and replace it with:\n\n```html\n\u003C!DOCTYPE html>\n\u003Chtml>\n  \u003Chead>\n    \u003Ctitle>GitLab Serverless Framework example\u003C/title>\n  \u003C/head>\n  \u003Cbody>\n    \u003Ch3>Add two values:\u003C/h3>\n    \u003Clabel>A: \u003Cinput type=\"text\" id=\"inputA\" placeholder=\"0\" name=\"A\"/>\u003C/label>\n    \u003Clabel>B: \u003Cinput type=\"text\" id=\"inputB\" placeholder=\"0\" name=\"B\"/>\u003C/label>\n    \u003Cstrong>=\u003C/strong>\n    \u003Cspan id=\"functionOutput\">?\u003C/span>\n    \u003Cbr />\n    \u003Cbutton>Calculate!\u003C/button>\n\n    \u003Cscript>\n      fetch(\"./stack.json\").then(response => {\n        response.json().then(myJson => {\n          const functionUrl = myJson.ServiceEndpoint + \"/add\";\n          const inputA = document.querySelector(\"#inputA\");\n          const inputB = document.querySelector(\"#inputB\");\n          const output = document.querySelector(\"#functionOutput\");\n\n          document.querySelector(\"button\").addEventListener(\"click\", () => {\n            const A = Number(inputA.value);\n            const B = Number(inputB.value);\n\n            fetch(functionUrl + \"?A=\" + A + \"&B=\" + B)\n              .then(response => response.text())\n              .then(result => (output.textContent = result));\n          });\n        });\n      });\n    \u003C/script>\n  \u003C/body>\n\u003C/html>\n```\n\nLastly, open `serverless.yml` and add an \"add\" function entry below our \"hello\" function like so:\n\n```yml\nfunctions:\n  hello:\n    handler: src/handler.hello\n    events:\n      - http:\n          path: hello\n          method: get\n          cors: true\n  add:\n    handler: src/handler.add\n    events:\n      - http:\n          path: add\n          method: get\n          cors: true\n```\n\nStage and commit these changes directly to the `master` branch. This will have triggered a new pipeline automatically. You can visit \"CI/CD -> Pipelines\" and watch it run.\n\nOnce the deployment is complete, our project page should look like this:\n\n![Step 5 Result](https://about.gitlab.com/images/blogimages/serverless-js-project-template/step-5.1.gif){: .shadow.medium.center}\n\nVoilà, we've just created our own serverless function and deployed it without a single terminal command. There's a lot more you can do from here, but this should be a good place to get started. Happy coding!\n\n\u003C!-- Content ends here -->\n\nCover image by [Kaushik Panchal](https://unsplash.com/@kaushikpanchal) on [Unsplash](https://unsplash.com/)\n{: .note}\n","unfiltered",[23,24,25],"integrations","features","cloud native",{"slug":27,"featured":6,"template":28},"serverless-js-project-template","BlogPost","content:en-us:blog:serverless-js-project-template.yml","yaml","Serverless Js Project Template","content","en-us/blog/serverless-js-project-template.yml","en-us/blog/serverless-js-project-template","yml",{"_path":37,"_dir":38,"_draft":6,"_partial":6,"_locale":7,"data":39,"_id":448,"_type":30,"title":449,"_source":32,"_file":450,"_stem":451,"_extension":35},"/shared/en-us/main-navigation","en-us",{"logo":40,"freeTrial":45,"sales":50,"login":55,"items":60,"search":389,"minimal":420,"duo":439},{"config":41},{"href":42,"dataGaName":43,"dataGaLocation":44},"/","gitlab logo","header",{"text":46,"config":47},"Get free trial",{"href":48,"dataGaName":49,"dataGaLocation":44},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":51,"config":52},"Talk to sales",{"href":53,"dataGaName":54,"dataGaLocation":44},"/sales/","sales",{"text":56,"config":57},"Sign in",{"href":58,"dataGaName":59,"dataGaLocation":44},"https://gitlab.com/users/sign_in/","sign in",[61,105,201,206,310,370],{"text":62,"config":63,"cards":65,"footer":88},"Platform",{"dataNavLevelOne":64},"platform",[66,72,80],{"title":62,"description":67,"link":68},"The most comprehensive AI-powered DevSecOps Platform",{"text":69,"config":70},"Explore our Platform",{"href":71,"dataGaName":64,"dataGaLocation":44},"/platform/",{"title":73,"description":74,"link":75},"GitLab Duo (AI)","Build software faster with AI at every stage of development",{"text":76,"config":77},"Meet GitLab Duo",{"href":78,"dataGaName":79,"dataGaLocation":44},"/gitlab-duo/","gitlab duo ai",{"title":81,"description":82,"link":83},"Why GitLab","10 reasons why Enterprises choose GitLab",{"text":84,"config":85},"Learn more",{"href":86,"dataGaName":87,"dataGaLocation":44},"/why-gitlab/","why gitlab",{"title":89,"items":90},"Get started with",[91,96,101],{"text":92,"config":93},"Platform Engineering",{"href":94,"dataGaName":95,"dataGaLocation":44},"/solutions/platform-engineering/","platform engineering",{"text":97,"config":98},"Developer Experience",{"href":99,"dataGaName":100,"dataGaLocation":44},"/developer-experience/","Developer experience",{"text":102,"config":103},"MLOps",{"href":104,"dataGaName":102,"dataGaLocation":44},"/topics/devops/the-role-of-ai-in-devops/",{"text":106,"left":107,"config":108,"link":110,"lists":114,"footer":183},"Product",true,{"dataNavLevelOne":109},"solutions",{"text":111,"config":112},"View all Solutions",{"href":113,"dataGaName":109,"dataGaLocation":44},"/solutions/",[115,140,162],{"title":116,"description":117,"link":118,"items":123},"Automation","CI/CD and automation to accelerate deployment",{"config":119},{"icon":120,"href":121,"dataGaName":122,"dataGaLocation":44},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[124,128,132,136],{"text":125,"config":126},"CI/CD",{"href":127,"dataGaLocation":44,"dataGaName":125},"/solutions/continuous-integration/",{"text":129,"config":130},"AI-Assisted Development",{"href":78,"dataGaLocation":44,"dataGaName":131},"AI assisted development",{"text":133,"config":134},"Source Code Management",{"href":135,"dataGaLocation":44,"dataGaName":133},"/solutions/source-code-management/",{"text":137,"config":138},"Automated Software Delivery",{"href":121,"dataGaLocation":44,"dataGaName":139},"Automated software delivery",{"title":141,"description":142,"link":143,"items":148},"Security","Deliver code faster without compromising security",{"config":144},{"href":145,"dataGaName":146,"dataGaLocation":44,"icon":147},"/solutions/security-compliance/","security and compliance","ShieldCheckLight",[149,152,157],{"text":150,"config":151},"Security & Compliance",{"href":145,"dataGaLocation":44,"dataGaName":150},{"text":153,"config":154},"Software Supply Chain Security",{"href":155,"dataGaLocation":44,"dataGaName":156},"/solutions/supply-chain/","Software supply chain security",{"text":158,"config":159},"Compliance & Governance",{"href":160,"dataGaLocation":44,"dataGaName":161},"/solutions/continuous-software-compliance/","Compliance and governance",{"title":163,"link":164,"items":169},"Measurement",{"config":165},{"icon":166,"href":167,"dataGaName":168,"dataGaLocation":44},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[170,174,178],{"text":171,"config":172},"Visibility & Measurement",{"href":167,"dataGaLocation":44,"dataGaName":173},"Visibility and Measurement",{"text":175,"config":176},"Value Stream Management",{"href":177,"dataGaLocation":44,"dataGaName":175},"/solutions/value-stream-management/",{"text":179,"config":180},"Analytics & Insights",{"href":181,"dataGaLocation":44,"dataGaName":182},"/solutions/analytics-and-insights/","Analytics and insights",{"title":184,"items":185},"GitLab for",[186,191,196],{"text":187,"config":188},"Enterprise",{"href":189,"dataGaLocation":44,"dataGaName":190},"/enterprise/","enterprise",{"text":192,"config":193},"Small Business",{"href":194,"dataGaLocation":44,"dataGaName":195},"/small-business/","small business",{"text":197,"config":198},"Public Sector",{"href":199,"dataGaLocation":44,"dataGaName":200},"/solutions/public-sector/","public sector",{"text":202,"config":203},"Pricing",{"href":204,"dataGaName":205,"dataGaLocation":44,"dataNavLevelOne":205},"/pricing/","pricing",{"text":207,"config":208,"link":210,"lists":214,"feature":297},"Resources",{"dataNavLevelOne":209},"resources",{"text":211,"config":212},"View all resources",{"href":213,"dataGaName":209,"dataGaLocation":44},"/resources/",[215,247,269],{"title":216,"items":217},"Getting started",[218,223,228,233,238,243],{"text":219,"config":220},"Install",{"href":221,"dataGaName":222,"dataGaLocation":44},"/install/","install",{"text":224,"config":225},"Quick start guides",{"href":226,"dataGaName":227,"dataGaLocation":44},"/get-started/","quick setup checklists",{"text":229,"config":230},"Learn",{"href":231,"dataGaLocation":44,"dataGaName":232},"https://university.gitlab.com/","learn",{"text":234,"config":235},"Product documentation",{"href":236,"dataGaName":237,"dataGaLocation":44},"https://docs.gitlab.com/","product documentation",{"text":239,"config":240},"Best practice videos",{"href":241,"dataGaName":242,"dataGaLocation":44},"/getting-started-videos/","best practice videos",{"text":244,"config":245},"Integrations",{"href":246,"dataGaName":23,"dataGaLocation":44},"/integrations/",{"title":248,"items":249},"Discover",[250,255,259,264],{"text":251,"config":252},"Customer success stories",{"href":253,"dataGaName":254,"dataGaLocation":44},"/customers/","customer success stories",{"text":256,"config":257},"Blog",{"href":258,"dataGaName":5,"dataGaLocation":44},"/blog/",{"text":260,"config":261},"Remote",{"href":262,"dataGaName":263,"dataGaLocation":44},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"text":265,"config":266},"TeamOps",{"href":267,"dataGaName":268,"dataGaLocation":44},"/teamops/","teamops",{"title":270,"items":271},"Connect",[272,277,282,287,292],{"text":273,"config":274},"GitLab Services",{"href":275,"dataGaName":276,"dataGaLocation":44},"/services/","services",{"text":278,"config":279},"Community",{"href":280,"dataGaName":281,"dataGaLocation":44},"/community/","community",{"text":283,"config":284},"Forum",{"href":285,"dataGaName":286,"dataGaLocation":44},"https://forum.gitlab.com/","forum",{"text":288,"config":289},"Events",{"href":290,"dataGaName":291,"dataGaLocation":44},"/events/","events",{"text":293,"config":294},"Partners",{"href":295,"dataGaName":296,"dataGaLocation":44},"/partners/","partners",{"backgroundColor":298,"textColor":299,"text":300,"image":301,"link":305},"#2f2a6b","#fff","Insights for the future of software development",{"altText":302,"config":303},"the source promo card",{"src":304},"/images/navigation/the-source-promo-card.svg",{"text":306,"config":307},"Read the latest",{"href":308,"dataGaName":309,"dataGaLocation":44},"/the-source/","the source",{"text":311,"config":312,"lists":314},"Company",{"dataNavLevelOne":313},"company",[315],{"items":316},[317,322,328,330,335,340,345,350,355,360,365],{"text":318,"config":319},"About",{"href":320,"dataGaName":321,"dataGaLocation":44},"/company/","about",{"text":323,"config":324,"footerGa":327},"Jobs",{"href":325,"dataGaName":326,"dataGaLocation":44},"/jobs/","jobs",{"dataGaName":326},{"text":288,"config":329},{"href":290,"dataGaName":291,"dataGaLocation":44},{"text":331,"config":332},"Leadership",{"href":333,"dataGaName":334,"dataGaLocation":44},"/company/team/e-group/","leadership",{"text":336,"config":337},"Team",{"href":338,"dataGaName":339,"dataGaLocation":44},"/company/team/","team",{"text":341,"config":342},"Handbook",{"href":343,"dataGaName":344,"dataGaLocation":44},"https://handbook.gitlab.com/","handbook",{"text":346,"config":347},"Investor relations",{"href":348,"dataGaName":349,"dataGaLocation":44},"https://ir.gitlab.com/","investor relations",{"text":351,"config":352},"Trust Center",{"href":353,"dataGaName":354,"dataGaLocation":44},"/security/","trust center",{"text":356,"config":357},"AI Transparency Center",{"href":358,"dataGaName":359,"dataGaLocation":44},"/ai-transparency-center/","ai transparency center",{"text":361,"config":362},"Newsletter",{"href":363,"dataGaName":364,"dataGaLocation":44},"/company/contact/","newsletter",{"text":366,"config":367},"Press",{"href":368,"dataGaName":369,"dataGaLocation":44},"/press/","press",{"text":371,"config":372,"lists":373},"Contact us",{"dataNavLevelOne":313},[374],{"items":375},[376,379,384],{"text":51,"config":377},{"href":53,"dataGaName":378,"dataGaLocation":44},"talk to sales",{"text":380,"config":381},"Get help",{"href":382,"dataGaName":383,"dataGaLocation":44},"/support/","get help",{"text":385,"config":386},"Customer portal",{"href":387,"dataGaName":388,"dataGaLocation":44},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":390,"login":391,"suggestions":398},"Close",{"text":392,"link":393},"To search repositories and projects, login to",{"text":394,"config":395},"gitlab.com",{"href":58,"dataGaName":396,"dataGaLocation":397},"search login","search",{"text":399,"default":400},"Suggestions",[401,403,407,409,413,417],{"text":73,"config":402},{"href":78,"dataGaName":73,"dataGaLocation":397},{"text":404,"config":405},"Code Suggestions (AI)",{"href":406,"dataGaName":404,"dataGaLocation":397},"/solutions/code-suggestions/",{"text":125,"config":408},{"href":127,"dataGaName":125,"dataGaLocation":397},{"text":410,"config":411},"GitLab on AWS",{"href":412,"dataGaName":410,"dataGaLocation":397},"/partners/technology-partners/aws/",{"text":414,"config":415},"GitLab on Google Cloud",{"href":416,"dataGaName":414,"dataGaLocation":397},"/partners/technology-partners/google-cloud-platform/",{"text":418,"config":419},"Why GitLab?",{"href":86,"dataGaName":418,"dataGaLocation":397},{"freeTrial":421,"mobileIcon":426,"desktopIcon":431,"secondaryButton":434},{"text":422,"config":423},"Start free trial",{"href":424,"dataGaName":49,"dataGaLocation":425},"https://gitlab.com/-/trials/new/","nav",{"altText":427,"config":428},"Gitlab Icon",{"src":429,"dataGaName":430,"dataGaLocation":425},"/images/brand/gitlab-logo-tanuki.svg","gitlab icon",{"altText":427,"config":432},{"src":433,"dataGaName":430,"dataGaLocation":425},"/images/brand/gitlab-logo-type.svg",{"text":435,"config":436},"Get Started",{"href":437,"dataGaName":438,"dataGaLocation":425},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":440,"mobileIcon":444,"desktopIcon":446},{"text":441,"config":442},"Learn more about GitLab Duo",{"href":78,"dataGaName":443,"dataGaLocation":425},"gitlab duo",{"altText":427,"config":445},{"src":429,"dataGaName":430,"dataGaLocation":425},{"altText":427,"config":447},{"src":433,"dataGaName":430,"dataGaLocation":425},"content:shared:en-us:main-navigation.yml","Main Navigation","shared/en-us/main-navigation.yml","shared/en-us/main-navigation",{"_path":453,"_dir":38,"_draft":6,"_partial":6,"_locale":7,"title":454,"button":455,"image":459,"config":462,"_id":464,"_type":30,"_source":32,"_file":465,"_stem":466,"_extension":35},"/shared/en-us/banner","is now in public beta!",{"text":84,"config":456},{"href":457,"dataGaName":458,"dataGaLocation":44},"/gitlab-duo/agent-platform/","duo banner",{"config":460},{"src":461},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1753720689/somrf9zaunk0xlt7ne4x.svg",{"layout":463},"release","content:shared:en-us:banner.yml","shared/en-us/banner.yml","shared/en-us/banner",{"_path":468,"_dir":38,"_draft":6,"_partial":6,"_locale":7,"data":469,"_id":674,"_type":30,"title":675,"_source":32,"_file":676,"_stem":677,"_extension":35},"/shared/en-us/main-footer",{"text":470,"source":471,"edit":477,"contribute":482,"config":487,"items":492,"minimal":666},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":472,"config":473},"View page source",{"href":474,"dataGaName":475,"dataGaLocation":476},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":478,"config":479},"Edit this page",{"href":480,"dataGaName":481,"dataGaLocation":476},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":483,"config":484},"Please contribute",{"href":485,"dataGaName":486,"dataGaLocation":476},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":488,"facebook":489,"youtube":490,"linkedin":491},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[493,516,573,602,636],{"title":62,"links":494,"subMenu":499},[495],{"text":496,"config":497},"DevSecOps platform",{"href":71,"dataGaName":498,"dataGaLocation":476},"devsecops platform",[500],{"title":202,"links":501},[502,506,511],{"text":503,"config":504},"View plans",{"href":204,"dataGaName":505,"dataGaLocation":476},"view plans",{"text":507,"config":508},"Why Premium?",{"href":509,"dataGaName":510,"dataGaLocation":476},"/pricing/premium/","why premium",{"text":512,"config":513},"Why Ultimate?",{"href":514,"dataGaName":515,"dataGaLocation":476},"/pricing/ultimate/","why ultimate",{"title":517,"links":518},"Solutions",[519,524,527,529,534,539,543,546,550,555,557,560,563,568],{"text":520,"config":521},"Digital transformation",{"href":522,"dataGaName":523,"dataGaLocation":476},"/topics/digital-transformation/","digital transformation",{"text":150,"config":525},{"href":145,"dataGaName":526,"dataGaLocation":476},"security & compliance",{"text":139,"config":528},{"href":121,"dataGaName":122,"dataGaLocation":476},{"text":530,"config":531},"Agile development",{"href":532,"dataGaName":533,"dataGaLocation":476},"/solutions/agile-delivery/","agile delivery",{"text":535,"config":536},"Cloud transformation",{"href":537,"dataGaName":538,"dataGaLocation":476},"/topics/cloud-native/","cloud transformation",{"text":540,"config":541},"SCM",{"href":135,"dataGaName":542,"dataGaLocation":476},"source code management",{"text":125,"config":544},{"href":127,"dataGaName":545,"dataGaLocation":476},"continuous integration & delivery",{"text":547,"config":548},"Value stream management",{"href":177,"dataGaName":549,"dataGaLocation":476},"value stream management",{"text":551,"config":552},"GitOps",{"href":553,"dataGaName":554,"dataGaLocation":476},"/solutions/gitops/","gitops",{"text":187,"config":556},{"href":189,"dataGaName":190,"dataGaLocation":476},{"text":558,"config":559},"Small business",{"href":194,"dataGaName":195,"dataGaLocation":476},{"text":561,"config":562},"Public sector",{"href":199,"dataGaName":200,"dataGaLocation":476},{"text":564,"config":565},"Education",{"href":566,"dataGaName":567,"dataGaLocation":476},"/solutions/education/","education",{"text":569,"config":570},"Financial services",{"href":571,"dataGaName":572,"dataGaLocation":476},"/solutions/finance/","financial services",{"title":207,"links":574},[575,577,579,581,584,586,588,590,592,594,596,598,600],{"text":219,"config":576},{"href":221,"dataGaName":222,"dataGaLocation":476},{"text":224,"config":578},{"href":226,"dataGaName":227,"dataGaLocation":476},{"text":229,"config":580},{"href":231,"dataGaName":232,"dataGaLocation":476},{"text":234,"config":582},{"href":236,"dataGaName":583,"dataGaLocation":476},"docs",{"text":256,"config":585},{"href":258,"dataGaName":5,"dataGaLocation":476},{"text":251,"config":587},{"href":253,"dataGaName":254,"dataGaLocation":476},{"text":260,"config":589},{"href":262,"dataGaName":263,"dataGaLocation":476},{"text":273,"config":591},{"href":275,"dataGaName":276,"dataGaLocation":476},{"text":265,"config":593},{"href":267,"dataGaName":268,"dataGaLocation":476},{"text":278,"config":595},{"href":280,"dataGaName":281,"dataGaLocation":476},{"text":283,"config":597},{"href":285,"dataGaName":286,"dataGaLocation":476},{"text":288,"config":599},{"href":290,"dataGaName":291,"dataGaLocation":476},{"text":293,"config":601},{"href":295,"dataGaName":296,"dataGaLocation":476},{"title":311,"links":603},[604,606,608,610,612,614,616,620,625,627,629,631],{"text":318,"config":605},{"href":320,"dataGaName":313,"dataGaLocation":476},{"text":323,"config":607},{"href":325,"dataGaName":326,"dataGaLocation":476},{"text":331,"config":609},{"href":333,"dataGaName":334,"dataGaLocation":476},{"text":336,"config":611},{"href":338,"dataGaName":339,"dataGaLocation":476},{"text":341,"config":613},{"href":343,"dataGaName":344,"dataGaLocation":476},{"text":346,"config":615},{"href":348,"dataGaName":349,"dataGaLocation":476},{"text":617,"config":618},"Sustainability",{"href":619,"dataGaName":617,"dataGaLocation":476},"/sustainability/",{"text":621,"config":622},"Diversity, inclusion and belonging (DIB)",{"href":623,"dataGaName":624,"dataGaLocation":476},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":351,"config":626},{"href":353,"dataGaName":354,"dataGaLocation":476},{"text":361,"config":628},{"href":363,"dataGaName":364,"dataGaLocation":476},{"text":366,"config":630},{"href":368,"dataGaName":369,"dataGaLocation":476},{"text":632,"config":633},"Modern Slavery Transparency Statement",{"href":634,"dataGaName":635,"dataGaLocation":476},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"title":637,"links":638},"Contact Us",[639,642,644,646,651,656,661],{"text":640,"config":641},"Contact an expert",{"href":53,"dataGaName":54,"dataGaLocation":476},{"text":380,"config":643},{"href":382,"dataGaName":383,"dataGaLocation":476},{"text":385,"config":645},{"href":387,"dataGaName":388,"dataGaLocation":476},{"text":647,"config":648},"Status",{"href":649,"dataGaName":650,"dataGaLocation":476},"https://status.gitlab.com/","status",{"text":652,"config":653},"Terms of use",{"href":654,"dataGaName":655,"dataGaLocation":476},"/terms/","terms of use",{"text":657,"config":658},"Privacy statement",{"href":659,"dataGaName":660,"dataGaLocation":476},"/privacy/","privacy statement",{"text":662,"config":663},"Cookie preferences",{"dataGaName":664,"dataGaLocation":476,"id":665,"isOneTrustButton":107},"cookie preferences","ot-sdk-btn",{"items":667},[668,670,672],{"text":652,"config":669},{"href":654,"dataGaName":655,"dataGaLocation":476},{"text":657,"config":671},{"href":659,"dataGaName":660,"dataGaLocation":476},{"text":662,"config":673},{"dataGaName":664,"dataGaLocation":476,"id":665,"isOneTrustButton":107},"content:shared:en-us:main-footer.yml","Main Footer","shared/en-us/main-footer.yml","shared/en-us/main-footer",[679],{"_path":680,"_dir":681,"_draft":6,"_partial":6,"_locale":7,"content":682,"config":685,"_id":687,"_type":30,"title":18,"_source":32,"_file":688,"_stem":689,"_extension":35},"/en-us/blog/authors/mike-greiling","authors",{"name":18,"config":683},{"headshot":7,"ctfId":684},"mikegreiling",{"template":686},"BlogAuthor","content:en-us:blog:authors:mike-greiling.yml","en-us/blog/authors/mike-greiling.yml","en-us/blog/authors/mike-greiling",{"_path":691,"_dir":38,"_draft":6,"_partial":6,"_locale":7,"header":692,"eyebrow":693,"blurb":694,"button":695,"secondaryButton":699,"_id":701,"_type":30,"title":702,"_source":32,"_file":703,"_stem":704,"_extension":35},"/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":46,"config":696},{"href":697,"dataGaName":49,"dataGaLocation":698},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":51,"config":700},{"href":53,"dataGaName":54,"dataGaLocation":698},"content:shared:en-us:next-steps.yml","Next Steps","shared/en-us/next-steps.yml","shared/en-us/next-steps",1753981659591]