Octopus Deploy Documentation

Deploy a Ruby application to NGINX using Octopus and Bamboo

In this tutorial, we show you how to build a fully-functional continuous delivery pipeline for a simple Ruby web application and deploy it to NGINX. We use Bamboo to build the code and run tests, and we use Octopus Deploy to deploy and promote releases.

To get up and running quickly, the TestDrive VMs provide preconfigured environments demonstrating various continuous delivery pipelines documented in these guides.

Video walkthrough

Introduction

The application we'll deploy is called Random Quotes, which is a simple web application that randomly displays a famous quote each time the page loads. It consists of a web front end and a database that contains the quotes. We'll build a complete Continuous Integration/Continuous Delivery (CI/CD) pipeline with automated builds, deployments to a dev environment, and sign offs for production deployments.

Deployment pipeline

For this tutorial, we assume you use Git for version controlling changes to your source code and Bamboo to compile code and run unit tests. Octopus Deploy will take care of the deployment. Here is what the full continuous integration and delivery pipeline will look like when we are finished:

Git C# C# C# TeamCity Artifactory create release DEV TEST PRODUCTION Release 1.1

The development team's workflow is:

  1. Developers commit code changes to Git.
  2. Bamboo detects the change and performs the continuous integration build, this includes resolving any dependencies and running unit tests.
  3. When the Bamboo build completes, the change will be deployed to the Dev environment.
  4. When one of your team members (perhaps a tester) wants to see what's in a particular release, they can use Octopus to manually deploy a release to the Test environment.
  5. When the team is satisfied with the quality of the release and they are ready for it to go to production, they use Octopus to promote the release from the Test environment to the Production environment.

Since Octopus is designed to be used by teams, in this tutorial we also set up some simple rules:

  • Anyone can deploy to the dev or test environments.
  • Only specific people can deploy to production.
  • Production deployments require sign off from someone in our project stakeholders group.
  • We'll send an email to the team after any test or production deployment has succeeded or failed.

This tutorial makes use of the following tools:

Octopus is an extremely powerful deployment automation tool, and there are numerous ways to model a development team's workflow in Octopus Deploy, but this tends to be the most common for small teams. If you're not sure how to configure Octopus, we recommend following this guide to learn the basics. You'll then know how to adjust Octopus to suit your team's workflow.

This tutorial takes about an hour to complete. That sounds like a long time, but keep in mind, at the end of the tutorial, you'll have a fully-functional CI/CD environment for your entire team, and you'll be ready to deploy to production at the click of a button. It's worth the effort!

Build vs. deployment

For any non-trivial application, you're going to deploy the software to multiple environments. For this tutorial, we're using the environments Dev, Test, and Prod. This means you need to choose between building your application once or building it before each deployment? To reduce the risk of a failed production deployment, Octopus strongly encourages the practice of building once, and deploying multiple times.

The following activities are a build time concern, so they will happen in Bamboo after any change to code is committed to Git:

  1. Check out the latest changes from Git.
  2. Resolve and install any dependencies from RubyGems.
  3. Run unit tests.
  4. Package the application by bundling all the files it needs to run into a ZIP file.

This results in a green CI build and a file that contains the application and everything it needs to run. Any configuration files will have their default values, but they won't know anything about dev vs. production settings just yet.

Lastly, it's very important that we give this artifact a unique version number. We will produce a new artifact file every time our CI build runs, and we don't want to accidentally deploy a previous version of the artifact.

An example of a package that is ready to be deployed is:

RandomQuotes.1.0.0.zip

At this point, we have a single artifact that contains all the files our application needs to run, ready to be deployed. We can deploy it over and over, using the same artifact in each environment. If we deploy a bad release, we can go and find the older version of the artifact and re-deploy it.

The following activities happen at deployment time by Octopus Deploy:

  1. Changing any configuration files to include settings appropriate for the environment, e.g., database connection strings, API keys, etc.
  2. Running tasks that need to be performed during the deployment such as database migrations or taking the application temporarily offline.

Prerequisites

