Managing Secrets with Azure Key Vault and Terraform
Introduction
Azure Key Vault is a cloud service designed for securely storing and managing sensitive information such as secrets, cryptographic keys, and certificates. It provides a centralized location for managing access to these resources, ensuring that only authorized users and applications can retrieve this sensitive information. Infrastructure as Code (IaC), which uses tools like Terraform, enables developers to automate the deployment and management of Azure resources, including Key Vault. This helps maintain consistency, reduces human error, and simplifies the management of secrets across environments.
Key use cases for Azure Key Vault include:
- Storing API keys, passwords, and connection strings securely.
- Managing cryptographic keys for encryption and decryption.
- Enforcing access control policies to secure sensitive data.
By utilizing Azure Key Vault with Terraform, organizations can enhance their security posture while automating resource management effectively. 🚀
Prerequisites
Before we start, ensure you have the following:
- Terraform CLI installed on your machine. You can download it from Terraform's official website.
- An Azure subscription. If you don’t have one, you can create a free account.
- Azure CLI installed for managing Azure resources. You can find installation instructions here.
- A service principal with the necessary permissions to create and manage resources in Azure.
Fundamental Concepts
Key Terminology
- Secret: Sensitive data like passwords or API keys stored in Key Vault.
- Key: Cryptographic keys used for encrypting or signing data.
- Access Policy: Defines permissions for users or applications to interact with Key Vault.
- Role-Based Access Control (RBAC): A method of regulating access based on roles assigned to users.
Resource Dependencies
When deploying resources with Terraform, understanding dependencies is crucial. For example, if a secret references a key, the key must be created before the secret.
State Management
Terraform uses a state file to keep track of the resources it manages. This file must be securely stored, as it contains sensitive information about your infrastructure.
Resource Syntax
The primary resource for creating a Key Vault in Terraform is azurerm_key_vault. Below is the HCL syntax for defining this resource:
resource "azurerm_key_vault" "example" {
name = var.vault_name
location = var.location
resource_group_name = azurerm_resource_group.example.name
sku_name = "standard"
tenant_id = data.azurerm_client_config.example.tenant_id
access_policy {
tenant_id = data.azurerm_client_config.example.tenant_id
object_id = var.object_id
key_permissions = [
"get",
"list",
]
secret_permissions = [
"get",
"list",
]
}
}
Arguments Table
| Argument | Type | Description |
|---|---|---|
name |
string |
The name of the Key Vault (must be globally unique). |
location |
string |
The Azure region where the Key Vault will be created. |
resource_group_name |
string |
The name of the resource group in which to create the Key Vault. |
sku_name |
string |
The SKU name for the Key Vault (e.g., "standard"). |
tenant_id |
string |
The Tenant ID of your Azure Active Directory. |
access_policy |
block |
Block defining access policies for users or applications. |
Practical Examples
1. Basic Key Vault Creation
provider "azurerm" {
features {}
}
resource "azurerm_resource_group" "example" {
name = "myResourceGroup"
location = "East US"
}
resource "azurerm_key_vault" "example" {
name = "myUniqueKeyVault"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
sku_name = "standard"
tenant_id = "your-tenant-id" # Update this with your tenant ID
}
2. Adding a Secret to Key Vault
resource "azurerm_key_vault_secret" "example_secret" {
name = "mySecret"
value = "s3cr3tValue!"
key_vault_id = azurerm_key_vault.example.id
}
3. Creating a Key in Key Vault
resource "azurerm_key_vault_key" "example_key" {
name = "myKey"
key_vault_id = azurerm_key_vault.example.id
key_type = "RSA"
key_size = 2048
}
4. Access Policy for Key Vault
resource "azurerm_key_vault_access_policy" "example_policy" {
key_vault_id = azurerm_key_vault.example.id
tenant_id = "your-tenant-id" # Update with your tenant ID
object_id = "your-object-id" # Update with the object's ID
key_permissions = ["get", "list"]
secret_permissions = ["get", "list"]
}
5. Enable Purge Protection
resource "azurerm_key_vault" "example" {
name = "myUniqueKeyVault"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
sku_name = "standard"
tenant_id = "your-tenant-id"
soft_delete_retention_days = 7
purge_protection_enabled = true
}
6. RBAC for Azure Key Vault
resource "azurerm_role_assignment" "example_role" {
principal_id = "your-principal-id" # Update with your principal ID
role_definition_name = "Key Vault Administrator"
scope = azurerm_key_vault.example.id
}
7. Using Variables for Dynamic Configuration
variable "vault_name" {
description = "The name of the Key Vault."
type = string
default = "myUniqueKeyVault"
}
resource "azurerm_key_vault" "example" {
name = var.vault_name
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
sku_name = "standard"
tenant_id = "your-tenant-id"
}
8. Output Key Vault ID
output "key_vault_id" {
value = azurerm_key_vault.example.id
}
Real-World Use Cases
Scenario 1: Secure API Keys for Applications
In this scenario, a web application requires access to sensitive API keys. Utilizing Azure Key Vault, you can store these keys securely and configure access policies to allow only the application to retrieve them.
Scenario 2: Managing Cryptographic Keys for Encryption
For applications that require encryption of sensitive data, Azure Key Vault can manage the encryption keys. This ensures that the keys are stored securely and are only accessible to authorized applications.
Scenario 3: Secrets Management in CI/CD Pipelines
Integrating Azure Key Vault with CI/CD pipelines allows for secure management of secrets used during the deployment process. This helps avoid hardcoding sensitive data in source code, reducing the risk of exposure.
Best Practices
- Use RBAC instead of Access Policies: Adopt Azure RBAC for managing access to Key Vault instead of legacy access policies.
- Enable Purge Protection: Protect against accidental or malicious deletion of Key Vault objects.
- Utilize Managed Identities: Use managed identities for Azure resources to eliminate hard-coded credentials.
- Implement Logging and Monitoring: Enable logging for your Key Vault and set up alerts for suspicious activities.
- Periodic Secret Rotation: Regularly rotate secrets and keys to minimize the risk of compromise.
Common Errors
Error: "Key Vault name must be unique"
- Cause: The specified Key Vault name is already in use.
- Solution: Ensure the Key Vault name is globally unique.
Error: "Access denied"
- Cause: The service principal or user does not have the required access permissions.
- Solution: Check and update access policies or RBAC settings.
Error: "Invalid tenant ID"
- Cause: The tenant ID provided does not match the Azure Active Directory tenant.
- Solution: Verify and correct the tenant ID.
Error: "The resource group does not exist"
- Cause: The specified resource group has not been created.
- Solution: Create the resource group before creating the Key Vault.
Related Resources
| Resource Name | Description |
|---|---|
azurerm_key_vault |
Terraform resource for Azure Key Vault. |
azurerm_key_vault_secret |
Terraform resource for managing secrets in Key Vault. |
azurerm_key_vault_key |
Terraform resource for managing keys in Key Vault. |
| Azure Key Vault Documentation | Official Azure Key Vault documentation. |
| Terraform Azure Provider | Official Terraform Azure provider documentation. |
Complete Infrastructure Script
Below is a complete Terraform configuration for managing secrets with Azure Key Vault, including variables for flexibility.
provider "azurerm" {
features {}
}
variable "vault_name" {
description = "The name of the Key Vault."
type = string
default = "myUniqueKeyVault"
}
variable "location" {
description = "Azure location."
type = string
default = "East US"
}
variable "object_id" {
description = "Object ID of the user or service principal."
type = string
}
resource "azurerm_resource_group" "example" {
name = "myResourceGroup"
location = var.location
}
resource "azurerm_key_vault" "example" {
name = var.vault_name
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
sku_name = "standard"
tenant_id = data.azurerm_client_config.example.tenant_id
access_policy {
tenant_id = data.azurerm_client_config.example.tenant_id
object_id = var.object_id
key_permissions = ["get", "list"]
secret_permissions = ["get", "list"]
}
}
resource "azurerm_key_vault_secret" "example_secret" {
name = "mySecret"
value = "s3cr3tValue!"
key_vault_id = azurerm_key_vault.example.id
}
output "key_vault_id" {
value = azurerm_key_vault.example.id
}
Conclusion
In this tutorial, we explored how to manage secrets with Azure Key Vault using Terraform. We covered the basic concepts, practical examples, and best practices for securing sensitive information. Implementing Azure Key Vault in your infrastructure not only enhances security but also simplifies the management of sensitive data.
Next Steps:
- Explore integrating Azure Key Vault with other Azure services.
- Learn about advanced access policies and RBAC configurations.
- Implement monitoring and alerting solutions for Key Vault activities.