donal
2018-04-26 abb5b10c6bc01f5e78918d93751724deccceb033
commit | author | age
b586be 1 # An Enslaved Hope
5a16fd 2
d43408 3 > In this exercise we'll break free from the chains of point'n'click Jenkins by introducing pipeline as code in the form of `Jenkinsfile`. Following this we will introduce some new Jenkins slaves that will be used in later labs. 
b586be 4
D 5 There are a number of ways pipeline as code can be achieved in Jenkins.
6  * The Job DSL Plugin - this is a slightly older but very functional DSL mechanism to create reusable pipelines. Create a `groovy` file to run Jenkins Domain Specific Language to create jobs, functions and other items. In Jenkins; you then can execute this file which will build all of the config.xml files needed for each Job. 
d43408 7  * The Scripted Pipeline - The scripted pipeline introduced the Jenkinsfile and the ability for developers to write their jenkins setup as groovy code. A repo with a Jenkinsfile in it's root can be pointed to by Jenkins and it will automatically build out each of the stages described within. The scripted pipeline is ultimately Groovy at it's core.
A 8  * The Declarative Pipeline - This approach looks to simplify and opinionate what you can do and when you can do it in a pipeline. It does this by giving you top level `block` which define sections, directives and steps. The declarative syntax is not run as groovy but you can execute groovy inside script blocks. The advantage of it over scripted is validation of the config and lighter approach with requirement to understand all of the `groovy` syntax
b586be 9
5a16fd 10 _____
D 11
12 ## Learning Outcomes
13 As a learner you will be able to
b586be 14 - Use a Jenkinsfile to create a declarative pipeline to build, bake and deploy the Todolist App 
D 15 - Identify the differences between scripted, declarative and DSL pipelines 
16 - Create Jenkins slave nodes for use in builds in future labs
5a16fd 17
D 18 ## Tools and Frameworks
19 > Name of tool - short description and link to docs or website
20
b586be 21 1. [Pipeline](https://jenkins.io/doc/book/pipeline/) - Overview of the Jenkinsfile approach
D 22 1. [Pipeline Syntax](https://jenkins.io/doc/book/pipeline/syntax/) - Documentation for the declarative pipeline
23 1. [Groovy](http://groovy-lang.org/) - Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming.
3fdb03 24 1. [Zed Attack Proxy](https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project) - The OWASP Zed Attack Proxy (ZAP) is one of the world’s most popular free security tools and is actively maintained by hundreds of international volunteers*. It can help you automatically find security vulnerabilities in your web applications while you are developing and testing your applications. Its also a great tool for experienced pentesters to use for manual security testing.
D 25 1. [Arachni Crawler](http://www.arachni-scanner.com/) - Arachni is a feature-full, modular, high-performance Ruby framework aimed towards helping penetration testers and administrators evaluate the security of modern web applications. It is free, with its source code public and available for review. It is versatile enough to cover a great deal of use cases, ranging from a simple command line scanner utility, to a global high performance grid of scanners, to a Ruby library allowing for scripted audits, to a multi-user multi-scan web collaboration platform. In addition, its simple REST API makes integration a cinch.
5a16fd 26
D 27 ## Big Picture
28 This exercise begins cluster containing blah blah
29
30 _____
31
32 ## 10,000 Ft View
b586be 33 > The goal of this exercise is to move to using the Jenkinsfile in the todolist-api and todolist-fe projects. Additionally we will create new slaves for use in the next lab
5a16fd 34
b586be 35 2. On Jenkins; create a multibranch pipeline project to scan the GitLab endpoint for each app. Use the Jenkinsfile provided to run the stages. Replace the `<YOUR_NAME>` with appropriate variable.
5a16fd 36
b586be 37 2. Create two new Jenkins slaves for the `OWASP ZAP` scanner and the `Arachni` WebCrawler
5a16fd 38
D 39 ## Step by Step Instructions
b586be 40 > This is a fairly structured guide with references to exact filenames and sections of text to be added. 
5a16fd 41
b586be 42 ### Part 1 - The Jenkinsfile
D 43 > _In this exercise we'll replace the Pipeline we created in Lab 2 with a Jenkinsfile approach_
5a16fd 44
b586be 45 2. On your terminal navigate to your `todolist-api` project and checkout the pipeline feature branch that's been already created for you.
D 46 ```bash
47 $ git checkout feature/jenkinsfile
5a16fd 48 ```
D 49
b586be 50 2. Open up your `todolist-api` application in your favourite editor and move to the `Jenkinsfile` in the root of the project. The highlevel structure of the file is shown collapsed below. 
D 51 ![pipeline-overview](../images/exercise4/pipeline-overview.png)
52 Some of the key things to note:
53     * `pipeline {}` is how all declarative jenkins pipelines begin.
498e55 54     * `environment {}` defines environment variables to be used across all build stages
A 55     * `options {}` contains specific Job specs you want to run globally across the jobs e.g. setting the terminal colour
56     * `stage {}` all jobs must have one stage. This is the logical part of the build that will be executed e.g. `bake-image`
b586be 57     * `steps {}` each `stage` has one or more steps involved. These could be execute shell or git checkout etc.
D 58     * `agent {}` specifies the node the build should be run on eg `jenkins-slave-npm`
59     * `post {}` hook is used to specify the post-build-actions. Jenkins declarative provides very useful callbacks for `success`, `failure` and `always` which are useful for controlling the job flow
60     * `when {}` is used for flow control. It can be used at stage level and be used to stop pipeline entering that stage. eg when branch is master; deploy to `test` environment.
61
5965fd 62 2. The Jenkinsfile is mostly complete to do all the testing etc that was done in previous labs. Some minor changes will be needed to orchestrate namespaces. Find and replace all instances of `<YOUR_NAME>` in the Jenkinsfile. Update the `<GIT_USERNAME>` to the one you login to the cluster with; this variable is used in the namespace of your git projects when checking out code etc. Ensure the `GITLAB_DOMAIN` matches your git host.
b586be 63 ```groovy
D 64     environment {
65         // GLobal Vars
d43408 66         PIPELINES_NAMESPACE = "<YOUR_NAME>-ci-cd"
b586be 67         APP_NAME = "todolist-api"
D 68
69         JENKINS_TAG = "${JOB_NAME}.${BUILD_NUMBER}".replace("/", "-")
70         JOB_NAME = "${JOB_NAME}".replace("/", "-")
71
72         GIT_SSL_NO_VERIFY = true
73         GIT_CREDENTIALS = credentials('jenkins-git-creds')
5965fd 74         GITLAB_DOMAIN = "gitlab.apps.lader.rht-labs.com"
D 75         GITLAB_PROJECT = "<GIT_USERNAME>"
b586be 76     }
D 77 ```
78
79 2. With these changes in place, push your changes to the `feature/jenkinsfile` branch.
80 ```bash
81 $ git add Jenkinsfile
82 $ git commit -m "ADD - namespace and git repo to pipeline"
83 $ git push
84 ```
85
86 2. When the changes have been successfully pushed; Open Jenkins.
87
88 2. Create a `New Item` on Jenkins. Give it the name `todolist-api` and select `Multibranch Pipeline` from the bottom of the list as the job type.
89 ![multibranch-select](../images/exercise4/multibranch-select.png)
90
91 2. On the job's configure page; set the Branch Sources to `git`
92 ![multibranch-select-git](../images/exercise4/multibranch-select-git.png)
93
5965fd 94 2. Fill in the Git settings with your `todolist-api` GitLab url and set the credentials as you've done before.
b586be 95 ![multibranch-git](../images/exercise4/multibranch-git.png)
D 96
97 2. Set the `Scan Multibranch Pipeline Triggers` to be periodical and the internal to 1 minute. This will poll the gitlab instance for new branches or change sets to build.
98 ![multibranch-scan-time](../images/exercise4/multibranch-scan-time.png)
99
100 2. Save the Job configuration to run the intial scan. The log will show scans for `master` and `develop` branch which have no `Jenkinsfile` so are skipped. The resulting view will show the `feature/jenkisifle` job corresponding the only branch that currently has one. The build should run automatically. 
101 ![todolist-api-multi](../images/exercise4/todolist-api-multi.png)
102
abb5b1 103 2. The pipeline file is setup to only run `bake` & `deploy` stages when on `master` or `develop` branch. This is to provide us with very fast feedback for team members working on feature or bug fix branches. Each time someone commits or creates a new branch a basic build with testing occurs to give very rapid feedback to the team. Let's now update our  `master` and `develop` branches to include the Jenkinsfile and delete the feature branch.
b586be 104 ```bash
D 105 $ git checkout develop
106 $ git merge feature/jenkinsfile
abb5b1 107 # you may get merge conflicts at this point
D 108 $ git add .
109 $ git commit -m "Jenkinsfile updates"
b586be 110 $ git checkout master
D 111 $ git merge develop
112 $ git push -u origin --all
113 # this is to delete the branch from the remote
114 $ git push origin :feature/jenkinsfile
115 ```
116
117 2. Back on Jenkins we should see our `todolist-api` pipelines have changed with the `develop` and `master` now appearing. The feature was deleted so this job should have gone away.
118 ![todolist-api-multi-dev-test](../images/exercise4/todolist-api-multi-dev-test.png)
119
120 2. With the builds running for  `develop` and `master` we can explore the Blue Ocean View for Jenkins. On the Job overview page, hit the Open Blue Ocean ![open-blue-ocean](../images/exercise4/open-blue-ocean.png)
121  button on the side to see what modern Jenkins looks like.
122 ![blue-ocean-todolist-api](../images/exercise4/blue-ocean-todolist-api.png)
123
124 2.  We can move on to the `todolist-fe` job. The process is the same as before, checkout the feature branch
125 ```bash
126 $ cd todolist-fe
127 $ git checkout feature/jenkinsfile
128 ```
129
abb5b1 130 2. Open up your `todolist-fe` application in your favourite editor and move to the `Jenkinsfile` in the root of the project. Update all `<YOUR_NAME>` and `<GIT_USERNAME>` as you did before, including in the prepare environment steps. Check the  `GITLAB_DOMAIN` is set too. 
D 131 ![jenkinsfile-prep](../images/exercise4/jenkinsfile-prep.png)
b586be 132
D 133 2. Commit your changes to your feature branch as you did previously. 
134 ```bash
135 $ git add Jenkinsfile
136 $ git commit -m "ADD - namespace and git repo to pipeline"
137 $ git push
138 ```
139
140 2. This time update your master and develop branches before creating config in Jenkins
141 ```
abb5b1 142 $ git checkout develop
D 143 $ git merge feature/jenkinsfile
144 # you may get merge conflicts at this point
145 $ git add .
146 $ git commit -m "Jenkinsfile updates"
147 $ git checkout master
148 $ git merge develop
149 # this is to delete the branch from the remote
150 $ git push origin :feature/jenkinsfile
151 $ git push -u origin --all
b586be 152 ```
D 153
154 2. On Jenkins; create a new `Multibranch Pipeline` job called `todolist-fe`.
155
156 2. Add the `todolist-fe` git repository and set the credentials for git accordingly. 
157
158 2. Set the trigger to scan every minute as done previously. Save the configuration and we should see the collection of Jobs as shown below.
159 ![todolist-fe-multi](../images/exercise4/todolist-fe-multi.png)
160
6e5c07 161 2. Run the jobs and validate the app is working as expected in the `test` environment!
abb5b1 162 ![todolist-test](../images/exercise4/todolist-test.png)
40c2e4 163
D 164 ### Part 2 - OCP Pipeline
165 > _This exercise adds a new BuildConfig to our cluster for the todolist-apps to run their pipelines in OpenShift using the OpenShift Jenkins Sync Plugin. We will use the OpenShift Applier to create the content in the cluster_
166
17cc59 167 2. Open the `todolist-fe` app in your favourite editor. Move to the `.openshift-applier` directory. Explore the `template/ocp-pipeline`. This template creates a BuildConfig for OpenShift with a Jenkinsfile from a given repo. In this case; it will be the `Jenkinsfile` at the root of our application.
40c2e4 168
D 169 2. Open the `params/ocp-pipeline` file and update `PIPELINE_SOURCE_REPOSITORY_URL` with the git url of your project (Don't forget to add the `.git` at the end). For example:
170 ```
5965fd 171 PIPELINE_SOURCE_REPOSITORY_URL=https://gitlab.apps.lader.rht-labs.com/<GIT_USERNAME>/todolist-fe.git
40c2e4 172 PIPELINE_SOURCE_REPOSITORY_REF=develop
D 173 NAME=todolist-fe
174 ```
175
17cc59 176 2. Create a new object in `inventory/group_vars/all.yml` to drive the `ocp-pipeline` template with the parameters file you've just created. It can be put under the existing `todolist-fe-build` object.
40c2e4 177 ```yaml
D 178   - name: todolist-ocp-pipeline
179     template: "{{ playbook_dir }}/templates/ocp-pipeline.yml"
180     params: "{{ playbook_dir }}/params/ocp-pipeline"
181     namespace: "{{ ci_cd_namespace }}"
182     tags:
183     - pipeline
184 ```
185 ![ocp-pipeline-applier](../images/exercise4/ocp-pipeline-applier.png)
186
187 2. Use the OpenShift Applier to create the cluster content 
188 ```bash
189 $ cd .openshift-applier
190 $ ansible-playbook apply.yml -i inventory/ \
191      -e "filter_tags=pipeline"
192 ```
193
194 2. Login to your OpenShift Cluster and go to the `<YOUR_NAME>-ci-cd` namespace. On the side menu; hit Builds > Pipeline to see your newly created pipeline running in OCP Land.
195 ![ocp-pipeline-view](../images/exercise4/ocp-pipeline-view.png)
196
197 2. Running the pipeline from here will run it in Jenkins. You can see the job sync between OpenShift and Jenkins if you login to Jenkins. You should see a folder with `<YOUR_NAME>-ci-cd` and your pipeline jobs inside of it.
198 ![ocp-pipeline-jenkins](../images/exercise4/ocp-pipeline-jenkins.png)
199
200 2. With the configuration in place for the `todolist-fe`; repeat the process for the `todolist-api`. Update the `todolist-api/.openshift-applier/inventory/group_vars/all.yml` with a new object to drive the params and template
201 ```yaml
202     - name: todolist-ocp-pipeline
203     template: "{{ playbook_dir }}/templates/ocp-pipeline.yml"
204     params: "{{ playbook_dir }}/params/ocp-pipeline"
205     namespace: "{{ ci_cd_namespace }}"
206     tags:
207     - pipeline
208 ```
209
210 2. Update the `todolist-api/.openshift-applier/params/ocp-pipeline`
211 ```
5965fd 212 PIPELINE_SOURCE_REPOSITORY_URL=https://gitlab.apps.lader.rht-labs.com/<GIT_USERNAME>/todolist-api.git
40c2e4 213 PIPELINE_SOURCE_REPOSITORY_REF=develop
D 214 NAME=todolist-api
215 ```
216
217 2. Use the OpenShift Applier to create the cluster content 
218 ```bash
219 $ cd .openshift-applier
220 $ ansible-playbook apply.yml -i inventory/ \
221      -e "filter_tags=pipeline"
222 ```
223
224 2. Login to your OpenShift Cluster and go to the `<YOUR_NAME>-ci-cd` namespace. On the side menu; hit Builds > Pipeline to see your newly created pipeline running in OCP Land.
225 ![ocp-pipeline-view2](../images/exercise4/ocp-pipeline-view2.png)
226
227
228 ### Part 3 - Security Scanning Slaves
b586be 229 > _This exercise focuses on updating the `enablement-ci-cd` repo with some new jenkins-slave pods for use in future exercise_
5a16fd 230
40c2e4 231 #### Part 3a - OWASP ZAP
6e5c07 232 > _OWASP ZAP (Zed Attack Proxy) is a free open source security tool used for finding security vulnerabilities in web applications._
A 233
234
b6e034 235 3. First we're going to take the generic jenkins slave template from our exercise4/zap branch and the params.
6e5c07 236 ```bash
b6e034 237 $ git checkout exercise4/zap-and-arachni params/ templates/jenkins-slave-generic-template.yml 
6e5c07 238 ```
A 239
240 3. This should have created the following files:
b6e034 241     - `templates/jenkins-slave-generic-template.yml`
ccc1ac 242     - `params/jenkins-slave-zap` and `params/jenkins-slave-arachni`
6e5c07 243
ccc1ac 244 3. Create an object in `inventory/host_vars/ci-cd-tooling.yml` called `jenkins-slave-zap` and add the following content:
64ae3c 245 ```yaml
ccc1ac 246     - name: "jenkins-slave-zap"
3fdb03 247       namespace: "{{ ci_cd_namespace }}"
D 248       template: "{{ playbook_dir }}/templates/jenkins-slave-generic-template.yml"
ccc1ac 249       params: "{{ playbook_dir }}/params/jenkins-slave-zap"
3fdb03 250       tags:
D 251       - zap
6e5c07 252 ```
3fdb03 253 <p class="tip">
D 254 NOTE- Install your Openshift Applier dependency if it's disappeared.
255 ```
256 $ ansible-galaxy install -r requirements.yml --roles-path=roles
6e5c07 257 ```
b6e034 258 </p>
6e5c07 259
A 260 3. Run the ansible playbook filtering with tag `zap` so only the zap build pods are run.
261 ```bash
3fdb03 262 $ ansible-playbook apply.yml -e target=tools \
D 263      -i inventory/ \
264      -e "filter_tags=zap"
6e5c07 265 ```
A 266
ccc1ac 267 3. Head to (https://console.somedomain.com/console/project/<YOUR_NAME>-ci-cd/browse/builds) on Openshift and you should see `jenkins-slave-zap`.
6e5c07 268 include screenshot here.
A 269
40c2e4 270 #### Part 3b - Arachni Scan
6e5c07 271 > _Arachni is a feature-full, modular, high-performance Ruby framework aimed towards helping penetration testers and administrators evaluate the security of web applications._
A 272
ccc1ac 273 3. Create an object in `inventory/host_vars/ci-cd-tooling.yml` called `jenkins-slave-arachni` with the following content:
64ae3c 274 ```yaml
ccc1ac 275     - name: "jenkins-slave-arachni"
3fdb03 276       namespace: "{{ ci_cd_namespace }}"
D 277       template: "{{ playbook_dir }}/templates/jenkins-slave-generic-template.yml"
ccc1ac 278       params: "{{ playbook_dir }}/params/jenkins-slave-arachni"
3fdb03 279       tags:
D 280       - arachni
6e5c07 281 ```
A 282
b6e034 283 3. Run the ansible playbook filtering with tag `arachni` so only the arachni build pods are run.
6e5c07 284 ```bash
3fdb03 285 $ ansible-playbook apply.yml -e target=tools \
D 286      -i inventory/ \
287      -e "filter_tags=arachni"
6e5c07 288 ```
A 289
ccc1ac 290 3. Head to (https://console.somedomain.com/console/project/<YOUR_NAME>-ci-cd/browse/builds) on Openshift and you should see `jenkins-slave-arachni`.
64ae3c 291 ![todolist-fe-multi](../images/exercise4/builds-zap-arachni.png)
5a16fd 292
D 293 _____
294
295 ## Extension Tasks
296 > _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._
b586be 297
D 298 Jenkins S2I
299  - Add the multi-branch configuration to the S2I to have Jenkins come alive with the `todolist-api` and `-fe` configuration cooked into it for future uses.
300
9af076 301 Jenkins Pipeline Extension
D 302  - Add an extension to the pipeline that promotes code to UAT environment once the master job has been successful. 
303  - Use a WAIT to allow for manual input to appove the promotion
304
305 Jenkins e2e extension (blue/green)
498e55 306  - Add a step in the pipeline to only deploy to the `test` environment if the e2e tests have run successfully against which ever environment (blue or green) is not deployed.
5a16fd 307
D 308 ## Additional Reading
309 > List of links or other reading that might be of use / reference for the exercise
310
4f0295 311 ## Slide Links
RH 312
313 - [Intro](https://docs.google.com/presentation/d/1B3Fv4g66zZ8ZkqBq9TYmImJhUDvMecXCt4q3DXGWhjc/)
314 - [Wrap-up](https://docs.google.com/presentation/d/1EOk6y798Xh1hsaQlxRuqyr23FIIf7sNY4any_yXIL7A/)
315 - [All Material](https://drive.google.com/drive/folders/1oCjpl33Db7aPocmpu3NNF0B9czRvFq3m)