Skip to content

Commit ee7c8b0

Browse files
committed
feat: support either WIF or SP app password
1 parent 4836bc3 commit ee7c8b0

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

modules/azure/storage-account/backplane/README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ The module supports two modes of operation:
1212
1. **Existing Service Principals**: Use `existing_principal_ids` to grant permissions to already existing service principals
1313
2. **Create New Service Principal**: Use `create_service_principal_name` to create a single new service principal and automatically grant it permissions
1414

15+
## Authentication Methods
16+
17+
When creating a new service principal, you can choose between two authentication methods:
18+
19+
- **Application Password** (default): A traditional client secret will be created
20+
- **Workload Identity Federation**: Configure federated identity credentials for passwordless authentication (e.g., from GitHub Actions, Azure DevOps, or other OIDC providers)
21+
1522
## Usage Examples
1623

1724
### Using Existing Service Principals
@@ -43,6 +50,23 @@ module "storage_account_backplane" {
4350
}
4451
```
4552

53+
### Creating a New Service Principal with Workload Identity Federation
54+
55+
```hcl
56+
module "storage_account_backplane" {
57+
source = "./modules/azure/storage-account/backplane"
58+
59+
name = "my-storage-account"
60+
scope = "/providers/Microsoft.Management/managementGroups/my-mg"
61+
62+
create_service_principal_name = "deployment-sp"
63+
workload_identity_federation = {
64+
issuer = "https://token.actions.githubusercontent.com"
65+
subject = "repo:my-org/my-repo:ref:refs/heads/main"
66+
}
67+
}
68+
```
69+
4670
### Mixed Usage (Both Existing and New)
4771

4872
```hcl
@@ -78,6 +102,8 @@ No modules.
78102
| Name | Type |
79103
|------|------|
80104
| [azuread_application.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application) | resource |
105+
| [azuread_application_federated_identity_credential.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_federated_identity_credential) | resource |
106+
| [azuread_application_password.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_password) | resource |
81107
| [azuread_service_principal.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal) | resource |
82108
| [azurerm_role_assignment.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/3.116.0/docs/resources/role_assignment) | resource |
83109
| [azurerm_role_definition.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/3.116.0/docs/resources/role_definition) | resource |
@@ -90,11 +116,13 @@ No modules.
90116
| <a name="input_existing_principal_ids"></a> [existing\_principal\_ids](#input\_existing\_principal\_ids) | set of existing principal ids that will be granted permissions to deploy the building block | `set(string)` | `[]` | no |
91117
| <a name="input_name"></a> [name](#input\_name) | name of the building block, used for naming resources | `string` | n/a | yes |
92118
| <a name="input_scope"></a> [scope](#input\_scope) | Scope where the building block should be deployable, typically the parent of all Landing Zones. | `string` | n/a | yes |
119+
| <a name="input_workload_identity_federation"></a> [workload\_identity\_federation](#input\_workload\_identity\_federation) | Configuration for workload identity federation. If not provided, an application password will be created instead. | <pre>object({<br> issuer = string<br> subject = string<br> })</pre> | `null` | no |
93120

94121
## Outputs
95122

96123
| Name | Description |
97124
|------|-------------|
125+
| <a name="output_application_password"></a> [application\_password](#output\_application\_password) | Information about the created application password (excludes the actual password value for security). |
98126
| <a name="output_created_application"></a> [created\_application](#output\_created\_application) | Information about the created Azure AD application. |
99127
| <a name="output_created_service_principal"></a> [created\_service\_principal](#output\_created\_service\_principal) | Information about the created service principal. |
100128
| <a name="output_documentation_md"></a> [documentation\_md](#output\_documentation\_md) | Markdown documentation with information about the Storage Account Building Block building block backplane |
@@ -103,4 +131,5 @@ No modules.
103131
| <a name="output_role_definition_id"></a> [role\_definition\_id](#output\_role\_definition\_id) | The ID of the role definition that enables deployment of the building block to subscriptions. |
104132
| <a name="output_role_definition_name"></a> [role\_definition\_name](#output\_role\_definition\_name) | The name of the role definition that enables deployment of the building block to subscriptions. |
105133
| <a name="output_scope"></a> [scope](#output\_scope) | The scope where the role definition and role assignments are applied. |
134+
| <a name="output_workload_identity_federation"></a> [workload\_identity\_federation](#output\_workload\_identity\_federation) | Information about the created workload identity federation credential. |
106135
<!-- END_TF_DOCS -->

modules/azure/storage-account/backplane/main.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,26 @@ resource "azuread_service_principal" "buildingblock_deploy" {
1212
app_role_assignment_required = false
1313
}
1414

15+
16+
# Create federated identity credentials
17+
resource "azuread_application_federated_identity_credential" "buildingblock_deploy" {
18+
count = var.create_service_principal_name != null && var.workload_identity_federation != null ? 1 : 0
19+
20+
application_id = azuread_application.buildingblock_deploy[0].id
21+
display_name = var.create_service_principal_name
22+
audiences = ["api://AzureADTokenExchange"]
23+
issuer = var.workload_identity_federation.issuer
24+
subject = var.workload_identity_federation.subject
25+
}
26+
27+
# Create application password (when not using workload identity federation)
28+
resource "azuread_application_password" "buildingblock_deploy" {
29+
count = var.create_service_principal_name != null && var.workload_identity_federation == null ? 1 : 0
30+
31+
application_id = azuread_application.buildingblock_deploy[0].id
32+
display_name = "${var.create_service_principal_name}-password"
33+
}
34+
1535
# Role Definition
1636
resource "azurerm_role_definition" "buildingblock_deploy" {
1737
name = "${var.name}-deploy"

modules/azure/storage-account/backplane/outputs.tf

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,26 @@ output "created_application" {
3737
description = "Information about the created Azure AD application."
3838
}
3939

40+
output "workload_identity_federation" {
41+
value = var.create_service_principal_name != null && var.workload_identity_federation != null ? {
42+
credential_id = azuread_application_federated_identity_credential.buildingblock_deploy[0].credential_id
43+
display_name = azuread_application_federated_identity_credential.buildingblock_deploy[0].display_name
44+
issuer = azuread_application_federated_identity_credential.buildingblock_deploy[0].issuer
45+
subject = azuread_application_federated_identity_credential.buildingblock_deploy[0].subject
46+
audiences = azuread_application_federated_identity_credential.buildingblock_deploy[0].audiences
47+
} : null
48+
description = "Information about the created workload identity federation credential."
49+
}
50+
51+
output "application_password" {
52+
value = var.create_service_principal_name != null && var.workload_identity_federation == null ? {
53+
key_id = azuread_application_password.buildingblock_deploy[0].key_id
54+
display_name = azuread_application_password.buildingblock_deploy[0].display_name
55+
} : null
56+
description = "Information about the created application password (excludes the actual password value for security)."
57+
sensitive = true
58+
}
59+
4060
output "scope" {
4161
value = var.scope
4262
description = "The scope where the role definition and role assignments are applied."

modules/azure/storage-account/backplane/variables.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,12 @@ variable "create_service_principal_name" {
3030
error_message = "Service principal name can only contain alphanumeric characters, hyphens, and underscores"
3131
}
3232
}
33+
34+
variable "workload_identity_federation" {
35+
type = object({
36+
issuer = string
37+
subject = string
38+
})
39+
default = null
40+
description = "Configuration for workload identity federation. If not provided, an application password will be created instead."
41+
}

0 commit comments

Comments
 (0)