fbpx

Learn Build5Nines Forum

Find answers, ask questions, and connect with our
global community of IT professionals.

Forums HashiCorp Terraform Having the Terraform azure state file under different subscription

  • Having the Terraform azure state file under different subscription

    Posted by Joshua Falken on March 15, 2024 at 3:18 pm

    I have two subscriptions in Azure. Let’s call them sub-dev and sub-prod. Under sub-dev I have resources for development (in a resource group rg-dev) and under sub-prod resources for production (in a resource group rg-prod).

    Now, I would like to have only one state-file for both dev and prod. I can do this as I am using Terraform workspaces (dev and prod). There is a Storage Account under sub-dev (rg-dev) named tfsate. It has a container etc. The Azure backend is configured like this:

    terraform {
      backend "azurerm" {
        resource_group_name  = "rg-dev"
        storage_account_name = "tfstate"
        container_name       = "tfcontainer"
        key                  = "terraform.tfstate" 
      }
    }
    

    If I want to apply to the dev environment I have to switch Az Cli to the sub-dev. Similarly, for production, I would have to use sub-prod. I switch the default subscription with az cli:

    az account set -s sub-prod
    

    Problem is that the state’s storage account is under sub-dev and not sub-prod. I will get access errors when trying to terraform init (or apply) when the default subscription is set to sub-prod.

    Error: Failed to get existing workspaces: Error retrieving keys for Storage Account "tfstate": storage.AccountsClient#ListKeys: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationFailed" Message="The client 'user@example.com' with object id '<redacted>' does not have authorization to perform action 'Microsoft.Storage/storageAccounts/listKeys/action' over scope '/subscriptions/sub-prod/resourceGroups/rg-dev/providers/Microsoft.Storage/storageAccounts/tfstate' or the scope is invalid. If access was recently granted, please refresh your credentials."
    

    I have tried couple of things:

    • I added subscription_id = "sub-dev"
    • I generated a SAS token for the tfstate storage account and added the sas_token config value (removed resource_group_name)

    but in vain and getting the same error.

    I tried to az logout but terraform requires me to login first. Do I have to tune the permissions in the Azure end somehow (this is hard as the Azure environment is configured by a 3rd party) or does Terraform support this kind of having your state file under different subscription setup at all?

    Joshua Falken replied 1 month, 2 weeks ago 1 Member · 1 Reply
  • 1 Reply
  • Joshua Falken

    Member
    March 15, 2024 at 3:19 pm

    To manage Terraform state files across multiple Azure subscriptions, you need to ensure that the Terraform process has the necessary permissions to access the storage account where the state file is located, regardless of the subscription under which the resources are being deployed.

    The error message you’re encountering indicates that the Terraform process does not have the necessary permissions to access the storage account in the sub-dev subscription when you’re operating under the sub-prod subscription context.

    Here are some steps you can take to resolve this issue:

    1. Service Principal Authentication: Create a Service Principal with access to both subscriptions. This Service Principal should have the necessary permissions to read and write to the storage account in sub-dev. You can then configure Terraform to use this Service Principal for authentication by setting the ARM_CLIENT_ID, ARM_CLIENT_SECRET, ARM_SUBSCRIPTION_ID, and ARM_TENANT_ID environment variables.

    2. Storage Account Access: Ensure that the Service Principal has the “Storage Blob Data Contributor” role assigned for the storage account in the sub-dev subscription. This can be done in the Azure Portal or using Azure CLI with the following command:

       az role assignment create --assignee <Service-Principal-AppId> --role "Storage Blob Data Contributor" --scope /subscriptions/sub-dev/resourceGroups/rg-dev/providers/Microsoft.Storage/storageAccounts/tfstate
    
    1. Terraform Backend Configuration: Configure the Terraform backend to use the Service Principal credentials. You can specify the subscription_id in the backend configuration to explicitly set which subscription the backend should use:
       terraform {
         backend "azurerm" {
           subscription_id      = "sub-dev"
           resource_group_name  = "rg-dev"
           storage_account_name = "tfstate"
           container_name       = "tfcontainer"
           key                  = "terraform.tfstate"
         }
       }
    
    1. Workspace-Specific Configuration: Since you are using Terraform workspaces, you can specify workspace-specific configuration for the backend using partial configuration and passing the workspace-specific variables during the terraform init command.

    Here’s an example of how you might pass the subscription ID when initializing Terraform for a specific workspace:

    terraform init -backend-config="subscription_id=sub-dev"
    

    By following these steps, you should be able to manage your Terraform state file across multiple Azure subscriptions without encountering access errors.

    The retrieved documents do not provide a direct solution to your problem, as they focus on manual deployment steps for SAP Library, infrastructure deployment, creating and configuring Azure DDoS Network Protection, enabling monitoring for Kubernetes clusters, and creating policy assignments . However, the principles of Terraform state management and Azure role assignments are relevant to your situation.

Log in to reply.