Skip to main content

Command Palette

Search for a command to run...

🚀 Migrating Terraform State to Terraform Cloud Utilizing Azure as the Cloud Provider

Published
12 min readView as Markdown
🚀 Migrating Terraform State to Terraform Cloud Utilizing Azure as the Cloud Provider
F

🎓 Certified: Aviatrix ACE

👋 Hi, I’m Betty Musari — a former food scientist now diving deep into the world of DevOps and cloud engineering. I write about my hands-on journey with AWS, Docker, and CI/CD, translating complex concepts into clear, beginner-friendly stories. With a scientific mindset and a passion for continuous learning, I'm on a mission to demystify the cloud — one container at a time. ✨As a Food Technologist & Sales Strategist turned DevOps Explorer, I leverage problem-solving and client-centric skills to build resilient cloud systems. Currently mastering CI/CD pipelines, Azure, and Infrastructure as Code (Terraform) to automate deployments like a well-oiled production line. Passionate about merging operational efficiency with technical innovation—because great systems, like great recipes, require precision and scalability.

By Betty Musari

Abstract

Ready to level up your Terraform game? This guide is your friendly walkthrough for moving your existing Terraform state from your local machine into the powerful, collaborative world of Terraform Cloud with a focus on managing Azure resources. Instead of relying on a local state file (or another remote backend like Azure Blob Storage), you’ll move to Terraform Cloud’s managed state service.

Why does this matter? Migrating to Terraform Cloud unlocks some serious benefits:

  • Remote operations (no more running everything locally).

  • Built-in policy enforcement and state locking.

  • Better collaboration (teams can share a single source of truth).

  • Version history for infrastructure changes.

The migration process typically starts by making sure your local state is up-to-date and matches what’s already deployed in Azure. From there, you configure your project to use Terraform Cloud as its backend, run a migration (terraform init -migrate-state), and then securely delete the old state file. After this, Terraform Cloud becomes your central hub for managing Azure infrastructure—simplifying collaboration, security, and governance.


Introduction

When working with Terraform, the state file is at the heart of everything—it tells Terraform what resources exist and how they connect. But keeping this file on your laptop (or in blob storage) can lead to messy collaboration, state conflicts, or even accidental corruption. That’s where Terraform Cloud comes in.

Migrating to Terraform Cloud solves all that. By migrating your state to Terraform Cloud, you centralize management, get built-in locking, and enable remote operations—all from a dedicated, secure platform. For your Azure resources, this means better security, smoother teamwork, and a whole lot less stress.

The migration journey is all about:
✅ Moving state from local (or Azure Blob Storage) → Terraform Cloud
✅ Unlocking features like remote runs, policy checks, version history
✅ Making teamwork easier with centralized state management

By the end, Terraform Cloud will be your new control tower 🛫 for managing Azure infrastructure—safer, cleaner, and way less stressful.

Here’s the high-level plan we'll follow

  1. Preparation – Authenticate with Azure and Terraform Cloud, ensuring both environments are ready.

  2. Backend Configuration – Update your Terraform project to point to Terraform Cloud instead of your old backend.

  3. State Migration – Use terraform init -migrate-state to transfer the existing state into your Terraform Cloud workspace.

  4. Verification – Run terraform plan to confirm Terraform Cloud recognizes and manages your Azure resources without proposing unnecessary changes.

By the end, you’ll have a safer, more collaborative setup for managing your Azure infrastructure.


Prerequisites

Before diving in, make sure you’ve got the following in place:

  • Terraform CLI – Download from Terraform’s website.

  • Terraform Cloud accountSign up here.

  • Terraform organization & workspace – Create these in Terraform Cloud for your project.

  • Azure CLI – Install from the official site and authenticate with az login.

  • Existing Terraform project – You should already have a working Azure-based configuration locally, with state managed in your project folder (or another backend).


🏗Step 1: Create Org & Workspace in Terraform Cloud

  1. Create an Organization – In Terraform Cloud, head to Organizations → Create New Organization. Give it a unique name and associate it with your email.

    Give your organization a unique name, input an email, and click on "Create Organization."

  2. Create a Workspace – Inside your org, create a new CLI-driven workspace. Name it after your Azure project, optionally add a description, and hit Create.

    Select a project "Default Project"

    Give an optional description, and click on the "Create" button.

    This workspace will hold your migrated state and any future runs.

    Now you can get an overview of Terraform Organization and Workspace, as shown below.

☁️Step 2: Configure Azure Resources Locally

Before migration, make sure you’ve got some Azure infrastructure to work with:

  • In the Azure Portal, create a Resource Group and a Virtual Machine (VM)

    Create a new resource group and other resources

    Create the VM by following the basic, disks, networking, management, monitoring, advanced, and tags, then create.

  • Next, navigate to the overview page's left side, click “Settings”, choose Properties from the drop-down menu, and copy the Resource Group ID from the Azure portal—it’ll be useful later.

Next, open VS Code and create a new folder for your Terraform project

Click On "New Folder" - Enter a name for your folder - Click "Select Folder"

