In the modern landscape of cloud infrastructure automation, the management of credentials represents one of the most significant security vulnerabilities. Traditional methods of authentication—such as service accounts with static passwords, API keys stored in environment variables, or certificates that inevitably expire—create a perpetual operational burden and an expanded attack surface. For DevOps engineers and cloud architects, the goal is to move toward a "secretless" architecture.
Azure Managed Identities provide the definitive solution to this problem by granting Azure resources an identity in Microsoft Entra ID (formerly Azure Active Directory) without requiring the developer or operator to manage any credentials. When paired with Terraform, the industry-standard Infrastructure as Code (IaC) tool, organizations can define, deploy, and govern these identities with surgical precision. This integration allows for the automated provisioning of resources that can authenticate to other Azure services—such as Key Vault or Storage Accounts—using native Azure Role-Based Access Control (RBAC), entirely eliminating the risk of credential leakage in source code.
Understanding Azure Managed Identities
Managed identities are essentially a wrapper around a service principal in Microsoft Entra ID. The primary distinction is that the management of the service principal's credentials (the rotation of keys and secrets) is handled entirely by Azure. There are two distinct types of managed identities, each serving different architectural requirements.
System-Assigned Managed Identity
A system-assigned managed identity is tied directly to the lifecycle of a specific Azure resource. It is created automatically when the identity is enabled on that resource. Because the identity is bound to the resource, if the resource is deleted, the associated identity is automatically purged from Entra ID. This creates a strict 1:1 relationship, making it ideal for workloads that require a unique identity that should not persist beyond the life of the resource itself.
User-Assigned Managed Identity
A user-assigned managed identity is created as a standalone Azure resource. Unlike system-assigned identities, a user-assigned identity is not tied to any single resource's lifecycle and can be assigned to multiple Azure resources simultaneously. This makes it a powerful tool for scaling applications where multiple Virtual Machines or App Services need to share the same set of permissions to access a common backend resource.
| Feature | System-Assigned | User-Assigned |
|---|---|---|
| Lifecycle | Tied to the resource | Independent standalone resource |
| Relationship | 1:1 (One identity per resource) | 1:Many (One identity, multiple resources) |
| Deletion | Deleted when resource is deleted | Persists until manually deleted |
| Use Case | Resource-specific unique permissions | Shared permissions across a cluster/app tier |
| Configuration | Enabled on the resource | Created first, then attached to resource |
Terraform Provider Authentication via Managed Identity
Terraform allows for the definition and deployment of cloud infrastructure using HashiCorp Configuration Language (HCL). When running Terraform in a non-interactive manner—such as within a CI/CD pipeline—HashiCorp recommends using either a Service Principal or a managed identity for authentication.
The Challenge with Remote Execution in HCP Terraform
A common point of failure occurs when attempting to use managed identity authentication within HCP Terraform. By default, HCP Terraform workspaces execute operations on HashiCorp-managed infrastructure. Because this infrastructure resides outside of your specific Azure environment, it cannot natively assume a managed identity that exists within your Azure subscription.
To resolve this, HCP Terraform Agents must be utilized. The architectural requirements for this configuration are as follows:
- The agent must be deployed on a supported Azure resource (such as a VM or a Kubernetes cluster) that supports managed identities.
- The resource hosting the agent must meet the specific system requirements for running HCP Terraform agents.
- The workspace must be configured to use the agent pool where the agent is registered.
- The managed identity on the agent-hosting resource must be granted the appropriate RBAC roles (e.g., Contributor) for the subscription it is intended to manage.
Implementing Managed Identity in Terraform Code
The power of Terraform lies in its ability to not only create the identity but also to assign roles and attach that identity to resources in a single execution plan.
Creating and Attaching User-Assigned Identities
When using a user-assigned identity, the identity must be defined as its own resource before it can be referenced by other components. For instance, when deploying a Linux Virtual Machine, the identity block within the azurerm_linux_virtual_machine resource is used to link the identity.
The following implementation demonstrates the creation of a production-grade Linux VM with a user-assigned identity:
```hcl
resource "azurermuserassignedidentity" "app" {
name = "ui-app-prod-identity"
resourcegroupname = azurermresourcegroup.app.name
location = azurermresource_group.app.location
}
resource "azurermlinuxvirtualmachine" "app" {
name = "vm-app-prod-01"
location = azurermresourcegroup.app.location
resourcegroupname = azurermresourcegroup.app.name
size = "StandardD2sv5"
adminusername = "azureuser"
adminsshkey {
username = "azureuser"
publickey = file("~/.ssh/idrsa.pub")
}
networkinterfaceids = [
azurermnetworkinterface.app.id,
]
osdisk {
caching = "ReadWrite"
storageaccounttype = "PremiumLRS"
}
sourceimagereference {
publisher = "Canonical"
offer = "0001-com-ubuntu-server-jammy"
sku = "22_04-lts"
version = "latest"
}
# Assign the user-assigned managed identity
identity {
type = "UserAssigned"
identityids = [azurermuserassignedidentity.app.id]
}
}
```
Combining Identity Types
Azure allows a single resource to possess both a system-assigned and a user-assigned identity. This is useful in hybrid scenarios where a resource needs a unique identity for its own logs and a shared identity for accessing a corporate database. In Terraform, this is achieved by updating the type attribute:
hcl
identity {
type = "SystemAssigned, UserAssigned"
identity_ids = [azurerm_user_assigned_identity.app.id]
}
Managed Identities for App Services
Managed identities are not limited to VMs. Cloud-native services like Azure App Service (Web Apps) and Function Apps support them as well. In the azurerm_linux_web_app resource, the identity block is applied similarly to the VM configuration, allowing the web application to authenticate to other Azure services without storing passwords in the application settings.
Role-Based Access Control (RBAC) and Permissions
Creating an identity is only the first step; the identity must be granted permission to perform specific actions. This is handled via the azurerm_role_assignment resource.
System-Assigned Role Assignment
For a system-assigned identity, the principal_id is an attribute of the resource itself. This creates a dependency: the VM must be created before the role can be assigned.
```hcl
data "azurerm_subscription" "current" {}
resource "azurermroleassignment" "example" {
scope = data.azurermsubscription.current.id
roledefinitionname = "Contributor"
principalid = azurermvirtualmachine.main.identity[0].principal_id
}
```
Best Practices for Identity Governance
To maintain a secure and auditable environment, the following principles should be applied to all Terraform-managed identities:
- Principle of Least Privilege: Avoid using broad roles like "Contributor" at the subscription level if a more granular role, such as "Reader" on a specific resource group, is sufficient.
- Separation of Concerns: Assign separate identities to different applications. If two applications require different permission sets, creating one "super-identity" for both increases the blast radius in the event of a compromise.
- Naming Conventions: Implement a strict naming schema. Identity names should include the application name, the environment (e.g., dev, stage, prod), and the purpose of the identity.
- Centralized Management: Organize all managed identities within a dedicated resource group. This simplifies the auditing process and provides a single point of visibility for identity access.
- Key Vault Integration: Instead of injecting secrets into application settings, use Key Vault references. The application uses its managed identity to authenticate to Key Vault and retrieve the secret at runtime, ensuring the secret never exists in plaintext within the configuration.
Advanced Implementation Strategies
When deploying at scale, the interaction between the identity, the resource, and the permission set becomes more complex. Utilizing Terraform's data sources and variables allows for more dynamic configurations.
For user-assigned identities, the id is available as a resource attribute. This eliminates the need for manual lookups and ensures that the azurerm_role_assignment is perfectly synced with the azurerm_user_assigned_identity.
Summary of Implementation Workflow
The standard workflow for deploying a secure, identity-driven resource in Azure via Terraform follows this logical sequence:
- Define the Resource Group to act as the container.
- Provision the
azurerm_user_assigned_identity(if not using system-assigned). - Provision the target resource (VM, Web App, etc.) and include the
identityblock referencing the ID from step 2. - Use
azurerm_role_assignmentto link the identity'sprincipal_idto a specific Azure Role and Scope. - Verify the connection by attempting to access a protected resource (e.g., a Storage Account blob) from within the provisioned resource.
Conclusion
The integration of Azure Managed Identities within Terraform represents a fundamental shift toward zero-trust architecture in cloud computing. By eliminating the need for static credentials, organizations can virtually remove the risk of password leakage, reduce the overhead of secret rotation, and simplify the auditing of their cloud environment.
Whether utilizing system-assigned identities for resource-specific tasks or user-assigned identities for scalable application tiers, the result is a more robust security posture. When executing these configurations through HCP Terraform, the use of Terraform Agents ensures that the identity-based authentication chain remains intact, even when operating from a remote management plane. Ultimately, adopting managed identities is not merely a technical convenience but a security imperative for any organization operating at scale within the Azure ecosystem.