Difficulty: beginner
Estimated Time: 10-15 minutes

The Manual Menace

In this exercise learners will use Ansible to drive automated provisioning of Projects in OpenShift, Git, Jenkins and Nexus.


Exercise Intro

In this exercise we will use automation tooling to create Project namespaces for our CI/CD tooling along with the dev and test namespaces for our deployments to live. We do this manually using the OpenShift CLI; but as we go from cluster to cluster or project to project Dev and Ops teams often find themselves having to redo these tasks again and again. Configuring our cluster using code; we can easily store this in Git and repeat the process again and again. By minimising the time taken to do these repetitive tasks we can accelerate our ability to deliver value to our customers; working on the hard problems they face.

This exercise uses Ansible to drive the creation of the cluster content. In particular; we'll use a play book called the OpenShift Applier. Once the project namespace have been created; we will add some tools to support CI/CD such as Jenkins, Git and Nexus. These tools will be needed by later lessons to automate the build and deploy of our apps. Again; we will use OpenShift Templates and drive their creation in the cluster using Ansible. To prove things are working, finally we'll delete all our content and re-apply the inventory to re-create our cluster's content.

Why is config-as-code important?

  • Assurance - Prevents unwanted config changes from people making arbitrary changes to environments. No more Snowflake servers!
  • Traceability - Committing config as code means a user has approved and changes can be tracked.
  • Phoenix Server - Burn it all to the ground and bring it back; exactly the way it was!

Learning Outcomes

As a learner you will be able to

  1. Run the OpenShift Applier to automate creating cluster content
  2. Create and admin project namespaces in OpenShift
  3. Deploy commonly used applications to support the development process

Tools and Frameworks

  • GitLab - Community driven Git server now with integrated DevOps Toolchain.
  • Nexus - Repository manager for storing lots of application types. Can also host npm and Docker registries.
  • Jenkins - OpenSource Build automation server. Highly customisable with plugins.
  • Ansible - IT Automation tool used to provision and manage state of cloud and physical infrastructure.
  • OpenShift Applier - used to apply OpenShift objects to an OpenShift Cluster.

Big Picture

The Big Picture is our emerging architecture; starting with an empty cluster we populate it with projects and some ci/cd tooling.


10,000 Ft View

This exercise is aimed at the creation of the tooling that will be used to support the rest of the Exercises. The high-level goal is to create a collection of project namespaces and populate them with Git, Jenkins & Nexus.

If you're feeling confident and don't want to follow the step-by-step guide these high-level instructions should provide a challenge for you:

  1. Clone the repo https://github.com/rht-labs/enablement-ci-cd which contains the scaffold of the project. Ensure you get all remote branches.

  2. Create <your-name>-ci-cd, <your-name>-dev and <your-name>-test project namespaces using the inventory and run them with the OpenShift Applier to populate the cluster

  3. Use the templates provided to create build of the jenkins-s2i. The templates are in exercise1/jenkins-s2i

  4. Use the templates provided to create build and deployment configs in <your-name>-ci-cd for. Templates are on a branch called exercise1/git-nexus && exercise1/jenkins:

    • Nexus
    • GitLab
    • Jenkins (using an s2i to pre-configure Jenkins)
  5. Commit your enablement-ci-cd repository to the GitLab Instance you've created

  6. Burn it all down and re-apply your inventory proving config-as-code works.

The Manual Menace (01)

Step 1 of 7

Part 1 - Create OpenShift Projects

