Historically, deploying applications to production was a somewhat haphazard, undefined process. It looked something like this:
- Build your application and compress it into a single file on a disk
- Bring the disk it to your Operations team along with a 20-page instruction manual describing in minute detail how to deploy your application, including database setup, configuration variables, and a host of other parameters.
- Operations would schedule the installation into their list of tasks, and about a week later, you would get an email from them that the application is installed.
- Hooray!!! Let’s get started.
- Not so fast.
- Invariably, there were errors in the installation. The environment might not be configured correctly, or there was a missing module, or some other critical detail had been missed. Eventually, you weren’t even surprised this happened on the first try because Operations needed to follow a long, tedious, and highly detailed list of instructions for a manual installation. Clearly, the whole process was very error-prone
- So, back to Operations for another try, more waiting…eventually, it would work.
The dawn of one-click provisioning
Infrastructure as Code (IaC) came along to make deployment of applications much more robust by using descriptions of the required infrastructure and configuration in highly structured file formats. Once the infrastructure was defined in files, those specifications could be version controlled, and provisioning became a repeatable, one-click process. Need to deploy infrastructure for your application on multiple environments for development, QA, and Staging? No problem. Deployments based on IaC were much faster while reducing both costs and the risk of error.
Pioneers like Chef, Puppet, and Ansible were game-changers in this domain, and as cloud computing started taking over the industry, all the major cloud providers offered corresponding templating tools like Cloud Deployment Manager for GCP, ARM for Azure, and CloudFormation for AWS. Now, infrastructure templates are great, but the problem is that each vendor uses a different templating language. Anything you write as an ARM template will have to be rewritten if you want to port it to a CloudFormation template for deployment on AWS. Terraform took it a step further with scripting templates that abstracted away the specific provider so you could use the same script on different clouds.
While these tools make provisioning a much easier task, they all use descriptive languages such as XML, JSON, and YAML, which places some limitations. For example, try creating some infrastructure in a loop using Terraform. It’s possible, but it ain’t pretty.
Next-gen IaC with Pulumi
Pulumi supports orchestration of any type of infrastructure, including serverless, Kubernetes, and containers, and currently works with the three major cloud providers, AWS, Azure, and GCP.
Time to get hands-on
Let’s see Pulumi in action. In this example, we’ll set up an environment on Azure with a web server and an SQL server database, and then deploy Ozcode Production Debugger to that environment. We’ll define all that using C# in Pulumi.
- Download Pulumi
On windows the installer is just a Chocolatey Nuget command.
If you want, there are alternatives including a snippet of Powershell code: https://www.pulumi.com/docs/get-started/install/
2. Make sure you have the latest .NET Core SDK installed. You can download it from: https://dotnet.microsoft.com/download
Finally, you need to install the latest Azure CLI which you can download from: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-windows?view=azure-cli-latest
4. Open a command prompt and create a new directory. In that directory, we’re going to start by running:
This will prompt you to log into your azure account.
5. Run Pulumi to create the structure
pulumi new azure-csharp
6. Copy the program.cs file contents from: https://github.com/stimms/pulumideploy/blob/master/Program.cs
7. If you have your own ASP.NET Core project you want to deploy, update the content directory in your project to point at this location:
If you don’t, you can use our example from here: https://github.com/stimms/pulumiwebapp, but you still need to update the path on line 56 up there to point at it.
Go ahead and build the WebApp.
8. Get a license key for Pulumi (I’m sure you have an explanation on the current way to do this) and update the code on line 89 to reference it.
This will stand up your new stack in Azure. You should be able to go to the site URL which is printed at the end of the
pulumi run command and see the site running and generating primes (if you used our example app).
10. In the Azure portal, we want to set up the Production Debugger. Go to the WebApp and search for extensions:
11. Select the Ozcode Production Debugger and install it:
12. Restart the Web App
13. Now we want to cause an exception to be thrown. In our App, you can simply append the following to the URL:
14. Sit back and watch the errors roll in. First time Ozcode Production Debugger detects an exception, it will instrument the relevant code. From then on, you will see all the information needed to debug the code including a complete stack trace, logs, variable values, network requests and more.
IaC pioneers like Chef, Puppet, and Ansible brought the benefits of version control and repeatability to infrastructure orchestration. Terraform took it a step further, abstracting away the actual cloud provider you’re using. Next-gen tools like Pulumi are at the forefront of this domain, enabling all the capabilities of popular programming languages in common use today.
To view a recording of the full webinar on which this blog is based, click below: