Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

api_managment - support user assigned managed identities #6783

Merged
merged 14 commits into from May 13, 2020
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -52,6 +52,34 @@ func dataSourceApiManagementService() *schema.Resource {
Computed: true,
},

"identity": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Computed: true,
},
"principal_id": {
Type: schema.TypeString,
Computed: true,
},
"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
"identity_ids": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},

"notification_sender_email": {
Type: schema.TypeString,
Computed: true,
Expand Down
69 changes: 60 additions & 9 deletions azurerm/internal/services/apimanagement/api_management_resource.go
Expand Up @@ -87,9 +87,13 @@ func resourceArmApiManagementService() *schema.Resource {
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
Optional: true,
Default: string(apimanagement.None),
ValidateFunc: validation.StringInSlice([]string{
"SystemAssigned",
string(apimanagement.None),
string(apimanagement.SystemAssigned),
sirlatrom marked this conversation as resolved.
Show resolved Hide resolved
string(apimanagement.UserAssigned),
string(apimanagement.SystemAssignedUserAssigned),
}, false),
},
"principal_id": {
Expand All @@ -100,6 +104,15 @@ func resourceArmApiManagementService() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
"identity_ids": {
Type: schema.TypeSet,
Optional: true,
MinItems: 1,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.NoZeroValues,
},
},
},
},
},
Expand Down Expand Up @@ -470,7 +483,11 @@ func resourceArmApiManagementServiceCreateUpdate(d *schema.ResourceData, meta in
}

if _, ok := d.GetOk("identity"); ok {
properties.Identity = expandAzureRmApiManagementIdentity(d)
identity, err := expandAzureRmApiManagementIdentity(d)
if err != nil {
return fmt.Errorf("Error expanding `identity`: %+v", err)
}
properties.Identity = identity
}

if _, ok := d.GetOk("additional_location"); ok {
Expand Down Expand Up @@ -899,17 +916,43 @@ func flattenApiManagementAdditionalLocations(input *[]apimanagement.AdditionalLo
return results
}

func expandAzureRmApiManagementIdentity(d *schema.ResourceData) *apimanagement.ServiceIdentity {
func expandAzureRmApiManagementIdentity(d *schema.ResourceData) (*apimanagement.ServiceIdentity, error) {
var identityIdSet *schema.Set
managedServiceIdentity := apimanagement.ServiceIdentity{}

vs := d.Get("identity").([]interface{})
if len(vs) == 0 {
return nil
managedServiceIdentity.Type = apimanagement.None
} else {
v := vs[0].(map[string]interface{})
identityType, exists := v["type"]
if !exists {
return nil, fmt.Errorf("`type` must be specified when `identity` is set")
}
managedServiceIdentity.Type = apimanagement.ApimIdentityType(identityType.(string))
if identityIds, exists := v["identity_ids"]; exists {
identityIdSet = (identityIds.(*schema.Set))
}
}

v := vs[0].(map[string]interface{})
identityType := v["type"].(string)
return &apimanagement.ServiceIdentity{
Type: apimanagement.ApimIdentityType(identityType),
// If type contains `UserAssigned`, `identity_ids` must be specified and have at least 1 element
if managedServiceIdentity.Type == apimanagement.UserAssigned || managedServiceIdentity.Type == apimanagement.SystemAssignedUserAssigned {
if identityIdSet == nil || identityIdSet.Len() == 0 {
return nil, fmt.Errorf("`identity_ids` must have at least 1 element when `type` includes `UserAssigned`")
}

userAssignedIdentities := make(map[string]*apimanagement.UserIdentityProperties)
for _, id := range identityIdSet.List() {
userAssignedIdentities[id.(string)] = &apimanagement.UserIdentityProperties{}
}

managedServiceIdentity.UserAssignedIdentities = userAssignedIdentities
} else if identityIdSet != nil && identityIdSet.Len() > 0 {
// If type does _not_ contain `UserAssigned` (i.e. is set to `SystemAssigned` or defaulted to `None`), `identity_ids` is not allowed
return nil, fmt.Errorf("`identity_ids` can only be specified when `type` includes `UserAssigned`; but `type` is currently %q", managedServiceIdentity.Type)
}

return &managedServiceIdentity, nil
}

func flattenAzureRmApiManagementMachineIdentity(identity *apimanagement.ServiceIdentity) []interface{} {
Expand All @@ -929,6 +972,14 @@ func flattenAzureRmApiManagementMachineIdentity(identity *apimanagement.ServiceI
result["tenant_id"] = identity.TenantID.String()
}

identityIds := make([]interface{}, 0)
if identity.UserAssignedIdentities != nil {
for key := range identity.UserAssignedIdentities {
identityIds = append(identityIds, key)
}
result["identity_ids"] = schema.NewSet(schema.HashString, identityIds)
}

return []interface{}{result}
}

Expand Down