Using Octopus Deploy, how can I deploy an entire application stack while having separation of duties while also only deploying what changed?

My application, Octo Pet Shop, has four components, a database, a shopping cart service, a product service, and a website. I have four environments, Development, Testing, Staging and Production.

The application has a single repo, but each component has its own build. Each component build monitors for changes in specific folders. For example, the database build looks for changes in the database folder. The build will trigger an automatic deployment to dev. We did this in the event we wanted to move to separate repos for each component. Only the repo the build monitors would need to change.

Very rarely does a merge to master include all three components. Typically it is Database + Windows Service or Database + Web. When pushing up to Test/Staging/Production, I only want to push the components which changed. They have to go in a specific order, database, then service, then web. I also want to configure notification and approvals, but only certain people should be able to change notification and approvals.

The teams I have are:

  • Developer: Can deploy to Dev and Test, can change application-specific projects.
  • QA: Approves releases to Staging and Production
  • Business Owner: Approves releases to Staging and Production
  • Auditor: Reviews deployments and looks at the audit log
  • Operations: Triggers deployments to Staging and Production

There is quite a bit to unpack here.

  1. Only want to deploy packages/projects which have changed.
  2. Developers can deploy to test, and can edit projects related to their application. But shouldn’t have permission to remove the manual intervention step.
  3. Projects have to be deployed in a specific order.
  4. Want to have a single project per application. Don’t want to duplicate effort.

Project Configuration

To start with, each application component should get its own project in Octopus Deploy.

The project for each component can have 1 to N number of steps. The build server could have a build for each project/component or it could have a single build for the entire stack. The reason for going with a build per project/component is the build can be configured to watch folders in the repo and only build when specific items are changed. And each build will be small and quick.

Either way, the build server will create the release and deploy that automatically to Development.

The build server is responsible for Development. How do those releases make it to Test, Staging, and Production?

If you opted for a build per project/component then applications were deployed to Development in a random order.

image

Deploying to the other environments requires a specific the database is deployed first, then the services, then the website.

This is where the deploy a release step comes in. Using that step a new project is created to deploy applications in a specific order. In addition, this is the project with the approvals.

Unlike the other projects, this project’s lifecycle starts in Test.

image

On each deploy a release step, the deployment condition will be changed to if the selected release has a higher version than the current release in the environment. Setting that will prevent redeployments of the same version.

Permissions

Permissions are how we are going to handle the separation of duties. Let’s start with the Developer.

  • They have permission to deploy to Development and Test for each project/component.
  • Permission to make changes for each project/component deployment process.
  • Only have permissions to create a release for the Deploy All project.

When signed as the Developer I can see in each project/component I have permissions to deploy to Test. No icon appears in Staging and Production indicating I don’t have permission to deploy to those environments.

Going into the Deploy All deployment process I see I don’t have permission to edit that process. I cannot change or remove those steps either.

As a developer, I can create a release for that project.

I can deploy that project to Test.

Just like the other projects, the Developer cannot deploy to Staging or Production.

I did add the following permissions to Release Creator to get that to work.

The operations team is the one responsible for the Deploy All project.

  • They have permission to modify Deploy All (that can be removed if the modify permission needs to be on another team).
  • They have permission to create/deploy releases for any project in any environment.
  • The do not have permission to modify the individual component projects.

Signing as an Operations person shows I don’t have permission to edit the component projects.

But I do have permission to deploy the latest release for the component project to Staging and Production.

The same is true for the Deploy All project.

I can also edit the Deploy All project.

I can easily trigger the deployment to staging. However, I do not have permission to approve the release.

That is the responsibility of someone from the QA team. They can view the project and take responsibility.

Deploying Only Components which changed

When a release is created for a project using the deploy a release step it will use the latest release of the child project. For example, I have pushed up a new version of the DB and Website. The two services are unchanged.

image

When I create the release for the Deploy All project, I can see that by default the new version of the database and website are selected.

I could exclude the service steps when I deploy it to Test.

But as I said earlier, I already configured the deployment condition to if the selected release has a higher version than the current release in the environment. Setting that will prevent redeployments of the same version.

When it tries to deploy that pre-existing version this message appears.

It takes a bit of setup, but it is possible to meet all those conditions.

1 Like