Skip to content

Commit 43c6b64

Browse files
committed
fix: sso integration
End to end sso service principal creation with required settings This should also provide outputs necessary to configure the identity provider from meshcloud's side
1 parent a633849 commit 43c6b64

File tree

8 files changed

+98
-48
lines changed

8 files changed

+98
-48
lines changed

README.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,19 @@ provide the SPN with access to the function.
142142
]
143143
```
144144

145+
## Single Sign On (SSO) Integration
146+
147+
>While this does not belong to a meshplatform, you can enable sso using this module. This is subject to change and sso can be moved out in the future.
148+
149+
To login to meshStack with Microsoft Entra ID, you can create an SSO service principal by adding the following inputs when calling this module:
150+
151+
```hcl
152+
sso_enabled = true
153+
154+
# This is required as it will construct the redirect uri. A default has been added only so that it's not mandatory to setup sso (i.e. when sso_enabled = false)
155+
sso_meshstack_idp_domain = "sso.<domain>"
156+
```
157+
145158
## Contributing Guide
146159

147160
Before opening a Pull Request, please do the following:
@@ -205,9 +218,11 @@ Before opening a Pull Request, please do the following:
205218
| <a name="input_replicator_enabled"></a> [replicator\_enabled](#input\_replicator\_enabled) | Whether to create replicator Service Principal or not. | `bool` | `true` | no |
206219
| <a name="input_replicator_rg_enabled"></a> [replicator\_rg\_enabled](#input\_replicator\_rg\_enabled) | Whether the created replicator Service Principal should be usable for Azure Resource Group based replication. Implicitly enables replicator\_enabled if set to true. | `bool` | `false` | no |
207220
| <a name="input_replicator_service_principal_name"></a> [replicator\_service\_principal\_name](#input\_replicator\_service\_principal\_name) | Service principal for managing subscriptions. Replicator is the name of the meshStack component. Name must be unique per Entra ID. | `string` | `"replicator"` | no |
208-
| <a name="input_sso_enabled"></a> [sso\_enabled](#input\_sso\_enabled) | Whether to create SSO Service Principal or not. | `bool` | `true` | no |
209-
| <a name="input_sso_meshstack_redirect_uri"></a> [sso\_meshstack\_redirect\_uri](#input\_sso\_meshstack\_redirect\_uri) | Redirect URI that was provided by meshcloud. It is individual per meshStack. | `string` | `"<replace with uri>"` | no |
210-
| <a name="input_sso_service_principal_name"></a> [sso\_service\_principal\_name](#input\_sso\_service\_principal\_name) | Service principal for Entra ID SSO. Name must be unique per Entra ID. | `string` | `"sso"` | no |
221+
| <a name="input_sso_app_role_assignment_required"></a> [sso\_app\_role\_assignment\_required](#input\_sso\_app\_role\_assignment\_required) | Whether all users can login using the created application (false), or only assigned users (true) | `bool` | `false` | no |
222+
| <a name="input_sso_enabled"></a> [sso\_enabled](#input\_sso\_enabled) | Whether to create SSO Service Principal. This service principal is used to integrate meshStack identity provider with your own identity provider. | `bool` | `false` | no |
223+
| <a name="input_sso_identity_provider_alias"></a> [sso\_identity\_provider\_alias](#input\_sso\_identity\_provider\_alias) | Identity provider alias. This value needs to be passed to meshcloud to configure the identity provider. | `string` | `"oidc"` | no |
224+
| <a name="input_sso_meshstack_idp_domain"></a> [sso\_meshstack\_idp\_domain](#input\_sso\_meshstack\_idp\_domain) | meshStack identity provider domain that was provided by meshcloud. It is individual per meshStack. In most cases it is sso.<portal-domain> | `string` | `"replaceme"` | no |
225+
| <a name="input_sso_service_principal_name"></a> [sso\_service\_principal\_name](#input\_sso\_service\_principal\_name) | Service principal for Entra ID SSO. Name must be unique per Entra ID. | `string` | `"meshcloud SSO"` | no |
211226
| <a name="input_workload_identity_federation"></a> [workload\_identity\_federation](#input\_workload\_identity\_federation) | Enable workload identity federation by creating federated credentials for enterprise applications. Usually you'd receive the required settings when attempting to configure a platform with workload identity federation in meshStack. | `object({ issuer = string, replicator_subject = string, kraken_subject = string })` | `null` | no |
212227

213228
## Outputs
@@ -221,6 +236,7 @@ Before opening a Pull Request, please do the following:
221236
| <a name="output_metering_service_principal_password"></a> [metering\_service\_principal\_password](#output\_metering\_service\_principal\_password) | Password for Metering Service Principal. |
222237
| <a name="output_replicator_service_principal"></a> [replicator\_service\_principal](#output\_replicator\_service\_principal) | Replicator Service Principal. |
223238
| <a name="output_replicator_service_principal_password"></a> [replicator\_service\_principal\_password](#output\_replicator\_service\_principal\_password) | Password for Replicator Service Principal. |
224-
| <a name="output_sso_service_principal"></a> [sso\_service\_principal](#output\_sso\_service\_principal) | SSO Service Principal. |
239+
| <a name="output_sso_discovery_url"></a> [sso\_discovery\_url](#output\_sso\_discovery\_url) | SSO applications's discovery url (OpenID Connect metadata document) |
240+
| <a name="output_sso_service_principal_client_id"></a> [sso\_service\_principal\_client\_id](#output\_sso\_service\_principal\_client\_id) | SSO Service Principal. |
225241
| <a name="output_sso_service_principal_password"></a> [sso\_service\_principal\_password](#output\_sso\_service\_principal\_password) | Password for SSO Service Principal. |
226242
<!-- END_TF_DOCS -->

main.tf

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,10 @@ module "sso_service_principal" {
100100
count = var.sso_enabled ? 1 : 0
101101
source = "./modules/meshcloud-sso/"
102102

103-
service_principal_name = var.sso_service_principal_name
104-
meshstack_redirect_uri = var.sso_meshstack_redirect_uri
103+
service_principal_name = var.sso_service_principal_name
104+
meshstack_idp_domain = var.sso_meshstack_idp_domain
105+
identity_provider_alias = var.sso_identity_provider_alias
106+
app_role_assignment_required = var.sso_app_role_assignment_required
105107
}
106108

107109
# facilitate migration from v0.1.0 of the module

modules/meshcloud-sso/README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
|------|---------|
66
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | > 1.0 |
77
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | 2.46.0 |
8-
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | 3.81.0 |
98

109
## Providers
1110

@@ -21,24 +20,28 @@ No modules.
2120

2221
| Name | Type |
2322
|------|------|
24-
| [azuread_app_role_assignment.meshcloud_sso_user_read](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/app_role_assignment) | resource |
2523
| [azuread_application.meshcloud_sso](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/application) | resource |
2624
| [azuread_application_password.meshcloud_sso](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/application_password) | resource |
25+
| [azuread_service_principal.meshcloud_sso](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/resources/service_principal) | resource |
2726
| [azuread_application_published_app_ids.well_known](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/data-sources/application_published_app_ids) | data source |
2827
| [azuread_application_template.enterprise_app](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/data-sources/application_template) | data source |
28+
| [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/data-sources/client_config) | data source |
2929
| [azuread_service_principal.msgraph](https://registry.terraform.io/providers/hashicorp/azuread/2.46.0/docs/data-sources/service_principal) | data source |
3030

3131
## Inputs
3232

3333
| Name | Description | Type | Default | Required |
3434
|------|-------------|------|---------|:--------:|
35-
| <a name="input_meshstack_redirect_uri"></a> [meshstack\_redirect\_uri](#input\_meshstack\_redirect\_uri) | Redirect URI that was provided by meshcloud. It is individual per meshStack. | `string` | n/a | yes |
36-
| <a name="input_service_principal_name"></a> [service\_principal\_name](#input\_service\_principal\_name) | Service principal name. | `string` | n/a | yes |
35+
| <a name="input_app_role_assignment_required"></a> [app\_role\_assignment\_required](#input\_app\_role\_assignment\_required) | Whether all users can login using the created application (false), or only assigned users (true) | `bool` | `false` | no |
36+
| <a name="input_identity_provider_alias"></a> [identity\_provider\_alias](#input\_identity\_provider\_alias) | Identity provider alias. This value needs to be passed to meshcloud to configure the identity provider. | `string` | `"oidc"` | no |
37+
| <a name="input_meshstack_idp_domain"></a> [meshstack\_idp\_domain](#input\_meshstack\_idp\_domain) | meshStack identity provider domain that was provided by meshcloud. It is individual per meshStack. In most cases it is sso.<portal-domain> | `string` | n/a | yes |
38+
| <a name="input_service_principal_name"></a> [service\_principal\_name](#input\_service\_principal\_name) | Service principal for Entra ID SSO. Name must be unique per Entra ID. | `string` | `"meshcloud SSO"` | no |
3739

3840
## Outputs
3941

4042
| Name | Description |
4143
|------|-------------|
42-
| <a name="output_application_client_secret"></a> [application\_client\_secret](#output\_application\_client\_secret) | Password for the application registration. |
43-
| <a name="output_credentials"></a> [credentials](#output\_credentials) | Service Principal application id and object id |
44+
| <a name="output_application_client_id"></a> [application\_client\_id](#output\_application\_client\_id) | n/a |
45+
| <a name="output_application_password"></a> [application\_password](#output\_application\_password) | Password for the SSO application. |
46+
| <a name="output_discovery_url"></a> [discovery\_url](#output\_discovery\_url) | SSO applications's discovery url (OpenID Connect metadata document) |
4447
<!-- END_TF_DOCS -->

modules/meshcloud-sso/module.tf

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
terraform {
22
required_version = "> 1.0"
33
required_providers {
4-
azurerm = {
5-
source = "hashicorp/azurerm"
6-
version = "3.81.0"
7-
}
84
azuread = {
95
source = "hashicorp/azuread"
106
version = "2.46.0"
@@ -42,20 +38,22 @@ resource "azuread_application" "meshcloud_sso" {
4238
resource_app_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph
4339

4440
resource_access {
45-
id = data.azuread_service_principal.msgraph.app_role_ids["User.Read"]
41+
id = data.azuread_service_principal.msgraph.oauth2_permission_scope_ids["User.Read"]
4642
type = "Scope"
4743
}
4844
}
4945
web {
50-
redirect_uris = [var.meshstack_redirect_uri]
46+
redirect_uris = ["https://${var.meshstack_idp_domain}/auth/realms/meshfed/broker/${var.identity_provider_alias}/endpoint"]
47+
implicit_grant {
48+
id_token_issuance_enabled = true
49+
}
5150
}
5251
}
5352

54-
resource "azuread_app_role_assignment" "meshcloud_sso_user_read" {
55-
app_role_id = data.azuread_service_principal.msgraph.app_role_ids["User.Read"]
56-
principal_object_id = azuread_application.meshcloud_sso.object_id
57-
resource_object_id = data.azuread_service_principal.msgraph.object_id
58-
depends_on = [azuread_application.meshcloud_sso]
53+
resource "azuread_service_principal" "meshcloud_sso" {
54+
use_existing = true
55+
app_role_assignment_required = var.app_role_assignment_required
56+
client_id = azuread_application.meshcloud_sso.client_id
5957
}
6058

6159
resource "azuread_application_password" "meshcloud_sso" {

modules/meshcloud-sso/outputs.tf

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1-
output "credentials" {
2-
description = "Service Principal application id and object id"
3-
value = {
4-
Enterprise_Application_Object_ID = azuread_application.meshcloud_sso.object_id
5-
Application_Client_ID = azuread_application.meshcloud_sso.client_id
6-
}
1+
output "application_client_id" {
2+
value = azuread_application.meshcloud_sso.client_id
73
}
84

9-
output "application_client_secret" {
10-
description = "Password for the application registration."
11-
value = azuread_application_password.meshcloud_sso.value
5+
output "application_password" {
6+
description = "Password for the SSO application."
127
sensitive = true
8+
value = azuread_application_password.meshcloud_sso.value
9+
}
10+
11+
data "azuread_client_config" "current" {}
12+
13+
output "discovery_url" {
14+
description = "SSO applications's discovery url (OpenID Connect metadata document)"
15+
value = "https://login.microsoftonline.com/${data.azuread_client_config.current.tenant_id}/v2.0/.well-known/openid-configuration"
1316
}

modules/meshcloud-sso/variables.tf

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
variable "service_principal_name" {
22
type = string
3-
description = "Service principal name."
3+
default = "meshcloud SSO"
4+
description = "Service principal for Entra ID SSO. Name must be unique per Entra ID."
45
}
56

6-
variable "meshstack_redirect_uri" {
7+
variable "meshstack_idp_domain" {
78
type = string
8-
description = "Redirect URI that was provided by meshcloud. It is individual per meshStack."
9+
description = "meshStack identity provider domain that was provided by meshcloud. It is individual per meshStack. In most cases it is sso.<portal-domain>"
10+
}
11+
12+
variable "identity_provider_alias" {
13+
type = string
14+
default = "oidc"
15+
description = "Identity provider alias. This value needs to be passed to meshcloud to configure the identity provider."
16+
}
17+
18+
variable "app_role_assignment_required" {
19+
type = bool
20+
default = false
21+
description = "Whether all users can login using the created application (false), or only assigned users (true)"
922
}

outputs.tf

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,20 @@ output "metering_service_principal_password" {
3131
sensitive = true
3232
}
3333

34-
output "sso_service_principal" {
34+
output "sso_service_principal_client_id" {
3535
description = "SSO Service Principal."
36-
value = length(module.sso_service_principal) > 0 ? module.sso_service_principal[0].credentials : null
36+
value = length(module.sso_service_principal) > 0 ? module.sso_service_principal[0].application_client_id : null
3737
}
3838

3939
output "sso_service_principal_password" {
4040
description = "Password for SSO Service Principal."
41-
value = length(module.sso_service_principal) > 0 ? module.sso_service_principal[0].application_client_secret : null
41+
value = length(module.sso_service_principal) > 0 ? module.sso_service_principal[0].application_password : null
42+
sensitive = true
43+
}
44+
45+
output "sso_discovery_url" {
46+
description = "SSO applications's discovery url (OpenID Connect metadata document)"
47+
value = length(module.sso_service_principal) > 0 ? module.sso_service_principal[0].discovery_url : null
4248
sensitive = true
4349
}
4450

variables.tf

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,28 +37,37 @@ variable "metering_assignment_scopes" {
3737
description = "Names or UUIDs of the Management Groups that kraken should collect costs for."
3838
}
3939

40+
# SSO inputs
41+
4042
variable "sso_enabled" {
4143
type = bool
42-
default = true
43-
description = "Whether to create SSO Service Principal or not."
44+
default = false
45+
description = "Whether to create SSO Service Principal. This service principal is used to integrate meshStack identity provider with your own identity provider."
4446
}
4547

4648
variable "sso_service_principal_name" {
4749
type = string
48-
default = "sso"
50+
default = "meshcloud SSO"
4951
description = "Service principal for Entra ID SSO. Name must be unique per Entra ID."
5052
}
5153

52-
variable "sso_meshstack_redirect_uri" {
54+
variable "sso_meshstack_idp_domain" {
5355
type = string
54-
default = "<replace with uri>"
55-
description = "Redirect URI that was provided by meshcloud. It is individual per meshStack."
56+
default = "replaceme"
57+
description = "meshStack identity provider domain that was provided by meshcloud. It is individual per meshStack. In most cases it is sso.<portal-domain>"
5658
}
5759

58-
# ---------------------------------------------------------------------------------------------------------------------
59-
# OPTIONAL PARAMETERS
60-
# These parameters have reasonable defaults.
61-
# ---------------------------------------------------------------------------------------------------------------------
60+
variable "sso_identity_provider_alias" {
61+
type = string
62+
default = "oidc"
63+
description = "Identity provider alias. This value needs to be passed to meshcloud to configure the identity provider."
64+
}
65+
66+
variable "sso_app_role_assignment_required" {
67+
type = bool
68+
default = false
69+
description = "Whether all users can login using the created application (false), or only assigned users (true)"
70+
}
6271

6372
variable "replicator_enabled" {
6473
type = bool

0 commit comments

Comments
 (0)