donal
2018-05-29 40c0ca61d8a44c6212aa1dab6210ac2455d8cee3
exercises/2-attack-of-the-pipelines/README.md
@@ -79,7 +79,7 @@
#### 1a Todolist-fe
2. Git clone the `todolist-fe` project to somewhere sensible and checkout the `develop` branch.
2. Git clone the `todolist-fe` project to somewhere sensible and checkout the `develop` branch using the following.
```bash
cd ~/innovation-labs
```
@@ -179,10 +179,14 @@
    * `./src/scss` contains custom  SCSS used in the application.
    * `./*.js` is mostly config files for running and managing the app and the tests
2. To prepare Nexus to host the binaries created by the frontend and backend builds we need to run a prepare-nexus script. Before we do this we need to export some variables change `<YOUR_NAME>` and `somedomain` accordingly.
2. To prepare Nexus to host the binaries created by the frontend and backend builds we need to run a prepare-nexus script. Before we do this we need to export some variables and change `<YOUR_NAME>` accordingly in the below commands.
```bash
export NEXUS_SERVICE_HOST=$(oc get route nexus --template='{{.spec.host}}' -n <YOUR_NAME>-ci-cd)
```
```bash
export NEXUS_SERVICE_PORT=80
```
```bash
npm run prepare-nexus
```
<p class="tip">
@@ -316,60 +320,7 @@
2. Now let's check out `todolist-fe` app by reloading the browser. We should now see our dummy front end data is replaced by the backend seed data. Adding new todos will add them in the backend, these will persist when the page is refreshed.
![fullstack-app](../images/exercise2/fullstack-app.png)
### Part 2 - Create a NodeJS Build slave
> _In this exercise; we will create a build configuration to generate a slave for Jenkins to use in it's builds_
3. In order for Jenkins to be able to run `npm` builds and installs as we have done locally, we must configure a `jenkins-build-slave` for Jenkins to use. This slave will be dynamically provisioned when we run a build. It needs to have NodeJS and npm installed in it. In your `enablement-ci-cd` repository, checkout the template and configuration. This will bring in the template, the params & the `Dockerfile`.
```bash
git checkout exercise2/jenkins-slave docker/ templates/ params/jenkins-slave-npm
```
3. Open the `params/jenkins-slave-npm` file and update `<GIT_URL>` accordingly. This set of parameters will clone from the enablement repo and run a docker build of the Dockerfile stored in `docker/jenkins-slave-npm`.
```bash
SOURCE_REPOSITORY_URL=<GIT_URL>
SOURCE_CONTEXT_DIR=docker/jenkins-slave-npm
NAME=jenkins-slave-npm
```
3. Create an item in the `inventory/host_vars/ci-cd-tooling.yml` under the `ci-cd-builds` object to run the template with.
```yaml
  - name: "jenkins-slave-npm"
    namespace: "{{ ci_cd_namespace }}"
    template: "{{ playbook_dir }}/templates/jenkins-slave-generic-template.yml"
    params: "{{ playbook_dir }}/params/jenkins-slave-npm"
    tags:
    - jenkins-slave
```
![jenkins-slave-ansible](../images/exercise2/jenkins-slave-ansible.png)
3. Commit your changes to the `enablement-ci-cd` repository!
```bash
git add .
```
```bash
git commit -m "ADD npm slave node for Jenkins"
```
```bash
git push
```
3. Run the OpenShift Applier to trigger a build of this jenkins slave image.
```bash
ansible-playbook apply.yml -e target=tools \
     -i inventory/ \
     -e "filter_tags=jenkins-slave"
```
3. Verify the build executed successfully by logging into the cluster and checking the `builds` tab of the `<YOUR_NAME>-ci-cd` project.
![jenkins-slave-npm-build](../images/exercise2/jenkins-slave-npm-build.png)
3. You should now be able to apply the label `jenkins-slave-npm` to a build job to run a build on this newly created slave as we will see in the rest of this exercise
<p class="tip">
NOTE - Jenkins may need to be restarted for the configuration to appear. To do this; navigate to your jenkins instance and add `/restart` to the url.
</p>
### Part 3 - Add configs to cluster
### Part 2 - Add configs to cluster
> _In this exercise; we will use the OpenShift Applier to drive the creation of cluster content required by the app such as MongoDB and the Apps Build / Deploy Config_
4. On your terminal navigate to the root of the `todolist-fe` application. The app contains a hidden folder called `.openshift-applier`. Move into this `.openshift-applier` directory and you should see a familiar looking directory structure for an ansible playbook. 
@@ -434,7 +385,7 @@
git push
```
4. Back on your terminal navigate to the root of the `todolist-api` application. Open the `.openshift-applier` directory. The same layout as seen in `todolist-fe` should be visible with one noticeable difference; the api requires `MongoDB` to connect to at runtime.
4. Back on your terminal navigate to the root of the `todolist-api` application. Open the `.openshift-applier` directory in your editor. The same layout as seen in `todolist-fe` should be visible with one noticeable difference; the api requires `MongoDB` to connect to at runtime.
4. In the `apply.yml` update the namespace `<YOUR_NAME>` variables accordingly. For example:
```yaml
@@ -477,7 +428,7 @@
4. Check `<YOUR_NAME>-dev` to see the deployment configs are in place
![ocp-app-dc](../images/exercise2/ocp-app-dc.png)
### Part 4 - Build > Bake > Deploy
### Part 3 - Build > Bake > Deploy
> _In this exercise; we take what we have working locally and get it working in OpenShift_
This exercise will involve creating three stages (or items) in our pipeline, each of these is detailed below at a very high level. Move on to the next step to begin implementation.
@@ -500,16 +451,16 @@
    4. Verify the deployment
