Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ draft: true
cascade:
draft: true

minutes_to_complete: 30
minutes_to_complete: 40

who_is_this_for: This is an Introductory topic for DevOps professionals who are looking to build a CI/CD pipeline with GitLab on Google Axion using GitLab-Hosted runners.

learning_objectives:
- Create a GitLab Project
- Understand basic pipeline script structure and how to use it
- Build and test a simple CI/CD pipeline Using Gitlab-hosted runners
- Build and test a simple CI/CD pipeline using Gitlab-hosted runners which will build and produce a tiny docker image from a simple "Hello world" "C" language program. The image will be built to run on Arm64 machines and will be saved in Gitlab Registery to be used later.


prerequisites:
Expand All @@ -26,10 +26,12 @@ subjects: CI-CD
cloud_service_providers: Google Cloud

armips:
- Neoverse
- Neoverse-N1

tools_software_languages:
- GitLab
- Docker
- C

operatingsystems:
- Linux
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ A GitLab Runner works with GitLab CI/CD to run jobs in a pipeline. It acts as an

3. Multi-architecture support: GitLab runners support multiple architectures including - **`x86/amd64`** and **`arm64`**.

## What is Google Axion?
Axion is Google's first Arm-based server processor, built using the Armv9 Neoverse V2 CPU. The VM instances are part of the **`C4A`** family of compute instances. To learn more about Google Axion refer to this [page](http://cloud.google.com/products/axion/) .

{{% notice Note %}}
All The information provided in the next section are from GitLab official Pages and it's provided here for convenience and can be changed by Gitlab at anytime. Please refer to the [Gitlab Documentation](https://docs.gitlab.com/ci/runners/hosted_runners/) for more details and for the latest updates.
All The information provided in the next section are from GitLab official Pages and it's provided here for convenience and can be changed by Gitlab at anytime. Please refer to the [Gitlab Documentation](https://docs.gitlab.com/ci/runners/hosted_runners/) for more details and for the latest updates. This section is optional.
{{% /notice %}}

## GitLab-Hosted Runners Facts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,83 +8,122 @@ layout: learningpathall

## How to Create a CI/CD Pipeline with Gitlab-hosted Runners?

To create the pipeline we only need to create a new **`.gitlab-ci.yml`** file in our Project and define it's stages. Nothing else is needed since Gtilab-hosted runners are readily available to any Project and doesn't need to be created or instantiated by the Gitlab users.
To create the pipeline you only need to create a new **`.gitlab-ci.yml`** file in your Project and define it's stages. Nothing else is needed since Gtilab-hosted runners are readily avilable to any Project and doesn't need to be created or instantiated by the Gitlab users.

Once we run our pipeline with the correct **`tags`** Gitlab will create everything that we need and yep it is as simple as that.
Once you run your pipeline with the correct **`tags`** Gitlab will create everything that you need and yep it is as simple as that.

## How are you going to test your pipeline functionality?

You will test the pipeline by building a Docker image from a simple C language "Hello World" program which can run on Arm64 instances/machines and to do that you will need to create the following files:

1) **`main.c`** File: which is the main program that will get executed when we will run your Docker image later. I only provided a simple example but please feel free to use any program that you like. Although, I advise to start with this simple program to test that everything is working then use anything later after by changing the **`main.c`** file.

```c
//main.c
#include <stdio.h>

int main(void) {
printf("Hello from an Arm64 Docker image built on GitLab hosted Arm runners!\n");
return 0;
}
```

2) **`DockerFile`** File: This file has a set of instruction for Docker on how to create a Docker image. It simply instructs the Docker on your runner on how to build and package your **``hello``** app into a Docker image. This produces a tiny image and will run on Arm64 hosts as long as the binary is Arm64 (which it will be, since we’re building on an Arm runner).

```DockerFile
# DockerFile
# syntax=docker/dockerfile:1

FROM alpine:3.20 AS build
RUN apk add --no-cache build-base
WORKDIR /src
COPY main.c .
RUN gcc -O2 -static -s -o hello main.c

FROM scratch
COPY --from=build /src/hello /hello
ENTRYPOINT ["/hello"]

```

