Ravi Srinivasan
2019-02-12 3de2841cf54dc51cc23e4420b23f5e22b1598516
commit | author | age
5d0992 1 # The Manual Menace
1173e5 2 > In this exercise learners will use Ansible to drive automated provisioning of Projects in OpenShift, Git, Jenkins and Nexus.
c951f7 3
49e3a8 4 <!-- ![automation-xkcd](https://imgs.xkcd.com/comics/automation.png) -->
7c832b 5
D 6 ## Exercise Intro
e43fd2 7 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.
7c832b 8
e43fd2 9 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.
5d0992 10
1173e5 11 #### Why is config-as-code important?
14cd2d 12 * Assurance - Prevents unwanted config changes from people making arbitrary changes to environments. No more Snowflake servers!
1173e5 13 * Traceability - Committing config as code means a user has approved and changes can be tracked.
14cd2d 14 * Phoenix Server -  Burn it all to the ground and bring it back; exactly the way it was!
D 15
5d0992 16 _____
c951f7 17
D 18 ## Learning Outcomes
19 As a learner you will be able to
5d0992 20
D 21 1. Run the OpenShift Applier to automate creating cluster content
22 1. Create and admin project namespaces in OpenShift
23 1. Deploy commonly used applications to support the development process
c951f7 24
D 25 ## Tools and Frameworks
26
5d0992 27 * [GitLab](https://about.gitlab.com/) - Community driven Git server now with integrated DevOps Toolchain.
D 28 * [Nexus](https://www.sonatype.com/nexus-repository-sonatype) - Repository manager for storing lots of application types. Can also host `npm` and `Docker` registries.
29 * [Jenkins](https://jenkins.io/) - OpenSource Build automation server. Highly customisable with plugins.
30 * [Ansible](https://www.ansible.com/) - IT Automation tool used to provision and manage state of cloud and physical infrastructure.
dba30b 31 * [OpenShift Applier](https://github.com/redhat-cop/openshift-applier) - used to apply OpenShift objects to an OpenShift Cluster.
A 32
5d0992 33 ## Big Picture
1173e5 34 > The Big Picture is our emerging architecture; starting with an empty cluster we populate it with projects and some ci/cd tooling.
5d0992 35
664135 36 ![big-picture](../images/big-picture/big-picture-1.jpg)
5d0992 37 _____
c951f7 38
49e3a8 39 <!-- ## 10,000 Ft View
1173e5 40 > 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.
5d0992 41
1173e5 42 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:
5d0992 43
2533e0 44 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.
3558ae 45
5d0992 46 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
da614f 47
2533e0 48 3. Use the templates provided to create build of the jenkins-s2i. The templates are in `exercise1/jenkins-s2i`
3558ae 49
2533e0 50 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`:
5d0992 51     * Nexus
D 52     * GitLab
1173e5 53     * Jenkins (using an s2i to pre-configure Jenkins)
3558ae 54
2533e0 55 5. Commit your `enablement-ci-cd` repository to the GitLab Instance you've created
3558ae 56
2533e0 57 6. Burn it all down and re-apply your inventory proving config-as-code works.
49e3a8 58 -->
c951f7 59
D 60 ## Step by Step Instructions
49e3a8 61 <!-- > This is a structured guide with references to exact filenames and explanations.  -->
c951f7 62
bc2e43 63 ### Part 1 - Create OpenShift Projects
de8ebb 64 > _Using the OpenShift Applier, we will add new project namespaces to the cluster which will be used throughout the exercise._
D 65
49e3a8 66 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).
RS 67
68 For Linux and MacOS systems
bc2e43 69 ```bash
49e3a8 70 mkdir -p ~/do500-workspace && cd ~/do500-workspace
RS 71 ```
72
73 For Microsoft Windows systems, navigate to the `C:\do500-workspace` directory
74 ```bash
75 cd C:\do500-workspace
e7c877 76 ```
f5f1ff 77 <p class="tip">
49e3a8 78 <b>NOTE</b> - If you do not want to have this folder at the root of your home directory, that's fine, just ensure any parent directories of this `do500-workspace` folder do <b>NOT</b> have any spaces in them as it breaks Ansible in later labs...
f5f1ff 79 </p>
D 80
49e3a8 81 2. Clone the scaffold project to your local machine's `do500-workspace` folder and pull all remote branches for use in later exercises. You may see an error saying `fatal: A branch named 'develop' already exists.` This error can be safely ignored.
RS 82
f5f1ff 83 ```bash
bec65b 84 git clone https://github.com/RedHatTraining/rht-labs-ci-cd enablement-ci-cd
RS 85 ```
86 ```bash
87 cd enablement-ci-cd
e7c877 88 ```
f5f1ff 89 ```bash
D 90 ./git-pull-all.sh
49e3a8 91 ```
RS 92
93 If you are using a Microsoft Windows system, run the above shell script using the `Git Bash` terminal instead of the default Windows command line. You need to navigate to the `C:\do500-workspace\enablement-ci-cd` directory by running
94 ```bash
95 cd /c/do500-workspace/enablement-ci-cd
96 ```
97 ```bash
98 ./git-pull-all.sh
99 ```
100 ```bash
101 exit
c951f7 102 ```
D 103
0b2c0f 104 3. Open the `enablement-ci-cd` folder in VSCode (or your favourite editor). The project is laid out as follows
bc2e43 105 ```
D 106 .
107 ├── README.md
62db52 108 ├── apply.yml
bc2e43 109 ├── docker
D 110 ├── inventory
62db52 111 │   ├── host_vars
D 112 │   │   ├── ci-cd-tooling.yml
113 │   │   └── projects-and-policies.yml
114 │   └── hosts
bc2e43 115 ├── jenkins-s2i
D 116 ├── params
62db52 117 │   └── project-requests-ci-cd
bc2e43 118 ├── requirements.yml
D 119 └── templates
62db52 120     └── project-requests.yml
bc2e43 121 ```
49e3a8 122  * `docker` folder contains sample Dockerfiles for our jenkins-slave images that will be used by the builds.
bc2e43 123  * `jenkins-s2i` contains the configuration and plugins we want to bring jenkins to life with
D 124  * `params` houses the variables we will load the templates with
125  * `templates` is a collection of OpenShift templates
62db52 126  * `inventory/host_vars/*.yml` is the collection of objects we want to insert into the cluster.
bc2e43 127  * `requirements.yml` is a manifest which contains the ansible modules needed to run the playbook
62db52 128  * `apply.yml` is a playbook that sets up some variables and runs the OpenShift Applier role.
bc2e43 129
49e3a8 130 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:
62db52 131 ```yaml
e6805f 132   hosts: "{{ target }}"
62db52 133   vars:
D 134     ci_cd_namespace: donal-ci-cd
135     dev_namespace: donal-dev
136     test_namespace: donal-test
e6805f 137   tasks:
62db52 138 ```
e6805f 139 <p class="tip">
49e3a8 140 NOTE - YAML is indentation sensitive so keep things lined up properly!
e6805f 141 </p>
62db52 142
49e3a8 143 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
62db52 144
49e3a8 145 6. Open the `params/project-requests-ci-cd` and replace the `<YOUR_NAME>` with your name to create the corresponding projects in the cluster.
ff1bd7 146 ![new-item](../images/exercise1/ci-cd-project-namespace.png)
bc2e43 147
49e3a8 148 7. Let's add two more params files to pass to our template to be able to create a `dev` and `test` project.
1173e5 149   * Create another two params files `params/project-requests-dev` & `params/project-requests-test`. On the terminal run
da614f 150 ```bash
f5f1ff 151 touch params/project-requests-dev params/project-requests-test
da614f 152 ```
f5f1ff 153   * In your editor; Open `params/project-requests-dev` and add the following by substituting `<YOUR_NAME>` accordingly
62db52 154 ```
D 155 NAMESPACE=<YOUR_NAME>-dev
156 NAMESPACE_DISPLAY_NAME=<YOUR-NAME> Dev
157 ```
f5f1ff 158   * In your editor; Open `params/project-requests-test` and add the following by substituting `<YOUR_NAME>` accordingly
62db52 159 ```
D 160 NAMESPACE=<YOUR_NAME>-test
161 NAMESPACE_DISPLAY_NAME=<YOUR-NAME> Test
162 ```
bc2e43 163
49e3a8 164 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.
bc2e43 165 ```yaml
62db52 166     - name: "{{ dev_namespace }}"
D 167       template: "{{ playbook_dir }}/templates/project-requests.yml"
3de284 168       action: create
62db52 169       params: "{{ playbook_dir }}/params/project-requests-dev"
ff1bd7 170       tags:
D 171       - projects
62db52 172     - name: "{{ test_namespace }}"
D 173       template: "{{ playbook_dir }}/templates/project-requests.yml"
3de284 174       action: create
62db52 175       params: "{{ playbook_dir }}/params/project-requests-test"
ff1bd7 176       tags:
D 177       - projects
bc2e43 178 ```
ff1bd7 179 ![project-request-yaml](../images/exercise1/project-request-yml.png)
bc2e43 180
3de284 181 For Microsoft Windows systems, you need to run Ansible and OpenShift client commands from inside the `do500-toolbox` container. Linux and MacOS users should skip this step and jump directly to Step 10.
49e3a8 182
RS 183 <p class="tip">
184 NOTE - On Microsoft Windows systems, we recommend you keep the container running for the duration of the lab. Run all Ansible and OpenShift client ("oc") CLI commands from inside the container. Do NOT launch the container on Linux and MacOS systems, since you should already have Ansible and the OpenShift client natively installed on your system by following the pre-requisites setup guide.
185 </p>
186
187 9. Launch the toolbox container using the Windows command line terminal, and navigate to the `enablement-ci-cd` directory inside the container
188 ```bash
313b88 189 docker run -it -v C:/do500-workspace:/home/tool-box/workarea:Z quay.io/redhat/do500-toolbox /bin/bash
49e3a8 190 bash-4.4$ cd workarea/enablement-ci-cd
RS 191 ```
192
193 10. With the configuration in place; install the OpenShift Applier dependency
bc2e43 194 ```bash
f5f1ff 195 ansible-galaxy install -r requirements.yml --roles-path=roles
bc2e43 196 ```
D 197
49e3a8 198 11. Apply the inventory by logging into OpenShift on the terminal and running the playbook as follows (<CLUSTER_URL> should be replaced with the one you've been provided by the instructor). Accept any insecure connection warning 👍:
bc2e43 199 ```bash
530a25 200 oc login <CLUSTER_URL>
f5f1ff 201 ```
D 202 ```bash
203 ansible-playbook apply.yml -i inventory/ -e target=bootstrap
62db52 204 ```
D 205 where the `-e target=bootstrap` is passing an additional variable specifying that we run the `bootstrap` inventory
bc2e43 206
49e3a8 207 12. Once successful you should see an output similar to this (Cows not included): ![playbook-success](../images/exercise1/play-book-success.png)
bc2e43 208
49e3a8 209 13. You can check to see the projects have been created successfully by running
e6805f 210 ```bash
f5f1ff 211 oc projects
e6805f 212 ```
D 213 ![project-success](../images/exercise1/project-success.png)
214
f5f1ff 215 ### Part 2 - Nexus
3f16e0 216 > _Now that we have our Projects setup; we can start to populate them with Apps to be used in our dev lifecycle_
bc2e43 217
49e3a8 218 1. In the `enablement-ci-cd` repo, checkout the templates for Nexus by running
3f16e0 219 ```bash
f5f1ff 220 git checkout exercise1/git-nexus templates/nexus.yml
3558ae 221 ```
f79b6f 222 The template contains all the things needed to setup a persistent nexus server, exposing a service and route while also creating the persistent volume needed. Have a read through the template; at the bottom you'll see a collection of parameters we will pass to the template.
3558ae 223
49e3a8 224 2. Add some parameters for running the template by creating a new file in the `params` directory.
3558ae 225 ```bash
f5f1ff 226 touch params/nexus
3f16e0 227 ```
D 228
49e3a8 229 3. The essential params to include in this file are:
3558ae 230 ```bash
D 231 VOLUME_CAPACITY=5Gi
84a614 232 MEMORY_LIMIT=1Gi
3558ae 233 ```
D 234
8894bf 235 4. Create a new object in the inventory variables `inventory/host_vars/ci-cd-tooling.yml` called `ci-cd-tooling` and populate its `content` is as follows
62db52 236
3558ae 237 ```yaml
62db52 238 ---
D 239 ansible_connection: local
240 openshift_cluster_content:
241 - object: ci-cd-tooling
242   content:
f9e1bc 243   - name: "nexus"
D 244     namespace: "{{ ci_cd_namespace }}"
245     template: "{{ playbook_dir }}/templates/nexus.yml"
246     params: "{{ playbook_dir }}/params/nexus"
247     tags:
248     - nexus
3558ae 249 ```
ff1bd7 250 ![ci-cd-deployments-yml](../images/exercise1/ci-cd-deployments-yml.png)
3558ae 251
49e3a8 252 5. Run the OpenShift applier, specifying the tag `nexus` to speed up its execution (`-e target=tools` is to run the other inventory).
3558ae 253 ```bash
f5f1ff 254 ansible-playbook apply.yml -e target=tools \
3558ae 255      -i inventory/ \
ff1bd7 256      -e "filter_tags=nexus"
3558ae 257 ```
D 258
49e3a8 259 6. Once successful; login to the cluster through the browser (using cluster URL) and navigate to the `<YOUR_NAME>-ci-cd`. You should see Nexus up and running. You can login with default credentials (admin / admin123) ![nexus-up-and-running](../images/exercise1/nexus-up-and-running.png)
3558ae 260
f5f1ff 261 ### Part 3 - GitLab
D 262
49e3a8 263 <!-- #### 3a - GitLab install -->
b43054 264 <p class="tip">
49e3a8 265 NOTE - A Gitlab instance in the cloud has already been set up for you, please check with your instructor for the Gitlab instance URL.
b43054 266 </p>
D 267
49e3a8 268 <!-- 4. Now let's do the same thing for GitLab to get it up and running. Checkout the template and params provided by running
3558ae 269 ```bash
f5f1ff 270 git checkout exercise1/git-nexus templates/gitlab.yml params/gitlab
1173e5 271 ```
3558ae 272 Explore the template; it contains the PVC, buildConfig and services. The DeploymentConfig is made up of these apps
D 273  - Redis (3.2.3)
274  - PostgreSQL (9.4)
275  - GitLab CE (v10.2.3)
276
b47510 277 4. Open the `params/gitlab` file and complete the following params
RH 278 <p class="tip">
279 Note - The values here for the LDAP and BIND credentials will be provided by your tutor.
280 </p>
3558ae 281 ```
D 282 LDAP_BIND_DN=uid=<BIND_USER>,ou=People,dc=<YOUR_DOMAIN>,dc=com
283 LDAP_USER_FILTER=(memberof=CN=YourGroup,OU=Users,DC=<YOUR_DOMAIN>,DC=com)
284 LDAP_PASSWORD=<BIND_USER_PASSWORD>
285 LDAP_HOST=<LDAP_HOST>
286 LDAP_BASE=ou=People,dc=<YOUR_DOMAIN>,dc=com
287 LDAP_LABEL="<LDAP_DESCRIPTION>"
288 GITLAB_ROOT_PASSWORD=<GITLAB_ROOT_USER_PASSWORD>
289 GITLAB_DATA_VOL_SIZE=2Gi
290 POSTGRESQL_VOL_SIZE=1Gi
291 APPLICATION_HOSTNAME=<GITLAB_URL>
c41b51 292 NAMESPACE=<YOUR_NAME>-ci-cd
3558ae 293 ```
D 294 where the following need to be replaced by actual values:
295     * `<BIND_USER>` is the user used to query the LDAP
296     * `<BIND_USER_PASSWORD>` is the password used when querying the LDAP
297     * `<YOUR_DOMAIN>` is the domain the LDAP is hosted on
298     * `<LDAP_HOST>` is fqdn of the LDAP server
1173e5 299     * `<LDAP_DESCRIPTION>` is the description to be used on the sign-in header for GitLab e.g. "Name LDAP Login"
CM 300     * `<GITLAB_ROOT_USER_PASSWORD>` is the root user for GOD access on the GitLab instance e.g. password123
3558ae 301     * `<GITLAB_URL>` is the endpoint for gitlab. It will take the form `gitlab-<YOUR_NAME>-ci-cd.apps.<ENV_ID>.<YOUR_DOMAIN>.com`
D 302
62db52 303 4. Create another object in the inventory `inventory/host_vars/ci-cd-tooling.yml` file to run the build & deploy of this template. Add the following and update the `namespace:` accordingly
3558ae 304 ```yaml
ff1bd7 305     - name: "gitlab"
62db52 306       namespace: "{{ ci_cd_namespace }}"
D 307       template: "{{ playbook_dir }}/templates/gitlab.yml"
308       params: "{{ playbook_dir }}/params/gitlab"
ff1bd7 309       tags:
D 310       - gitlab
3558ae 311 ```
D 312
8894bf 313 4. Run the OpenShift applier, specifying the tag `gitlab` to speed up its execution.
3558ae 314 ```bash
f5f1ff 315 ansible-playbook apply.yml -e target=tools \
3558ae 316      -i inventory/ \
ff1bd7 317      -e "filter_tags=gitlab"
3558ae 318 ```
D 319
49e3a8 320 4. Once successful; login to the cluster and navigate to the `<YOUR_NAME>-ci-cd`. You should see GitLab up and running. ![gitlab-up-and-running](../images/exercise1/gitlab-up-and-running.png) -->
f5f1ff 321
49e3a8 322 <!-- #### 3b - Commit CI/CD -->
c41b51 323
49e3a8 324 1. Navigate to GitLab login page. You can login using your cluster credentials using the LDAP tab
ff1bd7 325 ![gitlab-ui](../images/exercise1/gitlab-ui.png)
c41b51 326
49e3a8 327 2. Once logged in create a new project called `enablement-ci-cd` and mark it as internal. Once created; copy out the `git url` for use on the next step.
ff1bd7 328 ![gitlab-new-project](../images/exercise1/gitlab-new-project.png)
49e3a8 329 <!-- <p class="tip">
e43fd2 330 Note - we would not normally make the project under your name but create a group and add the project there on residency but for simplicity of the exercise we'll do that here
49e3a8 331 </p> -->
ff1bd7 332
49e3a8 333 3. If you have not used Git before; you may need to tell Git who you are and what your email is before we commit. Run the following commands, substituting your email and "Your Name". If you've done this before move on to the next step. The last git config command is used to bypass SSL key verification for the GitLab server instance since we are using self-signed certificates on the sever.
RS 334
ff1bd7 335 ```bash
f5f1ff 336 git config --global user.email "yourname@mail.com"
ff1bd7 337 ```
f5f1ff 338 ```bash
D 339 git config --global user.name "Your Name"
49e3a8 340 ```
RS 341
342 ```bash
343 git config --global http.sslVerify false
f5f1ff 344 ```
D 345
1173e5 346 4. Commit your local project to this new remote by first removing the existing origin (github) where the Ansible project was cloned from in the first steps. Remember to substitute `<GIT_URL>` accordingly with the one created for your `enablement-ci-cd` repository a moment ago.
f5f1ff 347 ```bash
D 348 git remote set-url origin <GIT_URL>
349 ```
350 ```bash
351 git add .
352 ```
353 ```bash
354 git commit -m "Adding git and nexus config"
355 ```
356 ```bash
357 git push -u origin --all
358 ```
359
49e3a8 360 ### Part 4 - MongoDB for CI tests
RS 361 > In order to run our API tests in CI in later labs; we need a MongoDB server instance available for executing our tests. As this is part of our CI/CD Lifecycle; we will add it now.
0d4d53 362
49e3a8 363 1. In our `enablement-ci-cd` repo; checkout the mongo templates as shown below to bring in the template and params. 
RS 364 <!-- The mongodb template we're using is the same as the one for our `todolist-fe` created in previous exercise. -->
0d4d53 365 ```bash
d43bf4 366 git checkout exercise1/mongodb params/mongodb templates/mongodb.yml
0d4d53 367 ```
D 368
49e3a8 369 2. Open `enablement-ci-cd` in your favourite editor. Edit the `inventory/host_vars/ci-cd-tooling.yml` to include a new object for our mongodb as shown below. This item can be added below the Jenkins slave in the `ci-cd-tooling` section.
0d4d53 370 ```yaml
D 371   - name: "jenkins-mongodb"
372     namespace: "{{ ci_cd_namespace }}"
373     template: "{{ playbook_dir }}/templates/mongodb.yml"
374     params: "{{ playbook_dir }}/params/mongodb"
375     tags:
376     - mongodb
377 ```
d43bf4 378 ![jenkins-mongo](../images/exercise1/jenkins-mongo.png)
0d4d53 379
49e3a8 380 3. Git commit your updates to the inventory to git for traceability.
0d4d53 381 ```bash
D 382 git add .
383 ```
384 ```bash
385 git commit -m "ADD - mongodb for use in the pipeline"
386 ```
387 ```bash
388 git push
389 ```
390
1173e5 391 4. Apply this change as done previously using Ansible. The deployment can be validated by going to your `<YOUR_NAME>-ci-cd` namespace and checking if it is there!
0d4d53 392 ```bash
D 393 ansible-playbook apply.yml -e target=tools \
394   -i inventory/ \
395   -e "filter_tags=mongodb"
396 ```
397 ![ocp-mongo](../images/exercise3/ocp-mongo.png)
398
49e3a8 399 <p class="tip">
RS 400 Note - When making changes to the "enablement-ci-cd" repo, you should frequently commit the changes to git.
401 </p>
bc2e43 402
49e3a8 403 ### Part 5 - Jenkins & S2I
RS 404 > _Create a build and deployment config for Jenkins. Add new configuration and plugins to the OpenShift default Jenkins image using s2i
bc2e43 405
49e3a8 406 1. Add the Jenkins Build & Deployment configs to the `enablement-ci-cd` repo by merging the contents from the `exercise1/jenkins` branch
ff1bd7 407 ```bash
f5f1ff 408 git checkout exercise1/jenkins templates/jenkins.yml
ff1bd7 409 ```
49e3a8 410 <!-- The Jenkins template is essentially the standard persistent Jenkins one with OpenShift. -->
ff1bd7 411
49e3a8 412 2. As before; create a new set of params by creating a `params/jenkins` file and adding some overrides to the template and updating the `<YOUR_NAME>` value accordingly.
2e44a7 413 ```
84a614 414 MEMORY_LIMIT=3Gi
f54f70 415 VOLUME_CAPACITY=10Gi
ff1bd7 416 JVM_ARCH=x86_64
D 417 NAMESPACE=<YOUR_NAME>-ci-cd
418 JENKINS_OPTS=--sessionTimeout=720
419 ```
62db52 420
49e3a8 421 3. Add a `jenkins` variable to the Ansible inventory underneath the jenkins-mongo (and git if you have it) in  `inventory/host_vars/ci-cd-tooling.yml`.
ff1bd7 422 ```yaml
D 423     - name: "jenkins"
62db52 424       namespace: "{{ ci_cd_namespace }}"
D 425       template: "{{ playbook_dir }}/templates/jenkins.yml"
426       params: "{{ playbook_dir }}/params/jenkins"
ff1bd7 427       tags:
D 428       - jenkins
429 ```
f79b6f 430 This configuration, if applied now, will create the deployment configuration needed for Jenkins but the `${NAMESPACE}:${JENKINS_IMAGE_STREAM_TAG}` in the template won't exist yet.
ff1bd7 431
49e3a8 432 4. To create this image we will take the supported OpenShift Jenkins Image and bake into it some extra configuration using an [s2i](https://github.com/openshift/source-to-image) builder image. More information on Jenkins s2i is found on the [openshift/jenkins](https://github.com/openshift/jenkins#installing-using-s2i-build) GitHub page. To create an s2i configuration for Jenkins, check out the pre-canned configuration source in the `enablement-ci-cd` repo
ff1bd7 433 ```bash
f5f1ff 434 git checkout exercise1/jenkins-s2i jenkins-s2i
ff1bd7 435 ```
1173e5 436 The structure of the Jenkins s2i config is
ff1bd7 437 ```
D 438 jenkins-s2i
439 ├── README.md
440 ├── configuration
441 │   ├── build-failure-analyzer.xml
442 │   ├── init.groovy
443 │   ├── jenkins.plugins.slack.SlackNotifier.xml
2e44a7 444 │   ├── scriptApproval.xml
ff1bd7 445 │   └── jobs
D 446 │       └── seed-multibranch-job
447 │           └── config.xml
448 └── plugins.txt
449 ```
450  * `plugins.txt` is a list of `pluginId:version` for Jenkins to pre-install when starting
451  * `./configuration` contains content that is placed in `${JENKINS_HOME}`. A `config.xml` could be placed in here to control the bulk of Jenkins configuration.
452  * `./configuration/jobs/*` contains job names and xml config that jenkins loads when starting. The seed job in there we will return to in later lessons.
de8ebb 453  * `build-failure-analyzer.xml` is config for the plugin to read the logs and look for key items based on a Regex. More on this in later lessons.
ff1bd7 454  * `init.groovy` contains a collection of settings jenkins configures itself with when launching
D 455
1173e5 456 5. Let's add a plugin for Jenkins to be started with, [green-balls](https://plugins.jenkins.io/greenballs). This simply changes the default `SUCCESS` status of Jenkins from Blue to Green. Append the `jenkins-s2i/plugins.txt` file with
ff1bd7 457 ```txt
D 458 greenballs:1.15
1173e5 459 ```
ff1bd7 460 ![green-balls.png](../images/exercise1/green-balls.png)
D 461
49e3a8 462 <!-- Why does Jenkins use blue to represent success? More can be found [on reddit](https://www.reddit.com/r/programming/comments/4lu6q8/why_does_jenkins_have_blue_balls/) or the [Jenkins blog](https://jenkins.io/blog/2012/03/13/why-does-jenkins-have-blue-balls/). -->
RS 463
464 6. Before building and deploying the Jenkins s2i; add your git credentials to it. These will be used by Jenkins to access the Git Repositories where our apps will be stored. We want Jenkins to be able to push tags to it, so write access is required. 
465
466 There are a few ways we can do this; either adding them to the `template/jenkins.yml` as environment variables and then including them in the `params/jenkins` file.  We could also create a token in GitLab and use it as the source secret in the Jenkins template.
467
468 For the sake of simplicity, just replace the `<USERNAME>` && `<PASSWORD>` in the `jenkins-s2i/configuration/init.groovy` with your LDAP credentials as seen below. This init file gets run when Jenkins launches, and will setup the credentials for use in our Jobs in the next exercises
ff1bd7 469 ```groovy
D 470 gitUsername = System.getenv("GIT_USERNAME") ?: "<USERNAME>"
471 gitPassword = System.getenv("GIT_PASSWORD") ?: "<PASSWORD>"
472 ```
49e3a8 473 <!-- <p class="tip">
1173e5 474 Note in a residency we would not use your GitCredentials for pushing and pulling from Git, a service user would be created for this.
49e3a8 475 </p> -->
ff1bd7 476
49e3a8 477 7. Checkout the params and the templates for the `jenkins-s2i`
2e44a7 478 ```bash
f5f1ff 479 git checkout exercise1/jenkins-s2i params/jenkins-s2i templates/jenkins-s2i.yml
2e44a7 480 ```
D 481
49e3a8 482 8. Open `params/jenkins-s2i` and add the following content; replacing variables as appropriate.
ff1bd7 483 ```
da614f 484 SOURCE_REPOSITORY_URL=<GIT_URL>
ff1bd7 485 NAME=jenkins
D 486 SOURCE_REPOSITORY_CONTEXT_DIR=jenkins-s2i
487 IMAGE_STREAM_NAMESPACE=<YOUR_NAME>-ci-cd
da614f 488 SOURCE_REPOSITORY_USERNAME=<YOUR_LDAP_USERNAME>
D 489 SOURCE_REPOSITORY_PASSWORD=<YOUR_LDAP_PASSWORD>
ff1bd7 490 ```
1173e5 491 where
e43fd2 492     * `<GIT_URL>` is the full clone path of the repo where this project is stored (including the https && .git)
de8ebb 493     * `<YOUR_NAME>` is the prefix for your `-ci-cd` project.
D 494     * Explore some of the other parameters in `templates/jenkins-s2i.yml`
da614f 495     * `<YOUR_LDAP_USERNAME>` is the username builder pod will use to login and clone the repo with
D 496     * `<YOUR_LDAP_PASSWORD>` is the password the builder pod will use to authenticate and clone the repo using
49e3a8 497 <!-- <p class="tip">
da614f 498 Note in a residency we would not use your GitCredentials for pushing and pulling from Git, A service user would be created or a token generated.
49e3a8 499 </p> -->
ff1bd7 500
49e3a8 501 9. Create a new object `ci-cd-builds` in the Ansible `inventory/host_vars/ci-cd-tooling.yml` to drive the s2i build configuration.
ff1bd7 502 ```yaml
D 503   - object: ci-cd-builds
504     content:
505     - name: "jenkins-s2i"
62db52 506       namespace: "{{ ci_cd_namespace }}"
D 507       template: "{{ playbook_dir }}/templates/jenkins-s2i.yml"
508       params: "{{ playbook_dir }}/params/jenkins-s2i"
ff1bd7 509       tags:
D 510       - jenkins
511 ```
512
49e3a8 513 10. Commit your code to your GitLab instance
ff1bd7 514 ```bash
f5f1ff 515 git add .
D 516 ```
517 ```bash
518 git commit -m "Adding Jenkins and Jenkins s2i"
519 ```
520 ```bash
521 git push
ff1bd7 522 ```
D 523
49e3a8 524 11.  In order for Jenkins to be able to run `npm` builds and installs we must configure a `jenkins-build-slave` for Jenkins to use. This slave will be dynamically provisioned when we run a build. It needs to have NodeJS and npm installed in it. These slaves can take a time to build themselves so to speed up we have placed the slave within OpenShift and you can use the following commands to be able to use them in your project.
bce8a5 525 ```bash
D 526 oc project <YOUR_NAME>-ci-cd
527 ```
5b1604 528 ```bash
T 529 oc tag openshift/jenkins-slave-npm:latest jenkins-slave-npm:latest
530 ```
531 ```bash
532 oc label is jenkins-slave-npm role=jenkins-slave
533 ```
bce8a5 534 This is pulling the container image into your namespace and then adding a label which will allow Jenkins to take notice of it. Don't worry if the label is already there and this last command fails!
5b1604 535
49e3a8 536 12. Now your code is commited, and you have bought in the Jenkins slave; run the OpenShift Applier to add the config to the cluster
ff1bd7 537 ```bash
f5f1ff 538 ansible-playbook apply.yml -e target=tools \
ff1bd7 539      -i inventory/ \
D 540      -e "filter_tags=jenkins"
541 ```
542
49e3a8 543 13. This will trigger a build of the s2i and when it's complete it will add an imagestream of `<YOUR_NAME>-ci-cd/jenkins:latest` to the project. The Deployment config should kick in and deploy the image once it arrives. You can follow the build of the s2i by going to the OpenShift console's project
de8ebb 544 ![jenkins-s2i-log](../images/exercise1/jenkins-s2i-log.png)
bc2e43 545
49e3a8 546 14. When the Jenkins deployment has completed; login (using your OpenShift credentials) and accept the role permissions. You should now see a fairly empty Jenkins with just the seed job
3558ae 547
1173e5 548 ### Part 6 - Jenkins Hello World
49e3a8 549 > _To test things are working end-to-end; create a hello world job that doesn't do much but proves we can pull code from git and that our builds are green._
de8ebb 550
49e3a8 551 1. Log in to Jenkins and hit `New Item` ![new-item](../images/exercise1/new-item.png).
de8ebb 552
49e3a8 553 2. Create a freestyle job called `hello-world` ![jenkins-new-hello-world](../images/exercise1/jenkins-new-hello-world.png).
de8ebb 554
49e3a8 555 3. On the Source Code Management tab; add your `enablement-ci-cd` git repo and hit the dropdown to add your credentials we baked into the s2i on previous steps ![jenkins-scm-git](../images/exercise1/jenkins-scm-git.png)
de8ebb 556
49e3a8 557 4. On the build tab add an Execute Shell step and fill it with `echo "Hello World"` ![jenkins-hello-world](../images/exercise1/jenkins-hello-world.png).
de8ebb 558
49e3a8 559 5. Run the build and we should see it pass successfully and with a Green ball! ![jenkins-green-balls](../images/exercise1/jenkins-green-balls.png)
de8ebb 560
6c0958 561 ### Part 7 - Live, Die, Repeat
1173e5 562 > _In this section you will prove the infra as code is working by deleting your Cluster Content and recreating it all_
de8ebb 563
49e3a8 564 1. Commit your code to the new repo in GitLab
7c832b 565 ```bash
f5f1ff 566 git add .
D 567 ```
568 ```bash
569 git commit -m "ADD - all ci/cd contents"
570 ```
571 ```bash
572 git push
7c832b 573 ```
de8ebb 574
49e3a8 575 2. Burn your OpenShift project resources to the ground
7c832b 576 ```bash
f5f1ff 577 oc delete project <YOUR_NAME>-ci-cd
D 578 ```
579 ```bash
580 oc delete project <YOUR_NAME>-dev
581 ```
582 ```bash
583 oc delete project <YOUR_NAME>-test
7c832b 584 ```
de8ebb 585
49e3a8 586 3. Check to see the projects that were marked for deletion are removed.
da614f 587 ```bash
f5f1ff 588 oc get projects | egrep '<YOUR_NAME>-ci-cd|<YOUR_NAME>-dev|<YOUR_NAME>-test'
da614f 589 ```
D 590
49e3a8 591 4. Re-apply the inventory to re-create it all!
7c832b 592 ```bash
530a25 593 oc login <CLUSTER_URL>
f5f1ff 594 ```
D 595 ```bash
596 ansible-playbook apply.yml -i inventory/ -e target=bootstrap
597 ```
598 ```bash
599 ansible-playbook apply.yml -i inventory/ -e target=tools
7c832b 600 ```
c951f7 601
5d0992 602 _____
D 603
49e3a8 604 <!-- ## Extension Tasks
de8ebb 605 > _Ideas for go-getters. Advanced topic for doers to get on with if they finish early. These will usually not have a solution and are provided for additional scope._
c951f7 606
0d4d53 607  - Install Cowsay for 100% more Ansible Fun!
3558ae 608  - Add more secure access for Nexus (ie not admin / admin123) using the automation to drive secret creation
ff1bd7 609  - Add a SonarQube persistent deployment to the `ci-cd-deployments` section.
49e3a8 610  - Add `jenkins.plugins.slack.SlackNotifier.xml` to `jenkins-s2i/configuration` to include URL of Slack for team build notifications and rebuild Jenkins s2i
c951f7 611
49e3a8 612 _____ -->
5d0992 613
ab9d82 614 <!-- ## Additional Reading
49e3a8 615 > List of links and other reading material that might be of use for the exercise
01c4da 616
RH 617 ## Slide links
618
49e3a8 619 - TBD
RS 620 - TBD
ab9d82 621 - TBD -->
49e3a8 622
RS 623 <!-- - [Intro](https://docs.google.com/presentation/d/1LsfAkH8GfIhulEoy_yd-usWBfDHnZEyQdNvYeTmAg4A/)
01c4da 624 - [Wrap-up](https://docs.google.com/presentation/d/1cfyJ6SHddZNbM61oz67r870rLYVKY335zGclXN2uLMY/)
49e3a8 625 - [All Material](https://drive.google.com/drive/folders/13Bt4BXf9P2OB8VI4YQNcNONF1786dqOx) -->