Skip to content

Commit b3ea01c

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

File tree

9 files changed

+50
-83
lines changed

9 files changed

+50
-83
lines changed

modules/azure/storage-account/backplane/.terraform.lock.hcl

Lines changed: 0 additions & 42 deletions
This file was deleted.

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
@@ -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

@@ -132,5 +135,5 @@ No modules.
132135
| <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. |
133136
| <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. |
134137
| <a name="output_scope"></a> [scope](#output\_scope) | The scope where the role definition and role assignments are applied. |
135-
| <a name="output_workload_identity_federation"></a> [workload\_identity\_federation](#output\_workload\_identity\_federation) | Information about the created workload identity federation credential. |
138+
| <a name="output_workload_identity_federation"></a> [workload\_identity\_federation](#output\_workload\_identity\_federation) | Information about the created workload identity federation credentials. |
136139
<!-- END_TF_DOCS -->

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

Lines changed: 5 additions & 5 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,15 @@ resource "azuread_service_principal" "buildingblock_deploy" {
1313
}
1414

1515

16-
# Create federated identity credentials
16+
# Create federated identity credentials (one per subject for migration paths)
1717
resource "azuread_application_federated_identity_credential" "buildingblock_deploy" {
18-
count = var.create_service_principal_name != null && var.workload_identity_federation != null ? 1 : 0
18+
for_each = var.create_service_principal_name != null && var.workload_identity_federation != null ? toset(var.workload_identity_federation.subjects) : toset([])
1919

2020
application_id = azuread_application.buildingblock_deploy[0].id
21-
display_name = var.create_service_principal_name
21+
display_name = "${var.create_service_principal_name}-${each.value}"
2222
audiences = ["api://AzureADTokenExchange"]
2323
issuer = var.workload_identity_federation.issuer
24-
subject = var.workload_identity_federation.subject
24+
subject = each.value
2525
}
2626

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

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,16 @@ output "created_application" {
4242
} : null
4343
description = "Information about the created Azure AD application."
4444
}
45-
4645
output "workload_identity_federation" {
47-
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
53-
} : null
54-
description = "Information about the created workload identity federation credential."
46+
value = var.create_service_principal_name != null && var.workload_identity_federation != null ? [
47+
for wif in azuread_application_federated_identity_credential.buildingblock_deploy : {
48+
credential_id = wif.credential_id
49+
display_name = wif.display_name
50+
issuer = wif.issuer
51+
subject = wif.subject
52+
audiences = wif.audiences
53+
}] : null
54+
description = "Information about the created workload identity federation credentials."
5555
}
5656

5757
output "application_password" {

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: 10 additions & 7 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

@@ -40,7 +43,7 @@ No modules.
4043
| [google_iam_workload_identity_pool_provider.meshstack](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool_provider) | resource |
4144
| [google_project_iam_member.storage_admin](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_iam_member) | resource |
4245
| [google_service_account.buildingblock_storage_sa](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource |
43-
| [google_service_account_iam_member.workload_identity_binding](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_member) | resource |
46+
| [google_service_account_iam_binding.workload_identity_binding](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_iam_binding) | resource |
4447
| [google_service_account_key.buildingblock_storage_key](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account_key) | resource |
4548

4649
## Inputs
@@ -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: 8 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,16 @@ 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+
"principal://iam.googleapis.com/${google_iam_workload_identity_pool.meshstack[0].name}/subject/${subject}"
44+
]
4245
}
4346

4447
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)