* We will now go through these steps in detail.
#### 4a - Build
#### 3a - Build
5. With the BuildConfig and DeployConfig in place for both our apps (`*-fe` & `*-api`) from previous steps; Log into Jenkins and create a `New Item`. This is just jenkins speak for a new job configuration. ![new-item](../images/exercise2/new-item.png)
5. Name this job `dev-todolist-fe-build` and select `Freestyle Job`. All our jobs will take the form of `<ENV>-<APP_NAME>-<JOB_PURPOSE>`. ![freestyle-job](../images/exercise2/freestyle-job.png)
5. Name this job `dev-todolist-fe-build` and select `Freestyle Project`. All our jobs will take the form of `<ENV>-<APP_NAME>-<JOB_PURPOSE>`. ![freestyle-job](../images/exercise2/freestyle-job.png)
5. The page that loads is the Job Configuration page and it can be returned to at anytime from Jenkins. Let's start configuring our job. To conserve space; we will make sure Jenkins only keeps the last builds artifacts. Tick the `Discard old builds` checkbox, then `Advanced` and set `Max # of builds to keep with artifacts` to 1 as indicated below 
![keep-artifacts](../images/exercise2/keep-artifacts.png)
5. Our NodeJS build needs to be run on the `jenkins-slave-npm` we created earlier. Specify this in the box labelled `Restrict where this project can be run` ![label-jenkins-slave](../images/exercise2/label-jenkins-slave.png)
5. Our NodeJS build needs to be run on the `jenkins-slave-npm` we bought in in the previous chapter. Specify this in the box labelled `Restrict where this project can be run` ![label-jenkins-slave](../images/exercise2/label-jenkins-slave.png)
5. On the Source Code Management tab, select the Git radio button, specify the endpoint for our GitLab `todolist-fe` Project and specify your credentials from the dropdown box. Set the Branch Specifier to `develop`. ![git-scm](../images/exercise2/git-scm.png)
@@ -556,7 +507,7 @@
5. Hit `save` which will take you to the job overview page - and that's it; our *build* phase is complete!
#### 4b - Bake
#### 3b - Bake
5. Next we will setup our *bake* phase; which is a little simpler. Go to Jenkins home and create another Freestyle Job (as before) called `dev-todolist-fe-bake`.
@@ -584,7 +535,9 @@
Remember to replace `<YOUR_NAME>` accordingly.
```bash
#!/bin/bash
curl -v -f http://admin:admin123@${NEXUS_SERVICE_HOST}:${NEXUS_SERVICE_PORT}/repository/zip/com/redhat/todolist/${BUILD_TAG}/package-contents.zip -o package-contents.zip
curl -v -f \
    http://admin:admin123@${NEXUS_SERVICE_HOST}:${NEXUS_SERVICE_PORT}/repository/zip/com/redhat/todolist/${BUILD_TAG}/package-contents.zip \
    -o package-contents.zip
unzip package-contents.zip
oc project <YOUR_NAME>-ci-cd
NAME=todolist-fe
@@ -601,7 +554,7 @@
5. Hit save! That's our *bake* phase done! Finally; on to our *deploy*
#### 4c - Deploy
#### 3c - Deploy
5. Next we will setup our *deploy* phase. This job is very similar in setup to the *bake* phase so this time go to Jenkins home and create `dev-todolist-fe-deploy` Job but scroll to the bottom and Copy from `dev-todolist-fe-bake`.
![copy-from](../images/exercise2/copy-from.png)
@@ -630,14 +583,18 @@
5. Finally; delete the Post Build Action to trigger another job (by hitting the red X). Save the configuration. We're almost ready to run the pipeline!
#### 4d - Pipeline
#### 3d - Pipeline
5. With our Jenkins setup in place; now move to our `todolist-fe` app's source code. We have to add our configuration to the frontend to tell it where the API layer will be hosted. Open the source in your favourite editor and navigate to `src/config/dev.js`.
5. Update `<YOUR_NAME>` accordingly with the route where the Todo List API will live when it is deployed, update the `somedomain` to the clusters domain. The correct full URL can also be found on the OpenShift Console; if you copy it from there remember to append `/api/todos` to the URL. For example:
5. Update `<YOUR_NAME>` accordingly with the route where the Todo List API will live when it is deployed. The correct full URL can also be found on the OpenShift Console; if you copy it from there remember to append `/api/todos` to the URL. For example:
![fe-dev-config](../images/exercise2/fe-dev-config.png)
5. Repeat this for `src/config/test.js` file. If you copy the URL from the previous step; change `dev` to `test`. Once done; commit your chanages and push them to GitLab
5. Repeat this for `src/config/test.js` file. If you copy the URL from the previous step; change `dev` to `test`.
For example:
![fe-test-config](../images/exercise2/fe-test-config.png)
5. With the config in place; commit your changes and push them to GitLab:
```bash
git add .
```
@@ -660,55 +617,13 @@
5. You should now see the pipeline view. Run the pipeline by hitting run (you can move onto the next part while it is running as it may take some time).
![dev-pipeline-view](../images/exercise2/dev-pipeline-view.jpeg)
### Part 5 - Backend Pipeline
> In this exercise we will use the Jobs created for the `todolist-fe` as a template to create a pipeline for the `todolist-api` app by copying the config.
6. On Jenkins home; create a new job for our backend build called `dev-todolist-api-build`. Use the `Copy from` section to copy all the configuration from the `dev-todolist-fe-build`.
![copy-fe-build](../images/exercise2/copy-fe-build.png)
6. When this has loaded; find and replace both occurrences `-fe` with `-api` within the Job's configuration. Places to make sure you check are:
    * The GitLab project URL
    * Projects to build on the Post Build Action
6. On the Build tab; remove the `:dev` from the `npm run build:ci:dev` so the line reads.
 The rest of the instructions can be left as they are.
```bash
npm run build:ci
```
![api-build-step](../images/exercise2/api-build-step.png)
6. Save the configuration for `dev-todolist-api-build`
6. On Jenkins home; create a new job for our backend bake called `dev-todolist-api-bake`. Use the Copy from section to copy all the configuration from the `dev-todolist-fe-bake` as you've just done.
6. When this has loaded; find and replace the occurrences `-fe` with `-api` within the Job's configuration. Places to make sure you check are:
    * The BUILD_TAG default value and description
    * NAME in the execute shell step
    * Projects to build on the Post Build Action
6. Save the configuration for `dev-todolist-api-build`
6. On Jenkins home; create a new job for our backend build called `dev-todolist-api-deploy`. Use the Copy from section to copy all the configuration from the `dev-todolist-fe-deploy` as you've just done.
6. When this has loaded; find and replace the occurrences `-fe` with `-api` within the Job's configuration. Places to make sure you check are:
    * The BUILD_TAG default value and description
    * NAME in the execute shell step
    * The name of the DeploymentConfig to validate in the Verify OpenShift Deployment
6. Save the configuration for `dev-todolist-api-deploy` and that's it for wiring together our `todolist-api` pipeline.
6. Run the `dev-todolist-api-build` to trigger the backend pipeline. While this is building, check our front end app and see if it has deployed successfully.
6. To check the deployment in OpenShift; open the console and go to your `dev` namespace. You should see the deployment was successful; hit the URL to open the app (the screenshot below has both apps deployed).
6. To check the deployment in OpenShift; open the web console and go to your `dev` namespace. You should see the deployment was successful; hit the URL to open the app (the screenshot below has both apps deployed).
![ocp-deployment](../images/exercise2/ocp-deployment.png)
6. If it has been a success we should see our dummyData. This is because there is no backend deployed.
6. If it has been a success we should see our dummyData. This is because there is no backend deployed, in later labs we will deploy the backend and the mongodb for persistence but to do this we will use Jenkins Pipeline as code.
![no-backend-app](../images/exercise2/no-backend-app.png)
6.  When `dev-todolist-api-build` has completed we should see the sample data has changed on refresh.
![with-backend-app](../images/exercise2/with-backend-app.png)
### Part 6 - GitLab Webhooks
### Part 4 - (Optional) GitLab Webhooks
> _In this exercise we will link GitLab to Jenkins so that new build jobs are triggered on each push to the `develop` branch._
<p class="tip" >
@@ -734,14 +649,6 @@
![gitlab-integrations-details](../images/exercise2/gitlab-webhook-test.png)
7. We can now test this properly by heading into the `todolist-fe` repository through <YOUR_FAVOURITE_EDITOR>. Make a small change to your code, then commit and push it, ensuring you're on the develop branch. Then head over to Jenkins and wait until the `dev-todolist-fe-build` job has been triggered.
7. All that's left to do is to repeat the same steps for `todolist-api` (Starting from step 3):
Create Build Trigger:
`https://jenkins-<YOUR_NAME>-ci-cd.apps.some.domain.com/job/dev-todolist-api-build/configure`
Create GitLab Integration:
`https://gitlab-<YOUR_NAME>-ci-cd.apps.some.domain.com/donal/todolist-api/settings/integrations`
Check your build status and you should see something like this. With `Started by Gitlab push by <YOUR_NAME>`:
![jenkins-gitlab-webhook-success](../images/exercise2/jenkins-gitlab-webhook-success.png)
7. We now have a working GitLab webhook so any time we push code it will automatically build! Next up we'll show you how to add tests to your pipeline.