Infrastructure as Code (IaC) is a useful way to maintain the configuration of your infrastructure components. It provides a way that you can store your infrastructure or application’s configuration in a versioned location and then coupled with CI/CD brings you the benefits of being able to enforce gatekeeping on any changes to the configuration, automate its deployment and even add in syntax or configuration tests before applying to the live environment.
In this example we’ll run through how you can use this methodology to manage the configuration of a simple Apache2 server running on Ubuntu Linux 20.04.2 LTS. The example given below is just an example for illustration, you should always ensure that your implementation doesn’t use excessive privileges and you should ensure any secrets are kept out of the Gitlab repository.
We’ll store the Apache2 configuration in a project repository, then we’ll configure a gitlab-runner that will trigger a pipeline upon an update to the main branch, or a merge into the main branch. The pipeline will trigger the gitlab-runner to pull down the latest version of the configuration files, then restart/reload apache2 to apply the new configuration.
We’ll assume you already have an Ubuntu Linux machine built and connected to the network (and Internet).
We’ll also assume you have created a gitlab project/repository that is empty, in this example we’ll call it apache2, don’t put anything in it just yet, we’ll do that later on.
We’ll also assume that you’ve installed Apache2 with the following and it is accessible and providing the default website page when accessed with a web browser.
apt install apache2
Importantly also note when you create your project, repository ensure you untick “Initalize repository with README”, as we’ll be populating it later on.
Install Gitlab Runner (gitlab-runner)
You’ll install the gitlab-runner onto the machine, we’ll need to add the packages repository though first.
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash
sudo apt-get install gitlab-runner
When you are prompted, we are needing the “shell” runner, because we’ll be using the gitlab-runner to run its tasks within the “shell”.
If you’d like to install a specific version of gitlab-runner, you can use apt-cache madison gitlab-runner then sudo apt-get install gitlab-runner=10.0.0 as an example.
Once installed verify with:
sudo gitlab-runner -version
sudo gitlab-runner status
To start, stop or restart you can use:
sudo gitlab-runner start
sudo gitlab-runner stop
sudo gitlab-runner restart
You’ll want to ensure that the gitlab-runner can run as a service, if you have a problem with this you may want to follow these steps instead, which are what gitlab provide:
# Download the binary for your system
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
# Give it permission to execute
sudo chmod +x /usr/local/bin/gitlab-runner
# Create a GitLab Runner user
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
# Install and run as a service
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start
Grant gitlab-runner sudo Permission
The gitlab-runner installer should have created a user for the gitlab-runner to run under, surprisingly called gitlab-runner.
sudo visudo
Within the file add the following lines, one will need to be added under the “User privilege specification” section and the second line can go near the bottom.
gitlab-runner ALL=(ALL:ALL) ALL
gitlab-runner ALL=(ALL) NOPASSWD: ALL
So for example your sudoers file might look like:
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
gitlab-runner ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
gitlab-runner ALL=(ALL) NOPASSWD: ALL
Register the Runner with Your Project/Repository
Login to Gitlab. Then navigate to your project, in this example apache2, then click “Settings” and then “CI/CD Settings”.
Look for the “Runners” section then click “expand”.
First step is to click the slider “Enable shared runners for this project” so that you have disabled shared runners, we don’t need these in this case, as we’ll have just our gitlab-runner as installed on the host with the web server on it.
Under the “Project Runners” section you should see that there are no runners currently selected. Click on the “three dots”, then click “Show runner configuration and registration instructions”, you now get a set of instructions, you’ll notice the install instructions are there, but in our case we’re interested in the registration command at the bottom.
Now on your host you need to run the command show with your unique token.
sudo gitlab-runner register --url https://gitlab.com/ --registration-token <TOKEN>
You’ll then need to complete a kind of wizard, stick with the defaults, when prompted for the “executor” enter: “shell“, because in this case we’ll be running commands within the shell of our host.
If you want to register the gitlab-runner with a docker executor instead you can use:
sudo gitlab-runner register \
--non-interactive \
--url "GITLAB_SERVER_URL" \
--registration-token "REGISTRATION_TOKEN" \
--description "docker-runner" \
--executor "docker" \
--docker-image ubuntu:latest
After a few moments, the gitlab-runner should check in and appear in your list of “Project Runners” for example like the below, you may need to click “Enable for this project” otherwise you’ll see it registered and ready for action (see the green dot).
That’s it for this part, please see the next part for the next steps to get your gitlab-runner set up.