There are a number of tools you need to install to implement a complete CI/CD workflow. These include the Bamboo and Octopus servers, some command-line tools, and NGINX to host the final deployment.

Git

The source code for the sample application is hosted on GitHub. To access the code, you need the Git client. The Git documentation has instructions to download and install the Git client.

Bamboo

Bamboo offers a free trial and can be downloaded from the project's website.

Octopus CLI

Bamboo calls the Octopus CLI tool to create and deploy releases in the Octopus Server. The Octopus CLI can be downloaded from the Octopus downloads page or installed from Chocolatey.

The Octopus CLI tool must be installed on the Bamboo server or any agents that will execute the Bamboo project.

Ruby

A Ruby distribution is required to run the sample application. Ruby is available from the Ruby homepage.

Octopus Deploy

The installation file used to install Octopus Server on-premises can be downloaded here.

Octopus requires a Microsoft SQL Server to host the database. Microsoft SQL Server Express can be downloaded for free here.

Complete the following steps to install Octopus:

  1. Start the Octopus Installer, click Next, accept the Terms in the License Agreement and click Next.
  2. Accept the default Destination Folder or choose a different location and click Next.
  3. Click Install, and give the app permission to make changes to your device.
  4. Click Finish to exit the installation wizard and launch the Getting started wizard to configure your Octopus Server.
  5. Click Get started... and either enter your details to start a free trial of Octopus Deploy or enter your license key and click Next.
  6. Accept the default Home Directory or enter a location of your choice and click Next.
  7. Decide whether to use a Local System Account or a Custom Domain Account.

Learn more about the permissions required for the Octopus Windows Service or using a Managed Service Account.

  1. On the Database page, click the dropdown arrow in the Server Name field to detect the SQL Server database. Octopus will create the database for you which is the recommended process; however, you can also create your own database.
  2. Enter a name for the database, and click Next and OK to create the database.

Be careful not to use the name of an existing database as the setup process will install Octopus into that pre-existing database.

  1. Accept the default port and directory or enter your own. This guide assumes Octopus is listening on port 80. Click Next.
  2. If you’re using a username and passwords stored in Octopus authentication mode, enter the username and password that will be used for the Octopus administrator. If you are using active directory, enter the active directory user details.
  3. Click Install.
  4. When the installation has completed, click Finish to launch the Octopus Manager.

NGINX

NGINX is used as a reverse proxy to expose web applications running in Linux. NGINX can be downloaded from your Linux package manager.

NGINX may be configured to listen on port 80 by default. If this conflicts with other services (this guide assumes Octopus is running on port 80), you will need to change it. Open the file /etc/nginx/sites-enabled/default and locate the following line:

listen 80 default_server;

Change the port number:

listen 4444 default_server;

Restart the nginx service.

Clone source code

The source code for the random quotes application is hosted in GitHub. The code can be cloned from https://github.com/OctopusSamples/RandomQuotes-Ruby.git with the command:

git clone https://github.com/OctopusSamples/RandomQuotes-Ruby.git

Octopus API key

In order to allow Bamboo to communicate with Octopus, we need to generate an API key. This is done in the Octopus web portal. The web portal can be opened from the Browse link in the Octopus Manager:

From the Octopus Deploy web portal, sign in, and view your profile:

Go to the API keys tab. This lists any previous API keys that you have created. Click on New API key:

Give the API key a name so that you remember what the key is for, and click Generate New:

Copy the new API key to your clipboard:

Continuous integration

Bamboo from Atlassian is a popular continuous integration server. In this tutorial, we rely on Bamboo to do the following:

  • Clone the code from Git.
  • Resolve and install any dependencies from RubyGems.
  • Run unit tests.
  • Package the application by bundling all the files it needs to run into a ZIP file.
  • Push the package to the Octopus (built-in) package repository.

Install the plugins

The Bamboo deployment process uses the Octopus Bamboo add-on. This add-on can be downloaded from the Atlassian Marketplace.

Log into Bamboo, click the gear icon, and click the Overview link:

Click the Manage apps link:

Click the Upload app link:

