donal
2018-05-16 a9627cced7c768500d543bdd100a8e4dbe57eef0
commit | author | age
74d1f1 1 # The Manual Menace
867471 2 > In this exercise learners will use Ansible to drive automated provisioning of Projects in Openshift, Git, Jenkins and Nexus.
0f4d08 3
9eed0b 4 ![automation-xkcd](https://imgs.xkcd.com/comics/automation.png)
D 5
6 ## Exercise Intro
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 to 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.
8
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 clusters content.
74d1f1 10
78b569 11 #### Why is config-as-code important? 
D 12 * Assurance - Prevents unwanted config changes from people making arbitrary changes to environments. No more Snowflake servers!
13 * Traceability - Commiting config as code means a user has approved and changes can be tracked.
14 * Phoenix Server -  Burn it all to the ground and bring it back; exactly the way it was!
15
74d1f1 16 _____
0f4d08 17
D 18 ## Learning Outcomes
19 As a learner you will be able to
74d1f1 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
0f4d08 24
D 25 ## Tools and Frameworks
26
74d1f1 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.
b4d469 31 * [OpenShift Applier](https://github.com/redhat-cop/openshift-applier) - used to apply OpenShift objects to an OpenShift Cluster.
A 32
33
74d1f1 34 ## Big Picture
45eb81 35 > The Big Picture is our emerging architecture; starting with an empty cluser we populate it with projects and some ci/cd tooling.
74d1f1 36
b62fab 37 ![ds-messing-around.gif](../images/exercise1/ds-messing-around.gif)
D 38
74d1f1 39 _____
0f4d08 40
D 41 ## 10,000 Ft View
867471 42 > This exercise is aimed at the creation of the tooling that will be used to support the rest of the Exercises. The highlevel goal is to create a collection of project namespaces and populate them with Git, Jenkins & Nexus.
74d1f1 43
D 44 If you're feeling confident and don't want to follow the step-by-step guide these highlevel instructions should provide a challenge for you:
45
e23af1 46 2. Clone the repo `https://github.com/rht-labs/enablement-ci-cd` which contains the scaffold of the project. Ensure you get all remote branches.
92099a 47
74d1f1 48 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
e23af1 49
D 50 2. Use the templates provided to create build of the jenkins-s2i. The templates are in `exercise1/jenkins-s2i`
92099a 51
D 52 2. 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`:
74d1f1 53     * Nexus
D 54     * GitLab
92099a 55     * Jenkins (using an s2i to pre-configure jenkins)
D 56
74d1f1 57 2. Commit your `enablement-ci-cd` repository to the GitLab Instance you've created
92099a 58
D 59 2. Burn it all down and re-apply your inventory proving config-as-code works. 
0f4d08 60
D 61 ## Step by Step Instructions
bd7806 62 > This is a structured guide with references to exact filenames and explanations.
0f4d08 63
bd7806 64 ### Part 1 - Create OpenShift Projects
d28811 65 > _Using the OpenShift Applier, we will add new project namespaces to the cluster which will be used throughout the exercise._
D 66
45eb81 67 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).
bd7806 68 ```bash
45eb81 69 mkdir -p ~/innovation-labs && cd ~/innovation-labs
2a3d5b 70 ```
784073 71 <p class="tip">
D 72 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...
73 </p>
74
75 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
76 ```bash
77 git clone https://github.com/rht-labs/enablement-ci-cd && cd enablement-ci-cd
2a3d5b 78 ```
784073 79 ```bash
D 80 ./git-pull-all.sh
0f4d08 81 ```
D 82
784073 83 3. Open the `innovation-labs` folder in VSCode (or your favourite editor). The project is laid out as follows
bd7806 84 ```
D 85 .
86 ├── README.md
fd78e6 87 ├── apply.yml
bd7806 88 ├── docker
fd78e6 89 │   └── jenkins-slave-npm
bd7806 90 ├── inventory
fd78e6 91 │   ├── host_vars
D 92 │   │   ├── ci-cd-tooling.yml
93 │   │   └── projects-and-policies.yml
94 │   └── hosts
bd7806 95 ├── jenkins-s2i
D 96 ├── params
fd78e6 97 │   └── project-requests-ci-cd
bd7806 98 ├── requirements.yml
D 99 └── templates
fd78e6 100     └── project-requests.yml
bd7806 101 ```
D 102  * `docker` folder contains our jenkins-slave images that will be used by the builds.
103  * `jenkins-s2i` contains the configuration and plugins we want to bring jenkins to life with
104  * `params` houses the variables we will load the templates with
105  * `templates` is a collection of OpenShift templates
fd78e6 106  * `inventory/host_vars/*.yml` is the collection of objects we want to insert into the cluster.
bd7806 107  * `requirements.yml` is a manifest which contains the ansible modules needed to run the playbook
fd78e6 108  * `apply.yml` is a playbook that sets up some variables and runs the OpenShift Applier role.
bd7806 109
e23af1 110 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: 
fd78e6 111 ```yaml
f49b0d 112   hosts: "{{ target }}"
fd78e6 113   vars:
D 114     ci_cd_namespace: donal-ci-cd
115     dev_namespace: donal-dev
116     test_namespace: donal-test
f49b0d 117   tasks:
fd78e6 118 ```
f49b0d 119 <p class="tip">
D 120 NOTE - yaml is indentation sensitive so keep things lined up properly!
121 </p>
fd78e6 122
D 123 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
124
125 3. Open the `params/project-requests-ci-cd` and replace the `<YOUR_NAME>` with your name to create the correstponding projects in the cluster. 
1c9328 126 ![new-item](../images/exercise1/ci-cd-project-namespace.png)
bd7806 127
fd78e6 128 3. Let's add two more param files to pass to our template to be able to create a `dev` and `test` project.
784073 129   * Create another two params files `params/project-requests-dev` & `params/project-requests-test`. On the terminal run 
e23af1 130 ```bash
784073 131 touch params/project-requests-dev params/project-requests-test
e23af1 132 ```
784073 133   * In your editor; Open `params/project-requests-dev` and add the following by substituting `<YOUR_NAME>` accordingly
fd78e6 134 ```
D 135 NAMESPACE=<YOUR_NAME>-dev
136 NAMESPACE_DISPLAY_NAME=<YOUR-NAME> Dev
137 ```
784073 138   * In your editor; Open `params/project-requests-test` and add the following by substituting `<YOUR_NAME>` accordingly
fd78e6 139 ```
D 140 NAMESPACE=<YOUR_NAME>-test
141 NAMESPACE_DISPLAY_NAME=<YOUR-NAME> Test
142 ```
bd7806 143
fd78e6 144 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.
bd7806 145 ```yaml
fd78e6 146     - name: "{{ dev_namespace }}"
D 147       template: "{{ playbook_dir }}/templates/project-requests.yml"
1c9328 148       template_action: create
fd78e6 149       params: "{{ playbook_dir }}/params/project-requests-dev"
1c9328 150       tags:
D 151       - projects
fd78e6 152     - name: "{{ test_namespace }}"
D 153       template: "{{ playbook_dir }}/templates/project-requests.yml"
1c9328 154       template_action: create
fd78e6 155       params: "{{ playbook_dir }}/params/project-requests-test"
1c9328 156       tags:
D 157       - projects
bd7806 158 ```
1c9328 159 ![project-request-yaml](../images/exercise1/project-request-yml.png)
bd7806 160
D 161 3. With the configuration in place; install the OpenShift Applier dependency
162 ```bash
784073 163 ansible-galaxy install -r requirements.yml --roles-path=roles
bd7806 164 ```
D 165
a9627c 166 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 👍: 
bd7806 167 ```bash
a9627c 168 oc login https://console.lader.rht-labs.com
784073 169 ```
D 170 ```bash
171 ansible-playbook apply.yml -i inventory/ -e target=bootstrap
fd78e6 172 ```
D 173 where the `-e target=bootstrap` is passing an additional variable specifying that we run the `bootstrap` inventory
bd7806 174
a9627c 175 3. Once successful you should see an output similar to this (Cow's not included): ![playbook-success](../images/exercise1/play-book-success.png)
bd7806 176
f49b0d 177 3. You can check to see the projects have been created successfully by running 
D 178 ```bash
784073 179 oc projects
f49b0d 180 ```
D 181 ![project-success](../images/exercise1/project-success.png)
182
784073 183 ### Part 2 - Nexus
da55a5 184 > _Now that we have our Projects setup; we can start to populate them with Apps to be used in our dev lifecycle_
bd7806 185
92099a 186 4. In the `enablement-ci-cd` repo, checkout the templates for Nexus by running
da55a5 187 ```bash
784073 188 git checkout exercise1/git-nexus templates/nexus.yml
92099a 189 ```
11198f 190 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.
92099a 191
D 192 4. Add some parameters for running the template by creating a new file in the `params` directory. 
193 ```bash
784073 194 touch params/nexus
da55a5 195 ```
D 196
8fc7f6 197 4. The essential params to include in this file are:
92099a 198 ```bash
D 199 VOLUME_CAPACITY=5Gi
200 MEMORY_LIMIT=2Gi
201 ```
202
4c20f0 203 4. Create a new object in the inventory variables `inventory/host_vars/ci-cd-tooling.yml` called `ci-cd-tooling` and populate it's `content` is as follows
fd78e6 204
92099a 205 ```yaml
fd78e6 206 ---
D 207 ansible_connection: local
208 openshift_cluster_content:
209 - object: ci-cd-tooling
210   content:
4c20f0 211   - name: "nexus"
D 212     namespace: "{{ ci_cd_namespace }}"
213     template: "{{ playbook_dir }}/templates/nexus.yml"
214     params: "{{ playbook_dir }}/params/nexus"
215     tags:
216     - nexus
92099a 217 ```
1c9328 218 ![ci-cd-deployments-yml](../images/exercise1/ci-cd-deployments-yml.png)
92099a 219
b92135 220 4. Run the OpenShift applier, specifying the tag `nexus` to speed up it's execution (`-e target=tools` is to run the other inventory).
92099a 221 ```bash
784073 222 ansible-playbook apply.yml -e target=tools \
92099a 223      -i inventory/ \
1c9328 224      -e "filter_tags=nexus"
92099a 225 ```
D 226
3acbf0 227 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)
92099a 228
784073 229 ### Part 3 - GitLab
D 230
231 #### 3a - GitLab install 
fdaee0 232 <p class="tip">
784073 233 NOTE - This section may already have been completed for you, please check with your tutor. If this is the case, skip to section 3b "Commit CI/CD" below to add your code to GitLab.
fdaee0 234 </p>
D 235
11198f 236 4. Now let's do the same thing for GitLab to get it up and running. Checkout the template and params provided by running
92099a 237 ```bash
784073 238 git checkout exercise1/git-nexus templates/gitlab.yml params/gitlab
92099a 239 ``` 
D 240 Explore the template; it contains the PVC, buildConfig and services. The DeploymentConfig is made up of these apps
241  - Redis (3.2.3)
242  - PostgreSQL (9.4)
243  - GitLab CE (v10.2.3)
244
3acbf0 245 4. Open the `params/gitlab` file and complete the following params
RH 246 <p class="tip">
247 Note - The values here for the LDAP and BIND credentials will be provided by your tutor.
248 </p>
92099a 249 ```
D 250 LDAP_BIND_DN=uid=<BIND_USER>,ou=People,dc=<YOUR_DOMAIN>,dc=com
251 LDAP_USER_FILTER=(memberof=CN=YourGroup,OU=Users,DC=<YOUR_DOMAIN>,DC=com)
252 LDAP_PASSWORD=<BIND_USER_PASSWORD>
253 LDAP_HOST=<LDAP_HOST>
254 LDAP_BASE=ou=People,dc=<YOUR_DOMAIN>,dc=com
255 LDAP_LABEL="<LDAP_DESCRIPTION>"
256 GITLAB_ROOT_PASSWORD=<GITLAB_ROOT_USER_PASSWORD>
257 GITLAB_DATA_VOL_SIZE=2Gi
258 POSTGRESQL_VOL_SIZE=1Gi
259 APPLICATION_HOSTNAME=<GITLAB_URL>
4feb7f 260 NAMESPACE=<YOUR_NAME>-ci-cd
92099a 261 ```
D 262 where the following need to be replaced by actual values:
263     * `<BIND_USER>` is the user used to query the LDAP
264     * `<BIND_USER_PASSWORD>` is the password used when querying the LDAP
265     * `<YOUR_DOMAIN>` is the domain the LDAP is hosted on
266     * `<LDAP_HOST>` is fqdn of the LDAP server
267     * `<LDAP_DESCRIPTION>` is the description to be used on the sign-in header for GitLab eg "Name LDAP Login"
268     * `<GITLAB_ROOT_USER_PASSWORD>` is the root user for GOD access on the GitLab instance eg password123
269     * `<GITLAB_URL>` is the endpoint for gitlab. It will take the form `gitlab-<YOUR_NAME>-ci-cd.apps.<ENV_ID>.<YOUR_DOMAIN>.com`
270
fd78e6 271 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
92099a 272 ```yaml
1c9328 273     - name: "gitlab"
fd78e6 274       namespace: "{{ ci_cd_namespace }}"
D 275       template: "{{ playbook_dir }}/templates/gitlab.yml"
276       params: "{{ playbook_dir }}/params/gitlab"
1c9328 277       tags:
D 278       - gitlab
92099a 279 ```
D 280
281 4. Run the OpenShift applier, specifying the tag `gitlab` to speed up it's execution.
282 ```bash
784073 283 ansible-playbook apply.yml -e target=tools \
92099a 284      -i inventory/ \
1c9328 285      -e "filter_tags=gitlab"
92099a 286 ```
D 287
1c9328 288 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)
784073 289
D 290 #### 3b - Commit CI/CD
4feb7f 291
4c20f0 292 4. Navigate to gitlab (if you have just skipped straight to this step; ask your tutor for the URL). You can login using your cluster credentials using the LDAP tab
1c9328 293 ![gitlab-ui](../images/exercise1/gitlab-ui.png)
4feb7f 294
4c20f0 295 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.
1c9328 296 ![gitlab-new-project](../images/exercise1/gitlab-new-project.png)
D 297 <p class="tip">
d28811 298 Note - we would not normally make the project under your name but create an group and add the project there on residency but for simplicity of the exercise we'll do that here
1c9328 299 </p>
D 300
784073 301 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, substitution your email and "Your Name". If you've done this before move on to the next step.
1c9328 302 ```bash
784073 303 git config --global user.email "yourname@mail.com"
1c9328 304 ```
784073 305 ```bash
D 306 git config --global user.name "Your Name"
307 ```
308
a6d2e9 309 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.
784073 310 ```bash
D 311 git remote set-url origin <GIT_URL>
312 ```
313 ```bash
314 git add .
315 ```
316 ```bash
317 git commit -m "Adding git and nexus config"
318 ```
319 ```bash
320 git push -u origin --all
321 ```
322
a9627c 323 #### 5 MongoDB for CI tests
D 324 > 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.
325
326 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.
327 ```bash
328 git checkout exercise3/mongodb params/mongodb templates/mongodb.yml
329 ```
330
331 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-builds` section.
332 ```yaml
333   - name: "jenkins-mongodb"
334     namespace: "{{ ci_cd_namespace }}"
335     template: "{{ playbook_dir }}/templates/mongodb.yml"
336     params: "{{ playbook_dir }}/params/mongodb"
337     tags:
338     - mongodb
339 ```
340 ![jenkins-mongo](../images/exercise3/jenkins-mongo.png)
341
342 4. Git commit your updates to the inventory to git for traceability.
343 ```bash
344 git add .
345 ```
346 ```bash
347 git commit -m "ADD - mongodb for use in the pipeline"
348 ```
349 ```bash
350 git push
351 ```
352
353 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! 
354 ```bash
355 ansible-playbook apply.yml -e target=tools \
356   -i inventory/ \
357   -e "filter_tags=mongodb"
358 ```
359 ![ocp-mongo](../images/exercise3/ocp-mongo.png)
360
5cf97a 361 **Note - When making changes to enablement-ci-cd you should frequently commit the changes to git.**
bd7806 362
a9627c 363 ### Part 6 - Jenkins & s2i
d28811 364 > _Create a build and deployment config for Jenkins. Add new configuration and plugins to the OCP Stock Jenkins using s2i_
bd7806 365
1c9328 366 5. Add the Jenkins Build & Deployment configs to the `enablement-ci-cd` repo by merging the contents `exercise1/jenkins` in
D 367 ```bash
784073 368 git checkout exercise1/jenkins templates/jenkins.yml
1c9328 369 ```
D 370 The Jenkins template is essentially the standard persistent jenkins one with OpenShift.
371
a7a123 372 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 373 ```
1c9328 374 MEMORY_LIMIT=8Gi
1adb94 375 VOLUME_CAPACITY=10Gi
1c9328 376 JVM_ARCH=x86_64
D 377 NAMESPACE=<YOUR_NAME>-ci-cd
378 JENKINS_OPTS=--sessionTimeout=720
379 ```
fd78e6 380
a7a123 381 5. Add a `jenkins` variable to the ansible inventory underneath the nexus (and git if you have it) in  `inventory/host_vars/ci-cd-tooling.yml`.
1c9328 382 ```yaml
D 383     - name: "jenkins"
fd78e6 384       namespace: "{{ ci_cd_namespace }}"
D 385       template: "{{ playbook_dir }}/templates/jenkins.yml"
386       params: "{{ playbook_dir }}/params/jenkins"
1c9328 387       tags:
D 388       - jenkins
389 ```
11198f 390 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.
1c9328 391
D 392 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
393 ```bash
784073 394 git checkout exercise1/jenkins-s2i jenkins-s2i
1c9328 395 ```
a7a123 396 The structure of the jenkins s2i config is
1c9328 397 ```
D 398 jenkins-s2i
399 ├── README.md
400 ├── configuration
401 │   ├── build-failure-analyzer.xml
402 │   ├── init.groovy
403 │   ├── jenkins.plugins.slack.SlackNotifier.xml
a7a123 404 │   ├── scriptApproval.xml
1c9328 405 │   └── jobs
D 406 │       └── seed-multibranch-job
407 │           └── config.xml
408 └── plugins.txt
409 ```
410  * `plugins.txt` is a list of `pluginId:version` for Jenkins to pre-install when starting
411  * `./configuration` contains content that is placed in `${JENKINS_HOME}`. A `config.xml` could be placed in here to control the bulk of Jenkins configuration.
412  * `./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.
d28811 413  * `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.
1c9328 414  * `init.groovy` contains a collection of settings jenkins configures itself with when launching
D 415
a7a123 416 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 
1c9328 417 ```txt
D 418 greenballs:1.15
419 ``` 
420 ![green-balls.png](../images/exercise1/green-balls.png)
421 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/)
422
5cf97a 423 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. 
RH 424 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
1c9328 425 ```groovy
D 426 gitUsername = System.getenv("GIT_USERNAME") ?: "<USERNAME>"
427 gitPassword = System.getenv("GIT_PASSWORD") ?: "<PASSWORD>"
428 ```
a7a123 429 <p class="tip">
D 430 Note in a residency we would not use your GitCredentials for pushing and pulling from Git, A service user would be created for this.
431 </p>
1c9328 432
afef19 433 5. Checkout the params and the templates for the `jenkins-s2i`
a7a123 434 ```bash
784073 435 git checkout exercise1/jenkins-s2i params/jenkins-s2i templates/jenkins-s2i.yml
a7a123 436 ```
D 437
438 5. Open `params/jenkins-s2i` and add the following content; replacing variables as appropriate. 
1c9328 439 ```
e23af1 440 SOURCE_REPOSITORY_URL=<GIT_URL>
1c9328 441 NAME=jenkins
D 442 SOURCE_REPOSITORY_CONTEXT_DIR=jenkins-s2i
443 IMAGE_STREAM_NAMESPACE=<YOUR_NAME>-ci-cd
e23af1 444 SOURCE_REPOSITORY_USERNAME=<YOUR_LDAP_USERNAME>
D 445 SOURCE_REPOSITORY_PASSWORD=<YOUR_LDAP_PASSWORD>
1c9328 446 ```
D 447 where 
e23af1 448     * `<GIT_URL>` is the full path clone path of the repo where this project is stored (including the https && .git)
d28811 449     * `<YOUR_NAME>` is the prefix for your `-ci-cd` project.
D 450     * Explore some of the other parameters in `templates/jenkins-s2i.yml`
e23af1 451     * `<YOUR_LDAP_USERNAME>` is the username builder pod will use to login and clone the repo with
D 452     * `<YOUR_LDAP_PASSWORD>` is the password the builder pod will use to authenticate and clone the repo using
d28811 453 <p class="tip">
e23af1 454 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.
d28811 455 </p>
1c9328 456
fd78e6 457 5. Create a new object `ci-cd-builds` in the ansible `inventory/host_vars/ci-cd-tooling.yml` to drive the s2i build configuration.
1c9328 458 ```yaml
D 459   - object: ci-cd-builds
460     content:
461     - name: "jenkins-s2i"
fd78e6 462       namespace: "{{ ci_cd_namespace }}"
D 463       template: "{{ playbook_dir }}/templates/jenkins-s2i.yml"
464       params: "{{ playbook_dir }}/params/jenkins-s2i"
1c9328 465       tags:
D 466       - jenkins
467 ```
468
469 5. Commit your code to your GitLab instance
470 ```bash
784073 471 git add .
D 472 ```
473 ```bash
474 git commit -m "Adding Jenkins and Jenkins s2i"
475 ```
476 ```bash
477 git push
1c9328 478 ```
D 479
480 5. When your code is commited; run the OpenShift Applier to add the config to the cluster
481 ```bash
784073 482 ansible-playbook apply.yml -e target=tools \
1c9328 483      -i inventory/ \
D 484      -e "filter_tags=jenkins"
485 ```
486
d28811 487 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 488 ![jenkins-s2i-log](../images/exercise1/jenkins-s2i-log.png)
bd7806 489
d28811 490 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
92099a 491
a9627c 492 ### Part 7 - Jenkins Hello World 
d28811 493 > _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 494
495 6. Log in to Jenkins and hit `New Item` ![new-item](../images/exercise1/new-item.png).
496
176e08 497 6. Create a freestyle job called `hello-world` ![jenkins-new-hello-world](../images/exercise1/jenkins-new-hello-world.png).
d28811 498
11198f 499 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)
d28811 500
D 501 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).
502
503 6. Run the build and we should see if pass succesfully and with Green Balls! ![jenkins-green-balls](../images/exercise1/jenkins-green-balls.png)
504
a9627c 505 ### Part 8 - Live, Die, Repeat
9eed0b 506 > _In this section you will proove the infra as code is working by deleting your Cluster Content and recreating it all_
d28811 507
D 508 7. Commit your code to the new repo in GitLab
9eed0b 509 ```bash
784073 510 git add .
D 511 ```
512 ```bash
513 git commit -m "ADD - all ci/cd contents"
514 ```
515 ```bash
516 git push
9eed0b 517 ```
d28811 518
D 519 7. Burn your OCP content to the ground
9eed0b 520 ```bash
784073 521 oc delete project <YOUR_NAME>-ci-cd
D 522 ```
523 ```bash
524 oc delete project <YOUR_NAME>-dev
525 ```
526 ```bash
527 oc delete project <YOUR_NAME>-test
9eed0b 528 ```
d28811 529
e23af1 530 7. Check to see the projects that were marked for deletion are removed.
D 531 ```bash
784073 532 oc get projects | egrep '<YOUR_NAME>-ci-cd|<YOUR_NAME>-dev|<YOUR_NAME>-test'
e23af1 533 ```
D 534
9eed0b 535 7. Re-apply the inventory to re-create it all!
D 536 ```bash
a9627c 537 oc login https://console.lader.rht-labs.com
784073 538 ```
D 539 ```bash
540 ansible-playbook apply.yml -i inventory/ -e target=bootstrap
541 ```
542 ```bash
543 ansible-playbook apply.yml -i inventory/ -e target=tools
9eed0b 544 ```
0f4d08 545
74d1f1 546 _____
D 547
0f4d08 548 ## Extension Tasks
d28811 549 > _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._
0f4d08 550
a9627c 551  - Install Cowsay for 100% more Ansible Fun!
92099a 552  - Add more secure access for Nexus (ie not admin / admin123) using the automation to drive secret creation
1c9328 553  - Add a SonarQube persistent deployment to the `ci-cd-deployments` section.
D 554  - Add `jenkins.plugins.slack.SlackNotifier.xml` to `jenkins-s2i/configuration` to include URL of Slack for team build notifications and rebuild Jenkins S2I
0f4d08 555
74d1f1 556 _____
D 557
0f4d08 558 ## Additional Reading
9eed0b 559 > List of links or other reading that might be of use / reference for the exercise
4f0295 560
RH 561 ## Slide links
562
563 - [Intro](https://docs.google.com/presentation/d/1LsfAkH8GfIhulEoy_yd-usWBfDHnZEyQdNvYeTmAg4A/)
564 - [Wrap-up](https://docs.google.com/presentation/d/1cfyJ6SHddZNbM61oz67r870rLYVKY335zGclXN2uLMY/)
3207b9 565 - [All Material](https://drive.google.com/drive/folders/13Bt4BXf9P2OB8VI4YQNcNONF1786dqOx)