3) Optionally **`.dockerignore`** file: This file instructs Docker to ignor certain files that has nothing to do with the image that it will create.

```.dockerignore
.git
.gitlab-ci.yml
```

4) You will also need to create a YML file as I mentioned before which I will explain in more details in the next section.

To Create any of those files simply follow the same steps in the next section but instead of choosing **`.gitlab-ci.yml`** file just change the name to each of the corresponding file names above. It is very important to create the 3 files from this section first because once you create and commit/save the **`.gitlab-ci.yml`** file, it will simply run the pipeline. If the other 3 files don't exist at that time then the pipeline will fail.

## How to Create .gitlab-ci.yml file in a Gitlab Project?

1. Start by going to the main project page where we will need to Create the CI/CD pipeline.
1. Start by going to the main project page where you will need to Create the CI/CD pipeline.

2. We can choose to create **`.gitlab-ci.yml`** file by using one of the 2 options circled in red in the image below.
![CI-CD-New #center](_images/ci-cd-new.webp)
2. You can choose to create **`.gitlab-ci.yml`** file by using one of the 2 options circled in red in the image below.
![CI-CD-New #center](_images/ci-cd-new.png)

Option1: We can Click on **`Set up CI/CD`** button/link and follow the wizard to create an empty **`.gitlab-ci.yml`** file.
Option1: You can Click on **`Set up CI/CD`** button/link and follow the wizad to create an empty **`.gitlab-ci.yml`** file.

Option2: Click on the "+" button. From the popup menu click on **`New File`** option and name the file **`.gitlab-ci.yml`** and then click on **`Commit Changes`** button on the top right hand side like in the image below (Add any message as your commit message).
![New-YML #center](_images/new-yml.png)

3. A page like the one in the image below will be visible with our **`.gitlab-ci.yml`** file. From here, we will need to Click on the **`Edit`** button. A menu will pop up, We will click on **`Edit in pipeline Editor`** which will allow us to add our CD/CD script.
![Editor-YML #center](_images/editor-yml.webp)
3. A page like the one in the image below will be visible with your **`.gitlab-ci.yml`** file. From here, you will need to Click on the **`Edit`** button. A menu will pop up, you will click on **`Edit in pipeline Editor`** which will allow you to add your CD/CD script.
![Editor-YML #center](_images/editor-yml.png)

4. In the pipeline editor, just copy and paste the following YML script and click on commit changes (Add any relevent message as your commit update message).
```YML
# This file is a template, and might need editing before it works on your project.
# This is a sample GitLab CI/CD configuration file that should run without any modifications.
# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
# it uses echo commands to simulate the pipeline execution.
#
# A pipeline is composed of independent jobs that run scripts, grouped into stages.
# Stages run in sequential order, but jobs within stages run in parallel.
#
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/#stages
#
# You can copy and paste this template into a new `.gitlab-ci.yml` file.
# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/development/cicd/templates/
# This specific template is located at:
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml

stages: # List of stages for jobs, and their order of execution
- build
- test
- deploy

build-job: # This job runs in the build stage, which runs first.
stage: build
tags:
- saas-linux-small-arm64 #Instruct Gitlab to use it's own Hosted runners that use Linux on Arm64 instance of size small.
script:
- echo "Compiling the code..."
- echo "Compile complete."
#First Section
stages: [build, test, push]

unit-test-job: # This job runs in the test stage.
stage: test # It only starts when the job in the build stage completes successfully.
tags:
- saas-linux-small-arm64 #Instruct Gitlab to use it's own Hosted runners that use Linux on Arm64 instance of size small.
script:
- echo "Running unit tests... This will take about 60 seconds."
- sleep 60
- echo "Code coverage is 90%"
variables:
IMAGE_TAG: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
IMAGE_LATEST: "$CI_REGISTRY_IMAGE:latest"

lint-test-job: # This job also runs in the test stage.
stage: test # It can run at the same time as unit-test-job (in parallel).
tags:
- saas-linux-small-arm64 #Instruct Gitlab to use it's own Hosted runners that use Linux on Arm64 instance of size small.
# Talk to docker:dind over TLS (default behavior for docker:dind)
DOCKER_HOST: "tcp://docker:2376"
DOCKER_TLS_CERTDIR: "/certs"
DOCKER_CERT_PATH: "/certs/client"
DOCKER_TLS_VERIFY: "1"

#Second Section
build_test_push:
stage: build
tags: # This tag is used to specify the size of the runner for each stage but it can be defined on the top of the file if you want to use the same exact runner size for all the stages in your pipeline
- saas-linux-small-arm64
image: docker:27
services:
- name: docker:27-dind
before_script:
- uname -m
# install lscpu (provided by util-linux) which is used to identify the CPU used for this stage runner
- apk add --no-cache util-linux
- lscpu
- docker version
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
script:
- echo "Linting code... This will take about 10 seconds."
- sleep 10
- echo "No lint issues found."
- docker build --pull -t "$IMAGE_TAG" .
- docker run --rm "$IMAGE_TAG"
- docker push "$IMAGE_TAG"

deploy-job: # This job runs in the deploy stage.
stage: deploy # It only runs when *both* jobs in the test stage complete successfully.
#Third Section
push_latest:
stage: push
tags:
- saas-linux-small-arm64 #Instruct Gitlab to use it's own Hosted runners that use Linux on Arm64 instance of size small.
environment: production
- saas-linux-small-arm64
image: docker:27
services:
- name: docker:27-dind
before_script:
- apk add --no-cache util-linux #since each stage is using a different runner then we need to check this CPU as well
- lscpu
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
script:
- echo "Deploying application..."
- echo "Application successfully deployed."
- docker pull "$IMAGE_TAG"
- docker tag "$IMAGE_TAG" "$IMAGE_LATEST"
- docker push "$IMAGE_LATEST"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
```
5. Once you commit the file updates, Gitlab will check the scripts for errors and will try to execute the pipeline directly.
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ weight: 10
layout: learningpathall
---

## Where Should We Start?
## Where Should you Start?

Start by logging into your GitLab account or create a new one in the [Gitlab](https://gitlab.com/) main page.

We will need to a new project/repo that will contain all our project files including our **`CI/CD`** pipeline configuration file.
You will need to a new project/repo that will contain all your project files including your **`CI/CD`** pipeline configuration file.

We can also choose to use any previously created projects in our Gitlab account. Simply open your previously created project. If that is the case then skip the rest of the steps in the current page and move to the next steps in this tutorial.
You can also choose to use any previously created projects in your Gitlab account. Simply open your previously created project, If that is the case then skip the rest of the steps in the current page and move to the next steps in this tutorial.

## Create a New Project in Gitlab

Expand All @@ -21,17 +21,17 @@ We can also choose to use any previously created projects in our Gitlab account.
2. Click on the **`New Project`** button on the top right hand side as the image below.
![Gitlab-Projects #center](_images/gitlab-projects.png)

3. We will get a new screen like the image below with multiple options. You can choose any of the 2 options highlighted in red from the image below.
3. You will get a new screen like the image below with multiple options. You can choose any of the 2 options highlighted in red from the image below.

{{% notice Note %}}
If we chose option 2 then we will need to choose **`GitLab CI/CD components`** option from the list of templates.
If you chose option 2 then you will need to choose the **`GitLab CI/CD components`** option from the list of templates.
{{%/notice%}}

![New-Project #center](_images/new-project.png)

4. Regardles of which option we choose, We will get a screen like the image below where we need to fill-in fields highlighted in red. The first field is the **`Project Name`** which we will name it **`CI-CD Runner`**. In the second field we need to choose any option from the **`Project Url`** list then click on the **`Create Project`** button at the end of the page.
4. Regardles of which option you choose, you will get a screen like the image below where you will need to fill-in the fields highlighted in red. The first field is the **`Project Name`** which you can name it **`CI-CD Runner`**. In the second field you need to choose any option from the **`Project Url`** list then click on the **`Create Project`** button at the end of the page.
![Project-Info #center](_images/project-info.png)

##### **If we did everything correctly then we should get a screen like the one in the image below.**
##### **If you did everything correctly then you should get a screen like the one in the image below.**
![Project-Done #center](_images/project-done.png)

Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@ layout: learningpathall

The Pipeline script has multiple sections where each section instructs the pipeline operator on what todo or use and how each Stage looks like.

### First Section: Stages
### First Section: The stages

In this section we are describing how many sequential stages will our pipeline have and what are their names (ex. **`Build, Test and Deploy`**). If we would like all the stages or jobs to run simultaneously then we simply don't define this section.
In this section you are describing how many squentional stages that your pipeline will have and what are their names (ex. **`Build, Test and Push`**). If you would like all the stages or jobs to run simultinously then you simply don't define this section.

### Second Section: Build-Job part of the Build stage
I am also defining some **`Variables`** that I will use in the other sections for simplisty.

In this section we are defining the Build-Job as part of the Build stage. This stage will run on Gitlab-Hosted runner that uses Linux OS on Arm64 instance of size small.
### Second Section: build_test_push part for the Build stage

In this section you are defining the build_test_push as the Build stage. This stage will run on Gitlab-Hosted runner that uses Linux OS on Arm64 instance of size small. I used the **`lscpu`** command to print out the CPU information for reference.

{{% notice Important Note %}}
Gitlab offers 3 Arm64 based Instances that use Linux as their OS.
Gitlab offers 3 Arm64 based Instances that use Linux as their OS. In the Free tier you can only use the small version.

- saas-linux-small-arm64
- saas-linux-medium-arm64
Expand All @@ -29,7 +31,11 @@ For more information about all Arm and other available Gitlab-hosted runners che

{{%/notice%}}

### Other Sections:
I am also saving my Docker image in GitLab registery because it's the easiest way to do that but you can modify your pipeline to save your image in any other registery that you prefer. To get the Gitlab registery creditiationals I am using **`$CI`** variables that are defined in the Gitlab enviornment and saving them in Docker for simplisty. Please note it's always recommended to encrypt your information or save it in a sercrets/passwords manages.

### Third Section:

You will notice that in this stage I am simply testing that I am able to get the image that I saved in my registery before and pushing it back as the latest version.

The rest of the other sections follow the same pattern. You will notice that the **`Test`** stage for example has 2 Jobs in it (unit-test-job and lint-test-job). The **`Deploy`** stage here has only 1 Job called **`deploy-job`**.
As you get to learn more YML scripting you will be able to add a lot more complex functionality to your pipelines.
Expand All @@ -46,6 +52,29 @@ From the left hand side panel, Navigate to **`Build`** then to **`Pipeline`** th
To check the status of your pipeline and to check the output of any of it's Jobs simply click on any of the **`Jobs`** as the image below (with red rectangle around them).
![pipeline-execution #center](_images/pipeline-execution.webp)

You can also download the docker image that you saved in your gitlab registery and run it on an Arm64 instance/box for testing using the following bash script.

```bash
docker login registry.gitlab.com
docker pull registry.gitlab.com/<namespace>/<project>:latest
docker run --rm registry.gitlab.com/<namespace>/<project>:latest
```

If everything works correctly you should see an output like in the box below.

```output
Hello from an Arm64 Docker image built on GitLab hosted Arm runners!
```

You can also check your Gitlab Registery by going to your project then:

- Go to Deploy → Container Registry
- You should see new-docker
- With tags like latest and **`<commit-sha>`**

If it’s there, the registry did its job.


## Gitlab Helpful tools

If you navigate to your pipeline editor from before you will notice that there are more tabs in that page other than the **`Edit`** tab. ![visual-pipeline #center](_images/visual-pipeline.webp)
Expand Down