Select the JAR file downloaded from the Atlassian Marketplace and clickUpload:

After the add-on has been installed, click the Close link:

Configure the executables

A number of build steps rely on external executables, which we will configure with the following steps.

Log into Bamboo, click the gear icon, and click the Overview link:

Click the Server capabilities link:

Next, we need to define paths to the Octopus CLI executable. Click the Server capabilities link and scroll to the Add capability section.

Select Executable as the Capability type, Octopus CLI as the Type, enter Octopus CLI as the Executable label, and then enter the path to the Octopus CLI executable. On Linux system it will be the location where the CLI was manually extracted, for example /opt/octo/Octo. On Windows systems the path will be C:\ProgramData\chocolatey\bin\Octo.exe if it was installed by Chocolatey. Then click Add:

Create the Bamboo project

We are now ready to define how the project will be built by Bamboo. Log into Bamboo and click Create your first build plan:

Enter Random Quotes for the Project name and Website for the Plan name:

Select the Git option as the Repository host, enter Random Quotes GitHub as the Display name, and enter https://github.com/OctopusSamples/RandomQuotes-Ruby.git as the Repository URL:

Click Test connection. If the Git executable has been configured correctly, you will see the message Connection successful.

Click Configure plan:

Click Add task:

Enter Script into the search box, and click the Script task tile:

Enter the following script as the Command:

# Set the default gem installation path to a directory alongside the Ruby application code.
# This allows the dependencies to be packaged with the application.
export GEM_HOME="$WORKSPACE/vendor"
export GEM_PATH="$WORKSPACE/vendor"
export PATH="$PATH:$WORKSPACE/vendor/bin"
# Install the specific version of Bundler defined in the Gemfile.lock file
gem install bundler -v "$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n 1)"
# Use bundler to install the other dependencies
bundle install
# Run the tests
rspec spec/index_spec.rb

Click Add task:

Enter Octopus into the search box, and click the Octopus Deploy: Pack Package task tile:

Enter RandomQuotes as the Package ID and 1.0.${bamboo.buildNumber} as the Version number:

Select the nuget Package format, enter ${bamboo.build.working.directory} as both the Base and Output folder, and click Save:

Click Add task:

Enter Octopus into the search box, and click the Octopus Deploy: Push Packages task tile:

Enter the Octopus URL and API key, and enter RandomQuotes.1.0.${bamboo.buildNumber}.nupkg as the Package paths. Click Save:

Click Create:

Click the build link:

After the build completes, the package will be pushed to the Octopus built-in feed.

Deploying with Octopus Deploy

Now that Bamboo has successfully built the application, we need to configure Octopus to deploy it into our environments.

Create the environments

Environments represent the stages that a deployment must move through as part of the deployment pipeline. We'll create three environments: Dev, Test, and Prod.

Log into Octopus, and click the Infrastructure link, then the Environments link, and click ADD ENVIRONMENT:

Enter Dev as the New environment name, and click SAVE:

Repeat the process for the Test and Prod environments:

Create the Octopus deployment project

With the environments defined and a target created, we now need to create a deployment project in Octopus.

Log into Octopus, click the Projects link, and click ADD PROJECT:

Enter Random Quotes for the project name, and click SAVE:

We start by defining the variables that we will consume as part of the deployment. Click the Variables link, and then select the Project option:

We define a variable called Nginx Port with unique values bound to each environment. This means that when we deploy the project to each environment, a new port will be used to expose the application via NGINX.

By exposing each environment as a unique port, we can implement multiple environments with a single physical target.

  • Define a value of 8081 scoped to the Dev environment.
  • Define a value of 8082 scoped to the Test environment.
  • Define a value of 8083 scoped to the Prod environment.

Save the changes by clicking SAVE:

We will now define the deployment process. Click the Deployments link, then click the Overview link, then click DEFINE YOUR DEPLOYMENT PROCESS:

Click ADD STEP:

Enter Nginx into the search box:

Click ADD on the Deploy to NGINX tile:

Enter Deploy web app to Nginx as the Step Name:

