diff --git a/docs/resources/conditional_access_policy.md b/docs/resources/conditional_access_policy.md index 1e3dba260..2f4db3eaa 100644 --- a/docs/resources/conditional_access_policy.md +++ b/docs/resources/conditional_access_policy.md @@ -175,8 +175,17 @@ The following arguments are supported: `applications` block supports the following: * `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. +* `filter` - (Optional) A `filter` block as described below. +* `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`, `included_user_actions` or `included_authentication_context_class_references` must be specified. +* `included_authentication_context_class_references` - (Optional) A list of authentication context class reference to include. Supported values are `c1` through `c99`. +* `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`, `included_user_actions` or `included_authentication_context_class_references` must be specified. + +--- + +`filter` block supports the following: + +* `mode` - (Required) Whether to include in, or exclude from, matching applications from the policy. Supported values are `include` or `exclude`. +* `rule` - (Required) Condition filter to match applications. For more information, see [official documentation](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-filter-for-applications). --- diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource.go b/internal/services/conditionalaccess/conditional_access_policy_resource.go index 407322034..4daa05c38 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "log" + "regexp" "time" "github.com/hashicorp/go-azure-helpers/lang/pointer" @@ -86,7 +87,7 @@ func conditionalAccessPolicyResource() *pluginsdk.Resource { "included_applications": { Type: pluginsdk.TypeList, Optional: true, - ExactlyOneOf: []string{"conditions.0.applications.0.included_applications", "conditions.0.applications.0.included_user_actions"}, + ExactlyOneOf: []string{"conditions.0.applications.0.included_applications", "conditions.0.applications.0.included_user_actions", "conditions.0.applications.0.included_authentication_context_class_references"}, Elem: &pluginsdk.Schema{ Type: pluginsdk.TypeString, ValidateFunc: validation.StringIsNotEmpty, @@ -102,15 +103,45 @@ func conditionalAccessPolicyResource() *pluginsdk.Resource { }, }, + "filter": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "mode": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(stable.PossibleValuesForFilterMode(), false), + }, + + "rule": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + }, + }, + "included_user_actions": { Type: pluginsdk.TypeList, Optional: true, - ExactlyOneOf: []string{"conditions.0.applications.0.included_applications", "conditions.0.applications.0.included_user_actions"}, + ExactlyOneOf: []string{"conditions.0.applications.0.included_applications", "conditions.0.applications.0.included_user_actions", "conditions.0.applications.0.included_authentication_context_class_references"}, Elem: &pluginsdk.Schema{ Type: pluginsdk.TypeString, ValidateFunc: validation.StringIsNotEmpty, }, }, + + "included_authentication_context_class_references": { + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.StringMatch(regexp.MustCompile("^c([1-9]|[1-9][0-9])$"), ""), + }, + }, }, }, }, diff --git a/internal/services/conditionalaccess/conditionalaccess.go b/internal/services/conditionalaccess/conditionalaccess.go index 704a2c9f4..0980c810b 100644 --- a/internal/services/conditionalaccess/conditionalaccess.go +++ b/internal/services/conditionalaccess/conditionalaccess.go @@ -58,7 +58,9 @@ func flattenConditionalAccessApplications(in stable.ConditionalAccessApplication map[string]interface{}{ "included_applications": tf.FlattenStringSlicePtr(in.IncludeApplications), "excluded_applications": tf.FlattenStringSlicePtr(in.ExcludeApplications), + "filter": flattenConditionalAccessFilter(in.ApplicationFilter), "included_user_actions": tf.FlattenStringSlicePtr(in.IncludeUserActions), + "included_authentication_context_class_references": tf.FlattenStringSlicePtr(in.IncludeAuthenticationContextClassReferences), }, } } @@ -102,7 +104,7 @@ func flattenConditionalAccessDevices(in *stable.ConditionalAccessDevices) []inte return []interface{}{ map[string]interface{}{ - "filter": flattenConditionalAccessDeviceFilter(in.DeviceFilter), + "filter": flattenConditionalAccessFilter(in.DeviceFilter), }, } } @@ -222,7 +224,7 @@ func flattenConditionalAccessSessionControls(in *stable.ConditionalAccessSession } } -func flattenConditionalAccessDeviceFilter(in *stable.ConditionalAccessFilter) []interface{} { +func flattenConditionalAccessFilter(in *stable.ConditionalAccessFilter) []interface{} { if in == nil { return []interface{}{} } @@ -398,11 +400,17 @@ func expandConditionalAccessApplications(in []interface{}) stable.ConditionalAcc includeApplications := config["included_applications"].([]interface{}) excludeApplications := config["excluded_applications"].([]interface{}) + applicationilter := config["filter"].([]interface{}) includeUserActions := config["included_user_actions"].([]interface{}) + includeAuthenticationContextClassReferences := config["included_authentication_context_class_references"].([]interface{}) result.IncludeApplications = tf.ExpandStringSlicePtr(includeApplications) result.ExcludeApplications = tf.ExpandStringSlicePtr(excludeApplications) + if len(applicationilter) > 0 { + result.ApplicationFilter = expandConditionalAccessFilter(applicationilter) + } result.IncludeUserActions = tf.ExpandStringSlicePtr(includeUserActions) + result.IncludeAuthenticationContextClassReferences = tf.ExpandStringSlicePtr(includeAuthenticationContextClassReferences) return result }