donal
2018-04-17 b921353e5ab3436b0ddaa10bd852b55433c8ad5e
commit | author | age
74d1f1 1 # The Manual Menace
0f4d08 2
74d1f1 3 > In this lab learners will use Ansible to drive automated provisioning of Projects, Access Control, Git, Jenkins and Nexus
D 4
5 _____
0f4d08 6
D 7 ## Learning Outcomes
8 As a learner you will be able to
74d1f1 9
D 10 1. Run the OpenShift Applier to automate creating cluster content
11 1. Create and admin project namespaces in OpenShift
12 1. Deploy commonly used applications to support the development process
0f4d08 13
D 14 ## Tools and Frameworks
15
74d1f1 16 * [GitLab](https://about.gitlab.com/) - Community driven Git server now with integrated DevOps Toolchain.
D 17 * [Nexus](https://www.sonatype.com/nexus-repository-sonatype) - Repository manager for storing lots of application types. Can also host `npm` and `Docker` registries.
18 * [Jenkins](https://jenkins.io/) - OpenSource Build automation server. Highly customisable with plugins.
19 * [Ansible](https://www.ansible.com/) - IT Automation tool used to provision and manage state of cloud and physical infrastructure.
b4d469 20 * [OpenShift Applier](https://github.com/redhat-cop/openshift-applier) - used to apply OpenShift objects to an OpenShift Cluster.
A 21
22
0f4d08 23
74d1f1 24 ## Big Picture
D 25 This exercise begins with an empty Cluster
26 > TODO - add big picture here...
27
28 _____
0f4d08 29
D 30 ## 10,000 Ft View
74d1f1 31 > This lab 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.
D 32
33 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:
34
4bf3e6 35 2. Clone the repo `https://github.com/rht-labs/enablement-ci-cd` which contains the scaffold of the project.
92099a 36
74d1f1 37 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
92099a 38
D 39 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 40     * Nexus
D 41     * GitLab
92099a 42     * Jenkins (using an s2i to pre-configure jenkins)
D 43
74d1f1 44 2. Commit your `enablement-ci-cd` repository to the GitLab Instance you've created
92099a 45
D 46 2. Burn it all down and re-apply your inventory proving config-as-code works. 
0f4d08 47
D 48 ## Step by Step Instructions
bd7806 49 > This is a structured guide with references to exact filenames and explanations.
0f4d08 50
bd7806 51 ### Part 1 - Create OpenShift Projects
d28811 52 > _Using the OpenShift Applier, we will add new project namespaces to the cluster which will be used throughout the exercise._
D 53
2a3d5b 54 3. Clone the scaffold project to your local machine and pull all remote branches for use in later labs. Open the repo in your favourite editor.
bd7806 55 ```bash
2a3d5b 56 $ git clone https://github.com/rht-labs/enablement-ci-cd && cd enablement-ci-cd
RH 57 ```
58 Followed by;
59 ```
60 $ for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do
61    git branch --track ${branch#remotes/origin/} $branch
62 done
0f4d08 63 ```
D 64
bd7806 65 3. The project is laid out as follows
D 66 ```
67 .
68 ├── README.md
fd78e6 69 ├── apply.yml
bd7806 70 ├── docker
fd78e6 71 │   └── jenkins-slave-npm
bd7806 72 ├── inventory
fd78e6 73 │   ├── host_vars
D 74 │   │   ├── ci-cd-tooling.yml
75 │   │   └── projects-and-policies.yml
76 │   └── hosts
bd7806 77 ├── jenkins-s2i
D 78 ├── params
fd78e6 79 │   └── project-requests-ci-cd
bd7806 80 ├── requirements.yml
D 81 └── templates
fd78e6 82     └── project-requests.yml
bd7806 83 ```
D 84  * `docker` folder contains our jenkins-slave images that will be used by the builds.
85  * `jenkins-s2i` contains the configuration and plugins we want to bring jenkins to life with
86  * `params` houses the variables we will load the templates with
87  * `templates` is a collection of OpenShift templates
fd78e6 88  * `inventory/host_vars/*.yml` is the collection of objects we want to insert into the cluster.
bd7806 89  * `requirements.yml` is a manifest which contains the ansible modules needed to run the playbook
fd78e6 90  * `apply.yml` is a playbook that sets up some variables and runs the OpenShift Applier role.
bd7806 91
fd78e6 92 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. For example; my name is Dónal so I've created: 
D 93 ```yaml
94   vars:
95     ci_cd_namespace: donal-ci-cd
96     dev_namespace: donal-dev
97     test_namespace: donal-test
98 ```
99
100 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
101
102 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 103 ![new-item](../images/exercise1/ci-cd-project-namespace.png)
bd7806 104
fd78e6 105 3. Let's add two more param files to pass to our template to be able to create a `dev` and `test` project.
D 106   * Create another two params files `params/project-requests-dev` & `params/project-requests-test`. 
107   * Add to `params/project-requests-dev` the following; substituting `<YOUR_NAME>` accordingly
108 ```
109 NAMESPACE=<YOUR_NAME>-dev
110 NAMESPACE_DISPLAY_NAME=<YOUR-NAME> Dev
111 ```
112   * Add to `params/project-requests-test` the following; substituting `<YOUR_NAME>` accordingly
113 ```
114 NAMESPACE=<YOUR_NAME>-test
115 NAMESPACE_DISPLAY_NAME=<YOUR-NAME> Test
116 ```
bd7806 117
fd78e6 118 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 119 ```yaml
fd78e6 120     - name: "{{ dev_namespace }}"
D 121       template: "{{ playbook_dir }}/templates/project-requests.yml"
1c9328 122       template_action: create
fd78e6 123       params: "{{ playbook_dir }}/params/project-requests-dev"
1c9328 124       tags:
D 125       - projects
fd78e6 126     - name: "{{ test_namespace }}"
D 127       template: "{{ playbook_dir }}/templates/project-requests.yml"
1c9328 128       template_action: create
fd78e6 129       params: "{{ playbook_dir }}/params/project-requests-test"
1c9328 130       tags:
D 131       - projects
bd7806 132 ```
1c9328 133 ![project-request-yaml](../images/exercise1/project-request-yml.png)
bd7806 134
D 135 3. With the configuration in place; install the OpenShift Applier dependency
136 ```bash
137 $ ansible-galaxy install -r requirements.yml --roles-path=roles
138 ```
139
11198f 140 3. Apply the inventory by logging into OpenShift and running the following: 
bd7806 141 ```bash
D 142 $ oc login -p <password> -u <user> <cluster_url>
fd78e6 143 $ ansible-playbook apply.yml -i inventory/ -e target=bootstrap
D 144 ```
145 where the `-e target=bootstrap` is passing an additional variable specifying that we run the `bootstrap` inventory
bd7806 146
11198f 147 3. Once successful you should see an output similar to this: ![playbook-success](../images/exercise1/play-book-success.png)
bd7806 148
D 149 ### Part 2 - Nexus and GitLab
da55a5 150 > _Now that we have our Projects setup; we can start to populate them with Apps to be used in our dev lifecycle_
bd7806 151
fdaee0 152 #### Part 2a - Nexus
92099a 153 4. In the `enablement-ci-cd` repo, checkout the templates for Nexus by running
da55a5 154 ```bash
92099a 155 $ git checkout exercise1/git-nexus templates/nexus.yml
D 156 ```
11198f 157 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 158
D 159 4. Add some parameters for running the template by creating a new file in the `params` directory. 
160 ```bash
161 $ touch params/nexus
da55a5 162 ```
D 163
92099a 164 4. The essential params to inclue in this file are: `params` directory. 
D 165 ```bash
166 VOLUME_CAPACITY=5Gi
167 MEMORY_LIMIT=2Gi
168 ```
169
fd78e6 170 4. Create a new object in the inventory variables `inventory/host_vars/ci-cd-tooling.yml` called `ci-cd-deployments` and populate it's `content` is as follows
D 171
92099a 172 ```yaml
fd78e6 173 ---
D 174 ansible_connection: local
175 openshift_cluster_content:
176 - object: ci-cd-tooling
177   content:
1c9328 178     - name: "nexus"
fd78e6 179       namespace: "{{ ci_cd_namespace }}"
D 180       template: "{{ playbook_dir }}/templates/nexus.yml"
181       params: "{{ playbook_dir }}/params/nexus"
1c9328 182       tags:
D 183       - nexus
92099a 184 ```
1c9328 185 ![ci-cd-deployments-yml](../images/exercise1/ci-cd-deployments-yml.png)
92099a 186
b92135 187 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 188 ```bash
b92135 189 $ ansible-playbook apply.yml -e target=tools \
92099a 190      -i inventory/ \
1c9328 191      -e "filter_tags=nexus"
92099a 192 ```
D 193
3acbf0 194 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 195
fdaee0 196 #### Part 2b - GitLab
D 197 <p class="tip">
198 NOTE - This section may already have been completed for you, please check with your tutor. If this is the case, skip to section 6 to add your code to GitLab.
199 </p>
200
11198f 201 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 202 ```bash
de26e3 203 $ git checkout exercise1/git-nexus templates/gitlab.yml params/gitlab
92099a 204 ``` 
D 205 Explore the template; it contains the PVC, buildConfig and services. The DeploymentConfig is made up of these apps
206  - Redis (3.2.3)
207  - PostgreSQL (9.4)
208  - GitLab CE (v10.2.3)
209
3acbf0 210 4. Open the `params/gitlab` file and complete the following params
RH 211 <p class="tip">
212 Note - The values here for the LDAP and BIND credentials will be provided by your tutor.
213 </p>
92099a 214 ```
D 215 LDAP_BIND_DN=uid=<BIND_USER>,ou=People,dc=<YOUR_DOMAIN>,dc=com
216 LDAP_USER_FILTER=(memberof=CN=YourGroup,OU=Users,DC=<YOUR_DOMAIN>,DC=com)
217 LDAP_PASSWORD=<BIND_USER_PASSWORD>
218 LDAP_HOST=<LDAP_HOST>
219 LDAP_BASE=ou=People,dc=<YOUR_DOMAIN>,dc=com
220 LDAP_LABEL="<LDAP_DESCRIPTION>"
221 GITLAB_ROOT_PASSWORD=<GITLAB_ROOT_USER_PASSWORD>
222 GITLAB_DATA_VOL_SIZE=2Gi
223 POSTGRESQL_VOL_SIZE=1Gi
224 APPLICATION_HOSTNAME=<GITLAB_URL>
4feb7f 225 NAMESPACE=<YOUR_NAME>-ci-cd
92099a 226 ```
D 227 where the following need to be replaced by actual values:
228     * `<BIND_USER>` is the user used to query the LDAP
229     * `<BIND_USER_PASSWORD>` is the password used when querying the LDAP
230     * `<YOUR_DOMAIN>` is the domain the LDAP is hosted on
231     * `<LDAP_HOST>` is fqdn of the LDAP server
232     * `<LDAP_DESCRIPTION>` is the description to be used on the sign-in header for GitLab eg "Name LDAP Login"
233     * `<GITLAB_ROOT_USER_PASSWORD>` is the root user for GOD access on the GitLab instance eg password123
234     * `<GITLAB_URL>` is the endpoint for gitlab. It will take the form `gitlab-<YOUR_NAME>-ci-cd.apps.<ENV_ID>.<YOUR_DOMAIN>.com`
235
fd78e6 236 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 237 ```yaml
1c9328 238     - name: "gitlab"
fd78e6 239       namespace: "{{ ci_cd_namespace }}"
D 240       template: "{{ playbook_dir }}/templates/gitlab.yml"
241       params: "{{ playbook_dir }}/params/gitlab"
1c9328 242       tags:
D 243       - gitlab
92099a 244 ```
D 245
246 4. Run the OpenShift applier, specifying the tag `gitlab` to speed up it's execution.
247 ```bash
b92135 248 $ ansible-playbook apply.yml -e target=tools \
92099a 249      -i inventory/ \
1c9328 250      -e "filter_tags=gitlab"
92099a 251 ```
D 252
1c9328 253 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)
4feb7f 254
de26e3 255 4. Navigate to gitlab. You can login using your cluster credentials using the LDAP tab displaying your `<LDAP_DESCRIPTION>` from previous steps
1c9328 256 ![gitlab-ui](../images/exercise1/gitlab-ui.png)
4feb7f 257
d28811 258 4. Once logged in create a new project called `enablement-ci-cd` and mark it as internal. Once created; copy out the `git remote add origin ...` instructions for use on the next step.
1c9328 259 ![gitlab-new-project](../images/exercise1/gitlab-new-project.png)
D 260 <p class="tip">
d28811 261 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 262 </p>
D 263
264 4. Commit your local project to this new origin by first removing the existing origin (github) where the the project was cloned from. Remember to substitute `<YOUR_NEW_GIT_PROJECT>` accordingly
265 ```bash
5cf97a 266 $ git remote set-url origin <YOUR_NEW_GIT_PROJECT>
1c9328 267 $ git add . 
D 268 $ git commit -m "Adding git and nexus config"
269 $ git push -u origin --all
270 ```
5cf97a 271 **Note - When making changes to enablement-ci-cd you should frequently commit the changes to git.**
bd7806 272
D 273 ### Part 3 - Jenkins & s2i
d28811 274 > _Create a build and deployment config for Jenkins. Add new configuration and plugins to the OCP Stock Jenkins using s2i_
bd7806 275
1c9328 276 5. Add the Jenkins Build & Deployment configs to the `enablement-ci-cd` repo by merging the contents `exercise1/jenkins` in
D 277 ```bash
278 $ git checkout exercise1/jenkins templates/jenkins.yml
279 ```
280 The Jenkins template is essentially the standard persistent jenkins one with OpenShift.
281
282 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 `NAMESPACE` value.
283 ```bash
284 MEMORY_LIMIT=8Gi
285 VOLUME_CAPACITY=5Gi
286 JVM_ARCH=x86_64
287 NAMESPACE=<YOUR_NAME>-ci-cd
288 JENKINS_OPTS=--sessionTimeout=720
289 ```
fd78e6 290
D 291 5. Add a `jenkins` variable to the ansible inventory underneath the git (if you have it) and nexus ones.
1c9328 292 ```yaml
D 293     - name: "jenkins"
fd78e6 294       namespace: "{{ ci_cd_namespace }}"
D 295       template: "{{ playbook_dir }}/templates/jenkins.yml"
296       params: "{{ playbook_dir }}/params/jenkins"
1c9328 297       tags:
D 298       - jenkins
299 ```
11198f 300 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 301
D 302 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
303 ```bash
304 $ git checkout exercise1/jenkins-s2i jenkins-s2i
305 ```
306 The structure of the jenkins s2i config is 
307 ```
308 jenkins-s2i
309 ├── README.md
310 ├── configuration
311 │   ├── build-failure-analyzer.xml
312 │   ├── init.groovy
313 │   ├── jenkins.plugins.slack.SlackNotifier.xml
314 │   └── jobs
315 │       └── seed-multibranch-job
316 │           └── config.xml
317 └── plugins.txt
318 ```
319  * `plugins.txt` is a list of `pluginId:version` for Jenkins to pre-install when starting
320  * `./configuration` contains content that is placed in `${JENKINS_HOME}`. A `config.xml` could be placed in here to control the bulk of Jenkins configuration.
321  * `./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 322  * `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 323  * `init.groovy` contains a collection of settings jenkins configures itself with when launching
D 324
325 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 `plugins.txt` file with 
326 ```txt
327 greenballs:1.15
328 ``` 
329 ![green-balls.png](../images/exercise1/green-balls.png)
330 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/)
331
5cf97a 332 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 333 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 334 <p class="tip">
d28811 335 Note in a residency we would not use your GitCredentials for pushing and pulling from Git, A service user would be created for this.
1c9328 336 </p>
D 337 ```groovy
338 gitUsername = System.getenv("GIT_USERNAME") ?: "<USERNAME>"
339 gitPassword = System.getenv("GIT_PASSWORD") ?: "<PASSWORD>"
340 ```
341
d28811 342 5. Open the `params/jenkins-s2i` file and add the following content; replacing variables as appropriate. 
1c9328 343 ```
D 344 SOURCE_REPOSITORY_URL=<YOUR_ENABLEMENT_REPO>
345 NAME=jenkins
346 SOURCE_REPOSITORY_CONTEXT_DIR=jenkins-s2i
347 IMAGE_STREAM_NAMESPACE=<YOUR_NAME>-ci-cd
5cf97a 348 SOURCE_REPOSITORY_USERNAME=<BASE64_YOUR_LDAP_USERNAME>
RH 349 SOURCE_REPOSITORY_PASSWORD=<BASE64_YOUR_LDAP_PASSWORD>
1c9328 350 ```
D 351 where 
d28811 352     * `<YOUR_ENABLEMENT_REPO>` is the full path clone path of the repo where this project is stored (including the https && .git)
D 353     * `<YOUR_NAME>` is the prefix for your `-ci-cd` project.
354     * Explore some of the other parameters in `templates/jenkins-s2i.yml`
5cf97a 355     * `<BASE64_YOUR_LDAP_USERNAME>` is the base64encoded username builder pod will use to login and clone the repo with
RH 356     * `<BASE64_YOUR_LDAP_PASSWORD>` is the base64encoded password the builder pod will use to authenticate and clone the repo using
11198f 357 You can use `echo -n '<YOUR_LDAP_PASSWORD>' | openssl base64` to encode your username and password accordingly. For example 'password' base64 encoded will look like `cGFzc3dvcmQ=`.
d28811 358 <p class="tip">
D 359 Note in a residency we would not use your GitCredentials for pushing and pulling from Git, A service user would be created for this.
360 </p>
1c9328 361
fd78e6 362 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 363 ```yaml
D 364   - object: ci-cd-builds
365     content:
366     - name: "jenkins-s2i"
fd78e6 367       namespace: "{{ ci_cd_namespace }}"
D 368       template: "{{ playbook_dir }}/templates/jenkins-s2i.yml"
369       params: "{{ playbook_dir }}/params/jenkins-s2i"
1c9328 370       tags:
D 371       - jenkins
372 ```
373
374 5. Commit your code to your GitLab instance
375 ```bash
d28811 376 $ git add .
1c9328 377 $ git commit -m "Adding Jenkins and Jenkins s2i"
D 378 $ git push
379 ```
380
381 5. When your code is commited; run the OpenShift Applier to add the config to the cluster
382 ```bash
b92135 383 $ ansible-playbook apply.yml -e target=tools \
1c9328 384      -i inventory/ \
D 385      -e "filter_tags=jenkins"
386 ```
387
d28811 388 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 389 ![jenkins-s2i-log](../images/exercise1/jenkins-s2i-log.png)
bd7806 390
d28811 391 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 392
d28811 393 ### Part 4 - Jenkins Hello World 
D 394 > _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._
395
396 6. Log in to Jenkins and hit `New Item` ![new-item](../images/exercise1/new-item.png).
397
176e08 398 6. Create a freestyle job called `hello-world` ![jenkins-new-hello-world](../images/exercise1/jenkins-new-hello-world.png).
d28811 399
11198f 400 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 401
D 402 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).
403
404 6. Run the build and we should see if pass succesfully and with Green Balls! ![jenkins-green-balls](../images/exercise1/jenkins-green-balls.png)
405
406 ### Part 5 - Live, Die, Repeat
407 > _TOOD - improve & flesh out this section ...._
408
409 7. Commit your code to the new repo in GitLab
410
411 7. Burn your OCP content to the ground
412
413 7. Re-apply the inventory!
0f4d08 414
74d1f1 415 _____
D 416
0f4d08 417 ## Extension Tasks
d28811 418 > _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 419
92099a 420  - Add more secure access for Nexus (ie not admin / admin123) using the automation to drive secret creation
1c9328 421  - Add a SonarQube persistent deployment to the `ci-cd-deployments` section.
D 422  - Add `jenkins.plugins.slack.SlackNotifier.xml` to `jenkins-s2i/configuration` to include URL of Slack for team build notifications and rebuild Jenkins S2I
0f4d08 423
74d1f1 424 _____
D 425
0f4d08 426 ## Additional Reading
D 427  > List of links or other reading that might be of use / reference for the exercise