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

Feature: azurerm_app_service - filesystem logging can now be set. #4025

Merged
merged 4 commits into from
Aug 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 88 additions & 8 deletions azurerm/helpers/azure/app_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ func SchemaAppServiceLogsConfig() *schema.Schema {
"application_logs": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -520,6 +521,35 @@ func SchemaAppServiceLogsConfig() *schema.Schema {
},
},
},
"http_logs": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"file_system": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"retention_in_mb": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntBetween(25, 100),
},
"retention_in_days": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(0),
},
},
},
},
},
},
},
},
},
}
Expand Down Expand Up @@ -1094,14 +1124,13 @@ func FlattenAppServiceLogs(input *web.SiteLogsConfigProperties) []interface{} {

result := make(map[string]interface{})

appLogs := make([]interface{}, 0)
if input.ApplicationLogs != nil {
appLogs := make([]interface{}, 0)

appLogsItem := make(map[string]interface{})

blobStorage := make([]interface{}, 0)
if blobStorageInput := input.ApplicationLogs.AzureBlobStorage; blobStorageInput != nil {
blobStorage := make([]interface{}, 0)

blobStorageItem := make(map[string]interface{})

blobStorageItem["level"] = string(blobStorageInput.Level)
Expand All @@ -1114,15 +1143,42 @@ func FlattenAppServiceLogs(input *web.SiteLogsConfigProperties) []interface{} {
blobStorageItem["retention_in_days"] = *blobStorageInput.RetentionInDays
}

blobStorage = append(blobStorage, blobStorageItem)

appLogsItem["azure_blob_storage"] = blobStorage
// The API returns a non nil application logs object when other logs are specified so we'll check that this structure is empty before adding it to the statefile.
if blobStorageInput.SasURL != nil && *blobStorageInput.SasURL != "" {
blobStorage = append(blobStorage, blobStorageItem)
}
}

appLogsItem["azure_blob_storage"] = blobStorage
appLogs = append(appLogs, appLogsItem)
}
result["application_logs"] = appLogs

httpLogs := make([]interface{}, 0)
if input.HTTPLogs != nil {
httpLogsItem := make(map[string]interface{})

fileSystem := make([]interface{}, 0)
if fileSystemInput := input.HTTPLogs.FileSystem; fileSystemInput != nil {

fileSystemItem := make(map[string]interface{})

result["application_logs"] = appLogs
if fileSystemInput.RetentionInDays != nil {
fileSystemItem["retention_in_days"] = *fileSystemInput.RetentionInDays
}

if fileSystemInput.RetentionInMb != nil {
fileSystemItem["retention_in_mb"] = *fileSystemInput.RetentionInMb
}

// The API returns a non nil filesystem logs object when other logs are specified so we'll check that this is disabled before adding it to the statefile.
mbfrahry marked this conversation as resolved.
Show resolved Hide resolved
if fileSystemInput.Enabled != nil && *fileSystemInput.Enabled {
fileSystem = append(fileSystem, fileSystemItem)
}
}
httpLogsItem["file_system"] = fileSystem
httpLogs = append(httpLogs, httpLogsItem)
}
result["http_logs"] = httpLogs

return append(results, result)
}
Expand Down Expand Up @@ -1161,6 +1217,30 @@ func ExpandAppServiceLogs(input interface{}) web.SiteLogsConfigProperties {
}
}

if v, ok := config["http_logs"]; ok {
httpLogsConfigs := v.([]interface{})

for _, config := range httpLogsConfigs {
httpLogsConfig := config.(map[string]interface{})

logs.HTTPLogs = &web.HTTPLogsConfig{}

if v, ok := httpLogsConfig["file_system"]; ok {
fileSystemConfigs := v.([]interface{})

for _, config := range fileSystemConfigs {
fileSystemConfig := config.(map[string]interface{})

logs.HTTPLogs.FileSystem = &web.FileSystemHTTPLogsConfig{
RetentionInMb: utils.Int32(int32(fileSystemConfig["retention_in_mb"].(int))),
RetentionInDays: utils.Int32(int32(fileSystemConfig["retention_in_days"].(int))),
Enabled: utils.Bool(true),
}
}
}
}
}

return logs
}

Expand Down
129 changes: 129 additions & 0 deletions azurerm/resource_arm_app_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,69 @@ func TestAccAzureRMAppService_applicationBlobStorageLogs(t *testing.T) {
})
}

func TestAccAzureRMAppService_httpFileSystemLogs(t *testing.T) {
resourceName := "azurerm_app_service.test"
ri := tf.AccRandTimeInt()
config := testAccAzureRMAppService_httpFileSystemLogs(ri, testLocation())
config2 := testAccAzureRMAppService_basic(ri, testLocation())

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMAppServiceDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMAppServiceExists(resourceName),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: config2,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMAppServiceExists(resourceName),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMAppService_httpFileSystemAndStorageBlobLogs(t *testing.T) {
resourceName := "azurerm_app_service.test"
ri := tf.AccRandTimeInt()
rs := acctest.RandString(5)
config := testAccAzureRMAppService_httpFileSystemAndStorageBlobLogs(ri, rs, testLocation())

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMAppServiceDestroy,
Steps: []resource.TestStep{
{
Config: config,
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMAppServiceExists(resourceName),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMAppService_managedPipelineMode(t *testing.T) {
resourceName := "azurerm_app_service.test"
ri := tf.AccRandTimeInt()
Expand Down Expand Up @@ -3172,6 +3235,72 @@ resource "azurerm_app_service" "test" {
`, rInt, location, rInt, rInt)
}

func testAccAzureRMAppService_httpFileSystemLogs(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_app_service_plan" "test" {
name = "acctestASP-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"

sku {
tier = "Standard"
size = "S1"
}
}

resource "azurerm_app_service" "test" {
name = "acctestAS-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
app_service_plan_id = "${azurerm_app_service_plan.test.id}"

logs {
http_logs {
file_system {
retention_in_days = 4
retention_in_mb = 25
}
}
}
}
`, rInt, location, rInt, rInt)
}

func testAccAzureRMAppService_httpFileSystemAndStorageBlobLogs(rInt int, rString string, location string) string {
template := testAccAzureRMAppService_backupTemplate(rInt, rString, location)
return fmt.Sprintf(`
%s

resource "azurerm_app_service" "test" {
name = "acctestAS-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
app_service_plan_id = "${azurerm_app_service_plan.test.id}"

logs {
application_logs {
azure_blob_storage {
level = "Information"
sas_url = "https://${azurerm_storage_account.test.name}.blob.core.windows.net/${azurerm_storage_container.test.name}${data.azurerm_storage_account_sas.test.sas}&sr=b"
retention_in_days = 3
}
}
http_logs {
file_system {
retention_in_days = 4
retention_in_mb = 25
}
}
}
}
`, template, rInt)
}

func testAccAzureRMAppService_managedPipelineMode(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
Expand Down
10 changes: 10 additions & 0 deletions website/docs/r/app_service.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ A `logs` block supports the following:

* `application_logs` - (Optional) An `application_logs` block as defined below.

* `http_logs` - (Optional) An `http_logs` block as defined below.

---

An `application_logs` block supports the following:
Expand All @@ -153,6 +155,14 @@ An `azure_blob_storage` block supports the following:

---

An `http_logs` block supports the following:

* `retention_in_days` - (Required) The number of days to retain logs for.

* `retention_in_mb` - (Required) The maximum size in megabytes that http log files can use before being removed.

---

A `site_config` block supports the following:

* `always_on` - (Optional) Should the app be loaded at all times? Defaults to `false`.
Expand Down