Skip to content

The .gitlab-ci.yml File

Filename Location Group Project/Repository
.gitlab-ci.yml ./.gitlab-ci.yml configuration ansible

Why?

We're going to be deploying our application and its statoc contents to multiple servers. This process isn't too difficult, but the point of automating it is to reduce errors and save time. That's what we're going to do with the pipeline configuration file for our Ansible code.

Breakdown

1
2
3
4
5
image: python:slim

variables:
  TARGET_PROJECT: 26664557 # default value
  TARGET_DEPLOYMENT: deployment

Here we're stating that we want to set the Docker image: to an offical Python image. This is because Ansible is written in Python, so we want the pip tool ready to use, allowing us to install Ansible easily enough.

We're also creating two new variables: TARGET_PROJECT and TARGET_DEPLOYMENT.

The TARGET_PROJECT has a (default) value set so that our "Playbook" job knows where to pull the ZIP file from. This is the same variable that's also passed in from the application trigger job, in the "Application" pipeline.

We have a variable called TARGET_DEPLOYMENT which is used, but doesn't add any value today. It will go on to allow us to support multiple environments in the future, however.

Note

We'll see how TARGET_DEPLOYMENT is used as this book evolves.

Our stages are as follows:

1
2
stages:
  - playbook

Playbook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
playbook:
  stage: playbook
  script:
    - apt update && apt install openssh-client wget -y
    - echo "$PRIVATE_KEY" | base64 -d > ./deployment.key
    - chmod 0400 deployment.key
    - 'wget --header="JOB-TOKEN: $CI_JOB_TOKEN" ${CI_API_V4_URL}/projects/${TARGET_PROJECT}/packages/generic/httpcats/${TARGET_DEPLOYMENT}/httpcats.zip'
    - mv httpcats.zip files/httpcats.zip
    - pip install ansible
    - ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook main.yaml -u ubuntu --private-key ./deployment.key -i inventory.yaml
    - rm -rf ./deployment.key

Script

There's a lot going on here:

  1. Update the OS inside the (Docker) container and install OpenSSH (client) and wget
  2. Take the private SSH key from the environment (CI variables) and write it to disk
    1. Taking care to convert it from its Base64 encoded state
  3. Set the permissions on the key so they're not too open and OpenSSH agrees to work with it
  4. Download the deployment package, the ZIP, we built in the "Application" pipeline, from the generic package repository
    1. Our CI_JOB_TOKEN is enough here because it takes on your permissions, as a user, which is sufficient to pull the package
  5. We move the ZIP into a location Ansible will find it
  6. We install Ansible inside the container
    1. Which is why we're using a Python image
  7. We execute our Playbook
  8. And finally we delete the deployment key from disk

Simple.

The Solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
image: python:slim

variables:
  TARGET_PROJECT: 26664557 # default value
  TARGET_DEPLOYMENT: deployment

stages:
  - playbook

playbook:
  stage: playbook
  script:
    - apt update && apt install openssh-client wget -y
    - echo "$PRIVATE_KEY" | base64 -d > ./deployment.key
    - chmod 0400 deployment.key
    - 'wget --header="JOB-TOKEN: $CI_JOB_TOKEN" ${CI_API_V4_URL}/projects/${TARGET_PROJECT}/packages/generic/httpcats/${TARGET_DEPLOYMENT}/httpcats.zip'
    - mv httpcats.zip files/httpcats.zip
    - pip install ansible
    - ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook main.yaml -u ubuntu --private-key ./deployment.key -i inventory.yaml
    - rm -rf ./deployment.key

Committing the Code

  1. Set your working directory to the configuration/ansible repository
  2. Save the file as .gitlab-ci.yml and use git add .gitlab-ci.yml to add it to the Git staging area
  3. Use git commit -am 'providing a CI pipeline for our CAC' to commit the file to our repository
  4. Push the code to GitLab.com: git push

Last update: August 25, 2021