Skip to main content

Intro to Deploying CI/CD Pipelines on Equinix Metal

Learn how to leverage Equinix Metal for robust and capable Continuous Integration and Continuous Deployment pipelines.

Intro to Deploying CI/CD Pipelines on Equinix Metal

Continuous Integration and Continuous Deployment pipelines on Equinix Metal

This series describes using Equinix Metal resources to build robust and capable Continuous Integration and Continuous Deployment (CI/CD) pipelines.

You will explore both augmenting existing CI/CD infrastructure with Equinix Metal resources, as well as building your entire infrastructure on Equinix Metal.

Word of caution

These guides aim to get you along the road towards total production usage. These are more than experimental guides or easy lessons to show you what you can do. Like all Equinix guides, we take your time and deployments very seriously.

Remember that no guide can replace your (or your security team's) judgment. Every production deployment should be scrutinized for its robustness, security and investment according to your business needs.

Different CI/CD scenarios

In this advanced guide, you will walk through several different CI/CD scenarios, each using different tools, serving varied purposes.

One of these scenarios may fit your needs exactly, or you may need to combine elements from multiple scenarios to fit your needs.

  • GitHub Actions Persistent Metal Runners: Deploy Equinix Metal devices as runners on which GitHub Actions pipelines will run.
  • GitHub Actions Ephemeral Metal Runners: Deploy Equinix Metal devices as a Kubernetes cluster on which ephemeral runners are launched and removed automatically, one per job.
  • Jenkins on Equinix Metal: Deploy an entire Jenkins infrastructure on Equinix Metal, using dedicated devices for the Jenkins controller, and others to run jobs as Jenkins agents.

Each scenario is described on its own page, with links from the description.

Each scenario has a unique set of requirements and tasks for deployment. Different software and tools have different processes. This set of guides will walk you through successfully deploying each scenario.

In addition, we include one simple but powerful scenario: GitHub Actions in-flow. Whereas all of the other scenarios deploy either the entire pipeline infrastructure or the job Runners on Equinix Metal, this scenario runs pipelines inside normal GitHub Actions Runners, creating and removing Equinix Metal resources as needed inside the pipeline.

Preparing to create a CI/CD pipeline

Before you start, take the following steps to prepare for creating your pipeline:

  1. Set up your Equinix Metal account and organization if you still need to do so.
  2. Set up a dedicated Equinix Metal CI/CD project.
  3. Decide which scenario you want to deploy.
  4. Determine in which Equinix metro these servers will run.
  5. Determine the size and number of Equinix Metal servers you will use.
  6. Determine the operating system you will deploy on the servers.
  7. Decide on the network architecture you will use.

With these in place, you can follow the detailed guide for your selected scenario.

1. Set up your Equinix Metal account and organization

If you don't have an Equinix Metal account, or this is the first time you are using Equinix Metal, we recommend beginning with our Equinix Metal quickstart guide.

2. Set up a dedicated Equinix Metal project

As described in the Equinix Metal quickstart guide, projects are the "buckets" you use to organize Equinix Metal resources.

When setting up a group of related resources, such as a CI/CD pipeline, you should use a dedicated project. This makes it easier to manage and understand the resources you are using for this purpose.

Equinix also wants to help you get started with your CI/CD infrastructure. In addition to this guide, if you are setting up a dedicated project for CI/CD, name the project "CI/CD Equinix Metal guided 2024" and we will give you credits to help you get started.

3. Decide which scenario you want to deploy

We described earlier the four scenarios we will cover in this guide. The next step is to pick which one works for your needs. Let's dig into what each one does briefly here. Once you have chosen, the specific deployment walk-through can be found in a separate guide, linked from this one.

GitHub Actions Create and Delete

This is the simplest scenario. If you are using GitHub Actions for your CI/CD, and you want to test deploying something onto a server and then deleting it, this is the one for you. You easily create servers as part of the job, rather than as runners, a location on which to run the job.

Good use cases for this scenario are:

  • Testing hardware drivers
  • Testing operating systems
  • Testing hypervisors

For example, if you are developing an operating system image, you want to be able to install it onto a server, boot it up, check its behaviour, and shut it down.

GitHub Actions persistent Metal runners

If you are using, or plan to use, GitHub Actions for your CI/CD, and you want somewhere to run your pipelines, with simple deployment and persistence between job runs, this is the one for you.

In this scenario, you select a set of Equinix Metal servers to be your runners. You deploy them once, and they stay up, ready to run your pipeline jobs. Each time a job needs to be run, the server (as a runner) picks up the job and runs it. As soon as it is done, it picks the next job off the queue and runs it. If there are no jobs, it sits and waits until one is ready.

You can add some "reset" or "cleanup" steps before and after runs, but you are not getting a freshly installed server for each job run. This has advantages when you need persistence. For example, if the runs have significant amounts of reporting data that you want to keep between runs, or if the tests work best with multiple runs, one after another, on the same precise hardware. However, you do need to be careful, as artifacts might exist between runs that can cause errors or lead to incorrect testing results.

That is why these runners are called "persistent"; they persist between job runs. Future jobs will run on the same server, with the same environment, until you decide to remove the server.

Good use cases for this scenario are:

  • Testing software that talks directly to hardware
  • Tests that require expensive preparation, such as staging a large amount of identical data

For example, if you are running tests on software that processes significant amounts of data, such as AI model training, and you do not want to download the data with each and every run, having the data downloaded once can make your tests run orders of magnitude faster.

GitHub Actions ephemeral Metal runners

If you are using, or plan to use, GitHub Actions for your CI/CD, and you want somewhere to run your pipelines, with automatic removal and cleanup after each job run, this is the one for you. This is the kind of classic CI job run you probably are used to, where the runner is created, the job runs, and then the runner is removed. Each and every run gets a fresh environment, hence "ephemeral".

In this case, the Metal device is not the runner, but rather the platform for the runners. An orchestration system deploys a virtual machine (VM) or container for each run and then destroys it immediately after the job is done. This is how you get a clean, fresh runner for each job, while the Equinix Metal server itself, the platform for the runners, remains in place.

A good use case for this scenario is:

  • Testing normal software, with a clean slate for each test run

When would you use this specifically on Metal? When you need the power of Equinix Metal for the tests. For example, if you are testing software that is sensitive to the exact hardware it runs on or to the exact network path between the servers.

A more advanced version of this scenario, which we will not cover in this guide, uses the Equinix Metal server as an ephemeral runner, i.e. deploy it, run the job, and then delete it. This takes much longer to run, as reinstalling the server takes much longer than deploying a container, and requires more work to set it up, as not all of the orchestration software is available off the shelf. This scenario may be covered in a future guide.

Jenkins on Equinix Metal

If you are using Jenkins for your CI/CD, and you want to run the entire Jenkins infrastructure on Equinix Metal, this is the scenario for you.

You will deploy a full Jenkins environment on Equinix Metal, using dedicated devices for the Jenkins controller and Jenkins agents, where jobs run.

Good use cases for this scenario are:

  • All types of jobs where you want to use Jenkins as your CI/CD platform

This configuration is useful when Jenkins is your CI system of choice, and you need the power of Equinix Metal for the tests. For example, if you are testing software that is sensitive to the exact hardware it runs on, or to the exact network path between the servers.

4. Determine the size and numbers of Equinix Metal servers you will use

Scoping the work involves determining how many servers you will need, and what size they will be. The answers depend on the scenario you pick.

For all scenarios, you must decide what size servers to use. This depends on how much CPU, memory, storage and compute power your jobs need. The specifications for Equinix Metal servers are available on the Equinix Metal website.

GitHub Actions Create and Delete

In this scenario, since you create servers as part of the job, rather than as runners on which to run the job, you do not need to decide how many servers in advance. You simply decide what size servers you will use, and then have the servers deployed on-demand as part of the jobs.

GitHub Actions persistent Metal runners

In this scenario, you need to decide how many runners you need, and what size they will be. The number of servers depends entirely on the number of jobs you expect to run at the same time. For example, if you deploy three runners, you will be able to run three jobs at the same time. If Actions needs to run four jobs, then three will run, and 1 will queue until one of the others finishes.

For this guide, you will deploy three runners, but you can deploy as many as you need.

GitHub Actions ephemeral Metal runners

In this scenario, you will be deploying runners as well as orchestration to manage communication with GitHub and deploy runner containers. The orchestration software, which we will review in more detail in the dedicated section, runs on Kubernetes. While you could run this on the same servers as the runner containers, it is generally best to keep them separate.

For redundancy, you will deploy three of the smallest servers for the control plane, and three servers for the runner containers.

Here, too, you need to decide how many runners you need. While proportional, the number of parallel jobs is not always equal to the servers. Depending on the size, each server might run two, three, or ten runner containers. To get the number of devices you need:

  1. Determine the number of parallel jobs you want to run simultaneously.
  2. Determine the resources for each runner container.
  3. Divide the total resources you need by each server's available resources, and round up to the nearest whole number.

For example, if you deploy three c3.medium.x86, each one has:

  • CPU: 24 cores
  • Memory: 64 GB

If you allocate 8 GB of memory and three cores to each job, you can deploy a maximum of 8 jobs per server at the same time. You won't quite get that, as you need to leave some amount for the operating system and management software itself, but it does illustrate the principle.

Jenkins on Equinix Metal

In this scenario, you will be deploying both controllers and agents. You will follow the Jenkins-on-Kubernetes approach for simplicity and scalability. This means that you will deploy three of the smallest servers for the Kubernetes control plane, and three servers for the agent containers.

Here, too, you need to decide how many runners you need. Although proportional, the number of parallel jobs is not always equal to the number of servers. Depending on the size, each server might run two, three, or ten runner containers.

  1. Determine the number of parallel jobs you want to run at the same time.
  2. Determine the resources for each runner container.
  3. Divide the total resources you need by the resources of each server, and round up to the nearest whole number.

For example, if you deploy 3x c3.medium.x86, each one has:

  • CPU: 24 cores
  • Memory: 64 GB

If you allocate 8 GB of memory and three cores to each job, you can deploy a maximum of 8 jobs per server at the same time. You won't quite get that, as you need to leave some amount for the operating system and management software itself, but it does illustrate the principle.

5. Decide on the network architecture

The network architecture you use will depend on the scenario you pick. In all the scenarios, you can choose between:

  • Complete Internet access by all servers, which is the Equinix Metal default
  • All servers on VLAN with no direct Internet access, with access provided via a Metal Gateway
  • A mix of the two, with some servers on VLAN with no direct Internet access, and others with direct access
  • No Internet access at all

In addition, you may benefit from an Equinix Metal Load Balancer (LBaaS) in some scenarios. Specifically, with Jenkins, you may want to use the LBaaS to distribute the inbound load to the Jenkins controller. In both Jenkins and GitHub Actions Ephemeral Runners, you may want to use the LBaaS in front of the Kubernetes control plane.

This is one particular area where you may want to "tighten the borders" somewhat when you deploy to production, as network access considerations vary considerably between different levels of production and different organizations.

Deploying

Let's get started!

Now that you have picked an environment; set up your Equinix Metal account, organization, and project; and scoped the resources; you can follow the detailed guide for your selected scenario.

Last updated

15 May, 2024

Category

Tagged

Article
Subscribe to our newsletter

A monthly digest of the latest news, articles, and resources.