This module creates and configures Azure AD Enterprise Applications for SAML Single Sign-On (SSO). It automates the Identity Provider (IdP) side of SAML federation, generating the necessary configuration to integrate with Service Providers like OCI and OVH.
- Enterprise Application Creation: Automatically creates Azure AD Enterprise Applications with SAML SSO enabled
- SAML Metadata Generation: Provides metadata URL for Service Provider configuration
- Group Creation: Optionally create new Azure AD groups and automatically assign them
- User & Group Assignments: Assign users and groups to the application
- Standard SAML Claims: Configures email, givenname, surname, and UPN claims
- Groups Claim: Optional groups claim for role-based access control
- Service Principal Configuration: Automatically creates and configures the service principal
module "oci_saml_app" {
source = "../../modules/azuread-saml-app"
display_name = "OCI Cloud SSO"
identifier_uris = ["https://idcs-xxx.identity.oraclecloud.com"]
redirect_uris = ["https://idcs-xxx.identity.oraclecloud.com/fed/v1/sp/sso"]
assigned_group_object_ids = [
"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"ffffffff-gggg-hhhh-iiii-jjjjjjjjjjjj"
]
}
output "metadata_url" {
value = module.oci_saml_app.saml_metadata_url
}module "oci_saml_app" {
source = "../../modules/azuread-saml-app"
display_name = "OCI Cloud SSO"
identifier_uris = ["https://idcs-xxx.identity.oraclecloud.com"]
redirect_uris = ["https://idcs-xxx.identity.oraclecloud.com/fed/v1/sp/sso"]
create_groups = {
"OCI-Administrators" = {
description = "Administrators for OCI Cloud"
}
"OCI-Users" = {} # Uses default description
}
}
output "created_groups" {
value = module.oci_saml_app.created_groups
}terraform {
required_providers {
azuread = {
source = "hashicorp/azuread"
version = ">= 3.7"
}
}
}
provider "azuread" {}
data "azuread_group" "oci_admins" {
display_name = "OCI-Administrators"
}
data "azuread_group" "ovh_admins" {
display_name = "OVH-Administrators"
}
module "oci_saml_app" {
source = "../../modules/azuread-saml-app"
display_name = "OCI Cloud SSO"
identifier_uris = ["https://idcs-xxx.identity.oraclecloud.com"]
redirect_uris = ["https://idcs-xxx.identity.oraclecloud.com/fed/v1/sp/sso"]
include_groups_claim = true
assigned_group_object_ids = [data.azuread_group.oci_admins.object_id]
}
module "ovh_saml_app" {
source = "../../modules/azuread-saml-app"
display_name = "OVH Cloud SSO"
identifier_uris = ["https://www.ovh.com/auth/saml/metadata"]
redirect_uris = ["https://www.ovh.com/auth/saml/acs"]
include_groups_claim = true
assigned_group_object_ids = [data.azuread_group.ovh_admins.object_id]
}Before using this module, you need the following from your Service Provider (OCI/OVH):
- Entity ID (Identifier URI)
- Assertion Consumer Service URL (Reply URL)
For OCI:
- Entity ID:
https://idcs-<guid>.identity.oraclecloud.com - ACS URL:
https://idcs-<guid>.identity.oraclecloud.com/fed/v1/sp/sso
For OVH:
- Follow OVH's documentation to obtain these values
terraform init
terraform applyThe module outputs a saml_metadata_url that you can use to configure your Service Provider:
terraform output saml_metadata_urlUse this URL in your Service Provider's SAML configuration (e.g., oci-saml-sso or ovh-saml-sso modules).
- In Azure Portal, navigate to Enterprise Applications
- Select your application
- Go to "Single sign-on" → SAML
- Verify the configuration matches your Service Provider requirements
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| display_name | Display name for the Azure AD Enterprise Application | string |
n/a | yes |
| identifier_uris | Entity ID / Identifier URIs for the SAML application (provided by Service Provider) | list(string) |
n/a | yes |
| redirect_uris | Reply URLs / Assertion Consumer Service (ACS) URLs (provided by Service Provider) | list(string) |
n/a | yes |
| logout_url | Logout URL for the SAML application | string |
null |
no |
| relay_state | SAML relay state parameter | string |
null |
no |
| owners | Additional object IDs of users or service principals who will be owners | list(string) |
[] |
no |
| assigned_user_object_ids | Object IDs of users to assign to the application | list(string) |
[] |
no |
| assigned_group_object_ids | Object IDs of groups to assign to the application | list(string) |
[] |
no |
| create_groups | Map of groups to create and assign. Key is group name, value is object with optional description | map(object({description = optional(string)})) |
{} |
no |
| include_groups_claim | Include groups claim in SAML token | bool |
true |
no |
| Name | Description |
|---|---|
| application_id | Application (client) ID of the Azure AD application |
| application_object_id | Object ID of the Azure AD application |
| service_principal_id | Object ID of the service principal |
| saml_metadata_url | Azure AD SAML metadata URL - Use this to configure the Service Provider |
| tenant_id | Azure AD tenant ID |
| configuration_instructions | Instructions for completing the SAML SSO configuration |
| created_groups | Map of created group names to their object IDs |
This module automatically configures the following SAML claims:
| Claim | Source | Description |
|---|---|---|
| Name ID | user.userprincipalname |
User's principal name (primary identifier) |
user.mail |
User's email address | |
| givenname | user.givenname |
User's first name |
| surname | user.surname |
User's last name |
| upn | user.userprincipalname |
User principal name |
| groups | user.groups |
User's group memberships (if enabled) |
The module can create new Azure AD groups and automatically assign them to the application:
module "saml_app" {
source = "../../modules/azuread-saml-app"
display_name = "Cloud SSO"
identifier_uris = ["https://example.com/saml"]
redirect_uris = ["https://example.com/saml/acs"]
create_groups = {
"Cloud-Admins" = {
description = "Cloud platform administrators"
}
"Cloud-Developers" = {
description = "Cloud platform developers"
}
}
}
output "group_ids" {
value = module.saml_app.created_groups
}data "azuread_user" "admin" {
user_principal_name = "admin@example.com"
}
data "azuread_group" "admins" {
display_name = "Cloud Administrators"
}
module "saml_app" {
source = "../../modules/azuread-saml-app"
display_name = "Cloud SSO"
identifier_uris = ["https://example.com/saml"]
redirect_uris = ["https://example.com/saml/acs"]
assigned_user_object_ids = [data.azuread_user.admin.object_id]
assigned_group_object_ids = [data.azuread_group.admins.object_id]
}data "azuread_group" "existing_group" {
display_name = "Existing-Admins"
}
module "saml_app" {
source = "../../modules/azuread-saml-app"
display_name = "Cloud SSO"
identifier_uris = ["https://example.com/saml"]
redirect_uris = ["https://example.com/saml/acs"]
create_groups = {
"New-Cloud-Users" = {
description = "Newly created cloud users group"
}
}
assigned_group_object_ids = [data.azuread_group.existing_group.object_id]
}- Navigate to Enterprise Applications in Azure AD
- Select your application
- Go to "Users and groups"
- Click "Add user/group"
- Select users or groups to assign
module "azuread_app" {
source = "../../modules/azuread-saml-app"
display_name = "OCI Cloud SSO"
identifier_uris = [module.oci_sso.entity_id]
redirect_uris = [module.oci_sso.acs_url]
assigned_group_object_ids = [data.azuread_group.oci_admins.object_id]
}
module "oci_sso" {
source = "../../modules/oci-saml-sso"
idcs_endpoint = "https://idcs-xxx.identity.oraclecloud.com"
compartment_id = var.compartment_id
saml_metadata_url = module.azuread_app.saml_metadata_url
group_mappings = {
"oci-admins" = { oci_group_name = "Administrators" }
}
}module "azuread_app" {
source = "../../modules/azuread-saml-app"
display_name = "OVH Cloud SSO"
identifier_uris = ["https://www.ovh.com/auth/saml/metadata"]
redirect_uris = ["https://www.ovh.com/auth/saml/acs"]
assigned_group_object_ids = [data.azuread_group.ovh_admins.object_id]
}
module "ovh_sso" {
source = "../../modules/ovh-saml-sso"
group_mappings = {
"ovh-admins" = { ovh_role = "ADMIN" }
}
}| Name | Version |
|---|---|
| terraform | >= 1.0 |
| azuread | >= 3.7 |
| Name | Version |
|---|---|
| azuread | >= 3.7 |
| Name | Type |
|---|---|
| azuread_application.saml_app | resource |
| azuread_service_principal.saml_app | resource |
| azuread_group.groups | resource |
| azuread_app_role_assignment.users | resource |
| azuread_app_role_assignment.groups | resource |
| azuread_client_config.current | data source |
- Ownership: The current authenticated user/service principal is automatically added as an owner
- User Assignment: Only assigned users/groups can access the application
- Groups Claim: Consider using group Object IDs instead of display names for security
- Metadata URL: The metadata URL is application-specific and safe to share with Service Providers
Problem: Users receive "access denied" errors.
Solution:
- Verify users are assigned to the application (either directly or via group membership)
- Check user/group assignments in Azure Portal → Enterprise Applications → Users and groups
Problem: Service Provider doesn't receive group memberships.
Solution:
- Ensure
include_groups_claim = truein module configuration - Verify users are members of Azure AD groups
- Check Token Configuration in Azure Portal → Enterprise Applications → Token configuration
Problem: Service Provider cannot fetch metadata.
Solution:
- Verify the metadata URL format:
https://login.microsoftonline.com/{tenant}/federationmetadata/2007-06/federationmetadata.xml?appid={app_id} - Ensure Service Provider can reach Azure AD endpoints
- Check that the Enterprise Application is properly configured
Problem: Cannot find the created application.
Solution:
- Navigate to Azure AD → Enterprise Applications (not App Registrations)
- Filter by "Application type: All applications"
- Search by the display name specified in configuration
module "saml_app" {
source = "../../modules/azuread-saml-app"
display_name = "Cloud SSO"
identifier_uris = ["https://example.com/saml"]
redirect_uris = ["https://example.com/saml/acs"]
relay_state = "https://example.com/dashboard"
}module "saml_app" {
source = "../../modules/azuread-saml-app"
display_name = "Cloud SSO"
identifier_uris = ["https://example.com/saml"]
redirect_uris = ["https://example.com/saml/acs"]
logout_url = "https://example.com/logout"
}module "saml_app" {
source = "../../modules/azuread-saml-app"
display_name = "Cloud SSO"
identifier_uris = ["https://example.com/saml"]
redirect_uris = ["https://example.com/saml/acs"]
include_groups_claim = false
}- Azure AD SAML Protocol Documentation
- Azure AD Terraform Provider Documentation
- Enterprise Applications in Azure AD
| Name | Version |
|---|---|
| terraform | >= 1.0 |
| azuread | >= 3.7 |
No modules.
| Name | Type |
|---|---|
| azuread_app_role_assignment.assigned_groups | resource |
| azuread_app_role_assignment.created_groups | resource |
| azuread_app_role_assignment.users | resource |
| azuread_application.saml_app | resource |
| azuread_group.groups | resource |
| azuread_service_principal.saml_app | resource |
| azuread_service_principal_token_signing_certificate.saml_cert | resource |
| azuread_client_config.current | data source |
| http_http.saml_metadata_xml | data source |
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| assigned_group_object_ids | Object IDs of groups to assign to the application | list(string) |
[] |
no |
| assigned_user_object_ids | Object IDs of users to assign to the application | list(string) |
[] |
no |
| create_groups | Map of groups to create and assign to the application. Key is group name, value is optional description. | map(object({ |
{} |
no |
| display_name | Display name for the Azure AD Enterprise Application | string |
n/a | yes |
| identifier_uris | Entity ID / Identifier URIs for the SAML application (provided by Service Provider) | list(string) |
n/a | yes |
| include_groups_claim | Include groups claim in SAML token | bool |
true |
no |
| login_url | Login URL for the SAML application | string |
null |
no |
| logout_url | Logout URL for the SAML application | string |
null |
no |
| owners | Additional object IDs of users or service principals who will be owners of the application | list(string) |
[] |
no |
| redirect_uris | Reply URLs / Assertion Consumer Service (ACS) URLs for the SAML application (provided by Service Provider) | list(string) |
n/a | yes |
| relay_state | SAML relay state parameter | string |
null |
no |
| Name | Description |
|---|---|
| application_id | Application (client) ID of the Azure AD application |
| application_object_id | Object ID of the Azure AD application |
| configuration_instructions | Instructions for completing the SAML SSO configuration |
| created_groups | Map of created group names to their object IDs |
| saml_entity_id | Azure AD Entity ID (Issuer) |
| saml_metadata_url | Azure AD SAML metadata URL - Use this to configure the Service Provider (OCI/OVH). Note: This returns WS-Fed format. For pure SAML, use the Azure Portal to download app-specific metadata. |
| saml_metadata_xml | Azure AD SAML metadata XML content (fetched from metadata URL) |
| saml_signing_certificate | Azure AD SAML token signing certificate (base64 encoded, no headers) |
| saml_sso_url | Azure AD SAML SSO URL (Single Sign-On endpoint) |
| service_principal_id | Object ID of the service principal |
| tenant_id | Azure AD tenant ID |