Enter web as the Role:

Select the RandomQuotes package:

Enter the following scripts in the Post-deployment script text area. This script creates a systemd service file to launch the Unicorn web server hosting the Ruby application we just deployed, reloads the systemd configuration, and starts or restarts the service:

SYSTEMD_CONF=/etc/systemd/system
SERVICE_USER=$(whoami)
ENVIRONMENT=#{Octopus.Environment.Name}

# This is used to generate the systemd filename, so we remove any chars that might be problematic for filenames
APPNAME=#{Octopus.Action[Deploy web app to Nginx].Package.PackageId | Replace "[^a-zA-Z0-9]" -}-#{Octopus.Environment.Name}
# This path is referenced by the systemd service in multiple places, and systemd treats the % char as special,
# so it is escaped with a second % char
ROOTDIR=#{Octopus.Action[Deploy web app to Nginx].Output.Package.InstallationDirectoryPath | Replace "%" "%%"}
SYSTEMD_SERVICE_FILE=${SYSTEMD_CONF}/${APPNAME}.service

# Application systemd service configuration
echo "Creating ${APPNAME} systemd service configuration"
cat > "${APPNAME}.service" <<-EOF
[Unit]
Description=${APPNAME} service
After=network.target

[Service]
# Expose the gems that were bundled up with the application package
Environment=GEM_PATH=${ROOTDIR}/vendor
Environment=PATH=${PATH}:${ROOTDIR}/vendor/bin
WorkingDirectory=${ROOTDIR}
User=${SERVICE_USER}
Group=${SERVICE_USER}
ExecStart=${ROOTDIR}/vendor/bin/unicorn -c ${ROOTDIR}/unicorn.rb -E ${ENVIRONMENT}
Restart=always
RestartSec=10
SyslogIdentifier=${APPNAME}
[Install]
WantedBy=multi-user.target
EOF
sudo mv "${APPNAME}.service" ${SYSTEMD_CONF}/${APPNAME}.service

# Ensure the bin files are executable
chmod +x -R "#{Octopus.Action[Deploy web app to Nginx].Output.Package.InstallationDirectoryPath}/vendor/bin"

# Any changes to a system file are picked up by reloading the systemd daemon
sudo systemctl daemon-reload
# Enable the service so it starts on boot
sudo systemctl enable "${APPNAME}.service"
# Start or restart the service to pick up any changes
sudo systemctl restart "${APPNAME}.service"

There are few settings in this systemd service file worth calling out.

Note the line Environment=GEM_PATH=${ROOTDIR}/vendor. This line sets the GEM_PATH environment variable to ${ROOTDIR}/vendor, which ensures that the gem dependencies bundled into the package alongside the Ruby application code are made available to the application.

Also note the line ExecStart=${ROOTDIR}/vendor/bin/unicorn -c ${ROOTDIR}/unicorn.rb -E ${ENVIRONMENT}. This is where the Unicorn server is run, defining the RACK_ENV environment to the name of the Octopus environment with the arguments -E ${ENVIRONMENT}. The RACK_ENV environment is referenced by the Ruby application to return the name of the current environment via the API endpoint it exposes.

Remove the default binding by clicking the cross icon:

Click ADD BINDING:

Enter #{NGINX Port} for the port, and click OK. This configures NGINX to listen on the specified port, which in this case, is one of the variables we defined earlier.

Click ADD LOCATION:

Enter @app for the Location, check the Reverse Proxy check box, and enter http://unix:#{Octopus.Action.Package.InstallationDirectoryPath}/tmp/sockets/unicorn.sock for the URL. This configures NGINX to direct traffic to the Unicorn server managed via systemd. The path to the socket file is defined in the unicorn.rb file.

Click ADD LOCATION:

The Ruby application is made up of static HTML and JavaScript resources as well as Ruby REST API endpoints. To serve this application, NGINX must first attempt to match the HTTP request to a static file, and if that fails then pass the request to the Ruby application. To implement this solution we need two locations.

