Skip to content

Commit

Permalink
Merge pull request #3897 from terraform-providers/f/app-service-slot-…
Browse files Browse the repository at this point in the history
…auth

r/app_service_slot: support for auth settings
  • Loading branch information
tombuildsstuff authored Jul 22, 2019
2 parents d037126 + a8d6a6e commit dfbe34f
Show file tree
Hide file tree
Showing 3 changed files with 1,555 additions and 336 deletions.
170 changes: 123 additions & 47 deletions azurerm/resource_arm_app_service_slot.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import (

func resourceArmAppServiceSlot() *schema.Resource {
return &schema.Resource{
Create: resourceArmAppServiceSlotCreateUpdate,
Create: resourceArmAppServiceSlotCreate,
Read: resourceArmAppServiceSlotRead,
Update: resourceArmAppServiceSlotCreateUpdate,
Update: resourceArmAppServiceSlotCreate,
Delete: resourceArmAppServiceSlotDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
Expand Down Expand Up @@ -50,6 +50,8 @@ func resourceArmAppServiceSlot() *schema.Resource {

"site_config": azure.SchemaAppServiceSiteConfig(),

"auth_settings": azure.SchemaAppServiceAuthSettings(),

"client_affinity_enabled": {
Type: schema.TypeBool,
Optional: true,
Expand Down Expand Up @@ -140,19 +142,19 @@ func resourceArmAppServiceSlot() *schema.Resource {
}
}

func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interface{}) error {
func resourceArmAppServiceSlotCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).appServicesClient
ctx := meta.(*ArmClient).StopContext

slot := d.Get("name").(string)
resGroup := d.Get("resource_group_name").(string)
resourceGroup := d.Get("resource_group_name").(string)
appServiceName := d.Get("app_service_name").(string)

if requireResourcesToBeImported && d.IsNewResource() {
existing, err := client.GetSlot(ctx, resGroup, appServiceName, slot)
existing, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("Error checking for presence of existing Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resGroup, err)
return fmt.Errorf("Error checking for presence of existing Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}
}

Expand Down Expand Up @@ -186,46 +188,107 @@ func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interfac
siteEnvelope.Identity = appServiceIdentity
}

createFuture, err := client.CreateOrUpdateSlot(ctx, resGroup, appServiceName, siteEnvelope, slot)
createFuture, err := client.CreateOrUpdateSlot(ctx, resourceGroup, appServiceName, siteEnvelope, slot)
if err != nil {
return err
return fmt.Errorf("Error creating Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

err = createFuture.WaitForCompletionRef(ctx, client.Client)
if err != nil {
return err
return fmt.Errorf("Error waiting for creation of Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

read, err := client.GetSlot(ctx, resGroup, appServiceName, slot)
read, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot)
if err != nil {
return err
return fmt.Errorf("Error retrieving Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

if read.ID == nil {
return fmt.Errorf("Cannot read App Service Slot %q/%q (resource group %q) ID", appServiceName, slot, resGroup)
return fmt.Errorf("Cannot read ID for Slot %q (App Service %q / Resource Group %q) ID", slot, appServiceName, resourceGroup)
}

d.SetId(*read.ID)

return resourceArmAppServiceSlotUpdate(d, meta)
}

func resourceArmAppServiceSlotUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).appServicesClient
ctx := meta.(*ArmClient).StopContext

id, err := parseAzureResourceID(d.Id())
if err != nil {
return err
}

resourceGroup := id.ResourceGroup
appServiceName := id.Path["sites"]
slot := id.Path["slots"]

location := azure.NormalizeLocation(d.Get("location").(string))
appServicePlanId := d.Get("app_service_plan_id").(string)
siteConfig := azure.ExpandAppServiceSiteConfig(d.Get("site_config"))
enabled := d.Get("enabled").(bool)
httpsOnly := d.Get("https_only").(bool)
tags := d.Get("tags").(map[string]interface{})

siteEnvelope := web.Site{
Location: &location,
Tags: expandTags(tags),
SiteProperties: &web.SiteProperties{
ServerFarmID: utils.String(appServicePlanId),
Enabled: utils.Bool(enabled),
HTTPSOnly: utils.Bool(httpsOnly),
SiteConfig: &siteConfig,
},
}
if v, ok := d.GetOk("client_affinity_enabled"); ok {
enabled := v.(bool)
siteEnvelope.SiteProperties.ClientAffinityEnabled = utils.Bool(enabled)
}
createFuture, err := client.CreateOrUpdateSlot(ctx, resourceGroup, appServiceName, siteEnvelope, slot)
if err != nil {
return fmt.Errorf("Error updating Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

err = createFuture.WaitForCompletionRef(ctx, client.Client)
if err != nil {
return fmt.Errorf("Error waiting for update of Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

if d.HasChange("site_config") {
// update the main configuration
siteConfig := azure.ExpandAppServiceSiteConfig(d.Get("site_config"))
siteConfigResource := web.SiteConfigResource{
SiteConfig: &siteConfig,
}
if _, err := client.CreateOrUpdateConfigurationSlot(ctx, resGroup, appServiceName, siteConfigResource, slot); err != nil {
if _, err := client.CreateOrUpdateConfigurationSlot(ctx, resourceGroup, appServiceName, siteConfigResource, slot); err != nil {
return fmt.Errorf("Error updating Configuration for App Service Slot %q/%q: %+v", appServiceName, slot, err)
}
}

if d.HasChange("auth_settings") {
authSettingsRaw := d.Get("auth_settings").([]interface{})
authSettingsProperties := azure.ExpandAppServiceAuthSettings(authSettingsRaw)
id := d.Id()
authSettings := web.SiteAuthSettings{
ID: &id,
SiteAuthSettingsProperties: &authSettingsProperties,
}

if _, err := client.UpdateAuthSettingsSlot(ctx, resourceGroup, appServiceName, authSettings, slot); err != nil {
return fmt.Errorf("Error updating Authentication Settings for App Service %q: %+v", appServiceName, err)
}
}

if d.HasChange("app_settings") {
// update the AppSettings
appSettings := expandAppServiceAppSettings(d)
settings := web.StringDictionary{
Properties: appSettings,
}

if _, err := client.UpdateApplicationSettingsSlot(ctx, resGroup, appServiceName, settings, slot); err != nil {
if _, err := client.UpdateApplicationSettingsSlot(ctx, resourceGroup, appServiceName, settings, slot); err != nil {
return fmt.Errorf("Error updating Application Settings for App Service Slot %q/%q: %+v", appServiceName, slot, err)
}
}
Expand All @@ -237,7 +300,7 @@ func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interfac
Properties: connectionStrings,
}

if _, err := client.UpdateConnectionStringsSlot(ctx, resGroup, appServiceName, properties, slot); err != nil {
if _, err := client.UpdateConnectionStringsSlot(ctx, resourceGroup, appServiceName, properties, slot); err != nil {
return fmt.Errorf("Error updating Connection Strings for App Service Slot %q/%q: %+v", appServiceName, slot, err)
}
}
Expand All @@ -248,7 +311,7 @@ func resourceArmAppServiceSlotCreateUpdate(d *schema.ResourceData, meta interfac
ID: utils.String(d.Id()),
Identity: identity,
}
_, err := client.UpdateSlot(ctx, resGroup, appServiceName, sitePatchResource, slot)
_, err := client.UpdateSlot(ctx, resourceGroup, appServiceName, sitePatchResource, slot)
if err != nil {
return fmt.Errorf("Error updating Managed Service Identity for App Service Slot %q/%q: %+v", appServiceName, slot, err)
}
Expand All @@ -265,94 +328,107 @@ func resourceArmAppServiceSlotRead(d *schema.ResourceData, meta interface{}) err
return err
}

resGroup := id.ResourceGroup
resourceGroup := id.ResourceGroup
appServiceName := id.Path["sites"]
slot := id.Path["slots"]

ctx := meta.(*ArmClient).StopContext
resp, err := client.GetSlot(ctx, resGroup, appServiceName, slot)
resp, err := client.GetSlot(ctx, resourceGroup, appServiceName, slot)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[DEBUG] App Service Slot %q/%q (resource group %q) was not found - removing from state", appServiceName, slot, resGroup)
log.Printf("[DEBUG] Slot %q (App Service %q / Resource Group %q) were not found - removing from state!", slot, appServiceName, resourceGroup)
d.SetId("")
return nil
}
return fmt.Errorf("Error making Read request on AzureRM App Service Slot %q/%q: %+v", appServiceName, slot, err)

return fmt.Errorf("Error reading Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

configResp, err := client.GetConfigurationSlot(ctx, resGroup, appServiceName, slot)
configResp, err := client.GetConfigurationSlot(ctx, resourceGroup, appServiceName, slot)
if err != nil {
if utils.ResponseWasNotFound(configResp.Response) {
log.Printf("[DEBUG] Configuration of App Service Slot %q/%q (resource group %q) was not found", appServiceName, slot, resGroup)
log.Printf("[DEBUG] Configuration for Slot %q (App Service %q / Resource Group %q) were not found - removing from state!", slot, appServiceName, resourceGroup)
d.SetId("")
return nil
}
return fmt.Errorf("Error making Read request on AzureRM App Service Slot Configuration %q/%q: %+v", appServiceName, slot, err)

return fmt.Errorf("Error reading Configuration for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

authResp, err := client.GetAuthSettingsSlot(ctx, resourceGroup, appServiceName, slot)
if err != nil {
return fmt.Errorf("Error reading Auth Settings for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

appSettingsResp, err := client.ListApplicationSettingsSlot(ctx, resGroup, appServiceName, slot)
appSettingsResp, err := client.ListApplicationSettingsSlot(ctx, resourceGroup, appServiceName, slot)
if err != nil {
if utils.ResponseWasNotFound(appSettingsResp.Response) {
log.Printf("[DEBUG] Application Settings of App Service Slot %q/%q (resource group %q) were not found", appServiceName, slot, resGroup)
log.Printf("[DEBUG] App Settings for Slot %q (App Service %q / Resource Group %q) were not found - removing from state!", slot, appServiceName, resourceGroup)
d.SetId("")
return nil
}
return fmt.Errorf("Error making Read request on AzureRM App Service Slot AppSettings %q/%q: %+v", appServiceName, slot, err)

return fmt.Errorf("Error reading App Settings for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

connectionStringsResp, err := client.ListConnectionStringsSlot(ctx, resGroup, appServiceName, slot)
connectionStringsResp, err := client.ListConnectionStringsSlot(ctx, resourceGroup, appServiceName, slot)
if err != nil {
return fmt.Errorf("Error making Read request on AzureRM App Service Slot ConnectionStrings %q/%q: %+v", appServiceName, slot, err)
return fmt.Errorf("Error listing Connection Strings for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

siteCredFuture, err := client.ListPublishingCredentialsSlot(ctx, resGroup, appServiceName, slot)
siteCredFuture, err := client.ListPublishingCredentialsSlot(ctx, resourceGroup, appServiceName, slot)
if err != nil {
return err
return fmt.Errorf("Error retrieving publishing credentials for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}
err = siteCredFuture.WaitForCompletionRef(ctx, client.Client)
if err != nil {
return err
return fmt.Errorf("Error waiting for publishing credentials for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}
siteCredResp, err := siteCredFuture.Result(client)
if err != nil {
return fmt.Errorf("Error making Read request on AzureRM App Service Slot Site Credential %q/%q: %+v", appServiceName, slot, err)
return fmt.Errorf("Error reading publishing credentials for Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}

d.Set("name", slot)
d.Set("app_service_name", appServiceName)
d.Set("resource_group_name", resGroup)
d.Set("resource_group_name", resourceGroup)
if location := resp.Location; location != nil {
d.Set("location", azure.NormalizeLocation(*location))
}

if props := resp.SiteProperties; props != nil {
d.Set("app_service_plan_id", props.ServerFarmID)
d.Set("client_affinity_enabled", props.ClientAffinityEnabled)
d.Set("default_site_hostname", props.DefaultHostName)
d.Set("enabled", props.Enabled)
d.Set("https_only", props.HTTPSOnly)
d.Set("default_site_hostname", props.DefaultHostName)
}

if err := d.Set("app_settings", flattenAppServiceAppSettings(appSettingsResp.Properties)); err != nil {
return err
return fmt.Errorf("Error setting `app_settings`: %s", err)
}
if err := d.Set("connection_string", flattenAppServiceConnectionStrings(connectionStringsResp.Properties)); err != nil {
return err
return fmt.Errorf("Error setting `connection_string`: %s", err)
}

siteConfig := azure.FlattenAppServiceSiteConfig(configResp.SiteConfig)
if err := d.Set("site_config", siteConfig); err != nil {
return err
authSettings := azure.FlattenAppServiceAuthSettings(authResp.SiteAuthSettingsProperties)
if err := d.Set("auth_settings", authSettings); err != nil {
return fmt.Errorf("Error setting `auth_settings`: %s", err)
}

identity := azure.FlattenAppServiceIdentity(resp.Identity)
if err := d.Set("identity", identity); err != nil {
return fmt.Errorf("Error setting `identity`: %s", err)
}

siteCred := flattenAppServiceSiteCredential(siteCredResp.UserProperties)
if err := d.Set("site_credential", siteCred); err != nil {
return err
return fmt.Errorf("Error setting `site_credential`: %s", err)
}

identity := azure.FlattenAppServiceIdentity(resp.Identity)
if err := d.Set("identity", identity); err != nil {
return err
siteConfig := azure.FlattenAppServiceSiteConfig(configResp.SiteConfig)
if err := d.Set("site_config", siteConfig); err != nil {
return fmt.Errorf("Error setting `site_config`: %s", err)
}

flattenAndSetTags(d, resp.Tags)
Expand All @@ -367,19 +443,19 @@ func resourceArmAppServiceSlotDelete(d *schema.ResourceData, meta interface{}) e
if err != nil {
return err
}
resGroup := id.ResourceGroup
resourceGroup := id.ResourceGroup
appServiceName := id.Path["sites"]
slot := id.Path["slots"]

log.Printf("[DEBUG] Deleting App Service Slot %q/%q (resource group %q)", appServiceName, slot, resGroup)
log.Printf("[DEBUG] Deleting Slot %q (App Service %q / Resource Group %q)", slot, appServiceName, resourceGroup)

deleteMetrics := true
deleteEmptyServerFarm := false
ctx := meta.(*ArmClient).StopContext
resp, err := client.DeleteSlot(ctx, resGroup, appServiceName, slot, &deleteMetrics, &deleteEmptyServerFarm)
resp, err := client.DeleteSlot(ctx, resourceGroup, appServiceName, slot, &deleteMetrics, &deleteEmptyServerFarm)
if err != nil {
if !utils.ResponseWasNotFound(resp) {
return err
return fmt.Errorf("Error deleting Slot %q (App Service %q / Resource Group %q): %s", slot, appServiceName, resourceGroup, err)
}
}

Expand Down
Loading

0 comments on commit dfbe34f

Please sign in to comment.