Skip to content

Commit 738fe51

Browse files
committed
chore: support additional subject for wif backplane (gcp and azure)
1 parent a00b0b5 commit 738fe51

File tree

8 files changed

+56
-38
lines changed

8 files changed

+56
-38
lines changed

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,11 @@ module "storage_account_backplane" {
6161
6262
create_service_principal_name = "deployment-sp"
6363
workload_identity_federation = {
64-
issuer = "https://token.actions.githubusercontent.com"
65-
subject = "repo:my-org/my-repo:ref:refs/heads/main"
64+
issuer = "https://token.actions.githubusercontent.com"
65+
subjects = [
66+
"repo:my-org/my-repo:ref:refs/heads/main",
67+
# "repo:my-org/my-repo:environment:production", # Additional subjects for migration
68+
]
6669
}
6770
}
6871
```
@@ -90,7 +93,7 @@ module "storage_account_backplane" {
9093
| Name | Version |
9194
|------|---------|
9295
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
93-
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | ~> 3.5.0 |
96+
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | ~> 3.7.0 |
9497
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | 3.116.0 |
9598

9699
## Modules
@@ -102,7 +105,7 @@ No modules.
102105
| Name | Type |
103106
|------|------|
104107
| [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 |
108+
| [azuread_application_flexible_federated_identity_credential.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_flexible_federated_identity_credential) | resource |
106109
| [azuread_application_password.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_password) | resource |
107110
| [azuread_service_principal.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal) | resource |
108111
| [azurerm_role_assignment.created_principal](https://registry.terraform.io/providers/hashicorp/azurerm/3.116.0/docs/resources/role_assignment) | resource |
@@ -117,7 +120,7 @@ No modules.
117120
| <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 |
118121
| <a name="input_name"></a> [name](#input\_name) | name of the building block, used for naming resources | `string` | n/a | yes |
119122
| <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 |
120-
| <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 |
123+
| <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. Supports multiple subjects for migration paths and wildcard patterns. | <pre>object({<br> issuer = string<br> subjects = list(string)<br> })</pre> | `null` | no |
121124

122125
## Outputs
123126

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
resource "azuread_application" "buildingblock_deploy" {
33
count = var.create_service_principal_name != null ? 1 : 0
44

5-
display_name = "${var.name}-${var.create_service_principal_name}"
5+
display_name = var.create_service_principal_name
66
}
77

88
resource "azuread_service_principal" "buildingblock_deploy" {
@@ -13,15 +13,21 @@ resource "azuread_service_principal" "buildingblock_deploy" {
1313
}
1414

1515

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
16+
# Create federated identity credentials (one per subject for migration paths)
17+
resource "azuread_application_flexible_federated_identity_credential" "buildingblock_deploy" {
18+
count = var.create_service_principal_name != null && var.workload_identity_federation != null ? length(var.workload_identity_federation.subjects) : 0
1919

2020
application_id = azuread_application.buildingblock_deploy[0].id
21-
display_name = var.create_service_principal_name
22-
audiences = ["api://AzureADTokenExchange"]
21+
display_name = "${var.create_service_principal_name}-${count.index}"
22+
audience = "api://AzureADTokenExchange"
2323
issuer = var.workload_identity_federation.issuer
24-
subject = var.workload_identity_federation.subject
24+
claims_matching_expression = strcontains(
25+
var.workload_identity_federation.subjects[count.index], "*"
26+
) ? (
27+
"claims['sub'] matches '${var.workload_identity_federation.subjects[count.index]}'"
28+
) : (
29+
"claims['sub'] eq '${var.workload_identity_federation.subjects[count.index]}'"
30+
)
2531
}
2632

2733
# Create application password (when not using workload identity federation)

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ output "created_application" {
4545

4646
output "workload_identity_federation" {
4747
value = var.create_service_principal_name != null && var.workload_identity_federation != null ? {
48-
credential_id = azuread_application_federated_identity_credential.buildingblock_deploy[0].credential_id
49-
display_name = azuread_application_federated_identity_credential.buildingblock_deploy[0].display_name
50-
issuer = azuread_application_federated_identity_credential.buildingblock_deploy[0].issuer
51-
subject = azuread_application_federated_identity_credential.buildingblock_deploy[0].subject
52-
audiences = azuread_application_federated_identity_credential.buildingblock_deploy[0].audiences
48+
credential_id = azuread_application_flexible_federated_identity_credential.buildingblock_deploy[0].credential_id
49+
display_name = azuread_application_flexible_federated_identity_credential.buildingblock_deploy[0].display_name
50+
issuer = azuread_application_flexible_federated_identity_credential.buildingblock_deploy[0].issuer
51+
claims_matching_expression = azuread_application_flexible_federated_identity_credential.buildingblock_deploy[0].claims_matching_expression
52+
audience = azuread_application_flexible_federated_identity_credential.buildingblock_deploy[0].audience
5353
} : null
5454
description = "Information about the created workload identity federation credential."
5555
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ variable "create_service_principal_name" {
3333

3434
variable "workload_identity_federation" {
3535
type = object({
36-
issuer = string
37-
subject = string
36+
issuer = string
37+
subjects = list(string)
3838
})
3939
default = null
40-
description = "Configuration for workload identity federation. If not provided, an application password will be created instead."
40+
description = "Configuration for workload identity federation. If not provided, an application password will be created instead. Supports multiple subjects for migration paths and wildcard patterns."
4141
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ terraform {
88
}
99
azuread = {
1010
source = "hashicorp/azuread"
11-
version = "~> 3.5.0"
11+
version = "~> 3.7.0"
1212
}
1313
}
1414
}

modules/gcp/storage-bucket/backplane/README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@ This module provisions the necessary IAM resources for the GCP Storage Bucket bu
88
module "gcp_storage_bucket_backplane" {
99
source = "git::https://github.com/meshcloud/meshstack-hub.git//modules/gcp/storage-bucket/backplane"
1010
11-
project_id = "your-gcp-project-id"
12-
service_account_id = "your-service-account-id" # Optional, defaults to "buildingblock-storage-sa"
11+
project_id = "your-gcp-project-id"
12+
service_account_id = "your-service-account-id" # Optional, defaults to "buildingblock-storage-sa"
1313
workload_identity_federation = {
1414
workload_identity_pool_identifier = "your-pool-identifier"
1515
audience = "your-audience"
1616
issuer = "https://your-oidc-issuer"
17-
subject = "system:serviceaccount:your-namespace:your-service-account-name"
18-
subject_token_file_path = "/path/to/your/token/file"
19-
} # Optional, if not provided, workload identity federation will not be set up and a service account key will be created
17+
subjects = [
18+
"system:serviceaccount:your-namespace:your-service-account-name",
19+
# "system:serviceaccount:your-namespace:*", # Wildcard for migration paths
20+
]
21+
subject_token_file_path = "/path/to/your/token/file"
22+
} # Optional, if not provided, a service account key will be created instead
2023
}
2124
```
2225

