Alk3my

Azure service principle for use with Terraform

October 29, 2019

In order to use the Azure provider with Terraform (and hence allow Terraform to create/alter/delete your environments) one approach is to set up a service principal and use that to authenticate via a client secret.

You can set up your principal either by command line or the Azure portal. I'll be covering the Azure portal approach as it's pretty straight forward.

  1. Log in to the portal (portal.azure.com) and click on "Azure Active Directory". Azure AD App registrations
  2. Click on "+ New Registration" and give it a meaningful name like "TerraformServicePrinciple". Leave "Supported account types" as is and set any Redirect URI with Web in the dropdown (e.g. https://terra.form).
  3. Click "Register" button down the bottom and then select it from the All applications list.
  4. At this point take note of a couple of things you'll need later, the client ID and the tenant ID as below. Then click on "Certificates & secrets". Azure AD App registration details
  5. Now we create a Client Secret by clicking into "Certificates & secrets" and then "+ New client secret".
  6. Give it a meaningful description / name and pick an expiry date (I'd go with one year for better security in case you accidentally expose the secret somewhere).
  7. Take note of the client secret and put it somewhere safe like a password vault / manager as you can't retrieve it again (although you can always generate a new secret).

At this point you've got your service principal and some credentials however you need to grant it permissions to modify resources in your subscription.

  1. Go to the "Subscriptions" blade in the portal and choose your subscription (assuming you've got more than one).
  2. In the overview taken note of your "Subscription ID", this is the final bit of info you need when running Terraform.
  3. Click on "Access control (IAM)" and then "Add a role assignment".
  4. Choose a Role, in most cases you'll need "Contributor" for Read/Write on all resources in the Subscription although you may want to drop this down to a lesser role for security later (e.g. Website Contributor).
  5. Search for your Service Principal and then Save.

Now you're set to use this Principal when you set up your provider in Terraform.

I usually create an "environment" folder at the root of the repository and then perhaps folders for dev, test, prod etc. You might even have folders per cloud provider if you're using multi-cloud resources. Add a provider.tf file with the following content.

variable "client_secret" {}

provider "azurerm" {
  version = "~> 1.36"
  subscription_id             = "00000000-0000-0000-0000-000000000000"
  client_id                   = "00000000-0000-0000-0000-000000000000"
  client_secret               = "${var.client_secret}"
  tenant_id                   = "00000000-0000-0000-0000-000000000000"
  skip_provider_registration  = true
}

The skip_provider_registration bit is optional and more if you're a bit pedantic like me. Essentially you're telling Terraform to skip registering a bunch of Resource providers. It tends to do as many as it can whereas you might only be creating a small subset of resources. Although it does mean you have to do the registrations manually which can be annoying and tedious (as well as giving less meaningful error messages). More details provided here.

At this point you should be able to initialise Terraform with terraform init.

Terraform also provide a detailed explanation and how to do this process using the Azure CLI.