From 416bb76b7a8251e8b5fb48497c79ff154b2f2b7d Mon Sep 17 00:00:00 2001 From: gowri padmaja s <48469089+gowripadmajas@users.noreply.github.com> Date: Thu, 2 Nov 2023 15:32:54 +0800 Subject: [PATCH] Enable Projects in Identity (#5) --- README.md | 6 +++--- main.tf | 24 +++++++++++++----------- outputs.tf | 22 +++++++++++----------- variables.tf | 6 +++--- 4 files changed, 30 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index ecf77f7..a6c9b1b 100644 --- a/README.md +++ b/README.md @@ -37,17 +37,17 @@ No modules. | [bound\_audiences](#input\_bound\_audiences) | List of audiences to be allowed for JWT auth roles | `list(string)` |
[| no | | [claim\_mappings](#input\_claim\_mappings) | Mapping of claims to metadata | `map(string)` |
"tfc.workload.identity"
]
{| no | | [enable\_identity\_management](#input\_enable\_identity\_management) | Enable Identity Entity management. This only works if workspace names contains no wildcard | `bool` | `true` | no | -| [identity\_name\_format](#input\_identity\_name\_format) | Identity name format string. The first parameter is the organization, and the second is the workspace name | `string` | `"tfc-%[1]s-%[2]s"` | no | +| [identity\_name\_format](#input\_identity\_name\_format) | Identity name format string. The first parameter is the organization, second parameter is the Project, and the third is the workspace name | `string` | `"tfc-%[1]s-%[2]s-%[3]s"` | no | | [namespace](#input\_namespace) | Namespace relative to the provider namespace. Vault Enterprise only | `string` | `null` | no | | [path](#input\_path) | Path to mount the JWT Auth backend | `string` | `"jwt"` | no | -| [role\_name\_format](#input\_role\_name\_format) | Format string to generate role namess. The first parameter is the organization, and the second is the workspace name | `string` | `"%[1]s-%[2]s"` | no | +| [role\_name\_format](#input\_role\_name\_format) | Format string to generate role namess. The first parameter is the organization, second parameter is the Project, and the third is the workspace name | `string` | `"%[1]s-%[2]s-%[3]s"` | no | | [tfc\_default\_project](#input\_tfc\_default\_project) | Name of TFC Default Project | `string` | `"Default Project"` | no | | [tfc\_project\_support\_match](#input\_tfc\_project\_support\_match) | The key to use for Terraform Cloud Project matching in the subject key. This is to work around the module not support projects. You should set this to 'Default Project' or '*' | `string` | `"*"` | no | | [token\_explicit\_max\_ttl](#input\_token\_explicit\_max\_ttl) | If set, will encode an explicit max TTL onto the token in number of seconds. This is a hard cap even if token\_ttl and token\_max\_ttl would otherwise allow a renewal. | `number` | `600` | no | | [token\_max\_ttl](#input\_token\_max\_ttl) | The maximum lifetime for generated tokens in number of seconds. Its current value will be referenced at renewal time. | `number` | `600` | no | | [token\_policies](#input\_token\_policies) | Default token policies to apply to all roles | `list(string)` | `[]` | no | | [token\_ttl](#input\_token\_ttl) | The incremental lifetime for generated tokens in number of seconds. Its current value will be referenced at renewal time. | `number` | `600` | no | -| [workspaces](#input\_workspaces) | List of workspaces to provide access to. Use * for wildcard. If wildcard is used, identity management cannot be enabled | `map(list(string))` | n/a | yes | +| [workspaces](#input\_workspaces) | List of workspaces to provide access to. Use * for wildcard. If wildcard is used, identity management cannot be enabled | `map(map(list(string)))` | n/a | yes | ## Outputs diff --git a/main.tf b/main.tf index 6943033..49d3f05 100644 --- a/main.tf +++ b/main.tf @@ -26,15 +26,15 @@ resource "vault_jwt_auth_backend" "this" { } locals { - workspaces = merge([for org, workspaces in var.workspaces : { - for ws in workspaces : "${org}-${ws}" => { - org = org - ws = ws - - role_name = format(var.role_name_format, org, ws) - identity_name = format(var.identity_name_format, org, ws) - } - }]...) + workspaces = merge(flatten([for org, project in var.workspaces : + [for proj, workspace in project : { for ws in workspace : "${org}-${proj}-${ws}" => { + org = org + project = proj + ws = ws + role_name = format(var.role_name_format, org, proj, ws) + identity_name = format(var.identity_name_format, org, proj, ws) + } }] + ])...) } resource "vault_jwt_auth_backend_role" "roles" { @@ -49,9 +49,10 @@ resource "vault_jwt_auth_backend_role" "roles" { bound_claims_type = "glob" bound_claims = { - sub = "organization:${each.value.org}:project:${var.tfc_project_support_match}:workspace:${each.value.ws}:run_phase:*" + sub = "organization:${each.value.org}:project:${each.value.project}:workspace:${each.value.ws}:run_phase:*" terraform_organization_name = each.value.org + terraform_project_name = each.value.project terraform_workspace_name = each.value.ws } @@ -73,6 +74,7 @@ resource "vault_identity_entity" "workspaces" { external_policies = true metadata = { terraform_organization_name = each.value.org + terraform_project_name = each.value.project terraform_workspace_name = each.value.ws } @@ -89,7 +91,7 @@ resource "vault_identity_entity_alias" "workspaces" { namespace = var.namespace - name = "organization:${each.value.org}:project:${var.tfc_default_project}:workspace:${each.value.ws}" + name = "organization:${each.value.org}:project:${each.value.project}:workspace:${each.value.ws}" mount_accessor = vault_jwt_auth_backend.this.accessor canonical_id = vault_identity_entity.workspaces[each.key].id diff --git a/outputs.tf b/outputs.tf index bbf1337..9d45379 100644 --- a/outputs.tf +++ b/outputs.tf @@ -5,19 +5,19 @@ output "auth_mount_accessor" { output "workspaces" { description = "Workspace information" - value = { for org, workspaces in var.workspaces : org => { - for ws in workspaces : ws => merge( + value = { for org, project in var.workspaces : org => merge([for proj, workspace in project : + { for ws in workspace : ws => merge( { - organization = org - workspace = ws - - role = vault_jwt_auth_backend_role.roles["${org}-${ws}"].role_name + org = org + project = proj + workspace = ws + role = vault_jwt_auth_backend_role.roles["${org}-${proj}-${ws}"].role_name }, var.enable_identity_management ? { - identity_name = vault_identity_entity.workspaces["${org}-${ws}"].name - identity_id = vault_identity_entity.workspaces["${org}-${ws}"].id - identity_alias = vault_identity_entity_alias.workspaces["${org}-${ws}"].name + identity_name = vault_identity_entity.workspaces["${org}-${proj}-${ws}"].name + identity_id = vault_identity_entity.workspaces["${org}-${proj}-${ws}"].id + identity_alias = vault_identity_entity_alias.workspaces["${org}-${proj}-${ws}"].name } : {} - ) - } } + ) }]...) + } } diff --git a/variables.tf b/variables.tf index 3181fdd..4f8894d 100644 --- a/variables.tf +++ b/variables.tf @@ -57,13 +57,13 @@ variable "bound_audiences" { variable "workspaces" { description = "List of workspaces to provide access to. Use * for wildcard. If wildcard is used, identity management cannot be enabled" - type = map(list(string)) # Key is Organisation name + type = map(map(list(string))) # First Key is Organisation name, second Key is Project } variable "role_name_format" { description = "Format string to generate role namess. The first parameter is the organization, and the second is the workspace name" type = string - default = "%[1]s-%[2]s" + default = "%[1]s-%[2]s-%[3]s" } variable "claim_mappings" { @@ -112,7 +112,7 @@ variable "enable_identity_management" { variable "identity_name_format" { description = "Identity name format string. The first parameter is the organization, and the second is the workspace name" type = string - default = "tfc-%[1]s-%[2]s" + default = "tfc-%[1]s-%[2]s-%[3]s" } variable "tfc_project_support_match" {
"terraform_full_workspace": "terraform_full_workspace",
"terraform_organization_id": "terraform_organization_id",
"terraform_organization_name": "terraform_organization_name",
"terraform_run_id": "terraform_run_id",
"terraform_run_phase": "terraform_run_phase",
"terraform_workspace_id": "terraform_workspace_id"
}