Skip to content
Closed
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
108 changes: 108 additions & 0 deletions azurerm/data_source_function.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package azurerm

import (
"context"
"crypto/sha256"
"encoding/hex"
"fmt"
"log"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/web"

webmgmt "github.com/Azure/azure-sdk-for-go/services/web/mgmt/2018-02-01/web"
)

func dataSourceArmFunction() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmFunctionRead,

Schema: map[string]*schema.Schema{
"function_app_name": {
Type: schema.TypeString,
Required: true,
},

"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),

"function_name": {
Type: schema.TypeString,
Required: true,
},

"key": {
Type: schema.TypeString,
Computed: true,
Sensitive: true,
},
"trigger_url": {
Type: schema.TypeString,
Computed: true,
Sensitive: true, // Note the trigger url contains the key
},
},
}
}

func dataSourceArmFunctionRead(d *schema.ResourceData, meta interface{}) error {
webClient := meta.(*ArmClient).Web
ctx := meta.(*ArmClient).StopContext

name := d.Get("function_app_name").(string)
functionName := d.Get("function_name").(string)
resourceGroup := d.Get("resource_group_name").(string)

log.Printf("[DEBUG] Waiting for Function %q in Function app %q (Resource Group %q) to become available", functionName, name, resourceGroup)
stateConf := &resource.StateChangeConf{
Pending: []string{"pending"},
Target: []string{"available"},
Refresh: functionAvailabilityChecker(ctx, name, functionName, resourceGroup, webClient),
Timeout: 10 * time.Minute,
Delay: 30 * time.Second,
PollInterval: 10 * time.Second,
}

resp, err := stateConf.WaitForState()
if err != nil {
return fmt.Errorf("Error waiting for Function %q in Function app %q (Resource Group %q) to become available", functionName, name, resourceGroup)
}

functionSecret, cast := resp.(webmgmt.FunctionSecrets)
if !cast {
return fmt.Errorf("Error retrieving key for Function %q in Function app %q (Resource Group %q). functionSecret returned nil from API", functionName, name, resourceGroup)
}

if functionSecret.TriggerURL == nil {
return fmt.Errorf("Error retrieving key for Function %q in Function app %q (Resource Group %q). TriggerURL returned nil from API", functionName, name, resourceGroup)
}
if functionSecret.Key == nil {
return fmt.Errorf("Error retrieving key for Function %q in Function app %q (Resource Group %q). Key returned nil from API", functionName, name, resourceGroup)
}

triggerUrlHash := sha256.Sum256([]byte(*functionSecret.TriggerURL))
d.SetId(hex.EncodeToString(triggerUrlHash[:]))

d.Set("trigger_url", functionSecret.TriggerURL)
d.Set("key", functionSecret.Key)

return nil
}

func functionAvailabilityChecker(ctx context.Context, name, functionName, resourceGroup string, client *web.Client) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
log.Printf("[DEBUG] Checking to see if Function %q is available..", functionName)

function, err := client.AppServicesClient.ListFunctionSecrets(ctx, resourceGroup, name, functionName)

if err != nil || function.StatusCode != 200 {
log.Printf("[DEBUG] Didn't find Function at %q", name)
return nil, "pending", err
}

log.Printf("[DEBUG] Found function at %q", functionName)
return function, "available", nil
}
}
119 changes: 119 additions & 0 deletions azurerm/data_source_function_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package azurerm

import (
"fmt"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
)

func TestAccDataSourceAzureRMFunction_basic(t *testing.T) {
dataSourceName := "data.azurerm_function.test"
rInt := tf.AccRandTimeInt()
location := testLocation()
rs := strings.ToLower(acctest.RandString(11))

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMFirewallDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceFunction_basic(rInt, location, rs),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(dataSourceName, "trigger_url"),
resource.TestCheckResourceAttrSet(dataSourceName, "key"),
),
},
},
})
}

