Skip to content

Commit

Permalink
Merge pull request #3637 from innovationnorway/f/webapp-user-assigned-id
Browse files Browse the repository at this point in the history
azurerm_app_service & azurerm_app_service_slot: support for specifying user-assigned identities
  • Loading branch information
tombuildsstuff authored Jul 7, 2019
2 parents 388b824 + 2eded91 commit af4a52c
Show file tree
Hide file tree
Showing 7 changed files with 384 additions and 87 deletions.
91 changes: 91 additions & 0 deletions azurerm/helpers/azure/app_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,47 @@ func SchemaAppServiceAuthSettings() *schema.Schema {
}
}

func SchemaAppServiceIdentity() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
string(web.ManagedServiceIdentityTypeNone),
string(web.ManagedServiceIdentityTypeSystemAssigned),
string(web.ManagedServiceIdentityTypeSystemAssignedUserAssigned),
string(web.ManagedServiceIdentityTypeUserAssigned),
}, true),
DiffSuppressFunc: suppress.CaseDifference,
},
"principal_id": {
Type: schema.TypeString,
Computed: true,
},
"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
"identity_ids": {
Type: schema.TypeList,
Optional: true,
MinItems: 1,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.NoZeroValues,
},
},
},
},
}
}

func SchemaAppServiceSiteConfig() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Expand Down Expand Up @@ -1193,6 +1234,56 @@ func ExpandAppServiceLogs(input interface{}) web.SiteLogsConfigProperties {
return logs
}

func ExpandAppServiceIdentity(d *schema.ResourceData) *web.ManagedServiceIdentity {
identities := d.Get("identity").([]interface{})
if len(identities) == 0 {
return nil
}
identity := identities[0].(map[string]interface{})
identityType := web.ManagedServiceIdentityType(identity["type"].(string))

identityIds := make(map[string]*web.ManagedServiceIdentityUserAssignedIdentitiesValue)
for _, id := range identity["identity_ids"].([]interface{}) {
identityIds[id.(string)] = &web.ManagedServiceIdentityUserAssignedIdentitiesValue{}
}

managedServiceIdentity := web.ManagedServiceIdentity{
Type: identityType,
}

if managedServiceIdentity.Type == web.ManagedServiceIdentityTypeUserAssigned || managedServiceIdentity.Type == web.ManagedServiceIdentityTypeSystemAssignedUserAssigned {
managedServiceIdentity.UserAssignedIdentities = identityIds
}

return &managedServiceIdentity
}

func FlattenAppServiceIdentity(identity *web.ManagedServiceIdentity) []interface{} {
if identity == nil {
return make([]interface{}, 0)
}

result := make(map[string]interface{})
result["type"] = string(identity.Type)

if identity.PrincipalID != nil {
result["principal_id"] = *identity.PrincipalID
}
if identity.TenantID != nil {
result["tenant_id"] = *identity.TenantID
}

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

return []interface{}{result}
}

func ExpandAppServiceSiteConfig(input interface{}) web.SiteConfig {
configs := input.([]interface{})
siteConfig := web.SiteConfig{}
Expand Down
60 changes: 4 additions & 56 deletions azurerm/resource_arm_app_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,7 @@ func resourceArmAppService() *schema.Resource {
ValidateFunc: validateAppServiceName,
},

"identity": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
ValidateFunc: validation.StringInSlice([]string{
"SystemAssigned",
}, true),
},
"principal_id": {
Type: schema.TypeString,
Computed: true,
},
"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"identity": azure.SchemaAppServiceIdentity(),

"resource_group_name": azure.SchemaResourceGroupName(),

Expand Down Expand Up @@ -251,7 +226,7 @@ func resourceArmAppServiceCreate(d *schema.ResourceData, meta interface{}) error
}

if _, ok := d.GetOk("identity"); ok {
appServiceIdentity := expandAzureRmAppServiceIdentity(d)
appServiceIdentity := azure.ExpandAppServiceIdentity(d)
siteEnvelope.Identity = appServiceIdentity
}

