Skip to content

Commit

Permalink
azurerm_pim_active_role_assignment: add support for RBAC conditions.
Browse files Browse the repository at this point in the history
  • Loading branch information
jkroepke committed Nov 8, 2024
1 parent e85a546 commit 2e7320f
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type PimEligibleRoleAssignmentModel struct {
Justification string `tfschema:"justification"`
TicketInfo []PimEligibleRoleAssignmentTicketInfo `tfschema:"ticket"`
ScheduleInfo []PimEligibleRoleAssignmentScheduleInfo `tfschema:"schedule"`
Condition string `tfschema:"condition"`
ConditionVersion string `tfschema:"condition_version"`
}

type PimEligibleRoleAssignmentTicketInfo struct {
Expand Down Expand Up @@ -114,6 +116,24 @@ func (PimEligibleRoleAssignmentResource) Arguments() map[string]*pluginsdk.Schem
Description: "The justification for this eligible role assignment",
},

"condition": {
Type: pluginsdk.TypeString,
Optional: true,
ForceNew: true,
RequiredWith: []string{"condition_version"},
ValidateFunc: validation.StringIsNotEmpty,
},

"condition_version": {
Type: pluginsdk.TypeString,
Optional: true,
ForceNew: true,
RequiredWith: []string{"condition"},
ValidateFunc: validation.StringInSlice([]string{
"2.0",
}, false),
},

"schedule": {
Type: pluginsdk.TypeList,
MaxItems: 1,
Expand Down Expand Up @@ -285,16 +305,28 @@ func (r PimEligibleRoleAssignmentResource) Create() sdk.ResourceFunc {
return err
}

properties := &roleeligibilityschedulerequests.RoleEligibilityScheduleRequestProperties{
Justification: pointer.To(config.Justification),
PrincipalId: id.PrincipalId,
RequestType: roleeligibilityschedulerequests.RequestTypeAdminAssign,
RoleDefinitionId: id.RoleDefinitionId,
Scope: pointer.To(scopeId.ID()),
ScheduleInfo: scheduleInfo,
TicketInfo: ticketInfo,
}

condition := config.Condition
conditionVersion := config.ConditionVersion

if condition != "" && conditionVersion != "" {
properties.Condition = pointer.To(condition)
properties.ConditionVersion = pointer.To(conditionVersion)
} else if condition != "" || conditionVersion != "" {
return fmt.Errorf("`condition` and `conditionVersion` should be both set or unset")
}

payload := roleeligibilityschedulerequests.RoleEligibilityScheduleRequest{
Properties: &roleeligibilityschedulerequests.RoleEligibilityScheduleRequestProperties{
Justification: pointer.To(config.Justification),
PrincipalId: id.PrincipalId,
RequestType: roleeligibilityschedulerequests.RequestTypeAdminAssign,
RoleDefinitionId: id.RoleDefinitionId,
Scope: pointer.To(scopeId.ID()),
ScheduleInfo: scheduleInfo,
TicketInfo: ticketInfo,
},
Properties: properties,
}

roleEligibilityScheduleRequestName, err := uuid.GenerateUUID()
Expand Down Expand Up @@ -396,6 +428,9 @@ func (r PimEligibleRoleAssignmentResource) Read() sdk.ResourceFunc {
state.PrincipalType = string(pointer.From(request.Properties.PrincipalType))
state.RoleDefinitionId = request.Properties.RoleDefinitionId

state.Condition = pointer.From(request.Properties.Condition)
state.ConditionVersion = pointer.From(request.Properties.ConditionVersion)

if ticketInfo := request.Properties.TicketInfo; ticketInfo != nil {
if len(state.TicketInfo) == 0 {
state.TicketInfo = make([]PimEligibleRoleAssignmentTicketInfo, 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,22 @@ func TestAccPimEligibleRoleAssignment_expirationByDate(t *testing.T) {
})
}

func TestAccPimEligibleRoleAssignment_condition(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_pim_eligible_role_assignment", "test")
r := PimEligibleRoleAssignmentResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.condition(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("condition").Exists(),
check.That(data.ResourceName).Key("condition_version").HasValue("2.0"),
),
},
})
}

func (r PimEligibleRoleAssignmentResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := parse.PimRoleAssignmentID(state.ID)
if err != nil {
Expand Down Expand Up @@ -412,3 +428,49 @@ resource "azurerm_pim_eligible_role_assignment" "import" {
}
`, r.importSetup(data))
}

func (r PimEligibleRoleAssignmentResource) condition(data acceptance.TestData) string {
return fmt.Sprintf(`
data "azurerm_subscription" "primary" {}
data "azurerm_client_config" "test" {}
data "azurerm_role_definition" "test" {
name = "Storage Blob Data Contributor"
}
/*
%[1]s
*/
resource "azurerm_resource_group" "test" {
name = "acctestRG-%[2]d"
location = "%[3]s"
}
resource "time_static" "test" {}
resource "azurerm_pim_eligible_role_assignment" "test" {
scope = data.azurerm_subscription.primary.id
role_definition_id = "${data.azurerm_subscription.primary.id}${data.azurerm_role_definition.test.id}"
principal_id = "fce9dbfd-1e1f-4c4a-95e7-dbe9211c191d"
schedule {
start_date_time = time_static.test.rfc3339
expiration {
duration_hours = 8
}
}
justification = "Expiration Duration Set"
condition_version = "2.0"
condition = "((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'})) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/containers:name] StringEquals 'test'))"
ticket {
number = "1"
system = "example ticket system"
}
}
`, r.template(data), data.RandomInteger, data.Locations.Primary)
}
7 changes: 7 additions & 0 deletions website/docs/r/pim_eligible_role_assignment.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ The following arguments are supported:

* `ticket` - (Optional) A `ticket` block as defined below. Changing this forces a new resource to be created.


~> **NOTE:** If one of `condition` or `condition_version` is set both fields must be present.

* `condition` - (Optional) The condition that limits the resources that the role can be assigned to. Changing this forces a new resource to be created.

* `condition_version` - (Optional) The version of the condition. Currently accepted value is `2.0`. Changing this forces a new resource to be created.

---

An `expiration` block supports the following:
Expand Down

0 comments on commit 2e7320f

Please sign in to comment.