[{"data":1,"prerenderedAt":762},["ShallowReactive",2],{"/en-us/blog/eks-fargate-runner":3,"navigation-en-us":37,"banner-en-us":465,"footer-en-us":482,"Darwin Sanoy":726,"next-steps-en-us":741,"footer-source-/en-us/blog/eks-fargate-runner/":756},{"_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/eks-fargate-runner","blog",false,"",{"title":9,"description":10,"ogTitle":9,"ogDescription":10,"noIndex":6,"ogImage":11,"ogUrl":12,"ogSiteName":13,"ogType":14,"canonicalUrls":12,"schema":15},"Setting up GitLab EKS Fargate Runners in just one hour","This detailed tutorial answers the question of how to leverage Amazon's AWS Fargate container technology for GitLab Runners.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663373/Blog/Hero%20Images/jeremy-lapak-CVvFVQ_-oUg-700unsplash.jpg","https://about.gitlab.com/blog/eks-fargate-runner","https://about.gitlab.com","article","\n                        {\n        \"@context\": \"https://schema.org\",\n        \"@type\": \"Article\",\n        \"headline\": \"Get started with GitLab EKS Fargate Runners in 1 hour and zero code, Iteration 1\",\n        \"author\": [{\"@type\":\"Person\",\"name\":\"Darwin Sanoy\"}],\n        \"datePublished\": \"2023-05-24\",\n      }",{"title":17,"description":10,"authors":18,"heroImage":11,"date":20,"body":21,"category":22,"tags":23},"Get started with GitLab EKS Fargate Runners in 1 hour and zero code, Iteration 1",[19],"Darwin Sanoy","2023-05-24","Leveraging Amazon's AWS Fargate container technology for [GitLab\nRunners](https://docs.gitlab.com/runner/) has been a longstanding ask from\nour customers. This tutorial gets you up and running with the GitLab EKS\nFargate Runner combo in less than an hour.\n\n\nGitLab has a pattern for this task for\n[Fargate](https://docs.aws.amazon.com/AmazonECS/latest/userguide/what-is-fargate.html)\nrunners under AWS Elastic Container Service (ECS). The primary challenge\nwith this solution is that AWS ECS itself does not allow for the overriding\nof what image is used when calling an ECS task. Therefore, each GitLab\nRunner manager ignores the gitlab-ci.yml `image:` tag and runs on the image\npreconfigured in the task during deployment of the runner manager. As a\nresult, you'll end up creating runner container images that contain every\ndependency for all the software built by the runner, or you'll create a lot\nof runner managers per image — or both.\n\n\nI have long wondered if Fargate-backed Elastic Kubernetes Service (EKS)\ncould get around this limitation since, by nature, Kubernetes must be able\nto run any image given to it.\n\n\n## The approach\n\n\nNothing takes the joy out of learning faster than a lot of complex setup\nbefore being able to get to the point of the exercise. To address this, this\ntutorial uses four things to dramatically reduce the time and steps required\nto get from zero to hero.\n\n\n1. AWS CloudShell to minimize the EKS Admin Tooling setup. This also leaves\nyour local machine environment untouched so that other tooling\nconfigurations don't get modified.\n\n2. A project called **AWS CloudShell ”Run From Web” Configuration Scripts**\nto rapidly add additional tooling to CloudShell. This includes some hacks to\nget large Terraform templates to work on AWS CloudShell.\n\n3. EKS Blueprints — specifically, a Terraform example that implements both\nthe [Karpenter\nautoscaler](https://aws.amazon.com/blogs/aws/introducing-karpenter-an-open-source-high-performance-kubernetes-cluster-autoscaler/)\nand Fargate, including for the kube-system namespace.\n\n4. A simple Helm install for GitLab Runner.\n\n\nAlthough you will be running CLI commands and editing config files, no\ncoding is required in the sense that you won't have to build something\ncomplex from scratch and then maintain it yourself.\n\n\n## The results\n\n\nIt works! It can run 2 x 200 (max allowed per job) parallel “Hello, World”\njobs on AWS Fargate-backed EKS in about 4 minutes, which demonstrates the\nunlimited scalability. It can also run a simple Auto DevOps pipeline, which\nproves out the ability to run a bunch of different containers.\n\n\nThe fact that the entire cluster - including kube-system - is Fargate backed\nreduces the Kubernetes specific long term SRE work to a much lower value\napproaching that of ECS Fargate clusters. Later on we discuss that this\ntrade-off has a cost and how it can be reconfigured.\n\n\n## What makes it possible: Product-managed IaC that is an extensible\nframework\n\n\nToolkitting made up of Infrastructure as Code (IaC) is frequently referred\nto as “templates,” and these templates have a reputation of not aging well\nbecause there is no active stewardship of the codebase — they are thought of\nas a one-and-done effort. However, this term does not reflect reality well\nwhen the underlying IaC code is actually being product-managed. You can tell\nif something is being product-managed by using these markers:\n\n\n- It has a scope-bounded vision of what it wants to do for the community\nbeing served (customer).\n\n- It has active stewardship that keeps the codebase moving along, even if it\nis open source.\n\n- It seeks to incorporate strategic enhancements, a.k.a. new features.\n\n- Things that are broken are considered bugs and are actively eliminated.\n\n- There is a cadence of taking underlying version updates and for supporting\nnew versions of the primary things they deploy.\n\n\nAs an extensible framework, EKS Blueprints:\n\n\n- Are purposefully architected to be extended by anyone.\n\n- Already have many extensions built.\n\n\nWhen implementing using EKS Blueprints and you come upon a new need, it is\nimportant to check if EKS Blueprints already handles that consideration -\nsimilarly to how you would look for Ruby Gems, NPM Modules or Python PyPI\npackages before building functionality from scratch.\n\n\nAll of the above are aspects of how the AWS EKS team is product-managing EKS\nBlueprints. They deserve a big round of applause because product-managing\nanything to prevent it from becoming yet another community-maintained\nshelfware project is a strong commitment that requires tenacity!\n\n\n## Reproducing the experiment\n\n\n### 1. Set up AWS CloudShell\n\n\n> **Note:** If you already have a fully persistent environment setup (like\nyour laptop) with: AWS CLI, kubectl, Terraform, then you can avoid\nenvironment rebuilds when AWS CloudShell times out by using that instead.\n\n\nAWS CloudShell comes with kubectl, Git, and AWS CLI, which are all needed.\nHowever, we also need a few other scripts. More information about these\nscripts can be read in [my blog post on AWS CloudShell “Run For Web”\nConfiguration\nScripts](https://missionimpossiblecode.io/aws-cloudshell-run-from-web-configuration-scripts).\n\n\n> **Note:** The steps in this section up through the `git clone` from GitLab\nstep (second clone operation) in the next section can be accomplished by\nrunning this: `s=prep-eksblueprint-karpenter.sh ; curl -sSL\nhttps://gitlab.com/guided-explorations/aws/aws-cloudshell-configs/-/raw/main/${s}\n-o /tmp/${s}; chmod +x /tmp/${s}; bash /tmp/${s}*` .\n\n\n1. Use the web console to login to an AWS account where you have admin\npermissions.\n\n2. Switch to the region of your choosing.\n\n3. In the bottom left of the console click the “CloudShell” icon.\n\n4. Copy and paste the following one-liner into the console to install Helm,\nTerraform, and the Nano text editor:\n   `curl -sSL https://gitlab.com/guided-explorations/aws/aws-cloudshell-configs/-/raw/main/add-all.sh -o $HOME/add-all.sh; chmod +x $HOME/add-all.sh; bash $HOME/add-all.sh`\n5. Since our Terraform template will grow larger than the 1GB limit of space\nin the $HOME directory, we need a workaround to use the template in one\ndirectory, but store the Terraform state in $HOME where it will be kept as\nlong as 120 days. The following one-liner triggers a script that performs\nthat setup for us, after which we can use the /terraform directory for our\ntemplate:\n   `curl -sSL https://gitlab.com/guided-explorations/aws/aws-cloudshell-configs/-/raw/main/prep-for-terraform.sh -o $HOME/prep-for-terraform.sh; chmod +x $HOME/prep-for-terraform.sh; bash $HOME/prep-for-terraform.sh`\n\n### 2. Run Terraform EKS Blueprint\n\n\n> **Note:** If at any time you leave your AWS CloudShell long enough for\nyour session to end, the /terraform directory will be tossed. Simply run the\nlast script above and the first four steps below to make it operable again.\nThis will most likely be necessary when it comes time to teardown the\nTerraform created AWS resources.\n\n>\n\n> Sometimes your AWS CloudShell credentials may expire with a message like:\n`Error: Kubernetes cluster unreachable: Get \">CLUSTER URL>\": getting\ncredentials: exec: executable aws failed with exit code 255`. Simply refresh\nthe entire browser tab where AWS CloudShell is running and you’ll generally\nhave new credentials.\n\n\n#### Version safety\n\n\nThis tutorial uses a specific release of the EKS Blueprint project so that\nyou have the known state at the time of publishing. The project version also\ncascades into the versions of all the many dependent modules. While it may\nalso work with the latest version, the version at the time of writing was\nVersion 4.29.0.\n\n\nThis tutorial also uses Terraform binary Version 1.4.5.\n\n\n#### Procedures\n\n\nIf, while using AWS CloudShell, you experience this error: `Error:\nconfiguring Terraform AWS Provider: no valid credential sources for\nTerraform AWS Provider found`, you will need to refresh your browser to\nupdate the cached credentials in the terminal session.\n\n\nPerform the following commands on the AWS CloudShell session:\n\n\n1. `git clone https://github.com/aws-ia/terraform-aws-eks-blueprints.git\n--no-checkout /terraform/terraform-aws-eks-blueprints` \n\n2. `cd /terraform/terraform-aws-eks-blueprints/`\n\n3. `git reset --hard tags/v4.29.0` #Version pegging to the code that this\narticle was authored with.\n\n4. `git clone\nhttps://gitlab.com/guided-explorations/aws/eks-runner-configs/gitlab-runner-eks-fargate.git\n/terraform/terraform-aws-eks-blueprints/examples/glrunner`\n\n   **Note:** Like other EKS Blueprints examples, the GitLab EKS Fargate Runner example references EKS Blueprint modules with a relative directory reference. This is why we are cloning it into a subdirectory of the EKS Blueprints project.\n5. `cd /terraform/terraform-aws-eks-blueprints/examples/glrunner`\n\n6. `terraform init`\n\n   **Important**: If you are using AWS CloudShell and your session times out, the /terraform folder and the installed utilities will be gone. You would have to reproduce the above steps to get the Terraform template in a usable state again. This is most likely to happen when you go to use Terraform to delete the stack after playing with it for some days.\n\n   The next few instructions are from: **https://github.com/aws-ia/terraform-aws-eks-blueprints/blob/main/examples/karpenter/README.md#user-content-deploy**. Note the `-state` switch ensures our state is in persistent storage.\n7. `terraform apply -target module.vpc -state=$HOME/tfstate/runner.tfstate`\n\n8. `terraform apply -target module.eks -state=$HOME/tfstate/runner.tfstate`\n\n9. **Note:** If you receive “Error: The configmap ”aws-auth” does not\nexist”, re-run the same command - it will usually update successfully.\n\n10. `terraform apply -state=$HOME/tfstate/runner.tfstate`\n\n\nThe previous command will output a kubeconfig command that needs to be run\nto ensure subsequent kubectl commands work. Run that command. If you are in\nAWS CloudShell and did not copy the command, this command should work and\nmap to the correct region:\n    `aws eks update-kubeconfig --region $AWS_DEFAULT_REGION --name \"glrunner\"`\n\nIf everything was done correctly, you will have an EKS cluster named\n`karpenter` in the CloudShell region web console like this:\n\n\n![codecountingcilog](https://about.gitlab.com/images/blogimages/eks-fargate-runner/eksclusterinconsole.png)  \n\n\nAnd the output of this console command `kubectl get pods -A` will look like\nthis:\n\n\n![codecountingcilog](https://about.gitlab.com/images/blogimages/eks-fargate-runner/cliplaincluster.png)\n\n\nThe output of this console command `kubectl get nodes -A` will show the\nFargate prefix:\n\n\n![codecountingcilog](https://about.gitlab.com/images/blogimages/eks-fargate-runner/clinodesarefargate.png)\n\n\n> **Note:** Notice that all the EKS extras (coredns, ebs-cni, and karpenter\nitself) are also running on Fargate. If you are willing to tolerate some\nregular Kubernetes nodes, you may be able to save cost by running always-on\npods on regular Kubernetes hosts. Since this cluster runs Karpenter, you\nwill not need to manually scale those hosts and EKS makes control plane and\nnode updates easier.\n\n\n### 3. Install GitLab Runner\n\n\nThese and other commands are available in the GitLab documentation for\n[GitLab Runner Helm\nChart](https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration).\n\n\n1. Create an empty GitLab project.\n\n2. Retrieve a GitLab Runner Token from the project. Keep in mind that using\na project token is the easiest way to ensure your experiment runs only on\nthe EKS Fargate Runner. Using a group token may cause your job to run on\nother runners already setup at your company. You can follow [“Obtain a\ntoken”](https://docs.gitlab.com/runner/register/#requirements) from the\ndocumentation if you need to.\n\n3. Perform the following commands back in the AWS CloudShell session.\n\n4. `nano runnerregistration.yaml`\n\n5. Paste the following:\n\n   ```yaml\n   gitlabUrl: https://_YOUR_GITLAB_URL_HERE_.com\n   runnerRegistrationToken: _YOUR_GITLAB_RUNNER_TOKEN_HERE_\n   concurrent: 200\n   rbac:\n     create: true\n   runners:\n     tags: eks-fargate\n     runUntagged: true\n     imagePullPolicy: if-not-present\n   envVars:\n     - name: KUBERNETES_POLL_TIMEOUT\n       value: 90  \n   ```\n\n   **Note:** Many more settings are discussed in the documentation for the [Kubernetes Executor](https://docs.gitlab.com/runner/executors/kubernetes.html). \n\n**Hard Lesson:** Using a setting for `concurrent` that is lower than our\n`parallel` setting in the GitLab job below results in all kinds of failures\ndue to some job pods having to wait for an execution slot. Since it’s\nFargate, there is no savings to keeping it lower and no negative impact to\nmaking it the complete parallel amount.\n\n\n6. Replace \\_YOUR_GITLAB_URL_HERE_ with your actual GitLab URL.\n\n7. Replace \\_YOUR_GITLAB_RUNNER_TOKEN_HERE_ with your actual runner token.\n\n8. Press CTRL-X to exit and press Y to the save prompt.\n\n9. `helm repo add gitlab https://charts.gitlab.io`\n\n10. `helm repo update gitlab`\n\n11. `helm install --namespace gitlab-runner --create-namespace runner1 -f\nrunnerregistration.yaml gitlab/gitlab-runner`\n\n12. Wait for a few minutes and check the project’s list of runners for a new\none with the tag `eks-fargate`\n\n\nIn AWS CloudShell the command `kubectl get pods -n gitlab-runner` should\nproduce output similar to this:\n\n\n![codecountingcilog](https://about.gitlab.com/images/blogimages/eks-fargate-runner/runnerlist.png)\n\n\nAnd in the GitLab Runner list, it will look similar to this:\n\n\n![codecountingcilog](https://about.gitlab.com/images/blogimages/eks-fargate-runner/glrunnerlist.png)\n\n\n### 4. Run a test job\n\n\nThe simplest way to test GitLab Runner scaling is using the `parallel:`\nkeyword to schedule multiple copies of a job. It can also be used to create\na job matrix where not all jobs do the same thing.\n\n\nOne or more GitLab Runner Helm deployments can live in any namespace, so you\nhave many to many mapping flexibility for how you think of runners and their\nKubernetes context.\n\n\nIn the GitLab project where you created the runner, use the web IDE to\ncreate .gitlab-ci.yml and populate it with the following content:\n   ```yaml\n   parallel-fargate-hello-world:\n     image: public.ecr.aws/docker/library/bash\n     stage: build\n     parallel: 200\n     script:\n       - echo \"Hello Fargate World\"\n   ```\n\n**Hard Lesson:** After hitting the Docker hub image pull rate limit, I\nshifted to the same container in the AWS Public Elastic Container Registry\n(ECR), which has an [image pull rate\nlimit](https://docs.aws.amazon.com/AmazonECR/latest/public/public-service-quotas.html)\nof 10 per second for this scenario.\n\n\nIf the job does not automatically start, use the pipeline page to force it\nto run.\n\n\nIf everything is configured correctly, your final pipeline status panel\nshould look something like this:\n\n\n![codecountingcilog](https://about.gitlab.com/images/blogimages/eks-fargate-runner/completedjobs.png)\n\n\n### 5. Runner scaling experimentation\n\n\nThese and other commands are available in the GitLab documentation for\n[GitLab Runner Helm\nChart](https://docs.gitlab.com/runner/install/kubernetes.html#additional-configuration).\n\n\nAdditional runners can be added by re-running the install command with a\ndifferent name for the runner (if using the same token you’ll have two\nrunners in the same group or project):\n\n\n`helm install --namespace gitlab-runner runner2 -f runnerregistration.yaml\ngitlab/gitlab-runner`\n\n\n200 jobs takes just under 2 minutes.\n\n\n#### 400 parallel jobs\n\n\nBy setting up a second identical job (with a unique job name), I was able to\nprocess 400 total jobs.\n\n\n**Hard Lesson:** The runner likes to schedule all jobs in a parallel job on\nthe same runner instance. It does not seem to want to split a large job\nacross multiple runners registered in the same project. So in order to get\nmore than 200 jobs to process, I had to have two registered runners set to\n`concurrent:200` and two seperate jobs set to `parallel: 200`\n\n\n400 jobs takes just over 3 minutes.\n\n\n#### More than 400 parallel jobs\n\n\nAs I tried to scale higher, jobs started to hang. I tried specifically\nrouting jobs to five runners each capable of 300 parallel jobs. I also tried\nmultiple stages and used a hack of `needs []` to get simultaneous execution\nof jobs in multiple stages.\n\n\nI was not successful and there could be a wide variety of reasons why — a\nriddle for a future iteration.\n\n\nThis command can be used to update a runner's settings after editing the\nHelm values file (including the token to move the runner to another\ncontext): \n\n\n`helm upgrade --namespace gitlab-runner -f runnerregistration.yaml runner2\ngitlab/gitlab-runner`\n\n\nI found that when I pushed the limits, I would sometimes end up with hung\npods until I understood what needed adjusting. Leaving hung Fargate pods\nwill add up to a lot of cash because the pricing assumes very short\nexecution times. This command helps you terminate job pods without\naccidentally terminating the runner manager pods:\n\n\n`kubectl get pods --all-namespaces --no-headers |  awk '{if ($2 ~\n\"_YOUR_JOB_POD_PREFACE_*\") print $2}' | xargs kubectl -n\n_YOUR_RUNNER_NAMESPACE_ delete pod`\n\n\nDon't forget to replace \\_YOUR_RUNNER_NAMESPACE_ and \\_YOUR_JOB_POD_PREFACE_\n“_YOUR_JOB_POD_PREFACE\\_” is the unique preface of ONLY the jobs from a\ngiven runner followed by the wildcard star character => \\*\n\n\nTo uninstall a runner, use:\n\n\n`helm delete --namespace gitlab-runner runner1`\n\n\n#### Testing Auto DevOps to prove `image:` tag is honored\n\n\nTechnically testing Auto DevOps to prove the `image:` tag is honored this\nisn’t entirely necessary since the above job loads the bash container\nwithout the container being specified in any of the runner or infrastructure\nsetup. However, I performed this as a litmus test anyway.\n\n\nFollow these steps:\n\n\n1. Create a new project by clicking the “+” sign in the top bar of GitLab.\n\n2. On the next page, select “New Project/Repository”.\n\n3. Then “Create from template”.\n\n4. Select “Ruby on Rails” (first choice).\n\n5. Once the project creation is complete, register an EKS runner to it (or\nre-register the existing runner to the new project).\n\n6. In the project, select “Settings (Gear Icon)” => “CI/CD” => Auto DevOps\n=> Default to Auto DevOps pipeline.\n\n7. Click “Save changes”.\n\n\nThe Auto DevOps pipeline should run. If you don’t have a cluster wired up,\nit will mainly do security scanning, which is sufficient to prove that\narbitrary containers can be used by the Fargate-backed GitLab Runner.\n\n\n### 6. Solution tuning via extensible platform\n\n\nEKS Blueprints is not only product-managed, it is also an extensible\nplatform or framework. In the spirit of fully leveraging the extensible\nproduct managed EKS Blueprints project, you will always want to check if\nBlueprints is already instrumented for your scenario before writing code.\nAdditionally, if you must write code, you can consider contributing it as an\nEKS Blueprint extension so the community can take on some responsibility for\nmaintaining it.\n\n\n1. The EKS Blueprints Managed IaC has a dizzing number of tuning parameters\nand optional extensions. For instance, if you want the full GitLab Runner\nlogs collected to AWS CloudWatch, it is a simple configuration to add\nfluentd log agent to push custom logs to CloudWatch.\n\n2. Using Fargate for always-on containers is a trade-off of compute costs to\nget rid of Kubernetes node management overhead. This trade-off can be easily\nreversed in this example by removing the \"kube-system\" from\n\"fargate_profiles\" - since Karpenter is also installed and configured, the\nhosts will autoscale for load.\n\n\n### 7. Teardown\n\n\nThe next few instructions are from\nhttps://github.com/aws-ia/terraform-aws-eks-blueprints/blob/main/examples/karpenter/README.md#user-content-destroy.\n\n\nIf you are using AWS CloudShell and the /terraform directory no longer\nexists, perform these steps to re-prepare AWS CloudShell to perform\nteardown.\n\n\nIf you are not using AWS CloudShell, skip forward to “Teardown steps”.\n\n\n1. `curl -sSL\nhttps://gitlab.com/guided-explorations/aws/aws-cloudshell-configs/-/raw/main/add-all.sh\n-o $HOME/add-all.sh; chmod +x $HOME/add-all.sh; bash $HOME/add-all.sh`\n\n2. `curl -sSL\nhttps://gitlab.com/guided-explorations/aws/aws-cloudshell-configs/-/raw/main/prep-for-terraform.sh\n-o $HOME/prep-for-terraform.sh; chmod +x $HOME/prep-for-terraform.sh; bash\n$HOME/prep-for-terraform.sh`\n\n3. `git clone https://github.com/aws-ia/terraform-aws-eks-blueprints.git\n--no-checkout /terraform/terraform-aws-eks-blueprints` \n\n4. `cd /terraform/terraform-aws-eks-blueprints/`\n\n5. `git reset --hard tags/v4.29.0`\n\n6. `git clone\nhttps://gitlab.com/guided-explorations/aws/eks-runner-configs/gitlab-runner-eks-fargate.git\n/terraform/terraform-aws-eks-blueprints/examples/glrunner`\n\n   > **Note:** The above steps can be accomplished by running this: `s=prep-eksblueprint-karpenter.sh ; curl -sSL https://gitlab.com/guided-explorations/aws/aws-cloudshell-configs/-/raw/main/${s} -o /tmp/${s}; chmod +x /tmp/${s}; bash /tmp/${s}` .\n\n7. `cd /terraform/terraform-aws-eks-blueprints/examples/glrunner`\n\n8. `terraform init`\n\n\nFollow these teardown steps:\n\n\n1. `helm delete --namespace gitlab-runner runner1`\n\n2. `helm delete --namespace gitlab-runner runner2`\n\n3. `terraform destroy -target=\"module.eks_blueprints_kubernetes_addons\"\n-auto-approve -state=$HOME/tfstate/runner.tfstate`\n\n4. `terraform destroy -target=\"module.eks\" -auto-approve\n-state=$HOME/tfstate/runner.tfstate`\n\n5. **Note:** If you receive an error about refreshing cached credentials,\nsimply re-run the command again and it will usually update successfully.\n\n6. `terraform destroy -auto-approve -state=$HOME/tfstate/runner.tfstate`\n\n\n### Iteration _n_ : We would love your input\n\n\nThis blog is \"Iteration 1\" precisely because it has not been production\nload-tested nor specifically cost-engineered. And obviously a “Hello, World”\nscript is not testing much in the way of real work. I really set out to\nunderstand if we could run arbitrary containers in a GitLab Fargate setup\n(and we can) and then got curious about what parallel job scaling might look\nlike with Fargate (and it looks good). The Kubernetes Runner executor has\nmany, many available customizations and it is likely that scaling a\nproduction loaded implementation on EKS will reveal the need to tune more of\nthese parameters. \n\n\n#### **Collaborative contribution challenges**\n\n\nHere are some ideas for further collaborative work on this project:\n\n\n- To push the limits, create a configuration that can scale to 1000\nsimultaneous jobs.\n\n- An aws-logging config map that uploads runner pod logs to AWS CloudWatch.\n\n- A cluster configuration where runner managers and everything that is not a\nrunner job run on non-Fargate nodes – if and only if it will be cheaper than\nFargate running 24 x 7.\n\n- A Fargate Spot configuration. It’s important that compute type be noted as\na runner tag and it’s important that the same cluster has non-spot instances\nbecause some jobs should not run on spot compute and the decision whether to\ndo so should be available to the GitLab CI Developer who is creating an\npipeline.\n\n\n#### Other runner scaling initiatives\n\n\nWhile GitLab is building the Next Runner Auto-scaling Architecture,\n[Kubernetes refinements are not a part of this architectural\ninitiative](https://docs.gitlab.com/ee/architecture/blueprints/runner_scaling/#proposal).\n\n\n#### Everyone can contribute\n\n\nThis tutorial, as well as code for additional examples, will be maintained\nas open source as a GitLab Alliances Solution and we’d love to have your\ncontributions as you iterate and discover the configurations necessary for\nyour real-world scenarios. This tutorial is in a group wiki and the code\nwill be in the projects under that group here: [AWS Guided Explorations for\nEKS Runner\nConfigurations](https://gitlab.com/guided-explorations/aws/eks-runner-configs/gitlab-runner-eks-fargate/-/blob/main/README.md). \n\n\nPhoto by [Jeremy\nLapak](https://unsplash.com/@jeremy_justin?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\non\n[Unsplash](https://unsplash.com/s/photos/runner?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText)\n\n{: .note}\n","engineering",[24,25,26],"DevOps","solutions architecture","AWS",{"slug":28,"featured":6,"template":29},"eks-fargate-runner","BlogPost","content:en-us:blog:eks-fargate-runner.yml","yaml","Eks Fargate Runner","content","en-us/blog/eks-fargate-runner.yml","en-us/blog/eks-fargate-runner","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":722,"_type":31,"title":723,"_source":33,"_file":724,"_stem":725,"_extension":36},"/shared/en-us/main-footer",{"text":485,"source":486,"edit":492,"contribute":497,"config":502,"items":507,"minimal":714},"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,607,651,680],{"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,578,582,587,592,597,602],{"text":569,"config":570},"CICD",{"href":571,"dataGaName":572,"dataGaLocation":491},"/topics/ci-cd/","cicd",{"text":574,"config":575},"GitOps",{"href":576,"dataGaName":577,"dataGaLocation":491},"/topics/gitops/","gitops",{"text":24,"config":579},{"href":580,"dataGaName":581,"dataGaLocation":491},"/topics/devops/","devops",{"text":583,"config":584},"Version Control",{"href":585,"dataGaName":586,"dataGaLocation":491},"/topics/version-control/","version control",{"text":588,"config":589},"DevSecOps",{"href":590,"dataGaName":591,"dataGaLocation":491},"/topics/devsecops/","devsecops",{"text":593,"config":594},"Cloud Native",{"href":595,"dataGaName":596,"dataGaLocation":491},"/topics/cloud-native/","cloud native",{"text":598,"config":599},"AI for Coding",{"href":600,"dataGaName":601,"dataGaLocation":491},"/topics/devops/ai-for-coding/","ai for coding",{"text":603,"config":604},"Agentic AI",{"href":605,"dataGaName":606,"dataGaLocation":491},"/topics/agentic-ai/","agentic ai",{"title":608,"links":609},"Solutions",[610,612,614,619,623,626,630,633,635,638,641,646],{"text":151,"config":611},{"href":146,"dataGaName":151,"dataGaLocation":491},{"text":140,"config":613},{"href":122,"dataGaName":123,"dataGaLocation":491},{"text":615,"config":616},"Agile development",{"href":617,"dataGaName":618,"dataGaLocation":491},"/solutions/agile-delivery/","agile delivery",{"text":620,"config":621},"SCM",{"href":136,"dataGaName":622,"dataGaLocation":491},"source code management",{"text":569,"config":624},{"href":128,"dataGaName":625,"dataGaLocation":491},"continuous integration & delivery",{"text":627,"config":628},"Value stream management",{"href":179,"dataGaName":629,"dataGaLocation":491},"value stream management",{"text":574,"config":631},{"href":632,"dataGaName":577,"dataGaLocation":491},"/solutions/gitops/",{"text":189,"config":634},{"href":191,"dataGaName":192,"dataGaLocation":491},{"text":636,"config":637},"Small business",{"href":196,"dataGaName":197,"dataGaLocation":491},{"text":639,"config":640},"Public sector",{"href":201,"dataGaName":202,"dataGaLocation":491},{"text":642,"config":643},"Education",{"href":644,"dataGaName":645,"dataGaLocation":491},"/solutions/education/","education",{"text":647,"config":648},"Financial services",{"href":649,"dataGaName":650,"dataGaLocation":491},"/solutions/finance/","financial services",{"title":209,"links":652},[653,655,657,659,662,664,666,668,670,672,674,676,678],{"text":221,"config":654},{"href":223,"dataGaName":224,"dataGaLocation":491},{"text":226,"config":656},{"href":228,"dataGaName":229,"dataGaLocation":491},{"text":231,"config":658},{"href":233,"dataGaName":234,"dataGaLocation":491},{"text":236,"config":660},{"href":238,"dataGaName":661,"dataGaLocation":491},"docs",{"text":259,"config":663},{"href":261,"dataGaName":5,"dataGaLocation":491},{"text":254,"config":665},{"href":256,"dataGaName":257,"dataGaLocation":491},{"text":263,"config":667},{"href":265,"dataGaName":266,"dataGaLocation":491},{"text":276,"config":669},{"href":278,"dataGaName":279,"dataGaLocation":491},{"text":268,"config":671},{"href":270,"dataGaName":271,"dataGaLocation":491},{"text":281,"config":673},{"href":283,"dataGaName":284,"dataGaLocation":491},{"text":286,"config":675},{"href":288,"dataGaName":289,"dataGaLocation":491},{"text":291,"config":677},{"href":293,"dataGaName":294,"dataGaLocation":491},{"text":296,"config":679},{"href":298,"dataGaName":299,"dataGaLocation":491},{"title":314,"links":681},[682,684,686,688,690,692,694,698,703,705,707,709],{"text":321,"config":683},{"href":323,"dataGaName":316,"dataGaLocation":491},{"text":326,"config":685},{"href":328,"dataGaName":329,"dataGaLocation":491},{"text":334,"config":687},{"href":336,"dataGaName":337,"dataGaLocation":491},{"text":339,"config":689},{"href":341,"dataGaName":342,"dataGaLocation":491},{"text":344,"config":691},{"href":346,"dataGaName":347,"dataGaLocation":491},{"text":349,"config":693},{"href":351,"dataGaName":352,"dataGaLocation":491},{"text":695,"config":696},"Sustainability",{"href":697,"dataGaName":695,"dataGaLocation":491},"/sustainability/",{"text":699,"config":700},"Diversity, inclusion and belonging (DIB)",{"href":701,"dataGaName":702,"dataGaLocation":491},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":354,"config":704},{"href":356,"dataGaName":357,"dataGaLocation":491},{"text":364,"config":706},{"href":366,"dataGaName":367,"dataGaLocation":491},{"text":369,"config":708},{"href":371,"dataGaName":372,"dataGaLocation":491},{"text":710,"config":711},"Modern Slavery Transparency Statement",{"href":712,"dataGaName":713,"dataGaLocation":491},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":715},[716,718,720],{"text":541,"config":717},{"href":543,"dataGaName":544,"dataGaLocation":491},{"text":546,"config":719},{"href":548,"dataGaName":549,"dataGaLocation":491},{"text":551,"config":721},{"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",[727],{"_path":728,"_dir":729,"_draft":6,"_partial":6,"_locale":7,"content":730,"config":736,"_id":738,"_type":31,"title":19,"_source":33,"_file":739,"_stem":740,"_extension":36},"/en-us/blog/authors/darwin-sanoy","authors",{"role":731,"name":19,"config":732},"Field Chief Cloud Architect",{"headshot":733,"linkedin":734,"ctfId":735},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659751/Blog/Author%20Headshots/Darwin-Sanoy-headshot-395-square-gitlab-teampage-avatar.png","https://linkedin.com/in/darwinsanoy","DarwinJS",{"template":737},"BlogAuthor","content:en-us:blog:authors:darwin-sanoy.yml","en-us/blog/authors/darwin-sanoy.yml","en-us/blog/authors/darwin-sanoy",{"_path":742,"_dir":39,"_draft":6,"_partial":6,"_locale":7,"header":743,"eyebrow":744,"blurb":745,"button":746,"secondaryButton":750,"_id":752,"_type":31,"title":753,"_source":33,"_file":754,"_stem":755,"_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":747},{"href":748,"dataGaName":50,"dataGaLocation":749},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":52,"config":751},{"href":54,"dataGaName":55,"dataGaLocation":749},"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":757,"content":758,"config":761,"_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":759,"heroImage":11,"date":20,"body":21,"category":22,"tags":760},[19],[24,25,26],{"slug":28,"featured":6,"template":29},1761814406471]