func TestAccDataSourceAzureRMFunction_wait(t *testing.T) {
dataSourceName := "data.azurerm_function.test"
rInt := tf.AccRandTimeInt()
location := testLocation()
rs := strings.ToLower(acctest.RandString(11))

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMFirewallDestroy,
Steps: []resource.TestStep{
{
Config: testAccDataSourceFunction_basic(rInt, location, rs),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(dataSourceName, "trigger_url"),
resource.TestCheckResourceAttrSet(dataSourceName, "key"),
),
},
},
})
}

func testAccDataSourceFunction_basic(rInt int, location, storage string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%[1]d"
location = "%[2]s"
}

resource "azurerm_storage_account" "test" {
name = "acctestsa%[3]s"
resource_group_name = "${azurerm_resource_group.test.name}"
location = "${azurerm_resource_group.test.location}"
account_tier = "Standard"
account_replication_type = "LRS"
}

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

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

resource "azurerm_storage_container" "test" {
name = "function-releases"

storage_account_name = "${azurerm_storage_account.test.name}"
container_access_type = "container"
}

resource "azurerm_storage_blob" "javazip" {
name = "testfunc.zip"

storage_account_name = "${azurerm_storage_account.test.name}"
storage_container_name = "${azurerm_storage_container.test.name}"

type = "block"
source = "testdata/testfunc.zip"
}

resource "azurerm_function_app" "test" {
name = "acctest-%[1]d-func"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
app_service_plan_id = "${azurerm_app_service_plan.test.id}"
storage_connection_string = "${azurerm_storage_account.test.primary_connection_string}"

app_settings = {
WEBSITE_RUN_FROM_PACKAGE = "https://${azurerm_storage_account.test.name}.blob.core.windows.net/${azurerm_storage_container.test.name}/testfunc.zip"
FUNCTIONS_WORKER_RUNTIME = "node"
}
}

