diff --git a/labs/cloudbees-cdro-compliance/content/_index.md b/labs/cloudbees-cdro-compliance/content/_index.md index 5243be5f..ba64b76f 100644 --- a/labs/cloudbees-cdro-compliance/content/_index.md +++ b/labs/cloudbees-cdro-compliance/content/_index.md @@ -6,4 +6,4 @@ weight: 1 # CloudBees CD/RO DevOps World 2023 Workshop -This workshop will familiarize you with CloudBees Software Delivery Automation and CloudBees CD/RO. Complete the hands-on labs to explore the features and technical advantages of the software. \ No newline at end of file +This workshop will familiarize you with CloudBees Software Delivery Automation and CloudBees CD/RO. Complete the hands-on labs to explore the features and technical advantages of CloudBees Platform for securing your SDLC. \ No newline at end of file diff --git a/labs/cloudbees-cdro-compliance/content/labs/01_pre-reqs.md b/labs/cloudbees-cdro-compliance/content/labs/01_pre-reqs.md new file mode 100644 index 00000000..62603d14 --- /dev/null +++ b/labs/cloudbees-cdro-compliance/content/labs/01_pre-reqs.md @@ -0,0 +1,21 @@ +--- +title: "Pre-requisites" +chapter: false +weight: 2 +--- + +Welcome to the workshop. + +--- + + +## Registration + +
+
+
+ + + diff --git a/labs/cloudbees-cdro-compliance/content/labs/03_basic-release.md b/labs/cloudbees-cdro-compliance/content/labs/03_basic-release.md new file mode 100644 index 00000000..9d825246 --- /dev/null +++ b/labs/cloudbees-cdro-compliance/content/labs/03_basic-release.md @@ -0,0 +1,184 @@ +--- +title: "Basic release" +chapter: false +weight: 3 +--- + +One of the primary objects in the CloudBees CD/RO application is the release. This is where you can map out the whole delivery process for a given software release. + +With a release pipeline in place you can be certain that all the operations occur in the correct order every single time. + +## Creating a release from a template + +When you're first logged in you'll see something that looks like this. + +![Release screen](1.png) + +This is where you'll see all the release across everyone's projects. You can filter this down using the set of filters at the top. We'll come back to this in a minute. + +First we'll go to the **Service Catalog** which you'll find in the top navigation. + +![Service catalog](2.png) + +The service catalog is a collection of pre-made content that can be instantiated by anyone with permissions. + +To get started with this lab you'll click create on the **1. Basic Release** item. + +![Service catalog form](3.png) + +Fill out the form with your desired release name. For your convenience in finding yours you may want to name it something like `my-username Release`. + +With that complete, you can navigate back to the release list by opening the "burger" menu at the top left and navigating to the **Release Orchestration > Releases** item. + +![Navigate to releases](4.png) +![Release list](5.png) + +If you'd like to make it easier to keep track of your specific release, you can use the project filter at the top. + +![Filter releases](6.png) +![Filtered releases](7.png) + +Now you can click on the name of your release, and it'll bring you into the release. + +![First release](8.png) + +A release is made up of a bunch of tasks spread across multiple stages. In this case, you can see that your release has 3 different stages: **Release Readiness**, **Quality Assurance**, and **Production**. + +You can have as many stages as you want. Typically, you'll have a stage to represent each of the different environments that are involved in the release process. In the next couple of labs we'll dive into the environment modeling capabilities. + +Let's look at what steps are already setup in this release. + +## Release overview + +In the **Release Readiness** stage there are two data gathering tasks. + +1. Grab the changelogs from the application source code in GitHub +2. Pull the static code analysis results of the latest SonarQube scan + +If you were using a tool like Jira for issue tracking, you would likely also want to pull information about the stories surrounding this release. + +Next is the exit gate on the **Release Readiness** stage. You can expand this by clicking the dark gray box on the right side of the stage. + +![Closed exit gate](9.png) +![First exit gate](10.png) + +This is the exit gate where the criteria to allow the release to continue past this stage is defined. The criteria can be both automatic and manual. + +Here you can see there is one called **No Code Smells** which is pulling information from the **Get latest SonarQube scan results** task and ensuring there were no code smells. + +Like the exit gate, you can also define an entry gate on each stage to specify the criteria for when the release can enter the stage. + +Next there are two stages, **Quality Assurance** and **Production** that each currently have a single task. These tasks are mocking where we'll eventually add a deployment step. Currently, they are just a simple `echo "Replace me"` command. + +![First release](8.png) +![Mock deployment](11.png) + +## Running the release + +Now that you've looked through your current release, go ahead and run it. Over on the right side of the screen, you'll see a floating green button with a play icon in it. + +![Start release](12.png) + +Once you click **Start release** a modal will pop up where you could pass in parameters and select which stages you want to run. + +![Start release form](13.png) +![Start release form](14.png) + +Let's leave the default options and run through all the stages. Go ahead and click **Run**. + +![First release run](15.png) + +This will take you to your release run. It should quickly execute. You should see that everything has turned green and each stage will have a checkmark showing that it was successfully completed. + +You can check out the summary for each stage by clicking the **Summary** button towards the top of each stage. + +![Release readiness summary](16.png) + +To do a deeper dive on the data from a given task you can click on the task. You can see the logs as well as the properties that are pulled from any external tools. + +![Release readiness summary](17.png) +![Release readiness summary](18.png) + +## Making a change +Our release pipeline isn't going to be winning any awards at the moment. Besides the fact that the deployments are just mocked out at the moment, there aren't any sort of checks between the QA deployment and the production deployment. + +Currently, if the deployment into QA failed, it would still go on to attempt the deployment into production. That is not what we want! + +What we'll do is add an approval to the entry gate into the **Production** stage to ensure the production deployment only occurs when it is safe to do so. + +_Note: You may want to get to a point where there are no manual approvals, everything is fully automated. This is easy to do. You need to add validators like we have on the exit gate of the **Release Readiness** stage which pull data from your tests. The key is to make sure that you have sufficient tests that you feel confident in deploying to production._ + +To add this entry gate, expand the entry gate panel on the left side of the **Production** stage. + +![New entry gate](20.png) + +You can call this entry gate whatever you would like. In the screenshot you can see it called `Manual approval`. Then select the rule type of **Approval**. + +![New entry gate](21.png) + +Then click on the **Define** button to configure the approval. + +![New entry gate](22.png) +![New entry gate](23.png) + +Go ahead and assign this approval to yourself. You can add a message if you'd like as well. + +You may notice when you go to assign yourself that you can assign both users and groups. Often times you'll want to assign a specific team rather than a person. You can specify the minimum number of users who need to approve it as well to ensure more than one set of eyes is looking at it. + +![New entry gate](24.png) + +Go ahead and click **OK**. + +With that you've successfully made your release a bit more practical. + +![Updated release](25.png) + +## Rerunning the release +With your new change in place, go ahead and kick off your release again. + +After having run your release before, you'll notice the floating green "play" button is now blue and a vertical dots icon. You can click **Run pipeline** to kick it off with a fresh set of settings, or you can do **Previous run** to reuse whatever settings you used previously. + +In our case, we just used the default settings so either one will work identically. + +![Rerun release](26.png) + +The release will start running and you'll quickly see that it is paused while waiting for the manual approval. + +![Rerun release](27.png) + +Before responding to the approval, let's take a quick look at a separate view where you can always see which releases are waiting on you. On the top bar, go ahead and click on the **My work** item. + +![My work](28.png) +![My work page](29.png) + +This list will have an always up-to-date list of all the manual tasks requiring your input. + +Alright, now back to the release run. If you didn't open the **My Work** page in a new tab, you can click on the **Go to** arrow on the right side of the list item to bring you back. + +Go ahead and click on the approval where it says **Response required**. Then click the item in the dropdown to bring up the approval modal. + +![Approval](30.png) +![Approval](31.png) + +And with that approval complete, your release should successfully complete. +![Complete release](32.png) + +## Automatic auditing + +Before we move on to the next lab, let's take a quick peak at the automatic auditing that has happened on this release. + +Go to the actions menu in the top right of the release run and click on **Audit Reports**. +![Audit report item](33.png) + +Here you can see all the information that is automatically gathered for each and every release run. You don't have to do anything to configure this, it just happens automatically. You can export this and share it with your auditors. + +![Audit report](34.png) +![Audit report](35.png) +![Audit report](36.png) + +And with that, we're on to the next lab where we'll take a look at the basics of **Deployment Automation**. + + + + + diff --git a/labs/cloudbees-cdro-compliance/content/labs/04_microservice-deployment.md b/labs/cloudbees-cdro-compliance/content/labs/04_microservice-deployment.md new file mode 100644 index 00000000..d1f22779 --- /dev/null +++ b/labs/cloudbees-cdro-compliance/content/labs/04_microservice-deployment.md @@ -0,0 +1,203 @@ +--- +title: "Microservice Deployment" +chapter: false +weight: 4 +--- + +Deploying an application is a standard part of most release pipelines. One of the challenges you want to avoid is duplicating effort by redefining the process of deploying your application over and over. + +CloudBees CD/RO has application and environment modeling capabilities which avoid this problem. It allows you to define the process once and use it over and over. + +An application model allows you to define all of the processes you may run in relation to a given application. This can include processes such as deploying, removing, upgrading, etc. + +Similar to object-oriented programming, this approach gives you the full context of what actions are available to you against a given application. + + +## Reviewing the application + +In this lab, you'll be going through the process of creating and running an application deployment model for the following application. + +![Demo application](demo-app.png) + +This application is a simple webpage, but it will take in a couple of environment variables, specifically `$NAME` and `$ENVIRONMENT`. This will illustrate which environment it was deployed to and by whom. + +There are many ways to deploy an application, especially one as simple as this. For this exercise we'll be employing [Helm](https://helm.sh), a Kubernetes package manager, to perform the deployment. + +### 30-second Helm primer + +CloudBees CD/RO will abstract away the need to run individual Helm commands, but it is helpful to know what Helm is doing behind the scenes. + +[Helm](https://helm.sh) is effectively a template engine and state manager for Kubernetes resources. + +It takes something that looks like this: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-app + labels: + application: my-app +spec: + replicas: 1 +``` + +And turns it into: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "chart.fullname" . }} + labels: + {{- include "chart.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} +``` + +It takes this template and runs it against a `values.yaml` file which includes the values to inject as well as values passed in via the command line. + +It then applies these generated resources into the cluster in what it calls a **release**. + +It keeps track of the configuration state from each of the releases so you can perform upgrades or rollback without issue. + +## Creating the application model + +First you'll need to navigate to the **Applications** page. + +![Applications page nav](applications-page-nav.png) + +Then you'll click on the New button in the top right. + +![New application button](new-application-button.png) + +Then **Create New** + +![Create new application](create-new-app.png) + +Then proceed to fill out the form. You can call the application `Workshop App` and target the project you created in the pre-reqs. Then select **Microservice** for the application type. + +![New application form](new-application-form.png) + +Now you have a blank microservice application model. + +![Blank application model](fresh-app-model.png) + +As you can see, there are two big components standing out here. There is the microservice model block on the left (in pink). There is the environment model on the right (in purple). + +### Defining the microservice component + +First we'll start with the microservice definition on the left. This is where you'll specify the Helm chart you want to deploy as well as any values you need to pass in. + +To begin, click the inner, pink "New microservice" button which will bring up the necessary form. +![New microservice button](new-microservice-button.png) + + +We'll create a new microservice from scratch. You can just click next and leave the default option selected. +![New microservice form](new-microservice-form-1.png) + +Next you need to fill out the definition form. + +| Field | Value | Description | +| --- | --- | --- | +| Name | `hello-app` | The name to identify your application | +| Description | *optional* | A field to help understand the context of this application | +| Definition type | `Helm` | The type of microservice deployment you want to run | +| Definition source | `Git repository` | The source for where to look for the target Helm chart. It could be a Helm registry, but for this workshop we're using a Git repo. | +| Configuration Name | `Git Bot` | The credentials to use for the Git connection when pulling the repository. In this case, we'll be using a shared GitHub service account since the repository is public. | +| Git repository | https://github.com/cloudbees-days/cdro-workshop-demo-app | The target repository where it will look for the Helm chart | +| Remote branch | `main` | The branch in GitHub it will checkout | +| Release name | `hello-app` | The name Helm will use to track your app release | +| Chart | `./chart` | The name or path to the chart we'll be using. In this case, since we're using a Git repo, we are passing in the path. | +| Chart Version | | If you wanted to specify a particular version of a Helm chart you can do so. In our case, we'll be leaving it blank to use the latest. | +| Additional options | `--create-namespace` | If you want to pass in arguments like you do using the Helm cli, you can pass them in here | +| Values | *Below* | You can also pass in values in YAML form. This is what we'll be doing for the workshop. | + +**Values** - You'll want to make sure the subdomain is targeting your username. +```yaml +ingress: + hosts: + - host: my-username.cdro-workshop.cb-demos.io + paths: + - path: / + pathType: ImplementationSpecific + tls: + - secretName: insurance-frontend-tls + hosts: + - my-username.cdro-workshop.cb-demos.io + +name: "my-username" +environment: "QA" +``` + +![New microservice form - part 2](new-microservice-form-2.png) + +Now hit "OK" and the microservice component will be created. +![Created microservice](new-microservice-done.png) + + +### Defining the environment + +Now, before we're able to deploy our newly-defined application, we need to define an environment to deploy it into. + +Get started by clicking the "New cluster" button on the right side. +![New cluster](new-environment-1.png) + +*It should be noted that we aren't creating a new Kubernetes cluster, but rather a new environment definition based on a cluster.* + +Similar to the application definition, you can just click "Next" and leave the default option of "New environment" on this page. +![New cluster - part 2](new-environment-2.png) + +Now you'll define the cluster environment. + +| Field | Value | Description | +| --- | --- | --- | +| Environment name | `QA` | The name to identify your environment | +| Project | Select your project | The project inside which this environment will be stored | +| Environment description | *Optional* | A field to give textual details about this environment | +| Cluster name | `default` | A name to identify this cluster | +| Cluster description | *Optional* | A field to give textual details about this cluster | +| Configuration provider | `Kubernetes (via Helm)` | The type of environment you're defining | +| Configuration name | `helm` | A reference to a configuration that lets CD/RO know where to use Helm | +| Namespace | `my-username-qa` | The Kubernetes namespace where your application will be deployed. You should update this to be YOUR_USERNAME-qa. | +| Kubeconfig context | | This allows you to target a specific cluster if your configuration is pointed at multiple. For this workshop you can leave this blank. | +| Utility resource name | `k8s-agent` | This is the name to identify the utility resource | +| Resource | `k8s-agent` | This is the agent which will communicate with the Kubernetes cluster | + +![New cluster - part 3](new-environment-3.png) + + +## Running the deployment + +![Environment created](environment-created.png) + +Now you're ready to deploy the application. + +Go ahead and click the "Deploy" button in the bottom right. This will launch a modal where you can specify which application process to run and which environment to target. + +In this case, you'll select `Deploy Application` as the process and `QA` as the environment (*these should be the only options presented*). When you're ready, hit "OK". + +![Deployment - part 1](deploy-1.png) + +It will bring you to the application run page where you can see the steps updating live as they are happening. + +![Deployment - part 2](deploy-2.png) + +After a short time, you should see a view like this where all of the stages are complete. + +![Deployment - part 3](deploy-3.png) + +You can click the top list item to see more detail on the overall run and you can also click the individual steps to see specific details from just that step. + +### Visiting our application + +Now we can visit the application we just deployed by visiting the URL from the values definition of our application. This will be in the form of `https://my-username.cdro-workshop.cb-demos.io`. + +You should see the name of your username and the environment QA listed. + +![Deployment app](deployed-app.png) + + +In the next lab we'll be diving deeper into the environments and setting up environment specific variables. + + diff --git a/labs/cloudbees-cdro-compliance/content/labs/05_environments.md b/labs/cloudbees-cdro-compliance/content/labs/05_environments.md new file mode 100644 index 00000000..ac23b3b4 --- /dev/null +++ b/labs/cloudbees-cdro-compliance/content/labs/05_environments.md @@ -0,0 +1,219 @@ +--- +title: "Environments" +chapter: false +weight: 5 +--- + +Application modeling is only one part of managing deployment automation with CloudBees CD/RO. The other main part is environment modeling. + +With application modeling you describe what the processes are that can be run against an application. Now with the environment modeling you are defining where these processes can occur. + +It is important that these two be separate or else there would be a lot of repetition of effort. With this setup you only need to define the application processes once and then point them at the target environments. Properties from the environment can then be passed along to the application process during runtime. + +In the previous lab we took a look at the application modeling process and setup a microservice definition. As part of this we created our first environment in which we would deploy our application. + +## Reviewing the environment we've created + +Let's take a look at the environment we created in the previous lab in more detail. On the *Hierarchy Menu* on the left side of the screen, you can click on the "Environment: QA" link at the bottom. This will bring you to the environment page. + +![Click on environment](click-environment.png) + +Here are the resources you defined in the environment creation form. There is the `default` Kubernetes cluster definition on the right and the *Utility Agent* named `k8s-agent` on the left. If there were more components involved in this environment they could be easily added. This is more prevalent in traditional applications where you may be targeting multiple different servers. + +In our case, since we're using Kubernetes, we don't need to worry about individual servers. +![Environment page](env-1.png) + +### Environment runs + +One of the challenges of maintaining many environments is keeping track of what has actually been going on in those environments. + +CD/RO makes this easy with the **Runs on this environment** view. Here you can see all of the application runs that have taken place in this environment. + +If you click on the **Runs on this environment** button on the secondary menu, you should see the application run that you performed from the previous lab. You could click into if you wanted to in order to review those details. + +![Environment runs](env-2.png) + + +### Environment inventory + +One of the other challenges of maintaining many environments is actually knowing what is installed in those environments. + +This is where the **Inventory** view comes into play. The inventory shows you what applications are installed in the environment, which version is installed, and when that occurred. + +If you navigate to this view by clicking the **Inventory** button on the secondary menu, you should see something like the following. + +![Environment inventory](env-3.png) + + +## Adding a production environment + +Now that we've got this fully functional QA environment, let's create another environment that we can deploy our application into. + +We'll call this our **Production** environment. + +To get started, let's go back to the application view by first going to the "Environment editor view" and clicking the `Application: Welcome App` link in the bottom of the *Hierarchy Menu*. + +![Environment editor](env-4.png) + +You can also navigate there via the main menu (aka the *burger menu*) by going to Applications under Deployment Automation. + +![App menu](app-burger-menu.png) + +To add a new environment, click the large plus button on the right side of the QA environment. + +![New environment button](prod-1.png) + +You'll now see a familiar "New environment" block with a "New cluster" block inside of it. We are essentially going to repeat our steps from the previous lab. + +![New environment block](prod-2.png) + +First, click on the "New Cluster" button in the inner block. This will pop up the New environment modal. Like before, you'll just click "Next", leaving the default option of "New environment". + +![New environment modal](prod-3.png) + +This will look remarkably similar to before. We'll just replace the values of QA that we used previously with that of Production. + +| Field | Value | Description | +|-------------------------|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------| +| Environment name | `Production` | The name to identify your environment | +| Project | Select your project | The project inside which this environment will be stored | +| Environment description | *Optional* | A field to give textual details about this environment | +| Cluster name | `default` | A name to identify this cluster | +| Cluster description | *Optional* | A field to give textual details about this cluster | +| Configuration provider | `Kubernetes (via Helm)` | The type of environment you're defining | +| Configuration name | `helm` | A reference to a configuration that lets CD/RO know where to use Helm | +| Namespace | `my-username-prod` | The Kubernetes namespace where your application will be deployed. You should update this to be YOUR_USERNAME-prod. | +| Kubeconfig context | | This allows you to target a specific cluster if your configuration is pointed at multiple. For this workshop you can leave this blank. | +| Utility resource name | `k8s-agent` | This is the name to identify the utility resource | +| Resource | `k8s-agent` | This is the agent which will communicate with the Kubernetes cluster | + +![New environment form](prod-4.png) + +Next we need to map this new environment to the application. + + +![Map new environment](prod-5.png) + +Drag the arrow into the Kubernetes cluster within the Production environment. +![Map environment](prod-6.png) + +You'll have a popup asking you to confirm the mapping. Go ahead and click "OK". + +![Map environment - confirm](prod-7.png) + +Now you're ready to deploy into the production environment. Like before, you can click the "Deploy" button, but this time select the Production environment. + +![Deploy app into prod](prod-8.png) + +This should fail to deploy into the production environment. + +![Production deploy success](prod-9.png) + + +One question may be occurring to you: Didn't we hardcode the URL for the application? + +That is right! Right now we've deployed our application into two different environments, yet we have the same URL set for both. That's not what we want! + +This is where we'll bring in some environment properties. + +## Environment specific properties + +We're going to make some modifications that will allow us to deploy to each environment with some key differences including different URLs and different environment variables passed into the deploy. + +### Adding subdomain environment variable +First, you'll add a property to the two environments that specifies a subdomain. Then you'll update the application model to use this subdomain so each deployment can actually be accessed. + +We'll start with the QA environment. You can add a property by clicking on the menu with the three dots on the QA environment box. + +![Add a property](envvars-1.png) +![Add a property](envvars-2.png) +![Add a property](envvars-3.png) + +Go ahead and fill it out with the properties: + +| Property | Value | +| --- | --- | +| subdomain | `my-username-qa` | + +You can leave all the other values default and save it by clicking **OK**. + +![New property](envvars-4.png) + +Now go ahead and do the same for the production environment, except use these properties: + +| Property | Value | +| --- |--------------------| +| subdomain | `my-username-prod` | + +![New property](envvars-5.png) + +And with that, we're ready to update the application model. + +### Updating the app model + +Let's go back to the application model. Go ahead and click on the **Details** option in the menu for the **hello-app** model. + +![Update app details](envvars-6.png) +![Update app details](envvars-7.png) + +We'll update the values block to interpolate some values rather than using the hardcoded values we started with. To make sure you get all the values right, you can copy the following block. + +```yaml +ingress: + hosts: + - host: $[/myEnvironment/subdomain].cdro-workshop.cb-demos.io + paths: + - path: / + pathType: ImplementationSpecific + tls: + - secretName: insurance-frontend-tls + hosts: + - $[/myEnvironment/subdomain].cdro-workshop.cb-demos.io + +name: "$[/myJob/launchedByUser]" +environment: "$[/myEnvironment/name]" +``` + +What we're doing here is using the `$[propertyName]` syntax to access the values of particular properties. There are a bunch of properties we can access throughout the platform, but in this case we want to reference a few related to this particular environment and deployment. + +| Property | Description | +|-------------------------------|------------------------------------------------------------------------------------| +| `$[/myEnvironment/subdomain]` | Accesses the `subdomain` property on the environment targeted by a deployment run. | +| `$[/myEnvironment/name]` | Accesses the name of the environment targed by a deployment run. | +| `$[/myJob/launchedByUser]` | Grabs the name of the user who kicked off the run. | + + +You can do this by using the syntax of `$[propertyName]` to access the value of a particular property. There are a bunch of properties we could access throughout the platform, but in this case we want to reference the current environment we're running against. + +## Running the deployments +With these new settings in place, go ahead and deploy into the QA environment. + +![New run](rerun-1.png) +![New run](rerun-2.png) +![New run](rerun-3.png) + +This should run fairly quickly. Once it is complete, you can access your application at: `my-username-qa.cdro-workshop.cb-demos.io` + + + +![QA new run](rerun-4.png) + +Now go ahead and do the same for the production environment. You'll be able to access the production application at: `my-username-prod.cdro-workshop.cb-demos.io` + + +![Production new run](rerun-5.png) + + +After deploying both applications you should now see: +1. You can now access the two different deployments on different URLs +2. Your username should appear in the **Deployed by** field +3. The **Environment** field should reflect the environment it is running in + + +## Up next + +In the next lab you'll be integrating the application and environment models you've worked on over the past 2 labs into the release from the first lab. + + + + diff --git a/labs/cloudbees-cdro-compliance/content/labs/06_deployment-in-release.md b/labs/cloudbees-cdro-compliance/content/labs/06_deployment-in-release.md new file mode 100644 index 00000000..f54e90f8 --- /dev/null +++ b/labs/cloudbees-cdro-compliance/content/labs/06_deployment-in-release.md @@ -0,0 +1,143 @@ +--- +title: "Adding deployment to release" +chapter: false +weight: 6 +--- + +So far you've created a release, an application model, and two environment models. Now it is time to tie these all together. + +You've got the deployment automation part working, you can successfully deploy the application. But being able to deploy the application is only half of the situation. You're not going to want to manually click **Deploy** on the application when there is a new version. + +With the **release** being the main orchestrator which maps your software release process, this is where you'll introduce the application deployments into an automated process. + +## Replacing the mocked steps + +First let's get back to our release. You can navigate to it by opening the "burger menu" in the top left and clicking on the **Release Orchestration > Releases** item. +![Release navigation](1.png) +![Release list](2.png) +![Release](3.png) + +Recall that our **Deploy to QA** and **Deploy to Production** tasks are just mocked out deployments at the moment. All they do is run an echo command. + +### Updating the QA stage + +Let's start by replacing the task in the **Quality Assurance** stage. To do this, click on the task and then click on the trash can icon above it. +![Delete task](4.png) +![Delete task](5.png) + +_Alternatively, you can delete tasks by clicking on the "more" menu on the task and click the delete item._ +![Delete task](6.png) + +Which ever way you deleted it, you should now see 0 Tasks in that stage. +![Empty stage](7.png) + +Now it is time to create a new task. Go ahead and click the **Add** button in the bottom of the stage. Go ahead and call it `Deploy to QA`. + +![New task](8.png) + +Next, click on **Select Task Type** and choose the **Deployer** option from under the **Native** section. +![New task](9.png) + +Then, click on **Define** to configure this task. +![Configure new task](10.png) + +Since we're only working with a single application, we can ignore these settings and just click **OK**. This is where you can change the behavior of how it chooses to deploy multiple applications. + +Now we're done with the QA stage. + +![QA task complete](11.png) + +### Updating the Production stage + +Go ahead and run through the same steps from the **Updating the QA stage** section in the **Production** stage. The only change you'll need to make is to call it `Deploy to Production` instead of `Deploy to QA`. + +By the end of it you should have both stages updated with these **Deployer** steps. + +![Production task complete](12.png) + +## Mapping applications and environments +You probably noticed that those **Deployer** steps didn't actually specify anything about our application or environments. + +Does it automatically figure out which environment based on the stage name? + +No, we believe it is better to be explicit. Anything that relies on a particular convention like this would be brittle and error-prone. + +What we need to do is tell this release which applications and environments to map to which stages. + +Over on the left-side of the release page you'll see the **Hierarchy Menu**. Towards the bottom you'll see the **Applications** and **Environments and Configurations** items. We'll be using both of these. + +### Mapping the application +Let's start by mapping the application to the release. Go ahead and click on the **Applications** button. + +![Map applications](13.png) + +To map the application to this release, you need to: + +1. Select your specific application (make sure it is the one that matches your project) +2. Click the blue button to assign it to the release +3. Close the application selector +4. Click **OK** to save it +![Map applications](14.png) +![Map applications](15.png) + +_Note that the application selector is a multi-select, so you can assign multiple applications to a given release. We're just using one, but you could deploy hundreds of applications if you wanted._ + +As easy as that, your application is now mapped to the release. Next up is assigning environments. + +### Mapping Environments and Configurations +Now, go ahead and click the **Environments and Configurations** button. +![Map envs](16.png) +_Note that you should now see **1 Application** in the box above it. If you don't, you'll want to click into it and make sure that the application from the previous section was saved._ + +![Map envs](17.png) + +Here you'll see that it recognizes the **Deploy to QA** and **Deploy to Production** tasks that you've created. + +#### Mapping the QA stage + +Go ahead and click on the **Quality Assurance** block. +![Map QA](18.png) + +Then click on the **Environment** button in the top right. This will open up a modal where you can select the environment. By default it'll be on Name Pattern, but you'll want to switch to **Select Environment**. Then go ahead and select the **QA** environment that corresponds to your project. Then hit **OK**. +![Map QA - environment](19.png) +![Map QA - environment](20.png) + +Next, with the QA environment still selected, click on the **Process** button in the top right. This will open a modal which will allow you to choose the application process for your **Welcome App**. There should only be one option, **Deploy Application**. Go ahead and select it and then hit **OK**. +![Map QA - process](21.png) +![Map QA - process](22.png) + +You'll notice there is also a **Parameters** button available. For this application deployment we aren't using any parameters, but rather using environment variables, so we don't need to use these. + +#### Mapping the Production stage +Now go ahead and perform the same steps from **Mapping the QA stage** for the **Production** stage. You'll need to target the Production environment instead of the QA environment. +![Map production](23.png) + +And with that, you've configured everything needed for these deployments to be part of the release. +![Map production](24.png) + +## Running the release +While nothing in the application has changed, it would be a shame after going through all those configurations to not kick it off. + +Go ahead and click the **Run pipeline** option from the floating blue button on the right-side of the page. Leave the default options so that it will run across all three stages. Then click **Run**. + +![Run the release](25.png) +![Run the release](26.png) +![Running release](27.png) +![Running release](28.png) + +And there you have it, your release successfully deployed. The live applications haven't changed since no changes were made to the code, but here you can access them again if you'd like to verify. + + + + + +Before, when we were looking at the audit reports, the deployments were empty since we hadn't done any yet. Now if you go back there you can see that those details are showing up. (You can access the audit report by going to **Actions > Audit Report > Deployments** on the release run) +![Running release](29.png) + +## Up next +In this lab you updated your release to actually perform the application deployments. Next up we'll look at how you can take this release pipeline and turn it into a self-service catalog item. + + + + + diff --git a/labs/cloudbees-cdro-compliance/content/labs/07_template-release-as-a-pipeline.md b/labs/cloudbees-cdro-compliance/content/labs/07_template-release-as-a-pipeline.md new file mode 100644 index 00000000..fad95916 --- /dev/null +++ b/labs/cloudbees-cdro-compliance/content/labs/07_template-release-as-a-pipeline.md @@ -0,0 +1,213 @@ +--- +title: "Pipelines and Releases" +chapter: false +weight: 7 +--- + +Now that you've spent all the time getting your release just right, you aren't going to want to create it from scratch again the next time you need a release. + +You started your release from an existing self-service catalog item. In this lab, you're going to look at another way of building the steps in the release. For this lab we are going to build a *pipeline*. Pipelines are kind of like releases in that they will allow us to orchestrate several steps over many stages. We can even have entry and exit gates to the different stages. Pipelines however do not keep track of planned start and end dates or support the deployer task. Once we define a pipeline we can use it as the basis for our new releases. + +Normally, you could define a pipeline similar to the way we built the stages in our release. For this lab and to save you the trouble of building the pipeline over by providing the DSL code here for you to use. + +# Building the Pipeline from DSL + +The DSL code to create our release as a pipeline is as follows: + +```groovy +def CurrentUser = getProperty("/myUser/userName").value +pipeline 'pipeline_Base', { + projectName = CurrentUser + + formalParameter 'ec_stagesToRun', { + expansionDeferred = '1' + } + + stage 'Release Readiness', { + colorCode = '#289ce1' + pipelineName = 'pipeline_Base' + gate 'PRE', { + } + + gate 'POST', { + task 'No Code Smells', { + gateCondition = '$[/javascript myStageRuntime.tasks[\'Get latest SonarQube scan results\'].job.getLastSonarMetrics.code_smells != null || myStageRuntime.tasks[\'Get latest SonarQube scan results\'].job.getLastSonarMetrics.code_smells < 1]' + gateType = 'POST' + subproject = CurrentUser + taskType = 'CONDITIONAL' + } + } + + task 'Git changelog', { + actualParameter = [ + 'branch': 'main', + 'commit': '', + 'config': '/projects/CloudBees/pluginConfigurations/cb-bot', + 'depth': '', + 'gitRepoFolder': '/tmp/demo-app', + 'mirror': 'false', + 'overwrite': 'true', + 'pathspecs': '', + 'referenceFolder': '', + 'repoUrl': 'https://github.com/cloudbees-days/cdro-workshop-demo-app', + 'resultPropertySheet': '/myJob/clone', + 'shallowSubmodules': 'false', + 'submodules': 'false', + 'tag': '', + ] + stageSummaryParameters = '[{"name":"cloneData","label":"cloneData"}]' + subpluginKey = 'EC-Git' + subprocedure = 'Clone' + taskType = 'PLUGIN' + } + + task 'Get latest SonarQube scan results', { + actualParameter = [ + 'config': '/projects/Default/pluginConfigurations/SonarQube', + 'resultFormat': 'propertysheet', + 'resultSonarProperty': '/myJob/getLastSonarMetrics', + 'sonarMetricsComplexity': 'all', + 'sonarMetricsDocumentation': 'all', + 'sonarMetricsDuplications': 'all', + 'sonarMetricsIssues': 'all', + 'sonarMetricsMaintainability': 'all', + 'sonarMetricsMetrics': 'all', + 'sonarMetricsQualityGates': 'all', + 'sonarMetricsReliability': 'all', + 'sonarMetricsSecurity': 'all', + 'sonarMetricsTests': 'all', + 'sonarProjectKey': 'demo-app', + 'sonarProjectName': 'demo-app', + 'sonarProjectVersion': '', + 'sonarTaskId': '', + 'sonarTimeout': '', + ] + subpluginKey = 'EC-SonarQube' + subprocedure = 'Get Last SonarQube Metrics' + taskType = 'PLUGIN' + } + } + + stage 'Quality Assurance', { + colorCode = '#ff7f0e' + pipelineName = 'pipeline_Base' + gate 'PRE', { + } + + gate 'POST', { + } + + task 'Deploy to QA', { + deployerRunType = 'serial' + subproject = CurrentUser + taskType = 'DEPLOYER' + } + } + + stage 'Production', { + colorCode = '#2ca02c' + pipelineName = 'pipeline_Base' + gate 'PRE', { + task 'Manual approval', { + gateType = 'PRE' + notificationEnabled = '1' + notificationTemplate = 'ec_default_gate_task_notification_template' + subproject = CurrentUser + taskType = 'APPROVAL' + approver = [ + CurrentUser, + ] + } + } + + gate 'POST', { + } + + task 'Deploy to Production', { + deployerRunType = 'serial' + subproject = CurrentUser + taskType = 'DEPLOYER' + } + } +} +``` + +If you were to go to the DSL IDE by going to the "burger menu" and going to **DevOps Essential > DSL IDE** you can paste this code and run it. This should run just fine. + +![DSL IDE](1.png) +![DSL IDE](2.png) +![DSL IDE](3.png) + +The operations here are idempotent, meaning you can run them over and over without issue. It will make sure that the described state is the state in the system. + +In this case, we've used DSL and created a new pipeline. We can see this pipeline by going to the "burger menu" and going to **Release Orchestration > Pipelines**. + +![DSL Template](4.png) +![DSL Template](5.png) + +Now I can use this pipeline to create releases. Since the deployer tasks are generic I can release any application with this pipeline. I will need to define the applications, environments and processes for each release though. Let's try that now then we will see how we cand automate even that. + +## Starting a Release from a Pipeline + +To start our release based on our new pipeline lets go to the "burger menu" and going to **Release Orchestration > Releases** and creating a new release, by clicking on the **New +** button. + +![Releases](7.png) +![New Release Button](6.png) + +The **New Release** dialog screen will popup. We are going to be selecting **Create new...** + +![New Release Step1](8.png) + +Next you will be prompted to provide some more information about the release as follows: + +![New Release Step2](9.png) + +Fill in this form for your release and click **Next**. + +![New Release Step3](10.png) + +We are going to create our release from the pipeline we just created from DSL. You can use the drop down at the top left to filter down to your project (`my-username`) and select your `pipeline_Base` + +![New Release](11.png) + +Click **OK** then **OK** and we have a new release. + +![New Release](12.png) + +We could start this release, but we haven't defined what applications will be deployed, which environments they will be deployed to and what process to use to deploy them. Let's do that now. + +## Defining what we want to deploy + +To define what we are deploying in the **Deployer** tasks in this release we will fist need to define what applications this release will be deploying. To do that we will first click on the **Applications** button. + +![Application Dialog](14.png) + +Now we have our application associated with the release + +![Application selected](15.png) + +Now lets define the environments and processes by clicking on **Envs & Configs** button. + +![Application Map1](17.png) + +Select a stage then add an environment + +![Application Map2](18.png) + +Select a stage then add a process + +![Application Map2](19.png) + +![Application Map2](20.png) + +Repeate the process for the next stage. + +![Application Map2](21.png) + +OK, now we are ready to run our new release. Click on the **Run** button + +![Application Map2](23.png) + +# Up Next + +That was a lot of work to start a release. We did make things more repeatable and maintainable, but moving most of our logic to the **pipeline**. We still had a lot of work to do once we started the release. Let's make that simpler next by creating a **Service Catalog** \ No newline at end of file diff --git a/labs/cloudbees-cdro-compliance/content/labs/08_catalog.md b/labs/cloudbees-cdro-compliance/content/labs/08_catalog.md new file mode 100644 index 00000000..48f4361a --- /dev/null +++ b/labs/cloudbees-cdro-compliance/content/labs/08_catalog.md @@ -0,0 +1,174 @@ +--- +title: "Self-service catalog" +chapter: false +weight: 8 +--- + +Now we have created the release in two ways. First we started with a basic release from the service catalog, then we created a pipeline and used that to start our release. The first way was nice because we just used the **Service Catalog** to start the release, but we needed to customized it a lot. The second way was nice because it gave us a nice way to see what the release pipeline would look like and a easy way to modify it before starting the release. + +Next, lets combine both methods together to give us a nice way to start a release by selecting the pipeline we want to use for the release and automatically add an application. We have been using DSL more and more through this workshop and here we will use DSL to define our new **Service Catalog** item. + +Again I have provided some DSL code so you don't need to write it all your self. + +## Getting familiar with the DSL + +Almost everything in the platform can be described as DSL. In fact, on most objects like releases, application models, environment models, permissions, and more you can click on the action menu and click **DSL Export** to get the code. + +When on the page for your release, you'll see a menu item at the top that says **DSL Editor** where you can directly see the DSL for this release pipeline. + +![Grabbing the DSL](1.png) +![DSL editor](2.png) + +As you navigate around, you'll see the different tasks that you've created. For instance, below is the manual approval we added in Lab 1. + +![Manual approval DSL](3.png) + +One thing you'll probably notice is that there are a lot of null values. This can be useful to see all the fields that are available to you, however when we export this we'll have an option to remove the blank fields so that we are only left with the fields that have been modified. + +An important note is that this is two-way bound. As you make changes in the DSL and save it, that will reflect in the **Release Editor** view. When you add tasks as we did in the previous labs, that will reflect in the DSL. + +It is beyond the scope of this workshop, but you can also [sync DSL with a git repository](https://docs.cloudbees.com/docs/cloudbees-cd/latest/configure/source-code-synchronization) to enable a GitOps approach for managing the configuration of your environment. + + +## Creating the self-service catalog with DSL + +I have already create some DSL you can use for your new catalog item as follows: + +```groovy +def CurrentUser = getProperty("/myUser/userName").value + +catalog CurrentUser, { + iconUrl = null + projectName = CurrentUser + + catalogItem 'Create Release From Pipeline', { + description = ''' + + Create a new released based on pipeline templates + + + + + + ''' + buttonLabel = 'Create' + catalogName = CurrentUser + dslString = '''def StartDate = (new Date()) + def StartDateStr = (String) StartDate.format( "yyyy-MM-dd" ) + def EndDateStr = (String) (StartDate+14).format( "yyyy-MM-dd" ) + + release args.releaseName, { + projectName = args.targetProject + + plannedStartDate = StartDateStr + plannedEndDate = EndDateStr + + pipelineProjectName = args.templateProject + pipelineName = args.templateRelease + + Release_Name = args.releaseTag + String[] tags = args.releaseTag.replaceAll("[.]", "").split(","); + for (String tagItem: tags) { + tag tagItem + } + + deployerApplication args.applicationName, { + processName = 'Deploy Application' + deployerConfiguration 'QA', { + deployerTaskName = 'Deploy to QA' + environmentName = 'QA' + processName = 'Deploy Application' + stageName = "Quality Assurance" + } + deployerConfiguration 'PROD', { + deployerTaskName = 'Deploy to Production' + environmentName = 'QA' + processName = 'Deploy Application' + stageName = "Production" + } + } + + + }''' + endTargetJson = '''{ + "source": "parameter", + "object": "release", + "objectName": "releaseName", + "objectProjectName": "targetProject", + "objectId": "id" + }''' + iconUrl = 'icon-pipeline.svg' + projectName = CurrentUser + useFormalParameter = '1' + + formalParameter 'templateProject', defaultValue: 'Default', { + label = 'Template Project' + orderIndex = '1' + required = '1' + type = 'project' + } + + formalParameter 'templateRelease', defaultValue: 'pipeline_Base', { + label = 'Template Release' + orderIndex = '2' + projectFormalParameterName = 'templateProject' + required = '1' + type = 'pipeline' + } + + formalParameter 'targetProject', defaultValue: CurrentUser, { + label = 'Target Project' + orderIndex = '3' + required = '1' + type = 'project' + } + + formalParameter 'releaseName', { + label = 'Release Name' + orderIndex = '4' + required = '1' + type = 'entry' + } + + formalParameter 'releaseTag', { + label = 'Release Tags' + orderIndex = '5' + required = '1' + type = 'entry' + } + + formalParameter 'applicationName', defaultValue: 'Workshop App', { + expansionDeferred = '0' + label = 'Application Name' + orderIndex = '6' + projectFormalParameterName = 'targetProject' + required = '1' + type = 'application' + } + + } + +} +``` + +Now this DSL can give us a release based on a release pipeline just like we did in the last module, but it also lets us specify an application. With that information it will have enough to generate a new release just like last time. + +If you were to go to the DSL IDE by going to the "burger menu" and going to **DevOps Essential > DSL IDE** you can paste this code and run it. This should run just fine. + +![DSL IDE](6.png) +![DSL IDE](7.png) +![DSL IDE](8.png) + +Now your catalog item is ready to go. You can switch back over to the usable catalog list by clicking on **Serive catalog** at the top. +![New SSC](25.png) + +Now you can create a new release from this template: +![New SSC](26.png) + + + + + + diff --git a/labs/cloudbees-cdro-compliance/content/labs/_index.md b/labs/cloudbees-cdro-compliance/content/labs/_index.md index 840e1a49..30fb4590 100644 --- a/labs/cloudbees-cdro-compliance/content/labs/_index.md +++ b/labs/cloudbees-cdro-compliance/content/labs/_index.md @@ -6,14 +6,19 @@ weight: 1 # Completing the hands-on labs -The step-by-step labs are provided to introduce you to the key features and applications of CloudBees CD/RO. The instructions are self-contained and can be performed with no further background so that you can be successful right away. +The step-by-step labs are provided to introduce you to the key features of CloudBees CD/RO. The instructions are self-contained and can be performed with no further background so that you can be successful right away. It is also recommended that you read the product features pages in the [CloudBees CD/RO documentation](https://docs.cloudbees.com/docs/cloudbees-cd/latest/) so you can get a practical understanding of the software. You can do this before or after you complete the examples. Workshop Labs: -- Creating a basic release -- Deploying a microservice and creating an application model -- Exploring the environment modeling -- Adding the deployment to the release -- Exploring the self-service catalog +- Creating A Release From the Service Catalog +- Release Quality Gates +- Dealing with Security Exceptions +- Gathering Release Evidence +- Audit Ready Pipelines +- Release Command Center Dashboard +- CloudBees Compliance +- Compliance Overview +- Compliance Verification and Remediation +