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