Ryan DeBeasi
2018-08-07 30c96c324e99c98d6a96ee2373e3eb12dedcb8e5
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
7c832b 4 ![automation-xkcd](https://imgs.xkcd.com/comics/automation.png)
D 5
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)
f52b28 37
5d0992 38 _____
c951f7 39
D 40 ## 10,000 Ft View
1173e5 41 > 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 42
1173e5 43 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 44
2533e0 45 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 46
5d0992 47 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 48
2533e0 49 3. Use the templates provided to create build of the jenkins-s2i. The templates are in `exercise1/jenkins-s2i`
3558ae 50
2533e0 51 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 52     * Nexus
D 53     * GitLab
1173e5 54     * Jenkins (using an s2i to pre-configure Jenkins)
3558ae 55
2533e0 56 5. Commit your `enablement-ci-cd` repository to the GitLab Instance you've created
3558ae 57
2533e0 58 6. Burn it all down and re-apply your inventory proving config-as-code works.
c951f7 59
D 60 ## Step by Step Instructions
bc2e43 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
33c738 66 3. 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).
bc2e43 67 ```bash
33c738 68 mkdir -p ~/innovation-labs && cd ~/innovation-labs
e7c877 69 ```
f5f1ff 70 <p class="tip">
D 71 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...
72 </p>
73
74 3. 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
75 ```bash
76 git clone https://github.com/rht-labs/enablement-ci-cd && cd enablement-ci-cd
e7c877 77 ```
f5f1ff 78 ```bash
D 79 ./git-pull-all.sh
c951f7 80 ```
D 81
f5f1ff 82 3. Open the `innovation-labs` folder in VSCode (or your favourite editor). The project is laid out as follows
bc2e43 83 ```
D 84 .
85 ├── README.md
62db52 86 ├── apply.yml
bc2e43 87 ├── docker
D 88 ├── inventory
62db52 89 │   ├── host_vars
D 90 │   │   ├── ci-cd-tooling.yml
91 │   │   └── projects-and-policies.yml
92 │   └── hosts
bc2e43 93 ├── jenkins-s2i
D 94 ├── params
62db52 95 │   └── project-requests-ci-cd
bc2e43 96 ├── requirements.yml
D 97 └── templates
62db52 98     └── project-requests.yml
bc2e43 99 ```
D 100  * `docker` folder contains our jenkins-slave images that will be used by the builds.
101  * `jenkins-s2i` contains the configuration and plugins we want to bring jenkins to life with
102  * `params` houses the variables we will load the templates with
103  * `templates` is a collection of OpenShift templates
62db52 104  * `inventory/host_vars/*.yml` is the collection of objects we want to insert into the cluster.
bc2e43 105  * `requirements.yml` is a manifest which contains the ansible modules needed to run the playbook
62db52 106  * `apply.yml` is a playbook that sets up some variables and runs the OpenShift Applier role.
bc2e43 107
1173e5 108 3. 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 109 ```yaml
e6805f 110   hosts: "{{ target }}"
62db52 111   vars:
D 112     ci_cd_namespace: donal-ci-cd
113     dev_namespace: donal-dev
114     test_namespace: donal-test
e6805f 115   tasks:
62db52 116 ```
e6805f 117 <p class="tip">
D 118 NOTE - yaml is indentation sensitive so keep things lined up properly!
119 </p>
62db52 120
D 121 3. 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
122
1173e5 123 3. Open the `params/project-requests-ci-cd` and replace the `<YOUR_NAME>` with your name to create the corresponding projects in the cluster.
ff1bd7 124 ![new-item](../images/exercise1/ci-cd-project-namespace.png)
bc2e43 125
1173e5 126 3. Let's add two more params files to pass to our template to be able to create a `dev` and `test` project.
CM 127   * Create another two params files `params/project-requests-dev` & `params/project-requests-test`. On the terminal run
da614f 128 ```bash
f5f1ff 129 touch params/project-requests-dev params/project-requests-test
da614f 130 ```
f5f1ff 131   * In your editor; Open `params/project-requests-dev` and add the following by substituting `<YOUR_NAME>` accordingly
62db52 132 ```
D 133 NAMESPACE=<YOUR_NAME>-dev
134 NAMESPACE_DISPLAY_NAME=<YOUR-NAME> Dev
135 ```
f5f1ff 136   * In your editor; Open `params/project-requests-test` and add the following by substituting `<YOUR_NAME>` accordingly
62db52 137 ```
D 138 NAMESPACE=<YOUR_NAME>-test
139 NAMESPACE_DISPLAY_NAME=<YOUR-NAME> Test
140 ```
bc2e43 141
62db52 142 3. 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 143 ```yaml
62db52 144     - name: "{{ dev_namespace }}"
D 145       template: "{{ playbook_dir }}/templates/project-requests.yml"
ff1bd7 146       template_action: create
62db52 147       params: "{{ playbook_dir }}/params/project-requests-dev"
ff1bd7 148       tags:
D 149       - projects
62db52 150     - name: "{{ test_namespace }}"
D 151       template: "{{ playbook_dir }}/templates/project-requests.yml"
ff1bd7 152       template_action: create
62db52 153       params: "{{ playbook_dir }}/params/project-requests-test"
ff1bd7 154       tags:
D 155       - projects
bc2e43 156 ```
ff1bd7 157 ![project-request-yaml](../images/exercise1/project-request-yml.png)
bc2e43 158
D 159 3. With the configuration in place; install the OpenShift Applier dependency
160 ```bash
f5f1ff 161 ansible-galaxy install -r requirements.yml --roles-path=roles
bc2e43 162 ```
D 163
1173e5 164 3. 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 sent as shown below). Accept any insecure connection warning 👍:
bc2e43 165 ```bash
0d4d53 166 oc login https://console.lader.rht-labs.com
f5f1ff 167 ```
D 168 ```bash
169 ansible-playbook apply.yml -i inventory/ -e target=bootstrap
62db52 170 ```
D 171 where the `-e target=bootstrap` is passing an additional variable specifying that we run the `bootstrap` inventory
bc2e43 172
e43fd2 173 3. Once successful you should see an output similar to this (Cows not included): ![playbook-success](../images/exercise1/play-book-success.png)
bc2e43 174
1173e5 175 3. You can check to see the projects have been created successfully by running
e6805f 176 ```bash
f5f1ff 177 oc projects
e6805f 178 ```
D 179 ![project-success](../images/exercise1/project-success.png)
180
f5f1ff 181 ### Part 2 - Nexus
3f16e0 182 > _Now that we have our Projects setup; we can start to populate them with Apps to be used in our dev lifecycle_
bc2e43 183
3558ae 184 4. In the `enablement-ci-cd` repo, checkout the templates for Nexus by running
3f16e0 185 ```bash
f5f1ff 186 git checkout exercise1/git-nexus templates/nexus.yml
3558ae 187 ```
f79b6f 188 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 189
1173e5 190 4. Add some parameters for running the template by creating a new file in the `params` directory.
3558ae 191 ```bash
f5f1ff 192 touch params/nexus
3f16e0 193 ```
D 194
90412a 195 4. The essential params to include in this file are:
3558ae 196 ```bash
D 197 VOLUME_CAPACITY=5Gi
84a614 198 MEMORY_LIMIT=1Gi
3558ae 199 ```
D 200
8894bf 201 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 202
3558ae 203 ```yaml
62db52 204 ---
D 205 ansible_connection: local
206 openshift_cluster_content:
207 - object: ci-cd-tooling
208   content:
f9e1bc 209   - name: "nexus"
D 210     namespace: "{{ ci_cd_namespace }}"
211     template: "{{ playbook_dir }}/templates/nexus.yml"
212     params: "{{ playbook_dir }}/params/nexus"
213     tags:
214     - nexus
3558ae 215 ```
ff1bd7 216 ![ci-cd-deployments-yml](../images/exercise1/ci-cd-deployments-yml.png)
3558ae 217
8894bf 218 4. Run the OpenShift applier, specifying the tag `nexus` to speed up its execution (`-e target=tools` is to run the other inventory).
3558ae 219 ```bash
f5f1ff 220 ansible-playbook apply.yml -e target=tools \
3558ae 221      -i inventory/ \
ff1bd7 222      -e "filter_tags=nexus"
3558ae 223 ```
D 224
b47510 225 4. 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 226
f5f1ff 227 ### Part 3 - GitLab
D 228
30c96c 229 Go to https://gitlab.com/ and create an account, or sign in with an existing account.
c41b51 230
f9e1bc 231 4. 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 232 ![gitlab-new-project](../images/exercise1/gitlab-new-project.png)
D 233 <p class="tip">
30c96c 234 Note - On a residency, you would create a group and add the project there. In this exercise, we'll add create the project under your name for simplicity's sake.
ff1bd7 235 </p>
D 236
e43fd2 237 4. 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.
ff1bd7 238 ```bash
f5f1ff 239 git config --global user.email "yourname@mail.com"
ff1bd7 240 ```
f5f1ff 241 ```bash
D 242 git config --global user.name "Your Name"
243 ```
244
1173e5 245 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 246 ```bash
D 247 git remote set-url origin <GIT_URL>
248 ```
249 ```bash
250 git add .
251 ```
252 ```bash
253 git commit -m "Adding git and nexus config"
254 ```
255 ```bash
256 git push -u origin --all
257 ```
258
6c0958 259 ### Part 4 MongoDB for CI tests
0d4d53 260 > In order to run our API tests in CI in later labs; we need there to be a MongoDB available for executing our tests. As this is part of our CI/CD Lifecycle; we will add it now.
D 261
262 4. In our `enablement-ci-cd` repo; checkout the mongo templates as shown below to bring in the template and params. The mongodb template we're using is the same as the one for our `todolist-fe` created in previous exercise.
263 ```bash
d43bf4 264 git checkout exercise1/mongodb params/mongodb templates/mongodb.yml
0d4d53 265 ```
D 266
1173e5 267 4. 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 268 ```yaml
D 269   - name: "jenkins-mongodb"
270     namespace: "{{ ci_cd_namespace }}"
271     template: "{{ playbook_dir }}/templates/mongodb.yml"
272     params: "{{ playbook_dir }}/params/mongodb"
273     tags:
274     - mongodb
275 ```
d43bf4 276 ![jenkins-mongo](../images/exercise1/jenkins-mongo.png)
0d4d53 277
D 278 4. Git commit your updates to the inventory to git for traceability.
279 ```bash
280 git add .
281 ```
282 ```bash
283 git commit -m "ADD - mongodb for use in the pipeline"
284 ```
285 ```bash
286 git push
287 ```
288
1173e5 289 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 290 ```bash
D 291 ansible-playbook apply.yml -e target=tools \
292   -i inventory/ \
293   -e "filter_tags=mongodb"
294 ```
295 ![ocp-mongo](../images/exercise3/ocp-mongo.png)
296
06e3b4 297 **Note - When making changes to enablement-ci-cd you should frequently commit the changes to git.**
bc2e43 298
6c0958 299 ### Part 5 - Jenkins & s2i
de8ebb 300 > _Create a build and deployment config for Jenkins. Add new configuration and plugins to the OCP Stock Jenkins using s2i_
bc2e43 301
ff1bd7 302 5. Add the Jenkins Build & Deployment configs to the `enablement-ci-cd` repo by merging the contents `exercise1/jenkins` in
D 303 ```bash
f5f1ff 304 git checkout exercise1/jenkins templates/jenkins.yml
ff1bd7 305 ```
1173e5 306 The Jenkins template is essentially the standard persistent Jenkins one with OpenShift.
ff1bd7 307
2e44a7 308 5. 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.
D 309 ```
84a614 310 MEMORY_LIMIT=3Gi
f54f70 311 VOLUME_CAPACITY=10Gi
ff1bd7 312 JVM_ARCH=x86_64
D 313 NAMESPACE=<YOUR_NAME>-ci-cd
314 JENKINS_OPTS=--sessionTimeout=720
315 ```
62db52 316
1173e5 317 5. 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 318 ```yaml
D 319     - name: "jenkins"
62db52 320       namespace: "{{ ci_cd_namespace }}"
D 321       template: "{{ playbook_dir }}/templates/jenkins.yml"
322       params: "{{ playbook_dir }}/params/jenkins"
ff1bd7 323       tags:
D 324       - jenkins
325 ```
f79b6f 326 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 327
1173e5 328 5. 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 329 ```bash
f5f1ff 330 git checkout exercise1/jenkins-s2i jenkins-s2i
ff1bd7 331 ```
1173e5 332 The structure of the Jenkins s2i config is
ff1bd7 333 ```
D 334 jenkins-s2i
335 ├── README.md
336 ├── configuration
337 │   ├── build-failure-analyzer.xml
338 │   ├── init.groovy
339 │   ├── jenkins.plugins.slack.SlackNotifier.xml
2e44a7 340 │   ├── scriptApproval.xml
ff1bd7 341 │   └── jobs
D 342 │       └── seed-multibranch-job
343 │           └── config.xml
344 └── plugins.txt
345 ```
346  * `plugins.txt` is a list of `pluginId:version` for Jenkins to pre-install when starting
347  * `./configuration` contains content that is placed in `${JENKINS_HOME}`. A `config.xml` could be placed in here to control the bulk of Jenkins configuration.
348  * `./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 349  * `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 350  * `init.groovy` contains a collection of settings jenkins configures itself with when launching
D 351
1173e5 352 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 353 ```txt
D 354 greenballs:1.15
1173e5 355 ```
ff1bd7 356 ![green-balls.png](../images/exercise1/green-balls.png)
D 357 Why does Jenkins have Blue Balls? 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/)
358
1173e5 359 5. Before building and deploying the Jenkins s2i; add 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. 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.
CM 360 But for 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 361 ```groovy
D 362 gitUsername = System.getenv("GIT_USERNAME") ?: "<USERNAME>"
363 gitPassword = System.getenv("GIT_PASSWORD") ?: "<PASSWORD>"
364 ```
2e44a7 365 <p class="tip">
1173e5 366 Note in a residency we would not use your GitCredentials for pushing and pulling from Git, a service user would be created for this.
2e44a7 367 </p>
ff1bd7 368
832672 369 5. Checkout the params and the templates for the `jenkins-s2i`
2e44a7 370 ```bash
f5f1ff 371 git checkout exercise1/jenkins-s2i params/jenkins-s2i templates/jenkins-s2i.yml
2e44a7 372 ```
D 373
1173e5 374 5. Open `params/jenkins-s2i` and add the following content; replacing variables as appropriate.
ff1bd7 375 ```
da614f 376 SOURCE_REPOSITORY_URL=<GIT_URL>
ff1bd7 377 NAME=jenkins
D 378 SOURCE_REPOSITORY_CONTEXT_DIR=jenkins-s2i
379 IMAGE_STREAM_NAMESPACE=<YOUR_NAME>-ci-cd
da614f 380 SOURCE_REPOSITORY_USERNAME=<YOUR_LDAP_USERNAME>
D 381 SOURCE_REPOSITORY_PASSWORD=<YOUR_LDAP_PASSWORD>
ff1bd7 382 ```
1173e5 383 where
e43fd2 384     * `<GIT_URL>` is the full clone path of the repo where this project is stored (including the https && .git)
de8ebb 385     * `<YOUR_NAME>` is the prefix for your `-ci-cd` project.
D 386     * Explore some of the other parameters in `templates/jenkins-s2i.yml`
da614f 387     * `<YOUR_LDAP_USERNAME>` is the username builder pod will use to login and clone the repo with
D 388     * `<YOUR_LDAP_PASSWORD>` is the password the builder pod will use to authenticate and clone the repo using
de8ebb 389 <p class="tip">
da614f 390 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.
de8ebb 391 </p>
ff1bd7 392
1173e5 393 5. Create a new object `ci-cd-builds` in the Ansible `inventory/host_vars/ci-cd-tooling.yml` to drive the s2i build configuration.
ff1bd7 394 ```yaml
D 395   - object: ci-cd-builds
396     content:
397     - name: "jenkins-s2i"
62db52 398       namespace: "{{ ci_cd_namespace }}"
D 399       template: "{{ playbook_dir }}/templates/jenkins-s2i.yml"
400       params: "{{ playbook_dir }}/params/jenkins-s2i"
ff1bd7 401       tags:
D 402       - jenkins
403 ```
404
405 5. Commit your code to your GitLab instance
406 ```bash
f5f1ff 407 git add .
D 408 ```
409 ```bash
410 git commit -m "Adding Jenkins and Jenkins s2i"
411 ```
412 ```bash
413 git push
ff1bd7 414 ```
D 415
1173e5 416 5.  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 417 ```bash
D 418 oc project <YOUR_NAME>-ci-cd
419 ```
5b1604 420 ```bash
T 421 oc tag openshift/jenkins-slave-npm:latest jenkins-slave-npm:latest
422 ```
423 ```bash
424 oc label is jenkins-slave-npm role=jenkins-slave
425 ```
bce8a5 426 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 427
T 428 5. 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 429 ```bash
f5f1ff 430 ansible-playbook apply.yml -e target=tools \
ff1bd7 431      -i inventory/ \
D 432      -e "filter_tags=jenkins"
433 ```
434
de8ebb 435 5. 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
D 436 ![jenkins-s2i-log](../images/exercise1/jenkins-s2i-log.png)
bc2e43 437
1173e5 438 5. 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 439
1173e5 440 ### Part 6 - Jenkins Hello World
de8ebb 441 > _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 balls are green._
D 442
443 6. Log in to Jenkins and hit `New Item` ![new-item](../images/exercise1/new-item.png).
444
e90e9c 445 6. Create a freestyle job called `hello-world` ![jenkins-new-hello-world](../images/exercise1/jenkins-new-hello-world.png).
de8ebb 446
f79b6f 447 6. 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 448
D 449 6. 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).
450
1173e5 451 6. Run the build and we should see if pass successfully and with Green Balls! ![jenkins-green-balls](../images/exercise1/jenkins-green-balls.png)
de8ebb 452
6c0958 453 ### Part 7 - Live, Die, Repeat
1173e5 454 > _In this section you will prove the infra as code is working by deleting your Cluster Content and recreating it all_
de8ebb 455
D 456 7. Commit your code to the new repo in GitLab
7c832b 457 ```bash
f5f1ff 458 git add .
D 459 ```
460 ```bash
461 git commit -m "ADD - all ci/cd contents"
462 ```
463 ```bash
464 git push
7c832b 465 ```
de8ebb 466
D 467 7. Burn your OCP content to the ground
7c832b 468 ```bash
f5f1ff 469 oc delete project <YOUR_NAME>-ci-cd
D 470 ```
471 ```bash
472 oc delete project <YOUR_NAME>-dev
473 ```
474 ```bash
475 oc delete project <YOUR_NAME>-test
7c832b 476 ```
de8ebb 477
da614f 478 7. Check to see the projects that were marked for deletion are removed.
D 479 ```bash
f5f1ff 480 oc get projects | egrep '<YOUR_NAME>-ci-cd|<YOUR_NAME>-dev|<YOUR_NAME>-test'
da614f 481 ```
D 482
7c832b 483 7. Re-apply the inventory to re-create it all!
D 484 ```bash
0d4d53 485 oc login https://console.lader.rht-labs.com
f5f1ff 486 ```
D 487 ```bash
488 ansible-playbook apply.yml -i inventory/ -e target=bootstrap
489 ```
490 ```bash
491 ansible-playbook apply.yml -i inventory/ -e target=tools
7c832b 492 ```
c951f7 493
5d0992 494 _____
D 495
c951f7 496 ## Extension Tasks
de8ebb 497 > _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 498
0d4d53 499  - Install Cowsay for 100% more Ansible Fun!
3558ae 500  - Add more secure access for Nexus (ie not admin / admin123) using the automation to drive secret creation
ff1bd7 501  - Add a SonarQube persistent deployment to the `ci-cd-deployments` section.
D 502  - Add `jenkins.plugins.slack.SlackNotifier.xml` to `jenkins-s2i/configuration` to include URL of Slack for team build notifications and rebuild Jenkins S2I
c951f7 503
5d0992 504 _____
D 505
c951f7 506 ## Additional Reading
7c832b 507 > List of links or other reading that might be of use / reference for the exercise
01c4da 508
RH 509 ## Slide links
510
511 - [Intro](https://docs.google.com/presentation/d/1LsfAkH8GfIhulEoy_yd-usWBfDHnZEyQdNvYeTmAg4A/)
512 - [Wrap-up](https://docs.google.com/presentation/d/1cfyJ6SHddZNbM61oz67r870rLYVKY335zGclXN2uLMY/)
5d4563 513 - [All Material](https://drive.google.com/drive/folders/13Bt4BXf9P2OB8VI4YQNcNONF1786dqOx)