Using the OpenShift Applier, we will add new project namespaces to the cluster which will be used throughout the exercise.

  1. In this course three different git projects will be created. To setup your local machine for each of these, create a new folder on the terminal in the root of your HOME directory for convenience. To do this, open a new Terminal session and create the new folder using the following command (new terminal sessions will start in your HOME dir).

    mkdir -p ~/innovation-labs && cd ~/innovation-labs

    NOTE - If you do not want to have this folder at the root of your home dir that's fine, just ensure any parent directories of this innovation-labs folder do NOT have any spaces in them as it breaks Ansible in later labs...

  2. Clone the scaffold project to your local machine's innovation-labs folder and pull all remote branches for use in later exercises. Note - this may error saying fatal: A branch named 'develop' already exists. but it can be ignored

    git clone https://github.com/rht-labs/enablement-ci-cd && cd enablement-ci-cd
  3. Open the innovation-labs folder in VSCode (or your favourite editor). The project is laid out as follows

    ├── README.md
    ├── apply.yml
    ├── docker
    ├── inventory
    │   ├── host_vars
    │   │   ├── ci-cd-tooling.yml
    │   │   └── projects-and-policies.yml
    │   └── hosts
    ├── jenkins-s2i
    ├── params
    │   └── project-requests-ci-cd
    ├── requirements.yml
    └── templates
     └── project-requests.yml
    • docker folder contains our jenkins-slave images that will be used by the builds.
    • jenkins-s2i contains the configuration and plugins we want to bring jenkins to life with
    • params houses the variables we will load the templates with
    • templates is a collection of OpenShift templates
    • inventory/host_vars/*.yml is the collection of objects we want to insert into the cluster.
    • requirements.yml is a manifest which contains the ansible modules needed to run the playbook
    • apply.yml is a playbook that sets up some variables and runs the OpenShift Applier role.
  4. Open the apply.yml file in the root of the project. Update the namespace variables by replacing the <YOUR_NAME> with your name or initials. Don't use uppercase or special characters. For example; my name is Dónal so I've created:

    hosts: "{{ target }}"
     ci_cd_namespace: donal-ci-cd
     dev_namespace: donal-dev
     test_namespace: donal-test

    NOTE - yaml is indentation sensitive so keep things lined up properly!

  5. Open the inventory/host_vars/projects-and-policies.yml file; you should see some variables setup already to create the <YOUR_NAME>-ci-cd namespace. This object is passed to the OpenShift Applier to call the templates/project-requests.yml template with the params/project-requests-ci-cd parameters. We will add some additional content here but first let's explore the parameters and the template

  6. Open the params/project-requests-ci-cd and replace the <YOUR_NAME> with your name to create the corresponding projects in the cluster. new-item

  7. Let's add two more params files to pass to our template to be able to create a dev and test project.

    • Create another two params files params/project-requests-dev & params/project-requests-test. On the terminal run
      touch params/project-requests-dev params/project-requests-test
    • In your editor; Open params/project-requests-dev and add the following by substituting <YOUR_NAME> accordingly NAMESPACE=<YOUR_NAME>-dev NAMESPACE_DISPLAY_NAME=<YOUR-NAME> Dev
    • In your editor; Open params/project-requests-test and add the following by substituting <YOUR_NAME> accordingly
  8. In the inventory/host_vars/projects-and-policies.yml file; add the new objects for the projects you want to create (dev & test) by adding another object to the content array for each. You can copy and paste them from the ci-cd example and update them accordingly. If you do this; remember to change the params file! e.g.

     - name: "{{ dev_namespace }}"
        template: "{{ playbook_dir }}/templates/project-requests.yml"
        template_action: create
        params: "{{ playbook_dir }}/params/project-requests-dev"
        - projects
     - name: "{{ test_namespace }}"
        template: "{{ playbook_dir }}/templates/project-requests.yml"
        template_action: create
        params: "{{ playbook_dir }}/params/project-requests-test"
        - projects


  1. With the configuration in place; install the OpenShift Applier dependency

    ansible-galaxy install -r requirements.yml --roles-path=roles
  2. Apply the inventory by logging into OpenShift on the terminal and running the playbook as follows ( should be replaced with the one you've been sent as shown below). Accept any insecure connection warning 👍:

    ansible-playbook apply.yml -i inventory/ -e target=bootstrap

    where the -e target=bootstrap is passing an additional variable specifying that we run the bootstrap inventory

  3. Once successful you should see an output similar to this (Cows not included): playbook-success

  1. You can check to see the projects have been created successfully by running
    oc projects