From d378e30b1d2435cf3faf4eaed78d98e31431f8fa Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Tue, 4 Apr 2017 20:14:58 +0000 Subject: [PATCH 1/3] Fix crash for outputs of type Object (#7353), and support bool and int outputs Included in this fix: 1) No crash 2) Debug log indicates problem, otherwise unsupported outputs are ignored 3) String, bool and int outputs are supported 4) Documentation indicates these limitations What is not included: 5) Array, object, securestring, secureobject still not supported --- .../resource_arm_template_deployment.go | 32 +++- .../resource_arm_template_deployment_test.go | 143 ++++++++++++++++++ .../r/template_deployment.html.markdown | 1 + 3 files changed, 172 insertions(+), 4 deletions(-) diff --git a/builtin/providers/azurerm/resource_arm_template_deployment.go b/builtin/providers/azurerm/resource_arm_template_deployment.go index 9349c9b6ab..b833eb0236 100644 --- a/builtin/providers/azurerm/resource_arm_template_deployment.go +++ b/builtin/providers/azurerm/resource_arm_template_deployment.go @@ -155,20 +155,44 @@ func resourceArmTemplateDeploymentRead(d *schema.ResourceData, meta interface{}) if resp.Properties.Outputs != nil && len(*resp.Properties.Outputs) > 0 { outputs = make(map[string]string) for key, output := range *resp.Properties.Outputs { + log.Printf("[DEBUG] Processing deployment output %s", key) outputMap := output.(map[string]interface{}) outputValue, ok := outputMap["value"] if !ok { // No value continue } + outputType := outputMap["type"] + var outputStringValue string - outputs[key] = outputValue.(string) + switch outputType { + case "Bool": + if outputValue == false { + outputStringValue = "0" + } else if outputValue == true { + outputStringValue = "1" + } else { + return fmt.Errorf("Invalid value %s for boolean output %s", outputValue, key) + } + + case "String": // Nothing to do + fallthrough + case "Int": + outputStringValue = fmt.Sprint(outputValue) + + case "SecureString", "Object", "SecureObject", "Array": + fallthrough + default: + log.Printf("[WARNING] Ignoring output %s: Outputs of type %s are not currently supported in azurerm_deployment_template.", + key, outputType) + continue + } + + outputs[key] = outputStringValue } } - d.Set("outputs", outputs) - - return nil + return d.Set("outputs", outputs) } func resourceArmTemplateDeploymentDelete(d *schema.ResourceData, meta interface{}) error { diff --git a/builtin/providers/azurerm/resource_arm_template_deployment_test.go b/builtin/providers/azurerm/resource_arm_template_deployment_test.go index d69716d8bf..459431779d 100644 --- a/builtin/providers/azurerm/resource_arm_template_deployment_test.go +++ b/builtin/providers/azurerm/resource_arm_template_deployment_test.go @@ -68,6 +68,29 @@ func TestAccAzureRMTemplateDeployment_withParams(t *testing.T) { }) } +func TestAccAzureRMTemplateDeployment_withOutputs(t *testing.T) { + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMTemplateDeployment_withOutputs, ri, ri, ri) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMTemplateDeploymentDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMTemplateDeploymentExists("azurerm_template_deployment.test"), + resource.TestCheckOutput("tfIntOutput", "-123"), + resource.TestCheckOutput("tfStringOutput", "Standard_GRS"), + resource.TestCheckOutput("tfFalseOutput", "0"), + resource.TestCheckOutput("tfTrueOutput", "1"), + resource.TestCheckResourceAttr("azurerm_template_deployment.test", "outputs.stringOutput", "Standard_GRS"), + ), + }, + }, + }) +} + func TestAccAzureRMTemplateDeployment_withError(t *testing.T) { ri := acctest.RandInt() config := fmt.Sprintf(testAccAzureRMTemplateDeployment_withError, ri, ri) @@ -352,6 +375,126 @@ DEPLOY ` +var testAccAzureRMTemplateDeployment_withOutputs = ` + resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US" + } + + output "tfStringOutput" { + value = "${azurerm_template_deployment.test.outputs.stringOutput}" + } + + output "tfIntOutput" { + value = "${azurerm_template_deployment.test.outputs.intOutput}" + } + + output "tfFalseOutput" { + value = "${azurerm_template_deployment.test.outputs.falseOutput}" + } + + output "tfTrueOutput" { + value = "${azurerm_template_deployment.test.outputs.trueOutput}" + } + + resource "azurerm_template_deployment" "test" { + name = "acctesttemplate-%d" + resource_group_name = "${azurerm_resource_group.test.name}" + template_body = < Date: Thu, 20 Apr 2017 23:27:36 +0000 Subject: [PATCH 2/3] PR fixes --- .../resource_arm_template_deployment.go | 39 ++++++++++--------- .../r/template_deployment.html.markdown | 2 +- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/builtin/providers/azurerm/resource_arm_template_deployment.go b/builtin/providers/azurerm/resource_arm_template_deployment.go index b833eb0236..2a060b3ba9 100644 --- a/builtin/providers/azurerm/resource_arm_template_deployment.go +++ b/builtin/providers/azurerm/resource_arm_template_deployment.go @@ -159,36 +159,37 @@ func resourceArmTemplateDeploymentRead(d *schema.ResourceData, meta interface{}) outputMap := output.(map[string]interface{}) outputValue, ok := outputMap["value"] if !ok { - // No value + log.Printf("[DEBUG] No value - skipping") + continue + } + outputType, ok := outputMap["type"] + if !ok { + log.Printf("[DEBUG] No type - skipping") continue } - outputType := outputMap["type"] - var outputStringValue string - switch outputType { - case "Bool": - if outputValue == false { - outputStringValue = "0" - } else if outputValue == true { - outputStringValue = "1" + var outputValueString string + switch strings.ToLower(outputType.(string)) { + case "bool": + // Use explicit "0"/"1" strings for boolean + if outputValue.(bool) { + outputValueString = "1" } else { - return fmt.Errorf("Invalid value %s for boolean output %s", outputValue, key) + outputValueString = "0" } - case "String": // Nothing to do - fallthrough - case "Int": - outputStringValue = fmt.Sprint(outputValue) + case "string": + outputValueString = outputValue.(string) + + case "int": + outputValueString = fmt.Sprint(outputValue) - case "SecureString", "Object", "SecureObject", "Array": - fallthrough default: - log.Printf("[WARNING] Ignoring output %s: Outputs of type %s are not currently supported in azurerm_deployment_template.", + log.Printf("[WARN] Ignoring output %s: Outputs of type %s are not currently supported in azurerm_template_deployment.", key, outputType) continue } - - outputs[key] = outputStringValue + outputs[key] = outputValueString } } diff --git a/website/source/docs/providers/azurerm/r/template_deployment.html.markdown b/website/source/docs/providers/azurerm/r/template_deployment.html.markdown index b266b1459a..825e16d86d 100644 --- a/website/source/docs/providers/azurerm/r/template_deployment.html.markdown +++ b/website/source/docs/providers/azurerm/r/template_deployment.html.markdown @@ -98,7 +98,7 @@ The following arguments are supported: The following attributes are exported: * `id` - The Template Deployment ID. -* `outputs` - A map of supported scalar output types returned from the deployment (currently, Azure template outputs of type String, Int and Bool are supported, and are converted to strings - others will be ignored). +* `outputs` - A map of supported scalar output types returned from the deployment (currently, Azure Template Deployment outputs of type String, Int and Bool are supported, and are converted to strings - others will be ignored). ## Note From 202ed9c6801b1759a031cdbd5224a17d59680726 Mon Sep 17 00:00:00 2001 From: Stephen Weatherford Date: Tue, 2 May 2017 19:13:25 +0000 Subject: [PATCH 3/3] Use false/true instead of 0/1 for bool --- .../providers/azurerm/resource_arm_template_deployment.go | 8 ++------ .../azurerm/resource_arm_template_deployment_test.go | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/builtin/providers/azurerm/resource_arm_template_deployment.go b/builtin/providers/azurerm/resource_arm_template_deployment.go index 2a060b3ba9..9538f61ee4 100644 --- a/builtin/providers/azurerm/resource_arm_template_deployment.go +++ b/builtin/providers/azurerm/resource_arm_template_deployment.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net/http" + "strconv" "strings" "time" @@ -171,12 +172,7 @@ func resourceArmTemplateDeploymentRead(d *schema.ResourceData, meta interface{}) var outputValueString string switch strings.ToLower(outputType.(string)) { case "bool": - // Use explicit "0"/"1" strings for boolean - if outputValue.(bool) { - outputValueString = "1" - } else { - outputValueString = "0" - } + outputValueString = strconv.FormatBool(outputValue.(bool)) case "string": outputValueString = outputValue.(string) diff --git a/builtin/providers/azurerm/resource_arm_template_deployment_test.go b/builtin/providers/azurerm/resource_arm_template_deployment_test.go index 459431779d..40f0bea405 100644 --- a/builtin/providers/azurerm/resource_arm_template_deployment_test.go +++ b/builtin/providers/azurerm/resource_arm_template_deployment_test.go @@ -82,8 +82,8 @@ func TestAccAzureRMTemplateDeployment_withOutputs(t *testing.T) { testCheckAzureRMTemplateDeploymentExists("azurerm_template_deployment.test"), resource.TestCheckOutput("tfIntOutput", "-123"), resource.TestCheckOutput("tfStringOutput", "Standard_GRS"), - resource.TestCheckOutput("tfFalseOutput", "0"), - resource.TestCheckOutput("tfTrueOutput", "1"), + resource.TestCheckOutput("tfFalseOutput", "false"), + resource.TestCheckOutput("tfTrueOutput", "true"), resource.TestCheckResourceAttr("azurerm_template_deployment.test", "outputs.stringOutput", "Standard_GRS"), ), },