Working with multiple MS Azure subscriptions using terraform

This article explains you to work with multiple Azure subscriptions using terraform. One of the greatest advantages of Terraform is that it allows us to work with multiple cloud providers and multiple subscriptions/accounts of the same cloud provider. Most of the time, you may not limit your deployments to a single subscription. You manage the subscriptions specific to various environments and establish communication between these resources. Terraform makes it so easy, all you need to work with the provider block to make this happen.

The following is two of the scenarios on Microsoft Azure, where I need to work with:

  1. Multiple subscriptions of the same Azure Tenant
  2. Multiple Subscriptions of the different tenants

In both of the scenarios, we make use of the service principal and you can check this article to create the service principal.

Multiple subscriptions of the same Azure Tenant:

The following is the step-by-step process to work with multiple Azure subscriptions using terraform in the same tenant. We will create a resource group in two subscriptions as an example.

Make ensure that the service principal has been added to IAM of the subscription with at least contributor access (to create and delete the resources at the subscription level). From the dropdown of the Roles in the below screenshot, choose Contributor and for Select, choose the service principal that you have created.

Create a provider.tf file with the following code block. By default terraform accepts one provider for the configuration, but you can make use of the aliases to define multiple provider blocks in the same terraform configuration file as below.

provider "azurerm" {
    alias = "dev-sub1"
    subscription_id = "your subscription-1 id"
    client_secret = "service pricipal secret"
    client_id = "service principal id"
    tenant_id = "Azure Tenanr Id"
    features {}
}

provider "azurerm" {
    alias = "dev-sub2"
    subscription_id = "you subscription-2 id"
    client_secret = "service principal secret"
    client_id = "service principal id"
    tenant_id = "Azure Tanant Id"
    features {}
}

Now the resource group creation terraform configuration would be:

resource "azurerm_resource_group" "hub_rg" {
    provider = "azurerm.dev-sub1"
    name = "dev_rg"
    location = "East US"
}

resource "azurerm_resource_group" "dev_rg" {
    provider = "azurm.dev-sub2"
    name = "dev_rg"
    location = "East US"
}

Run the terraform commands to initialize, plan and execute and the following the terraform plan output.

Multiple subscriptions of the different Azure Tenants:

When working with multiple tenants, we have two options. One is, create a service principal with the cross-tenant scope and the Second is to create two service principles for each tenant and use it in the provider block of the Terraform configuration. Let us go by creating two service principals for each tenant.

  • Create two service principals across two tenants by following the article and provide the access to these service principals to their respective subscriptions.
  • create a provider.tf with the following terraform code block with aliases with different tenant ids and service principals.
provider "azurerm" {
    alias = "dev-sub1"
    subscription_id = "your subscription-1 id"
    client_secret = "service principal-1 secret"
    client_id = "service principal-1 id"
    tenant_id = "Azure Tenant-2 Id"
    features {}
}

provider "azurerm" {
    alias = "dev-sub2"
    subscription_id = "you subscription-2 id"
    client_secret = "service principal-2 secret"
    client_id = "service principal-2 id"
    tenant_id = "Azure Tenant-2 Id"
    features {}
}

Run the terraform commands to deploy the resource groups. The Resource Group creation template remains the same.

Similarly, you can work with multiple subscriptions within a tenant or across tenants.

Share your love

Newsletter Updates

Enter your email address below and subscribe to our newsletter

Leave a Reply

Your email address will not be published. Required fields are marked *