Skip to content

Commit

Permalink
arm_role_assignment: add pricipal_type and `skip_servicepricipal_…
Browse files Browse the repository at this point in the history
…aad_check` properties (#4168)

* Expose Principal Type attribute

* Update azurerm/resource_arm_role_assignment_test.go

Co-Authored-By: Tom Harvey <[email protected]>

* Update azurerm/resource_arm_role_assignment_test.go

Co-Authored-By: kt <[email protected]>

* Updates per PR comments

* Missed a comma

* Revert name change

* Update per PR review

* Change of direction

* Removing unused resource

* added set to read CRUD

* Update read

* gofmt

* Changes per PR comments

* Added principal_type as a computed attribute
  • Loading branch information
WodansSon authored Sep 7, 2019
1 parent 5bb657e commit 06eae21
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 7 deletions.
19 changes: 19 additions & 0 deletions azurerm/resource_arm_role_assignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ func resourceArmRoleAssignment() *schema.Resource {
Required: true,
ForceNew: true,
},

"principal_type": {
Type: schema.TypeString,
Computed: true,
},

"skip_service_principal_aad_check": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
},
},
}
}
Expand Down Expand Up @@ -126,6 +138,12 @@ func resourceArmRoleAssignmentCreate(d *schema.ResourceData, meta interface{}) e
},
}

skipPrincipalCheck := d.Get("skip_service_principal_aad_check").(bool)

if skipPrincipalCheck {
properties.RoleAssignmentProperties.PrincipalType = authorization.ServicePrincipal
}

if err := resource.Retry(300*time.Second, retryRoleAssignmentsClient(scope, name, properties, meta)); err != nil {
return err
}
Expand Down Expand Up @@ -164,6 +182,7 @@ func resourceArmRoleAssignmentRead(d *schema.ResourceData, meta interface{}) err
d.Set("scope", props.Scope)
d.Set("role_definition_id", props.RoleDefinitionID)
d.Set("principal_id", props.PrincipalID)
d.Set("principal_type", props.PrincipalType)

//allows for import when role name is used (also if the role name changes a plan will show a diff)
if roleId := props.RoleDefinitionID; roleId != nil {
Expand Down
73 changes: 66 additions & 7 deletions azurerm/resource_arm_role_assignment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ func TestAccAzureRMRoleAssignment(t *testing.T) {
"requiresImport": testAccAzureRMRoleAssignment_requiresImport,
},
"assignment": {
"sp": testAccAzureRMActiveDirectoryServicePrincipal_servicePrincipal,
"group": testAccAzureRMActiveDirectoryServicePrincipal_group,
"sp": testAccAzureRMActiveDirectoryServicePrincipal_servicePrincipal,
"spType": testAccAzureRMActiveDirectoryServicePrincipal_servicePrincipalWithType,
"group": testAccAzureRMActiveDirectoryServicePrincipal_group,
},
"management": {
"assign": testAccAzureRMRoleAssignment_managementGroup,
Expand Down Expand Up @@ -65,6 +66,9 @@ func testAccAzureRMRoleAssignment_emptyName(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"skip_service_principal_aad_check",
},
},
},
})
Expand All @@ -91,6 +95,9 @@ func testAccAzureRMRoleAssignment_roleName(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"skip_service_principal_aad_check",
},
},
},
})
Expand Down Expand Up @@ -146,6 +153,9 @@ func testAccAzureRMRoleAssignment_dataActions(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"skip_service_principal_aad_check",
},
},
},
})
Expand All @@ -170,6 +180,9 @@ func testAccAzureRMRoleAssignment_builtin(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"skip_service_principal_aad_check",
},
},
},
})
Expand All @@ -196,12 +209,16 @@ func testAccAzureRMRoleAssignment_custom(t *testing.T) {
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"skip_service_principal_aad_check",
},
},
},
})
}

func testAccAzureRMActiveDirectoryServicePrincipal_servicePrincipal(t *testing.T) {
resourceName := "azurerm_role_assignment.test"
ri := tf.AccRandTimeInt()
id := uuid.New().String()

Expand All @@ -212,6 +229,26 @@ func testAccAzureRMActiveDirectoryServicePrincipal_servicePrincipal(t *testing.T
Steps: []resource.TestStep{
{
Config: testAccAzureRMRoleAssignment_servicePrincipal(ri, id),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMRoleAssignmentExists("azurerm_role_assignment.test"),
resource.TestCheckResourceAttr(resourceName, "principal_type", "ServicePrincipal"),
),
},
},
})
}

func testAccAzureRMActiveDirectoryServicePrincipal_servicePrincipalWithType(t *testing.T) {
ri := tf.AccRandTimeInt()
id := uuid.New().String()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMRoleAssignmentDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMRoleAssignment_servicePrincipalWithType(ri, id),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMRoleAssignmentExists("azurerm_role_assignment.test"),
),
Expand Down Expand Up @@ -441,6 +478,28 @@ resource "azurerm_role_assignment" "test" {
`, rInt, roleAssignmentID)
}

func testAccAzureRMRoleAssignment_servicePrincipalWithType(rInt int, roleAssignmentID string) string {
return fmt.Sprintf(`
data "azurerm_subscription" "current" {}
resource "azuread_application" "test" {
name = "acctestspa-%d"
}
resource "azuread_service_principal" "test" {
application_id = "${azuread_application.test.application_id}"
}
resource "azurerm_role_assignment" "test" {
name = "%s"
scope = "${data.azurerm_subscription.current.id}"
role_definition_name = "Reader"
principal_id = "${azuread_service_principal.test.id}"
skip_service_principal_aad_check = true
}
`, rInt, roleAssignmentID)
}

func testAccAzureRMRoleAssignment_group(rInt int, roleAssignmentID string) string {
return fmt.Sprintf(`
data "azurerm_subscription" "current" {}
Expand All @@ -465,17 +524,17 @@ data "azurerm_subscription" "primary" {}
data "azurerm_client_config" "test" {}
data "azurerm_role_definition" "test" {
name = "Monitoring Reader"
name = "Monitoring Reader"
}
resource "azurerm_management_group" "test" {
group_id = "%s"
group_id = "%s"
}
resource "azurerm_role_assignment" "test" {
scope = "${azurerm_management_group.test.id}"
role_definition_id = "${data.azurerm_role_definition.test.id}"
principal_id = "${data.azurerm_client_config.test.service_principal_object_id}"
scope = "${azurerm_management_group.test.id}"
role_definition_id = "${data.azurerm_role_definition.test.id}"
principal_id = "${data.azurerm_client_config.test.service_principal_object_id}"
}
`, groupId)
}
4 changes: 4 additions & 0 deletions website/docs/r/role_assignment.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,16 @@ The following arguments are supported:

~> **NOTE:** The Principal ID is also known as the Object ID (ie not the "Application ID" for applications).

* `skip_service_principal_aad_check` - (Optional) If the `principal_id` is a newly provisioned `Service Principal` set this value to `true` to skip the `Azure Active Directory` check which may fail due to replication lag. This argument is only valid if the `principal_id` is a `Service Principal` identity. If it is not a `Service Principal` identity it will cause the role assignment to fail. Defaults to `false`.

## Attributes Reference

The following attributes are exported:

* `id` - The Role Assignment ID.

* `principal_type` - The type of the `principal_id`, e.g. User, Group, Service Principal, Application, etc.

## Import

Role Assignments can be imported using the `resource id`, e.g.
Expand Down

0 comments on commit 06eae21

Please sign in to comment.