diff --git a/internal/services/apimanagement/api_management_identity_provider_aad_resource.go b/internal/services/apimanagement/api_management_identity_provider_aad_resource.go index 89b6e9132c4c..3870799dbe36 100644 --- a/internal/services/apimanagement/api_management_identity_provider_aad_resource.go +++ b/internal/services/apimanagement/api_management_identity_provider_aad_resource.go @@ -63,6 +63,13 @@ func resourceApiManagementIdentityProviderAAD() *pluginsdk.Resource { ValidateFunc: validation.IsUUID, }, }, + + "client_library": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 16), + }, + "signin_tenant": { Type: pluginsdk.TypeString, Optional: true, @@ -80,6 +87,7 @@ func resourceApiManagementIdentityProviderAADCreateUpdate(d *pluginsdk.ResourceD clientID := d.Get("client_id").(string) clientSecret := d.Get("client_secret").(string) + clientLibrary := d.Get("client_library").(string) allowedTenants := d.Get("allowed_tenants").([]interface{}) signinTenant := d.Get("signin_tenant").(string) id := identityprovider.NewIdentityProviderID(subscriptionId, d.Get("resource_group_name").(string), d.Get("api_management_name").(string), identityprovider.IdentityProviderTypeAad) @@ -100,6 +108,7 @@ func resourceApiManagementIdentityProviderAADCreateUpdate(d *pluginsdk.ResourceD parameters := identityprovider.IdentityProviderCreateContract{ Properties: &identityprovider.IdentityProviderCreateContractProperties{ ClientId: clientID, + ClientLibrary: pointer.To(clientLibrary), ClientSecret: clientSecret, Type: pointer.To(identityprovider.IdentityProviderTypeAad), AllowedTenants: utils.ExpandStringSlice(allowedTenants), @@ -145,6 +154,7 @@ func resourceApiManagementIdentityProviderAADRead(d *pluginsdk.ResourceData, met if model := resp.Model; model != nil { if props := model.Properties; props != nil { d.Set("client_id", props.ClientId) + d.Set("client_library", props.ClientLibrary) d.Set("allowed_tenants", pointer.From(props.AllowedTenants)) d.Set("signin_tenant", pointer.From(props.SigninTenant)) } diff --git a/internal/services/apimanagement/api_management_identity_provider_aad_resource_test.go b/internal/services/apimanagement/api_management_identity_provider_aad_resource_test.go index 3f6badb95ee8..2e5ed6f762fa 100644 --- a/internal/services/apimanagement/api_management_identity_provider_aad_resource_test.go +++ b/internal/services/apimanagement/api_management_identity_provider_aad_resource_test.go @@ -33,6 +33,35 @@ func TestAccApiManagementIdentityProviderAAD_basic(t *testing.T) { }) } +func TestAccApiManagementIdentityProviderAAD_clientLibrary(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_api_management_identity_provider_aad", "test") + r := ApiManagementIdentityProviderAADResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.clientLibrary(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("client_secret"), + { + Config: r.clientLibraryUpdate(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("client_secret"), + { + Config: r.clientLibrary(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("client_secret"), + }) +} + func TestAccApiManagementIdentityProviderAAD_update(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_api_management_identity_provider_aad", "test") r := ApiManagementIdentityProviderAADResource{} @@ -92,6 +121,70 @@ func (ApiManagementIdentityProviderAADResource) Exists(ctx context.Context, clie return pointer.To(resp.Model != nil && resp.Model.Id != nil), nil } +func (ApiManagementIdentityProviderAADResource) clientLibrary(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-api-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + publisher_name = "pub1" + publisher_email = "pub1@email.com" + sku_name = "Developer_1" +} + +resource "azurerm_api_management_identity_provider_aad" "test" { + resource_group_name = azurerm_resource_group.test.name + api_management_name = azurerm_api_management.test.name + client_id = "00000000-0000-0000-0000-000000000000" + client_library = "MSAL" + client_secret = "00000000000000000000000000000000" + signin_tenant = "00000000-0000-0000-0000-000000000000" + allowed_tenants = ["%s"] +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.Client().TenantID) +} + +func (ApiManagementIdentityProviderAADResource) clientLibraryUpdate(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-api-%d" + location = "%s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + publisher_name = "pub1" + publisher_email = "pub1@email.com" + sku_name = "Developer_1" +} + +resource "azurerm_api_management_identity_provider_aad" "test" { + resource_group_name = azurerm_resource_group.test.name + api_management_name = azurerm_api_management.test.name + client_id = "00000000-0000-0000-0000-000000000000" + client_library = "MSAL-2" + client_secret = "00000000000000000000000000000000" + signin_tenant = "00000000-0000-0000-0000-000000000000" + allowed_tenants = ["%s"] +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.Client().TenantID) +} + func (ApiManagementIdentityProviderAADResource) basic(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { diff --git a/internal/services/apimanagement/api_management_identity_provider_aadb2c_resource.go b/internal/services/apimanagement/api_management_identity_provider_aadb2c_resource.go index 3e3f4c346d14..912b425819a2 100644 --- a/internal/services/apimanagement/api_management_identity_provider_aadb2c_resource.go +++ b/internal/services/apimanagement/api_management_identity_provider_aadb2c_resource.go @@ -88,6 +88,12 @@ func resourceArmApiManagementIdentityProviderAADB2C() *pluginsdk.Resource { ValidateFunc: validation.StringIsNotEmpty, }, + "client_library": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 16), + }, + "profile_editing_policy": { Type: pluginsdk.TypeString, Optional: true, @@ -113,6 +119,7 @@ func resourceArmApiManagementIdentityProviderAADB2CCreateUpdate(d *pluginsdk.Res clientID := d.Get("client_id").(string) clientSecret := d.Get("client_secret").(string) + clientLibrary := d.Get("client_library").(string) allowedTenant := d.Get("allowed_tenant").(string) signinTenant := d.Get("signin_tenant").(string) @@ -139,6 +146,7 @@ func resourceArmApiManagementIdentityProviderAADB2CCreateUpdate(d *pluginsdk.Res parameters := identityprovider.IdentityProviderCreateContract{ Properties: &identityprovider.IdentityProviderCreateContractProperties{ ClientId: clientID, + ClientLibrary: pointer.To(clientLibrary), ClientSecret: clientSecret, Type: pointer.To(identityprovider.IdentityProviderTypeAadBTwoC), AllowedTenants: utils.ExpandStringSlice([]interface{}{allowedTenant}), @@ -186,6 +194,7 @@ func resourceArmApiManagementIdentityProviderAADB2CRead(d *pluginsdk.ResourceDat if model := resp.Model; model != nil { if props := model.Properties; props != nil { d.Set("client_id", props.ClientId) + d.Set("client_library", pointer.From(props.ClientLibrary)) d.Set("signin_tenant", props.SigninTenant) d.Set("authority", props.Authority) d.Set("signup_policy", props.SignupPolicyName) diff --git a/internal/services/apimanagement/api_management_identity_provider_aadb2c_resource_test.go b/internal/services/apimanagement/api_management_identity_provider_aadb2c_resource_test.go index faf0fe69ef72..40643a393481 100644 --- a/internal/services/apimanagement/api_management_identity_provider_aadb2c_resource_test.go +++ b/internal/services/apimanagement/api_management_identity_provider_aadb2c_resource_test.go @@ -45,6 +45,36 @@ func TestAccAzureRMApiManagementIdentityProviderAADB2C_basic(t *testing.T) { }) } +func TestAccAzureRMApiManagementIdentityProviderAADB2C_clientLibrary(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_api_management_identity_provider_aadb2c", "test") + r := ApiManagementIdentityProviderAADB2CResource{} + b2cConfig := testAccAzureRMApiManagementIdentityProviderAADB2C_getB2CConfig(t) + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.clientLibrary(data, b2cConfig), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("client_secret"), + { + Config: r.clientLibraryUpdate(data, b2cConfig), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("client_secret"), + { + Config: r.clientLibrary(data, b2cConfig), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep("client_secret"), + }) +} + func TestAccAzureRMApiManagementIdentityProviderAADB2C_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_api_management_identity_provider_aadb2c", "test") r := ApiManagementIdentityProviderAADB2CResource{} @@ -162,6 +192,126 @@ resource "azurerm_api_management_identity_provider_aadb2c" "test" { `, b2cConfig["tenant_id"], b2cConfig["client_id"], b2cConfig["client_secret"], b2cConfig["tenant_slug"], data.RandomInteger, data.Locations.Primary) } +func (ApiManagementIdentityProviderAADB2CResource) clientLibrary(data acceptance.TestData, b2cConfig map[string]string) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +provider "azuread" { + tenant_id = "%[1]s" + client_id = "%[2]s" + client_secret = "%[3]s" +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-api-%[5]d" + location = "%[6]s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%[5]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + publisher_name = "pub1" + publisher_email = "pub1@email.com" + sku_name = "Developer_1" +} + +resource "azuread_application" "test" { + display_name = "acctestAM-%[5]d" + web { + redirect_uris = [azurerm_api_management.test.developer_portal_url] + + implicit_grant { + access_token_issuance_enabled = true + } + } +} + +resource "azuread_application_password" "test" { + application_object_id = azuread_application.test.object_id +} + +resource "azurerm_api_management_identity_provider_aadb2c" "test" { + resource_group_name = azurerm_resource_group.test.name + api_management_name = azurerm_api_management.test.name + client_id = azuread_application.test.application_id + client_library = "MSAL" + client_secret = azuread_application_password.test.value + allowed_tenant = "%[4]s.onmicrosoft.com" + signin_tenant = "%[4]s.onmicrosoft.com" + authority = "%[4]s.b2clogin.com" + signin_policy = "B2C_1_Login" + signup_policy = "B2C_1_Signup" + profile_editing_policy = "B2C_1_EditProfile" + password_reset_policy = "B2C_1_ResetPassword" + + depends_on = [azuread_application_password.test] +} +`, b2cConfig["tenant_id"], b2cConfig["client_id"], b2cConfig["client_secret"], b2cConfig["tenant_slug"], data.RandomInteger, data.Locations.Primary) +} + +func (ApiManagementIdentityProviderAADB2CResource) clientLibraryUpdate(data acceptance.TestData, b2cConfig map[string]string) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +provider "azuread" { + tenant_id = "%[1]s" + client_id = "%[2]s" + client_secret = "%[3]s" +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-api-%[5]d" + location = "%[6]s" +} + +resource "azurerm_api_management" "test" { + name = "acctestAM-%[5]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + publisher_name = "pub1" + publisher_email = "pub1@email.com" + sku_name = "Developer_1" +} + +resource "azuread_application" "test" { + display_name = "acctestAM-%[5]d" + web { + redirect_uris = [azurerm_api_management.test.developer_portal_url] + + implicit_grant { + access_token_issuance_enabled = true + } + } +} + +resource "azuread_application_password" "test" { + application_object_id = azuread_application.test.object_id +} + +resource "azurerm_api_management_identity_provider_aadb2c" "test" { + resource_group_name = azurerm_resource_group.test.name + api_management_name = azurerm_api_management.test.name + client_id = azuread_application.test.application_id + client_library = "MSAL-2" + client_secret = azuread_application_password.test.value + allowed_tenant = "%[4]s.onmicrosoft.com" + signin_tenant = "%[4]s.onmicrosoft.com" + authority = "%[4]s.b2clogin.com" + signin_policy = "B2C_1_Login" + signup_policy = "B2C_1_Signup" + profile_editing_policy = "B2C_1_EditProfile" + password_reset_policy = "B2C_1_ResetPassword" + + depends_on = [azuread_application_password.test] +} +`, b2cConfig["tenant_id"], b2cConfig["client_id"], b2cConfig["client_secret"], b2cConfig["tenant_slug"], data.RandomInteger, data.Locations.Primary) +} + func (r ApiManagementIdentityProviderAADB2CResource) requiresImport(data acceptance.TestData, b2cConfig map[string]string) string { template := r.basic(data, b2cConfig) return fmt.Sprintf(` diff --git a/website/docs/r/api_management_identity_provider_aad.html.markdown b/website/docs/r/api_management_identity_provider_aad.html.markdown index 194ca6726515..2b5d5ed6233f 100644 --- a/website/docs/r/api_management_identity_provider_aad.html.markdown +++ b/website/docs/r/api_management_identity_provider_aad.html.markdown @@ -50,7 +50,9 @@ The following arguments are supported: * `allowed_tenants` - (Required) List of allowed AAD Tenants. -* `signin_tenant` - (Optional) The AAD Tenant to use instead of Common when logging into Active Directory +* `client_library` - (Optional) The client library to be used in the AAD Identity Provider. + +* `signin_tenant` - (Optional) The AAD Tenant to use instead of Common when logging into Active Directory. --- diff --git a/website/docs/r/api_management_identity_provider_aadb2c.html.markdown b/website/docs/r/api_management_identity_provider_aadb2c.html.markdown index a6d1f86b9f0a..e4ea68c40c2c 100644 --- a/website/docs/r/api_management_identity_provider_aadb2c.html.markdown +++ b/website/docs/r/api_management_identity_provider_aadb2c.html.markdown @@ -73,6 +73,8 @@ The following arguments are supported: * `signup_policy` - (Required) Signup Policy Name. +* `client_library` - (Optional) The client library to be used in the Azure AD B2C Identity Provider. + --- * `password_reset_policy` - (Optional) Password reset Policy Name.