Expand Down Expand Up @@ -449,7 +424,7 @@ func resourceArmAppServiceUpdate(d *schema.ResourceData, meta interface{}) error
return fmt.Errorf("Error getting configuration for App Service %q: %+v", name, err)
}

appServiceIdentity := expandAzureRmAppServiceIdentity(d)
appServiceIdentity := azure.ExpandAppServiceIdentity(d)
site.Identity = appServiceIdentity

future, err := client.CreateOrUpdate(ctx, resGroup, name, site)
Expand Down Expand Up @@ -606,7 +581,7 @@ func resourceArmAppServiceRead(d *schema.ResourceData, meta interface{}) error {
return err
}

identity := flattenAzureRmAppServiceMachineIdentity(resp.Identity)
identity := azure.FlattenAppServiceIdentity(resp.Identity)
if err := d.Set("identity", identity); err != nil {
return err
}
Expand Down Expand Up @@ -718,33 +693,6 @@ func flattenAppServiceAppSettings(input map[string]*string) map[string]string {
return output
}

func expandAzureRmAppServiceIdentity(d *schema.ResourceData) *web.ManagedServiceIdentity {
identities := d.Get("identity").([]interface{})
identity := identities[0].(map[string]interface{})
identityType := identity["type"].(string)
return &web.ManagedServiceIdentity{
Type: web.ManagedServiceIdentityType(identityType),
}
}

func flattenAzureRmAppServiceMachineIdentity(identity *web.ManagedServiceIdentity) []interface{} {
if identity == nil {
return make([]interface{}, 0)
}

result := make(map[string]interface{})
result["type"] = string(identity.Type)

if identity.PrincipalID != nil {
result["principal_id"] = *identity.PrincipalID
}
if identity.TenantID != nil {
result["tenant_id"] = *identity.TenantID
}

return []interface{}{result}
}

func validateAppServiceName(v interface{}, k string) (warnings []string, errors []error) {
value := v.(string)

Expand Down
42 changes: 15 additions & 27 deletions azurerm/resource_arm_app_service_slot.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,7 @@ func resourceArmAppServiceSlot() *schema.Resource {

"location": azure.SchemaLocation(),

"identity": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
ValidateFunc: validation.StringInSlice([]string{
"SystemAssigned",
}, true),
},
"principal_id": {
Type: schema.TypeString,
Computed: true,
},
"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"identity": azure.SchemaAppServiceIdentity(),

"app_service_name": {
Type: schema.TypeString,
Expand Down Expand Up @@ -206,7 +182,7 @@ func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interfac
}

if _, ok := d.GetOk("identity"); ok {
appServiceIdentity := expandAzureRmAppServiceIdentity(d)
appServiceIdentity := azure.ExpandAppServiceIdentity(d)
siteEnvelope.Identity = appServiceIdentity
}

Expand Down Expand Up @@ -266,6 +242,18 @@ func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interfac
}
}

if d.HasChange("identity") {
identity := azure.ExpandAppServiceIdentity(d)
sitePatchResource := web.SitePatchResource{
ID: utils.String(d.Id()),
Identity: identity,
}
_, err := client.UpdateSlot(ctx, resGroup, appServiceName, sitePatchResource, slot)
if err != nil {
return fmt.Errorf("Error updating Managed Service Identity for App Service Slot %q/%q: %+v", appServiceName, slot, err)
}
}

return resourceArmAppServiceSlotRead(d, meta)
}

Expand Down Expand Up @@ -362,7 +350,7 @@ func resourceArmAppServiceSlotRead(d *schema.ResourceData, meta interface{}) err
return err
}

identity := flattenAzureRmAppServiceMachineIdentity(resp.Identity)
identity := azure.FlattenAppServiceIdentity(resp.Identity)
if err := d.Set("identity", identity); err != nil {
return err
}
Expand Down
Loading

0 comments on commit af4a52c

Please sign in to comment.