@@ -49,7 +52,7 @@ No modules.
4952
|------|-------------|------|---------|:--------:|
5053
| <a name="input_project_id"></a> [project\_id](#input\_project\_id) | The GCP project ID | `string` | n/a | yes |
5154
| <a name="input_service_account_id"></a> [service\_account\_id](#input\_service\_account\_id) | The ID of the service account to create | `string` | `"buildingblock-storage-sa"` | no |
52-
| <a name="input_workload_identity_federation"></a> [workload\_identity\_federation](#input\_workload\_identity\_federation) | Configuration for workload identity federation | <pre>object({<br> workload_identity_pool_identifier = string // Identifier for the workload identity pool<br> audience = string // Audience for the OIDC tokens<br> issuer = string // OIDC issuer URL<br> subject = string // Subject for workload identity federation (e.g., system:serviceaccount:namespace:service-account-name)<br> subject_token_file_path = string // Path to the file containing the OIDC token<br> })</pre> | `null` | no |
55+
| <a name="input_workload_identity_federation"></a> [workload\_identity\_federation](#input\_workload\_identity\_federation) | Configuration for workload identity federation. Supports multiple subjects for migration paths and wildcard patterns. | <pre>object({<br> workload_identity_pool_identifier = string // Identifier for the workload identity pool<br> audience = string // Audience for the OIDC tokens<br> issuer = string // OIDC issuer URL<br> subjects = list(string) // Subjects for workload identity federation (e.g., system:serviceaccount:namespace:service-account-name)<br> subject_token_file_path = string // Path to the file containing the OIDC token<br> })</pre> | `null` | no |
5356

5457
## Outputs
5558

modules/gcp/storage-bucket/backplane/iam.tf

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@ resource "google_iam_workload_identity_pool_provider" "meshstack" {
1616
description = "OIDC identity provider for meshStack building blocks"
1717

1818
oidc {
19-
allowed_audiences = [var.workload_identity_federation.audience]
2019
issuer_uri = var.workload_identity_federation.issuer
20+
allowed_audiences = [var.workload_identity_federation.audience]
2121
}
2222

23+
# Map the OIDC token's `sub` claim to google.subject
2324
attribute_mapping = {
2425
"google.subject" = "assertion.sub"
2526
}
26-
27-
attribute_condition = "google.subject == '${var.workload_identity_federation.subject}'"
2827
}
2928

3029
resource "google_service_account" "buildingblock_storage_sa" {
@@ -33,12 +32,19 @@ resource "google_service_account" "buildingblock_storage_sa" {
3332
description = "Service account for storage bucket building block"
3433
}
3534

36-
resource "google_service_account_iam_member" "workload_identity_binding" {
35+
resource "google_service_account_iam_binding" "workload_identity_binding" {
3736
count = var.workload_identity_federation == null ? 0 : 1
3837

3938
service_account_id = google_service_account.buildingblock_storage_sa.name
4039
role = "roles/iam.workloadIdentityUser"
41-
member = "principal://iam.googleapis.com/${google_iam_workload_identity_pool.meshstack[0].name}/subject/${var.workload_identity_federation.subject}"
40+
41+
members = [
42+
for subject in var.workload_identity_federation.subjects : (
43+
strcontains(subject, "*")
44+
? "principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.meshstack[0].name}/attribute.google.subject/${subject}"
45+
: "principal://iam.googleapis.com/${google_iam_workload_identity_pool.meshstack[0].name}/subject/${subject}"
46+
)
47+
]
4248
}
4349

4450
resource "google_project_iam_member" "storage_admin" {

modules/gcp/storage-bucket/backplane/variables.tf

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ variable "service_account_id" {
1010
}
1111

1212
variable "workload_identity_federation" {
13-
description = "Configuration for workload identity federation"
13+
description = "Configuration for workload identity federation. Supports multiple subjects for migration paths and wildcard patterns."
1414
type = object({
15-
workload_identity_pool_identifier = string // Identifier for the workload identity pool
16-
audience = string // Audience for the OIDC tokens
17-
issuer = string // OIDC issuer URL
18-
subject = string // Subject for workload identity federation (e.g., system:serviceaccount:namespace:service-account-name)
19-
subject_token_file_path = string // Path to the file containing the OIDC token
15+
workload_identity_pool_identifier = string // Identifier for the workload identity pool
16+
audience = string // Audience for the OIDC tokens
17+
issuer = string // OIDC issuer URL
18+
subjects = list(string) // Subjects for workload identity federation (e.g., system:serviceaccount:namespace:service-account-name)
19+
subject_token_file_path = string // Path to the file containing the OIDC token
2020
})
2121
default = null
2222
}

0 commit comments

Comments
 (0)