diff --git a/docs/resources/conditional_access_policy.md b/docs/resources/conditional_access_policy.md index 501214961..bb84fd468 100644 --- a/docs/resources/conditional_access_policy.md +++ b/docs/resources/conditional_access_policy.md @@ -175,6 +175,10 @@ The following arguments are supported: `applications` block supports the following: +* `application_filter` - (Optional) A `filter` block as documented below. + +~> **Note:** Specifying `filter` requires the `Attribute Definition Reader` role, this is not included in the `Global Administrator` or other administrator roles and must be separately assigned. + * `excluded_applications` - (Optional) A list of application IDs explicitly excluded from the policy. Can also be set to `Office365`. * `included_applications` - (Optional) A list of application IDs the policy applies to, unless explicitly excluded (in `excluded_applications`). Can also be set to `All`, `None` or `Office365`. Cannot be specified with `included_user_actions`. One of `included_applications` or `included_user_actions` must be specified. * `included_user_actions` - (Optional) A list of user actions to include. Supported values are `urn:user:registerdevice` and `urn:user:registersecurityinfo`. Cannot be specified with `included_applications`. One of `included_applications` or `included_user_actions` must be specified. diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource.go b/internal/services/conditionalaccess/conditional_access_policy_resource.go index f37e5c5bf..c8c2c4eb0 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource.go @@ -111,6 +111,8 @@ func conditionalAccessPolicyResource() *pluginsdk.Resource { ValidateFunc: validation.StringIsNotEmpty, }, }, + + "application_filter": schemaConditionalAccessFilter(), }, }, }, diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource_test.go b/internal/services/conditionalaccess/conditional_access_policy_resource_test.go index 571547960..01726dae7 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource_test.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource_test.go @@ -481,6 +481,24 @@ func TestAccConditionalAccessPolicy_namedLocation(t *testing.T) { }) } +func TestAccConditionalAccessPolicy_applicationFilter(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_conditional_access_policy", "test") + r := ConditionalAccessPolicyResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.applicationFilter(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("id").Exists(), + check.That(data.ResourceName).Key("display_name").HasValue(fmt.Sprintf("acctest-CONPOLICY-%d", data.RandomInteger)), + check.That(data.ResourceName).Key("state").HasValue("disabled"), + ), + }, + data.ImportStep(), + }) +} + func (ConditionalAccessPolicyResource) basic(data acceptance.TestData) string { return fmt.Sprintf(` provider "azuread" {} @@ -1278,3 +1296,36 @@ resource "azuread_conditional_access_policy" "test" { %s `, data.RandomInteger, location) } + +func (ConditionalAccessPolicyResource) applicationFilter(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_conditional_access_policy" "test" { + display_name = "acctest-CONPOLICY-%[1]d" + state = "disabled" + + conditions { + client_app_types = ["all"] + + applications { + included_applications = ["All"] + + application_filter { + mode = "include" + rule = "CustomSecurityAttribute.AzureADProviderTesting_Usage -contains \"Acceptance Tests\"" + } + } + + users { + included_users = ["All"] + } + } + + grant_controls { + operator = "OR" + built_in_controls = ["mfa"] + } +} +`, data.RandomInteger) +} diff --git a/internal/services/conditionalaccess/conditionalaccess.go b/internal/services/conditionalaccess/conditionalaccess.go index 455d437ca..f6f639873 100644 --- a/internal/services/conditionalaccess/conditionalaccess.go +++ b/internal/services/conditionalaccess/conditionalaccess.go @@ -90,6 +90,7 @@ func flattenConditionalAccessApplications(in stable.ConditionalAccessApplication "included_applications": tf.FlattenStringSlicePtr(in.IncludeApplications), "excluded_applications": tf.FlattenStringSlicePtr(in.ExcludeApplications), "included_user_actions": tf.FlattenStringSlicePtr(in.IncludeUserActions), + "application_filter": flattenConditionalAccessFilter(in.ApplicationFilter), }, } } @@ -450,11 +451,16 @@ func expandConditionalAccessApplications(in []interface{}) stable.ConditionalAcc includeApplications := config["included_applications"].([]interface{}) excludeApplications := config["excluded_applications"].([]interface{}) includeUserActions := config["included_user_actions"].([]interface{}) + applicationFilter := config["application_filter"].([]interface{}) result.IncludeApplications = tf.ExpandStringSlicePtr(includeApplications) result.ExcludeApplications = tf.ExpandStringSlicePtr(excludeApplications) result.IncludeUserActions = tf.ExpandStringSlicePtr(includeUserActions) + if len(applicationFilter) > 0 { + result.ApplicationFilter = expandConditionalAccessFilter(applicationFilter) + } + return result }