Inside your new folder, create a file by clicking the "add file icon" and naming it "main.tf". This main.tf file acts as Terraform's main configuration file, where you define your resource specifications and apply code logic to your infrastructure.

⚙️Step 3: Configure Your Local Terraform Project

Now, let's tell your local code where its new home is.

To select a provider, head over to the Terraform website at registry.terraform.io/browse/providers. We choose Azure as the provider for this project

Once there, highlight the URL in your browser to find the latest version of the AzureRM provider, which is available at https://registry.terraform.io/providers/hashicorp/azurerm. Simply click the "USE PROVIDER" button to easily copy the code.

  1. Open your main.tf file in VS Code (or your editor of choice).

  2. In main.tf, define your AzureRM provider by pasting the configuration code you got from the terraform registry

Incomplete Configuration Error: You might run into this issue if the provider "azurerm" block is left empty and only includes a comment (# Configuration options). Although an empty provider block isn't inherently an error in Terraform, your editor may highlight it as an incomplete configuration.

Updated Configuration: Replacing “#Configuration” options with the “features {}” block resolves the editor’s error by making the provider configuration complete and compliant with Terraform’s expectations. This block is where you would typically configure provider-specific features and settings.

📦Step 4 : Create a Resource Group

Created two resource groups.

The resource "azurerm_resource_group" "bettyrg" serves as a default resource group for Terraform, with the name = "Joteks_terra_demo_group" specifying the Azure resource group that contains our virtual machine.

🔑Step 5: Open the Terminal and Log in to Azure

Log in to your Azure account using the Azure CLI. Run command az login

🔑Step 6: Connect Terraform to Terraform Cloud

Login to Terraform Cloud

Youwill be prompted to generate an API token for integration. Follow these steps to generate the token:

  1. Navigate to the section where you can generate an API token.

  2. Follow the on-screen instructions to generate the token.

  3. Once generated, the token will be stored locally for future Terraform tasks.

  4. Copy the token and right-click to paste it into the prompt labeled "Enter a value," then click "Enter" to proceed.

    ⚠️ Don’t panic if you don’t see anything when you paste—it’s encrypted, so it stays invisible. Totally normal.

👩‍💻 You’re now connected!

Note: Keep the API token confidential as it provides access to your Terraform Cloud account and resources. Unauthorized access to the token could lead to unauthorized changes to your infrastructure, exposure of sensitive data, and potential security breaches. Ensuring the token remains secret allows only authorized personnel to manage and modify your Terraform configurations and state, maintaining the security and integrity of your cloud environment.

Step 7: Initialize and Authenticate Terraform CLI with Terraform Cloud.

In the terminal, initialize Terraform within your project directory: This command downloads the Azure provider and sets up your working directory

Then authenticate

Update your code by adding your “Subscription ID” and “Tenant ID”

Then use Service Principal Authentication (Recommended). And add tags to allow terraform import and manage the resources.

This modifys your provider configuration to use service principal credentials instead of relying on Azure CLI:

provider "azurerm" {
  features {}

  subscription_id = "99d25bdf-c49c-4d8b-9b1e-09fd36fe7d68"
  client_id       = "your-client-id"       # Azure AD App Registration Application ID
  client_secret   = "your-client-secret"   # Azure AD App Registration Secret
  tenant_id       = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

How to get Service Principal credentials:

  1. Create Azure AD App Registration:

    • Navigate to the Azure portal and select "Azure Active Directory."

    • Click on "App registrations" and then "New registration."

    • Enter a name for your application and select the appropriate account type.

    • Click "Register" to create the application.

    az ad sp create-for-rbac --name "terraform-sp" --role Contributor --scopes /subscriptions/99d25bdf-c49c-4d8b-9b1e-09fd36fe7d68

This will output something like:

json

    {
      "appId": "00000000-0000-0000-0000-000000000000",
      "displayName": "terraform-sp",
      "password": "your-client-secret",
      "tenant": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }
  1. Generate Client Secret:

    • In the app registration, go to "Certificates & secrets."

    • Click on "New client secret" and provide a description.

    • Set an expiration period and click "Add."

    • Copy the client secret value immediately as it will be hidden later.

  2. Assign Roles:

    • Go to your subscription and select "Access control (IAM)."

    • Click "Add role assignment" and choose a role (e.g., Contributor).

    • Select your application and click "Save."

  3. Assign Roles:

    • Go to your subscription and select "Access control (IAM)."

    • Click "Add role assignment" and choose a role (e.g., Contributor).

    • Select your application and click "Save."

Set Environment Variables in HCP Terraform

Go to your HCP Terraform workspace → Variables → Add these as environment variables (mark client_secret as sensitive):

  • ARM_SUBSCRIPTION_ID = xxxxxxxxxxxxxxxxxxxxxx

  • ARM_CLIENT_ID = your-app-id

  • ARM_CLIENT_SECRET = your-client-secret (✓ sensitive)

  • ARM_TENANT_ID = xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

🔑 Step 8: Connect Terraform to Terraform Cloud

Now run: terraform plan -out main.tfplan orterraform plan

⚙️Step 9: Import

Once the plan works, run your import command: azurerm_resource_group.bettyrg "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/Joteks_terra__demo_group"

At this point, you can check the Imported State to make sure everything was imported correctly. To see your Terraform-managed infrastructure's current status, run the command terraform show.

🚀 Step 10: Set Up Cloud Integration

First things first, let’s get Terraform Cloud talking to our project.
To do this, we’ll drop in a Cloud Integration block inside the Terraform configuration file.

(That little snippet of code you see highlighted in red? Yep, that’s the one you need to paste in.)

💡 Why bother?
Because this step is the glue that holds everything together. By integrating with Terraform Cloud, you unlock:

  • Centralized state management (no more lost .tfstate files 🙌)

  • Built-in security and automation

  • A smooth collaboration setup for your team

Think of it as giving your Terraform setup a brain upgrade—it stops being “just code” and starts working smarter. Here’s the breakdown of what we added (the snippet ):

  • organization → This is the name of your Terraform Cloud org. In our case: Alpha-demo.

  • workspaces → Think of this as your project folder inside Terraform Cloud.

  • name → We’re calling ours azure_terra_demo.

By setting this up, you’re basically telling Terraform:
👉 “Use the azurerm provider, but keep my state files neatly tucked away in Terraform Cloud under this organization and workspace.”

📂 Step 11: Check Your Imported File in JSON

Take a peek at the JSON contents of your imported file.
This is just to confirm that Terraform actually knows what you brought in.

Step12: View your Resource group in Terraform

📦 Step 13: Verify Your Resource Group

Run the command to view your Resource Group in Terraform.
If it shows up here, you’re golden ✨.

🚀Step 13: Initialize Terraform Cloud

Re-initialize Terraform Cloud to apply the updated backend configuration. When prompted by Terraform to migrate your current state to Terraform Cloud, type "yes" to confirm the migration.

Congrats—you’ve just moved your state off your local machine and into the cloud. And that’s it! With just a few steps, you’ve leveled up your Terraform setup by moving your state to Terraform Cloud.

📊 Your Current Status:

  • ✅ Authentication: Working perfectly with Service Principal

  • ✅ Import: Successful for your resource group

  • ✅ Configuration: Perfectly synced with Azure

  • ✅ HCP Terraform: Fully operational

You've successfully set up Terraform to manage your Azure infrastructure! 🎊

🗑️ Step 14: Clean Up Old State Files

You can view the terraform.tfstatebackup as shown below

To remove the local tfstate file, run: rm terraform.tfstate* This deletes the old state files hanging around locally.
Since we’ve migrated everything, they’re no longer needed.

To cleanup all resources,run, terraform destroy This clears out all resources created and is irreversible. Good for practice,but in production,take caution.

🎯 If you want to keep learning:

You could now practice creating NEW infrastructure instead of destroying:

# Add more resources to your configuration
# Then run terraform apply to create them

You've mastered the hardest parts of Terraform! 🚀 Whether you destroy or continue building, you now have the skills to manage Azure infrastructure with Terraform!

🚀 What You Can Practice Now:

1. Add More Resources to Your Configuration

Try adding these to your main.tf:

# Add a storage account
resource "azurerm_storage_account" "example" {
  name                     = "joteksstorage123"  # Must be unique globally
  resource_group_name      = azurerm_resource_group.bettyrg.name
  location                 = azurerm_resource_group.bettyrg.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

# Add a virtual network
resource "azurerm_virtual_network" "example" {
  name                = "joteks-vnet"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.bettyrg.location
  resource_group_name = azurerm_resource_group.bettyrg.name
}

2. Practice Terraform Commands:

# See what changes would be made
terraform plan

# Apply the changes
terraform apply

# Check the state
terraform state list

# Practice modifying resources

3. Learn Important Concepts:

  • Variables and outputs

  • Terraform state management

  • Resource dependencies

  • Azure resource configurations

💡 Why This is Valuable:

  • Free hands-on practice with real Azure resources

  • No cost risk while learning

  • Build muscle memory with Terraform commands

  • Prepare for more complex infrastructure

🎯 When You're Done Learning:

# Clean up everything
terraform destroy

You've got a perfect sandbox environment to master Terraform! 🎓 Take advantage of this zero-cost opportunity to build your skills!

🔑 Glossary:

  • Terraform State: A file that tracks the current state of your infrastructure, allowing Terraform to manage and update resources efficiently.

  • Backend: The storage location for Terraform state files, which can be local or remote (e.g., Terraform Cloud).

  • Provider: A plugin that allows Terraform to interact with cloud providers like Azure, AWS, etc.

🎯 Final Thoughts

By moving your Terraform state into Terraform Cloud, you’ve taken a huge step forward in managing your Azure resources. No more juggling local state files or worrying about who has the latest version—everything now lives in a centralized, secure, and collaborative hub.

This migration unlocks:

  • Stronger security 🔐

  • Seamless team collaboration 🤝

  • Handy extras like remote runs, policy checks, and version history 📜

Think of Terraform Cloud as your new control tower—keeping your Azure infrastructure organized, efficient, and stress-free. 🚀

You’ve laid a solid foundation—now keep exploring, keep experimenting, and keep scaling. The cloud is wide open for you. 🌍✨