The first location is used to redirect a request to the root path to the index.html file. Enter = / for the Location. This location defines an exact match to the root path. Click ADD DIRECTIVE and define a directive called index with a value of index.html. The index directive redirects requests to a default page.

Click OK to save the location:

Click ADD LOCATION:

The second location attempts to serve static resources if they match the request. Enter / for the Location. This location defines a match for all requests that do not match another more specific location.

Add two directives to the location.

The first directive is called root, and has a value of #{Octopus.Action.Package.InstallationDirectoryPath}/lib/public. This directive defines the directory NGINX will attempt to find static resources in. The Octopus.Action.Package.InstallationDirectoryPath variable resolves to a path like /home/Octopus/Applications/Dev/RandomQuotes/1.0.1, which contains the files from the extracted package.

The second directive is called try_files, and has a value of $uri @app. This directive instructs NGINX to first attempt to serve a file that matches the request. If no file can be found, the request is redirected to the @app location, which will proxy the request to the Unicorn server, which executes the Ruby application.

Click OK to save the location:

Click SAVE:

Deploy!

We now have a deployment project in Octopus ready to deploy our Ruby application to our Dev, Test, and Prod environments. The next step is to create and deploy a release.

Click CREATE RELEASE.

The release creation screen provides an opportunity to review the packages that will be included and to add any release notes. By default, the latest package is selected automatically. Click SAVE:

This screen allows you to select the environment that will be deployed into. Lifecycles can be used to customize the progression of deployments through environments (this is demonstrated later in the guide), however, we will accept the default option to deploy to the Dev environment by clicking DEPLOY TO DEV...:

Click DEPLOY to deploy the application into the Dev environment:

The application is then deployed:

Congratulations! You have now built and deployed your first application. Visit http://localhost:8081 in a browser to view a random quote. Note the port matches the variable Nginx Port that we assigned to the environment. Ensuring each environment deploys to a unique port is how we can use a single virtual machine to host multiple environments:

Continuous deployments

The process of deploying a successful build to the Dev environment is currently a manual one; Bamboo pushes the file to Octopus, and we must trigger the initial deployment to the Dev environment from within Octopus. Typically though, deployments to the Dev environment will be performed automatically if a build and all of its tests succeed.

To trigger the initial deployment to the Dev environment after a successful build, we will go back to the project we created in Bamboo and add an additional step to create an Octopus release and then deploy it to the Dev environment.

Add a create and deploy release step

We make use of the Octopus add-in to interact with the Octopus server. In this case, we use an add-in task to create and deploy a release in Octopus after the package has been pushed.

Log back into Bamboo, and click the edit icon next to the Random Quotes project link:

Click the Default job link:

Click Add task:

Enter Octopus into the search box, and click the Octopus Deploy: Create Release task tile:

Enter the Octopus URL and API key:

Enter Random Quotes as the Project:

Enter Dev as the Environment(s), and click Save:

Click Run, and then select Run plan:

When the build is complete, a deployment will have been triggered in Octopus to the Dev environment.

We now have a complete CI/CD pipeline! Bamboo will watch for any changes committed to the Git repository, compile the code, run any tests, and then call Octopus to deploy the result.

Additional configuration

Now we will explore some of the more advanced features of Octopus that allow us to customize the deployment progression through environments, secure deployments to production environments, add deployment sign offs, view the audit logs, and add notifications.

Lifecycles

Our project currently uses the default lifecycle, which defines a progression through all the environments in the order they were created.

A custom lifecycle allows the progression of a deployment to be further refined, by defining only a subset of environments that can be deployed to, allowing some environments to be skipped entirely, or requiring that a minimum number of environments are successfully deployed to before moving onto the next environment.

Here we will create a custom lifecycle that makes deployments to the Dev environment optional. This means that initial deployments can be made to the Dev or Test environments, but a successful deployment must be made to the Test environment before it can be progressed to the Prod environment.

Skipping the Dev environment like this may be useful for promoting a release candidate build directly to the Test environment for product owners or testers to review.

Click the Library link, click the Lifecycles link, and click ADD LIFECYCLE:

