Infrastructure developers write code to automate the process of configuring cloud and on-premises infrastructure, in this post, I show you how to use Terraform and Octopus Deploy to deploy services to Azure.
Prerequisites
To follow along with this blog post, you need the following:
- An Octopus Deploy server, either on-premises or a cloud instance
- An Azure subscription. If you don't already have one, you can sign up for a 30-day free trial.
- An Azure Service Principal (app registration) that has access to create resources in your Azure subscription.
- Knowledge of Terraform at a beginner-to-intermediate level.
Using Octopus and Terraform together
Terraform is an open-source Infrastructure as code platform created by Hashicorp that is supported by default in Octopus Deploy.
You can deploy Terraform resources to:
- Azure
- AWS
- On-premises (hardware and virtualized environments)
One of the major benefits of using Terraform in a continuous delivery and deployment tool is that you can focus on writing the code, not manually deploying it. Combining Octopus and Terraform allows you to automate the entire lifecycle.
The Terraform code
To create a resource or service in Azure, you need to write the HCL code. In this section, I show you the HCL code to create a Resource Group in Azure using Terraform.
The Azure Terraform provider
Whenever you interact with a Terraform provider, you need to specify some inputs and authentication in a code block. The provider that is used to interact with Azure is the azurerm
provider.
There are four ways to authenticate to the azurerm
Terraform provider:
- Authenticating to Azure using the Azure CLI
- Authenticating to Azure using Managed Service Identity
- Authenticating to Azure using a Service Principal and a Client Certificate
- Authenticating to Azure using a Service Principal and a Client Secret
For the purposes of this blog post, we're using an Azure Service Principal.
The provider needs the following information:
- Azure Subscription ID
- Client ID
- Client Secret
- Tenant ID
There is also a features
parameter, but it can be left blank.
The provider config block looks like the following code:
provider "azurerm" {
subscription_id = "#{subscriptionID}"
client_id = "#{clientID}"
client_secret = "#{clientSecret}"
tenant_id = "#{tenantID}"
features = {}
}
Notice, the subscription ID, client ID, client secret, and tenant ID have variables for their values. I'll go over configuring these variables in a later section.
Creating the Azure resource
The resource create operation will call upon the azurerm_resource_group
resource type. The resource type contains two parameters in the config block:
- name: The name of the resource group you're creating.
- location: The location where the resource group will reside, for example,
eastus
.
resource "azurerm_resource_group" "resourceGroup" {
name = "#{resourceGroupName}"
location = "#{location}"
}
After you have the provider and resource code, it should look like the following code snippet:
provider "azurerm" {
subscription_id = "#{subscriptionID}"
client_id = "#{clientID}"
client_secret = "#{clientSecret}"
tenant_id = "#{tenantID}"
features = {}
}
resource "azurerm_resource_group" "myterraformgroup" {
name = "#{resourceGroupName}"
location = "#{location}"
}
Authentication from Octopus Deploy to Azure
Next, you need a way to authenticate from Octopus Deploy to Azure. Octopus Deploy has a way to create accounts for authentication to cloud and on-premises environments.
Create an Azure account
- Log into the Octopus Deploy web portal and go to Infrastructure ➜ Accounts
- Click ADD ACCOUNT and choose the Azure Subscription option.
- Add the associated information for the Azure Service Principal you are using to create resources in the Azure Portal.
- To confirm that the Azure Service Principal works, click SAVE AND TEST.
Creating a new project in Octopus Deploy
After the authentication is complete from Octopus Deploy to Azure, you can start thinking about how and where you want the Terraform runbook to exist. To ensure that the runbook is in its own project, you can create the project in the Octopus Web Portal.
Create a project in Octopus Deploy
- Log into the Azure portal and go to Projects.
- Choose which project group you'd like to store the project in and click ADD PROJECT.
- Create a new project and name it TerraformAzure.
When the project is created, it's time to create the runbook.
Creating the Octopus variables
Navigate to the variables section of the project to add your project variables:
AzureAuth = AzureAuth Account
clientID = guid_client_id
clientSecret = client_secret
location = eastus
resourceGroupName = your_resource_group_name
subscriptionID = your_subscription_id
tenantID = guid_tenant_id
These values will differ based on the environment you're using. The Name
of the variables should match the example below, but the values will be different for your environment.
Configure the runbook
Because you're deploying a service in Azure and not code for an application, using a runbook is the most efficient method. The runbook will give you the ability to use the Terraform step template and create the Resource Group.
Create a runbook
- Navigate to Project and select Operations ➜ Runbooks.
- Click ADD RUNBOOK.
- Create a runbook and name it ResourceGroup.
Add steps to the runbook
- Navigate to the runbook, select Process, and click ADD STEP.
- Click on the Terraform category.
- Choose the Apply a Terraform template step.
Configuring the Terraform step
Depending on the environment you're running in, these steps could be different. For example, you could use a different Worker Pool than the default. These are the key steps to include for Terraform:
- Under Managed Accounts, choose Azure Account and add the Azure account you created in the Authentication to Octopus Deploy from Azure section.
- Under Template, choose Template Source and use the Source code option. Then paste in the following code:
provider "azurerm" {
subscription_id = "#{subscriptionID}"
client_id = "#{clientID}"
client_secret = "#{clientSecret}"
tenant_id = "#{tenantID}"
features = {}
}
resource "azurerm_resource_group" "myterraformgroup" {
name = "#{resourceGroupName}"
location = "#{location}"
}
As you can see, this uses the variables you created in the Creating the Octopus variables section.
Executing the runbook
The configuration of the project, authentication, steps, and code is all complete. Now, it's time to see the code in action.
- Under Runbooks, you'll see the ResourceGroup runbook. Click RUN.
- Select the environment that you'd like to run the runbook under and click RUN.
After the runbook has executed, the task summary will show you have successfully created a Resource Group in Azure using Octopus Deploy and Terraform.
Conclusion
Combining the power of continuous deployment and infrastructure as code is key to any automated environment. Not only does it give you automation, but a place for fellow team members to collaborate, see what's happening, and understand the process instead of manually doing it yourself.