Deploying An ASP.NET Core Site, You're Still Doing It Wrong: Part 3 - Octopus Deploy: Installation And Targets
This day and age, predictability and reliability are two of the most important words when it comes deployments. In this series, I am going to talk about how to add both predictability and reliability to your ASP.NET Core Continuous Integration pipeline using TeamCity and Octopus Deploy.
In the last post of this series, we went over some reasoning as to why it is bad to not have a continuous build server in your pipeline and how we can set one up using TeamCity in conjunction with a git repository hosted at GitHub. In this post, we will add another step to the process that will allow us to automate configuration and deployments to x-number of deployment targets. With .NET Core being cross platform, I will show you how to set up targets for both a Linux and Windows based machine.
Get Your Hands Off That Configuration File
If we have TeamCity producing builds for us, why can't we just use those assets for our deployments?
TeamCity (in most cases) is used to do one thing and do it well, produce validated builds. When we push changes to our repository TeamCity grabs the source, builds it, runs tests against the build and publishes a validated artifact to any external system registered to receive them. But what happens when we need to configure those builds to conform to a deployment's needs? Often the person in charge of the deployment would handle these steps manually. Of which might consist of...
- Manually obtain the assets built by TeamCity.
- Manually open the assets up in a local environment.
- Manually open any configuration files and manually change configuration values like connection strings and app settings.
If you recall our desires to build predictability and reliability through automation, you will quickly be able to identify the red flag in this process. Relying on a human to be able to open up configuration files and manually update them is one step away from crazy. The more deployments you add to the mix, the crazier the situation becomes. The goal instead should be to have one single source of truth for configuration values and to automate the configure process so no human hand ever touches it.
Oh No, You Just Copied That?
If we have a build that is configured through automation, what are we to make of the actual deployment step. Typically, the person responsible for the deployment would...
- Manually make a connection to the deployment target.
- Manually copy the now manually configured group of assets to the target.
- Manually restart any services to apply the changes.
- Hope for the best!
This process, much like the one above, has proven time and time to be unpredictable and by way of unreliable. Like in the past, we should move away from having someone manually deploy to targets and instead look to utilize automation.
Luckily, when installed and configure appropriately, Octopus Deploy will handle all this for us!
Let's start this process by installing the Octopus Deploy Server. You can either head over to the Octopus Deploy Server official download page or use Chocolatey by running the following command.
choco install octopusdeploy
Select the free trial and fill out the necessary information. After 45 days is up, you will be able to continue with the Community Edition of Octopus Deploy. This will get you up to 5 projects and 5 users to use for free.
Select where you want Octopus to store its assets.
Select what account you want to run the Octopus service under. In most cases, your "Local System Account" will suffice.
Create a new database in your SQL Server instance and connect to it with appropriate credentials.
Octopus has its own internal web server, of which defaults to port 80. Based on your TeamCity setup and other variables specific to your environment, you most likely will need to change this port to avoid port conflicts. In my setup, I change it to port 8080.
Set up an account to login with.
Default options will suffice.
Once you click "Install", a bunch of scripts will kick off and you will end up at the follow screen after a minute or two.
One of the first steps you are going to want to take is creating what is called an Environment. Environments are high-level buckets we can use to organize our various targets. For example, a typical deployment pipeline might consist of a dev, test, stage and production steps. Each of these steps in an application deployment life-cycle would map nicely to an Environment inside of Octopus.
Head to the environment page in your portal and click "Add Environment". Go ahead and add a name and description as you see fit and click "Save". In my case, I created a "Test (Windows)" and "Production (Linux)" Environment.
Targets are the servers where your applications will be deployed. Octopus Deploy
To start, let's create a new Account that Octopus will use to access our Windows target. Head to the "Accounts" page located at environment > accounts. For my Windows target, I will create an Account of the type "Usernames/Passwords" and assign it to my "Test" Environment.
After you have an Account setup with the proper access, head back to the environment page and under your Environment of choice, select "Add Target". You will be prompted with a number of target types to choose from. For my Windows target, which exists inside the same network as my TeamCity instance, I am able to use the type "Listening Tentacle". If your TeamCity install does not have access to an open port on the Octopus instance, you will have to poll for changes instead of listening for them.
You will also be notified that you need to ensure a Tentacle is installed on your target machine. We will take care of this in the next step.
A Tentacle is a secure, lightweight agent service that Octopus uses to deploy software. Octopus Deploy
On your target machine, either head to the official Octopus Deploy Tentacle download site or do it like a modern developer and use Chocolatey.
choco install octopusdeploy.tentacle
Once installed, open up your Tentacle Manager and follow the prompts to configure it. Start by identifying where you want your Tentacle to store its data.
Next, choose your Communication Style.
Next, you need to set the port in which the Tentacle with handle its communications on. You will also need to add the "Octopus Thumbprint" that is supplied when adding your Target. This validates the connection between the two nodes.
Finally, click the "Install" button and after a minute or so you will end up a screen that looks like the following.
Once you have your Tentacle installed, head back to the "Add Target" screen in your Octopus Deploy portal and select "Discover". If everything went okay, you will be prompted to name your new Target and supply it a role to operate under. Click "Save" to commit your changes and your new Target should show up under your Environment on the environment page of your portal.
Once you have your Target created, Octopus offers up a great diagnostics tool called "Check health". When activated, this will initiate a series of diagnostic request made from your Octopus Deploy server to your Target(s).
If there are issues, you will be provided feedback on that particular issue or Octopus will attempt to fix itself. For example, I was notified that Calamari was not installed on my Windows Target and offered an option to do a click-once automated install.
Our account this time around with be of the type "SSH Key Pair". This will allow the Target to ssh into our Linux box and validate using the SSK Key. Head to the environment > account page and add the new Account. The main difference being you will now need a private pass key and passpharse if applicable.
For more information about my deployment process prior to setting up my CI environment, take a look at the following posts.
As of current, my production ASP.NET Core application deployment lives at DigitalOcean on an Ubuntu distribution. Since Octopus Deploy 3.0 was released the sub-system components used by Octopus, mainly Calamari, can run on most Linux distribution so long as some basic requirements are met. The combination of Calamari running bash scripts and communicating via SSH, for the most part creates a Tentacle parity rich experience. Long story short, it works and works good.
Octopus did a pretty good job documenting the requirements to make this work at SSH Targets. At this link you will see a list of distributions guaranteed to work and a detailed list of features you need to ensure are enabled or installed on your target.
Had back to your environments page and click "Add Target" under your desired Environment. This time we are going to select the "SSH Connection" type, supply an appropriate Hostname and port, and hit "Discovery". Most of what is needed will be pre-populated after the discovery operation completes, except the Account to tie to this target. Add the SSH Key Pair Account we just created and then hit save.
Head back to the environments page and run a "Check Health" operation on this Target. During its first pass, I first was informed I was missing Mono. To solve this, I SSH'ed into my machine, and ran the following.
sudo apt-get install mono-complete
If you don't have the proper key Signing Key and Repository available, you might have to run the following.
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list sudo apt-get update sudo apt-get install mono-complete
After I went on the server and installed Mono manually, I went back to Octopus and ran the "Check health" step again. At this all checks passed.
We now have Octopus Deploy installed in our pipe-line, configured with an Environment, Accounts, and Targets. With that out of the way, we can start work on creating a Project inside of Octopus Deploy that we will use to define our configuration and deployment process. Until then, feel free to leave any comments or suggestions below.Deploying An ASP.NET Core Site, You're Still Doing It Wrong : Part 4 - Octopus Deploy: Configuration And Deployments