In this post I want to show how easy it is to create aĀ SpaceliftĀ Stack that manages Azure resources. To keep things simple, Iām going to assume that you already know what Spacelift can do, and the basics of creating and running Stacks, but if not check out ourĀ terraform-starterĀ repo that walks you through the process of setting up an account, and getting started.
In order to allow Spacelift to manage Azure resources, we need to do the following:
- Create a Service Principal in Azure with the correct ARM permissions to manage our resources.
- Create a Stack in Spacelift that uses theĀ AzureĀ provider.
- Give our Stack the credentials for our Service Principal.
All of the information you need to configure the Azure provider can be foundĀ here. This post just explains how to combine that information with Spacelift.
To create our Service Principal, we need to use theĀ az ad sp create-for-rbacĀ command (replacing <subscription-id>Ā with your actual subscription ID):
az ad sp create-for-rbac --name spacelift-sp --role="Contributor" --scopes="/subscriptions/<subscription-id>"This will output something like the following:
Changing "spacelift-sp" to a valid URI of "http://spacelift-sp", which is the required format used for service principal names
Creating 'Contributor' role assignment under scope '/subscriptions/<subscription-id>'
The output includes credentials that you must protect. Be sure that you do not include these credentials in your code or check the credentials into your source control. For more information, see https://aka.ms/azadsp-cli
{
"appId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"displayName": "spacelift-sp",
"name": "http://spacelift-sp",
"password": "A4xFo3z-Hv9BMOFlmHfXP2ESXugHMdaike",
"tenant": "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"
}The command creates a new Service Principal calledĀ spacelift-sp, and grants it theĀ ContributorĀ role on your subscription. It also outputs theĀ appId,Ā passwordĀ andĀ tenantĀ for the Service Principal. Make a note of these because you’ll need them later.
If you would rather assign permissions yourself later, you can run the following command to just create a Service Principal with no permissions:
az ad sp create-for-rbac --name spacelift-sp --skip-assignmentYou should now be able to view your Service Principal in theĀ Azure Active Directory -> App registrationsĀ section of the Azure Portal:
Now that weāve got a service principal, we need to create a Stack to actually create some Azure resources. To keep things simple all weāre going to do is add some terraform definitions that specify the version of the Azure Provider we want to use, and create an Azure Resource Group:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "=2.46.0"
}
}
}
# Configure the Microsoft Azure Provider
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "test-group" {
name = "test-group"
location = "West Europe"
}If you commit that change and try to run your Stack just now, you should see something similar to the following failure:
Hereās the full error message:
Error building AzureRM Client: obtain subscription() from Azure CLI: Error parsing json result from the Azure CLI: Error launching Azure CLI: exec: āazā: executable file not found in $PATH
At first glance this error is slightly confusing, but what it means is that because we didnāt provide any credentials to the Azure provider it attempted to fallback to using theĀ azĀ CLI for authentication. This works fine locally, but won’t work on Spacelift.
To solve this, we need to provide our stack with our credentials, which is explained in the next section.
If you take a look at theĀ Terraform documentation, youāll find that there are a number of different ways that you can authenticate Terraform with Azure. What weāre going to do here is authenticate using a Service Principal with a Client Secret, and provide that configuration via environment variables.
To do this we need to set the following environment variables, using the information returned by the Azure CLI when we created our Service Principal:
- ARM_CLIENT_ID ā theĀ
appIdĀ from the response. - ARM_CLIENT_SECRET ā theĀ
passwordĀ from the response. - ARM_SUBSCRIPTION_ID ā your subscription ID.
- ARM_TENANT_ID ā theĀ
tenantĀ from the response.
You can set these environment variables directly on your Stack, but what weāre going to do here is create aĀ Spacelift ContextĀ and attach it to our Stack. This allows us to share the same credentials with multiple Stacks if we want.
Add a new Context via theĀ ContextsĀ screen in Spacelift:
Once your context has been created, edit it and enter your environment variables, making sure to mark theĀ ARM_CLIENT_SECRETĀ as a secret rather than plaintext:
Now that weāve got a Context containing our credentials, you can attach it to your Stack. To do this, click on theĀ ManageĀ link next to your Stack, go toĀ Contexts, choose your Context, and clickĀ Attach:
Now that your Context is attached, you should be able to see the it in theĀ EnvironmentĀ section of your Stack:
If you try to run your Azure Stack again you should get a successful plan:
And applying should now succeed:
If you take a look in the Azure Portal, you should now be able to see the Resource Group that was created:
Before finishing up, I wanted to just point out a few things about the Service Principal credential expiry. Although this isnāt really related to Spacelift, itās something that you need to be aware of.
When you create your Service Principal via the Azure CLI, it automatically creates a Client Secret for you with an expiry of 1 year:
What this means is that if you do absolutely nothing, your Spacelift Stacks will stop working after the credentials expire a year later. To solve this, all you need to do is generate a new Client Secret, and update theĀ ARM_CLIENT_SECRETĀ environment variable in your Context.
Hopefully, in this post, Iāve shown that although Spacelift doesnāt have an official Azure integration (yet!), itās simple to manage Azure resources using Spacelift. Once youāve performed a little bit of initial setup, you should be able to rapidly get new Stacks up and running, creating Azure resources.
The most flexible management platform for Infrastructure as Code
Spacelift is a sophisticated SaaS product for Infrastructure as Code that helps DevOps develop and deploy new infrastructures or changes quickly and with confidence.