data "azurerm_function" "test" {
function_app_name = "${azurerm_function_app.test.name}"
resource_group_name = "${azurerm_resource_group.test.name}"
function_name = "testfunc"
}
`, rInt, location, storage)
}
1 change: 1 addition & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_eventhub_namespace": dataSourceEventHubNamespace(),
"azurerm_express_route_circuit": dataSourceArmExpressRouteCircuit(),
"azurerm_firewall": dataSourceArmFirewall(),
"azurerm_function": dataSourceArmFunction(),
"azurerm_image": dataSourceArmImage(),
"azurerm_hdinsight_cluster": dataSourceArmHDInsightSparkCluster(),
"azurerm_healthcare_service": dataSourceArmHealthcareService(),
Expand Down
Binary file added azurerm/testdata/testfunc.zip
Binary file not shown.
13 changes: 0 additions & 13 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@ cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbf
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
contrib.go.opencensus.io/exporter/ocagent v0.5.0 h1:TKXjQSRS0/cCDrP7KvkgU6SmILtF/yV2TOs/02K/WZQ=
contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0=
github.com/Azure/azure-sdk-for-go v21.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v32.5.0+incompatible h1:Hn/DsObfmw0M7dMGS/c0MlVrJuGFzHzOpBWL89acR68=
github.com/Azure/azure-sdk-for-go v32.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v34.1.0+incompatible h1:uW/dgSzmRQEPXwaRUN8WzBHJy5J2cp8cw1ea908uFj0=
github.com/Azure/azure-sdk-for-go v34.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v35.0.0+incompatible h1:PkmdmQUmeSdQQ5258f4SyCf2Zcz0w67qztEg37cOR7U=
github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/azure-sdk-for-go v36.2.0+incompatible h1:09cv2WoH0g6jl6m2iT+R9qcIPZKhXEL0sbmLhxP895s=
github.com/Azure/azure-sdk-for-go v36.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-autorest v10.15.4+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v13.0.0+incompatible h1:56c11ykhsFSPNNQuS73Ri8h/ezqVhr2h6t9LJIEKVO0=
github.com/Azure/go-autorest v13.0.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
Expand Down Expand Up @@ -194,8 +185,6 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf
github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE=
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/aws-sdk-go-base v0.3.0/go.mod h1:ZIWACGGi0N7a4DZbf15yuE1JQORmWLtBcVM6F5SXNFU=
github.com/hashicorp/azure-sdk-for-go v36.2.1-hashi+incompatible h1:JuiGr8Ys+Gtp/O0EFi37se0Z5rY7PIqWNnUwjASWVEM=
github.com/hashicorp/azure-sdk-for-go v36.2.1-hashi+incompatible/go.mod h1:9MzMWzN0gJiWgGzEfgaJaj/sHWDDDwU0LUYAnE+GbHQ=
github.com/hashicorp/azure-sdk-for-go v36.2.2-hashi+incompatible h1:iWg/0ZhDQ4lmvTyGarUXqkcgVbtSXb+Bsqa5vuHD08E=
github.com/hashicorp/azure-sdk-for-go v36.2.2-hashi+incompatible/go.mod h1:9MzMWzN0gJiWgGzEfgaJaj/sHWDDDwU0LUYAnE+GbHQ=
github.com/hashicorp/consul v0.0.0-20171026175957-610f3c86a089/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI=
Expand All @@ -207,8 +196,6 @@ github.com/hashicorp/go-azure-helpers v0.4.1 h1:aEWYW4hxAVVmxmq7nPXGK8F44A6HBXQ4
github.com/hashicorp/go-azure-helpers v0.4.1/go.mod h1:lu62V//auUow6k0IykxLK2DCNW8qTmpm8KqhYVWattA=
github.com/hashicorp/go-azure-helpers v0.7.0 h1:wxGpOyWYp15bjBMeL3pXKP5X3oFLZbThAMcJcU6x4FA=
github.com/hashicorp/go-azure-helpers v0.7.0/go.mod h1:3xdjhbL7qs69rnwxA0UENOzkPJjtTFIRb5aRyrEpbCU=
github.com/hashicorp/go-azure-helpers v0.9.0 h1:KERW4n9AukvQ6kXGJdqXLaR0S2yxH3Xwj+rio/3/uLI=
github.com/hashicorp/go-azure-helpers v0.9.0/go.mod h1:3xdjhbL7qs69rnwxA0UENOzkPJjtTFIRb5aRyrEpbCU=
github.com/hashicorp/go-azure-helpers v0.10.0 h1:KhjDnQhCqEMKlt4yH00MCevJQPJ6LkHFdSveXINO6vE=
github.com/hashicorp/go-azure-helpers v0.10.0/go.mod h1:YuAtHxm2v74s+IjQwUG88dHBJPd5jL+cXr5BGVzSKhE=
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
Expand Down
2 changes: 1 addition & 1 deletion vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cloud.google.com/go/internal/optional
cloud.google.com/go/internal/trace
cloud.google.com/go/internal/version
cloud.google.com/go/storage
# github.com/Azure/azure-sdk-for-go v36.2.0+incompatible => github.com/hashicorp/azure-sdk-for-go v36.2.2-hashi+incompatible
github.com/Azure/azure-sdk-for-go v36.2.0+incompatible => github.com/hashicorp/azure-sdk-for-go v36.2.2-hashi+incompatible
github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/resources/mgmt/resources
github.com/Azure/azure-sdk-for-go/services/analysisservices/mgmt/2017-08-01/analysisservices
github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2018-01-01/apimanagement
Expand Down
36 changes: 36 additions & 0 deletions website/docs/d/function.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
layout: "azurerm"
page_title: "Azure Resource Manager: azurerm_function"
sidebar_current: "docs-azurerm-datasource-function"
description: |-
Gets information about an Azure Function hosted in an FunctionApp.
---

# Data Source: azurerm_function

Use this data source to access information about an Azure Function hosted in a Function App.

## Example Usage

```hcl
data "azurerm_functions_key" "test" {
function_app_name = "function_app_name_here"
resource_group_name = "resource_group_here"
function_name = "name_of_function_you_want_key_for_here"
}

output "key" {
value = "${data.azurerm_function.test.key}"
}
```

## Argument Reference

* `function_app_name` - (Required) Specifies the name of the Function App in which the Function is hosted.
* `function_name` - (Required) Specifies the name of the Function.
* `resource_group_name` - (Required) Specifies the name of the resource group the Function App is located.

## Attributes Reference

* `key` - The Function Key
* `trigger_url` - The full URL with Function Key used to trigger the function