Set the lifecycle name to Dev, Test, and Prod, and the description to Progression from the Dev to the Prod environments:

Phases are used to group environments that can accept a deployment. Simple lifecycles, such as the lifecycle we are creating, have a one-to-one relationship between phases and environments.

Click ADD PHASE:

Enter Dev as the phase name, and select the Optional phase option. This means that deployments can skip this phase and any environments defined in it, and deploy directly to the next phase.

Because we are mapping each environment to its own phase, the name of the phase matches the name of the environment:

Click ADD ENVIRONMENT:

Click the dropdown arrow, select the Dev environment, and click OK:

Repeat the process to add a new phase for the Test and Prod environments, leaving the default All must complete option selected:

Click SAVE:

Now, we need to switch the deployment project from the Default Lifecycle to the newly created lifecycle.

Click the Projects link, and click the Random Quotes project tile:

Click the Process link, and click CHANGE:

Select the Dev, Test, and Prod lifecycle. Notice the Dev environment is shown as optional.

Click SAVE:

Click CREATE RELEASE, and click SAVE to save the new release:

Because the Dev environment has been configured as optional, the initial release can be made to either the Dev or Test environments. We'll skip the Dev environment and deploy straight to Test.

Click DEPLOY TO..., and select the Test environment:

Click DEPLOY to deploy the application to the Test environment:

The deployment is then performed directly in the Test environment, skipping the Dev environment:

Opening http://localhost:8082 displays the copy of the Random Quotes application deployed to the Test environment. Note the port 8082 matches the variable Nginx Port that we assigned to the environment.

Also see the footer text that says running in Test. This is the result of the environment variable RACK_ENV being defined by the -E ${ENVIRONMENT} argument passed to the Unicorn server by systemd.

Approvals

It's a common business requirement to have testers or product owners manually verify that a particular build meets the requirements before a deployment can be considered successful.

Octopus supports this workflow through the use of manual intervention steps. We'll add a manual intervention step to the end of the deployment process, which requires a responsible party to verify the build meets the requirements.

Open the Random Quotes project, click the Process link, and click the ADD STEP button:

Search for the Manual Intervention Required step, and add it to the process:

Enter Deployment Sign Off for the Step Name:

Enter the following for the Instructions:

Open the application and confirm it meets all the requirements.

Because every build is automatically deployed to the Dev environment, it doesn't make sense to force someone to manually approve all those deployments. To accommodate this, we do not enable the manual intervention step for deployments to the Dev environment.

Expand the Environments section under the Conditions heading, select the Skip specific environments option, and select the Dev environment.

Click SAVE to save the step:

When this application is deployed to the Test or Prod environments, a prompt will be displayed requiring manual sign off. Click ASSIGN TO ME to assign the task to yourself:

Add a note in the provided text box, and click PROCEED to complete the deployment:

The deployment will then complete successfully:

Email notifications

Octopus has native support for sending email notifications as part of the deployment process. We will add a step to the deployment process to let people know when a release has been deployed to an environment.

To start, we need to configure an SMTP server to send our emails. For this guide, we'll use the free SMTP server provided by Google.

Click the Configuration link:

Click the SMTP link:

  • Enter smtp.gmail.com as the SMTP Host.
  • Enter 587 as the SMTP Port.
  • Enable the Use SSL/TLS option.
  • Enter your Gmail address as the From Address.
  • Enter your Gmail address and password in the credentials.

You will enable the Less secure apps option on your Google account for Octopus to send emails via the Google SMTP server.

Open the Random Quotes project, click the Process link, and click ADD STEP:

Search for the Send an Email step, and add it to the process:

Enter Random quotes deployment status for the Step Name:

Enter the email address to receive the notification in the To field:

Enter Random quotes deployment status as the Subject:

Enter the following as the Body:

Deployment to #{Octopus.Environment.Name}
#{each step in Octopus.Step}
StepName: #{step}
Status: #{step.Status.Code}
#{/each}

Here we use the #{Octopus.Environment.Name} variable provided by Octopus to add the name of the environment that was deployed to, and then loop over the status codes in the #{Octopus.Step} variable to return the status of each individual step.

The complete list of system variables can be found in the Octopus documentation.

We want to be notified of the status of this deployment regardless of whether the deployment succeeded or failed. Click the Run Conditions section to expand it.

Select the Always run option, which ensures the notification email is sent even when the deployment or the manual intervention fail:

Given every change to the source code will result in a deployment to the Dev environment, we do not want to generate reports for deployments to this environment.

Click the Environments section to expand it. Select the Skip specific environments option, and select the Dev environment to skip it.

This is the last piece of configuration for the step, so click SAVE to save the changes:

Deploy the project to the Test or Prod environments. When the deployment succeeds, the notification email will be sent:

Permissions

One of the strengths of Octopus is that it models environments as first-class entities. This means the security layer can apply rules granting access only to specific environments. We'll take advantage of this ability to model and secure environments to create two users, an internal deployer who can deploy to the Dev and Test environments, and a production deployer who can deploy to the Prod environment.

We start by creating the users. Click the Configuration link:

Click the Users link:

Click ADD USER:

Enter internaldeployer as the Username:

Enter Internal Deployer as the Display Name:

Enter the user's email address. We have used a dummy address of internaldeployer@example.org here:

Enter a password and confirm it. Then click SAVE to create the user:

Repeat the process for a user called productiondeployer. The summary for the productiondeployer user is shown below:

The newly created users are not assigned to any teams and have no permissions to do anything. To grant them permissions, we must first create two teams. The internal deployment team will grant access to deploy to the Dev and Test environments, while the production deployment team will grant access to deploy to the Prod environment.

Click the Configuration link:

Click the Teams link:

Click ADD TEAM:

Enter Internal Deployers for the New team name, and Grants access to perform a deployment to the internal environments for the Team description. Click SAVE to create the team:

We need to add the internaldeployer user to this team. Click ADD MEMBER:

Select the Internal Deployer user from the dropdown list, and click ADD:

The team does not grant any permissions yet. To add permissions click the USER ROLES tab, and click INCLUDE USER ROLE:

Select the Deployment creator role from the dropdown list. As the name suggests, this role allows a user to create a deployment, which results in the deployment process being executed.

Click DEFINE SCOPE:

We only want to allow the internal deployer to deploy to the internal environments. Select the Dev and Test environments, and click APPLY:

The permissions are then applied. We need a second permission to allow the internal deployer to view the projects dashboard. Click INCLUDE USER ROLE again:

Select the Project viewer role. This role does not need to be scoped, so click the APPLY button:

Here are the final set of roles applied to the team:

Repeat the process to create a team called Production Deployers that includes the productiondeployer user, and grants the Deployment creator role scoped to the Prod environment:

When we log in as the internaldeployer user, we see that the Random Quotes project dashboard shows DEPLOY... buttons for the Dev and Test environments. Any deployments in the production environment will be visible, but they cannot be created by this user:

When we log in as the productiondeployer user, we see that the Random Quotes project dashboard shows DEPLOY... buttons only for the Prod environment. Also note that the lifecycle rules still apply, and only successful deployments to the Test environment are available to be promoted to the Prod environment:

Audit Log

Important interactions in Octopus are tracked in the audit log. This is useful for teams that have security or legislative requirements to track the changes and deployments made to their infrastructure.

To view the audit log, click the Configuration link:

Click the Audit link:

A complete list of records are shown, with filtering available to help find specific events:

Conclusion

In this guide we ran through the process of building a complete CI/CD pipeline with:

  • Bamboo building and testing the source code and pushing the package to Octopus.
  • Octopus deploying the package to the Dev, Test, and Prod environments.
  • Email notifications generated when deployments succeed or fail.
  • Manual sign off for deployments to the Test and Prod environments.
  • Users with limited access to create releases in a subset of environments.

This is a solid starting point for any development team, but Octopus offers so much more! Below are more resources you can access to learn about the advanced functionality provided by Octopus:

Need support? We're here to help.