diff --git a/internal/services/streamanalytics/registration.go b/internal/services/streamanalytics/registration.go
index 445dd1b4fcc6..5cb9684327c1 100644
--- a/internal/services/streamanalytics/registration.go
+++ b/internal/services/streamanalytics/registration.go
@@ -52,6 +52,7 @@ func (r Registration) SupportedDataSources() map[string]*pluginsdk.Resource {
 func (r Registration) SupportedResources() map[string]*pluginsdk.Resource {
 	return map[string]*pluginsdk.Resource{
 		"azurerm_stream_analytics_job":                     resourceStreamAnalyticsJob(),
+		"azurerm_stream_analytics_function_javascript_uda": resourceStreamAnalyticsFunctionUDA(),
 		"azurerm_stream_analytics_function_javascript_udf": resourceStreamAnalyticsFunctionUDF(),
 		"azurerm_stream_analytics_output_blob":             resourceStreamAnalyticsOutputBlob(),
 		"azurerm_stream_analytics_output_mssql":            resourceStreamAnalyticsOutputSql(),
diff --git a/internal/services/streamanalytics/stream_analytics_function_javascript_uda_resource.go b/internal/services/streamanalytics/stream_analytics_function_javascript_uda_resource.go
new file mode 100644
index 000000000000..b392d3d0e896
--- /dev/null
+++ b/internal/services/streamanalytics/stream_analytics_function_javascript_uda_resource.go
@@ -0,0 +1,322 @@
+package streamanalytics
+
+import (
+	"fmt"
+	"log"
+	"time"
+
+	"github.com/Azure/azure-sdk-for-go/services/preview/streamanalytics/mgmt/2020-03-01-preview/streamanalytics"
+	"github.com/hashicorp/go-azure-helpers/lang/response"
+	"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
+	"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
+	"github.com/hashicorp/terraform-provider-azurerm/internal/services/streamanalytics/parse"
+	"github.com/hashicorp/terraform-provider-azurerm/internal/services/streamanalytics/validate"
+	"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
+	"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
+	"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
+	"github.com/hashicorp/terraform-provider-azurerm/utils"
+)
+
+func resourceStreamAnalyticsFunctionUDA() *pluginsdk.Resource {
+	return &pluginsdk.Resource{
+		Create: resourceStreamAnalyticsFunctionUDACreate,
+		Read:   resourceStreamAnalyticsFunctionUDARead,
+		Update: resourceStreamAnalyticsFunctionUDAUpdate,
+		Delete: resourceStreamAnalyticsFunctionUDADelete,
+
+		Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error {
+			_, err := parse.FunctionID(id)
+			return err
+		}),
+
+		Timeouts: &pluginsdk.ResourceTimeout{
+			Create: pluginsdk.DefaultTimeout(30 * time.Minute),
+			Read:   pluginsdk.DefaultTimeout(5 * time.Minute),
+			Update: pluginsdk.DefaultTimeout(30 * time.Minute),
+			Delete: pluginsdk.DefaultTimeout(30 * time.Minute),
+		},
+
+		Schema: map[string]*pluginsdk.Schema{
+			"name": {
+				Type:         pluginsdk.TypeString,
+				Required:     true,
+				ForceNew:     true,
+				ValidateFunc: validate.FunctionName,
+			},
+
+			"stream_analytics_job_id": {
+				Type:         pluginsdk.TypeString,
+				Required:     true,
+				ForceNew:     true,
+				ValidateFunc: validate.StreamingJobID,
+			},
+
+			"input": {
+				Type:     pluginsdk.TypeList,
+				Required: true,
+				MinItems: 1,
+				Elem: &pluginsdk.Resource{
+					Schema: map[string]*pluginsdk.Schema{
+						"type": {
+							Type:     pluginsdk.TypeString,
+							Required: true,
+							ValidateFunc: validation.StringInSlice([]string{
+								"any",
+								"array",
+								"bigint",
+								"datetime",
+								"float",
+								"nvarchar(max)",
+								"record",
+							}, false),
+						},
+					},
+				},
+			},
+
+			"output": {
+				Type:     pluginsdk.TypeList,
+				Required: true,
+				MaxItems: 1,
+				Elem: &pluginsdk.Resource{
+					Schema: map[string]*pluginsdk.Schema{
+						"type": {
+							Type:     pluginsdk.TypeString,
+							Required: true,
+							ValidateFunc: validation.StringInSlice([]string{
+								"any",
+								"array",
+								"bigint",
+								"datetime",
+								"float",
+								"nvarchar(max)",
+								"record",
+							}, false),
+						},
+					},
+				},
+			},
+
+			"script": {
+				Type:         pluginsdk.TypeString,
+				Required:     true,
+				ValidateFunc: validation.StringIsNotEmpty,
+			},
+		},
+	}
+}
+
+func resourceStreamAnalyticsFunctionUDACreate(d *pluginsdk.ResourceData, meta interface{}) error {
+	client := meta.(*clients.Client).StreamAnalytics.FunctionsClient
+	subscriptionId := meta.(*clients.Client).Account.SubscriptionId
+	ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
+	defer cancel()
+
+	jobId, err := parse.StreamingJobID(d.Get("stream_analytics_job_id").(string))
+	if err != nil {
+		return err
+	}
+
+	id := parse.NewFunctionID(subscriptionId, jobId.ResourceGroup, jobId.Name, d.Get("name").(string))
+
+	existing, err := client.Get(ctx, id.ResourceGroup, id.StreamingjobName, id.Name)
+	if err != nil {
+		if !utils.ResponseWasNotFound(existing.Response) {
+			return fmt.Errorf("checking for presence of existing %s: %+v", id, err)
+		}
+	}
+
+	if !utils.ResponseWasNotFound(existing.Response) {
+		return tf.ImportAsExistsError("azurerm_stream_analytics_function_javascript_uda", id.ID())
+	}
+
+	props := streamanalytics.Function{
+		Properties: &streamanalytics.AggregateFunctionProperties{
+			Type: streamanalytics.TypeAggregate,
+			FunctionConfiguration: &streamanalytics.FunctionConfiguration{
+				Binding: &streamanalytics.JavaScriptFunctionBinding{
+					Type: streamanalytics.TypeMicrosoftStreamAnalyticsJavascriptUdf,
+					JavaScriptFunctionBindingProperties: &streamanalytics.JavaScriptFunctionBindingProperties{
+						Script: utils.String(d.Get("script").(string)),
+					},
+				},
+				Inputs: expandStreamAnalyticsFunctionUDAInputs(d.Get("input").([]interface{})),
+				Output: expandStreamAnalyticsFunctionUDAOutput(d.Get("output").([]interface{})),
+			},
+		},
+	}
+
+	if _, err := client.CreateOrReplace(ctx, props, id.ResourceGroup, id.StreamingjobName, id.Name, "", ""); err != nil {
+		return fmt.Errorf("creating %s: %+v", id, err)
+	}
+
+	d.SetId(id.ID())
+
+	return resourceStreamAnalyticsFunctionUDARead(d, meta)
+}
+
+func resourceStreamAnalyticsFunctionUDARead(d *pluginsdk.ResourceData, meta interface{}) error {
+	client := meta.(*clients.Client).StreamAnalytics.FunctionsClient
+	ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
+	defer cancel()
+
+	id, err := parse.FunctionID(d.Id())
+	if err != nil {
+		return err
+	}
+
+	resp, err := client.Get(ctx, id.ResourceGroup, id.StreamingjobName, id.Name)
+	if err != nil {
+		if utils.ResponseWasNotFound(resp.Response) {
+			log.Printf("[DEBUG] %q was not found - removing from state!", *id)
+			d.SetId("")
+			return nil
+		}
+
+		return fmt.Errorf("retrieving %s: %+v", *id, err)
+	}
+
+	d.Set("name", id.Name)
+
+	jobId := parse.NewStreamingJobID(id.SubscriptionId, id.ResourceGroup, id.StreamingjobName)
+	d.Set("stream_analytics_job_id", jobId.ID())
+
+	if props := resp.Properties; props != nil {
+		aggregateProps, ok := props.AsAggregateFunctionProperties()
+		if !ok {
+			return fmt.Errorf("converting Props to a Aggregate Function")
+		}
+
+		binding, ok := aggregateProps.Binding.AsJavaScriptFunctionBinding()
+		if !ok {
+			return fmt.Errorf("converting Binding to a JavaScript Function Binding")
+		}
+
+		if bindingProps := binding.JavaScriptFunctionBindingProperties; bindingProps != nil {
+			d.Set("script", bindingProps.Script)
+		}
+
+		if err := d.Set("input", flattenStreamAnalyticsFunctionUDAInputs(aggregateProps.Inputs)); err != nil {
+			return fmt.Errorf("flattening `input`: %+v", err)
+		}
+
+		if err := d.Set("output", flattenStreamAnalyticsFunctionUDAOutput(aggregateProps.Output)); err != nil {
+			return fmt.Errorf("flattening `output`: %+v", err)
+		}
+	}
+
+	return nil
+}
+
+func resourceStreamAnalyticsFunctionUDAUpdate(d *pluginsdk.ResourceData, meta interface{}) error {
+	client := meta.(*clients.Client).StreamAnalytics.FunctionsClient
+	ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
+	defer cancel()
+
+	id, err := parse.FunctionID(d.Id())
+	if err != nil {
+		return err
+	}
+
+	props := streamanalytics.Function{
+		Properties: &streamanalytics.AggregateFunctionProperties{
+			Type: streamanalytics.TypeAggregate,
+			FunctionConfiguration: &streamanalytics.FunctionConfiguration{
+				Binding: &streamanalytics.JavaScriptFunctionBinding{
+					Type: streamanalytics.TypeMicrosoftStreamAnalyticsJavascriptUdf,
+					JavaScriptFunctionBindingProperties: &streamanalytics.JavaScriptFunctionBindingProperties{
+						Script: utils.String(d.Get("script").(string)),
+					},
+				},
+				Inputs: expandStreamAnalyticsFunctionUDAInputs(d.Get("input").([]interface{})),
+				Output: expandStreamAnalyticsFunctionUDAOutput(d.Get("output").([]interface{})),
+			},
+		},
+	}
+
+	if _, err := client.Update(ctx, props, id.ResourceGroup, id.StreamingjobName, id.Name, ""); err != nil {
+		return fmt.Errorf("updating %s: %+v", id, err)
+	}
+
+	return resourceStreamAnalyticsFunctionUDARead(d, meta)
+}
+
+func resourceStreamAnalyticsFunctionUDADelete(d *pluginsdk.ResourceData, meta interface{}) error {
+	client := meta.(*clients.Client).StreamAnalytics.FunctionsClient
+	ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
+	defer cancel()
+
+	id, err := parse.FunctionID(d.Id())
+	if err != nil {
+		return err
+	}
+
+	if resp, err := client.Delete(ctx, id.ResourceGroup, id.StreamingjobName, id.Name); err != nil {
+		if !response.WasNotFound(resp.Response) {
+			return fmt.Errorf("deleting %s: %+v", *id, err)
+		}
+	}
+
+	return nil
+}
+
+func expandStreamAnalyticsFunctionUDAInputs(input []interface{}) *[]streamanalytics.FunctionInput {
+	outputs := make([]streamanalytics.FunctionInput, 0)
+
+	for _, raw := range input {
+		v := raw.(map[string]interface{})
+		variableType := v["type"].(string)
+		outputs = append(outputs, streamanalytics.FunctionInput{
+			DataType: utils.String(variableType),
+		})
+	}
+
+	return &outputs
+}
+
+func flattenStreamAnalyticsFunctionUDAInputs(input *[]streamanalytics.FunctionInput) []interface{} {
+	if input == nil {
+		return []interface{}{}
+	}
+
+	outputs := make([]interface{}, 0)
+
+	for _, v := range *input {
+		var variableType string
+		if v.DataType != nil {
+			variableType = *v.DataType
+		}
+
+		outputs = append(outputs, map[string]interface{}{
+			"type": variableType,
+		})
+	}
+
+	return outputs
+}
+
+func expandStreamAnalyticsFunctionUDAOutput(input []interface{}) *streamanalytics.FunctionOutput {
+	output := input[0].(map[string]interface{})
+
+	dataType := output["type"].(string)
+	return &streamanalytics.FunctionOutput{
+		DataType: utils.String(dataType),
+	}
+}
+
+func flattenStreamAnalyticsFunctionUDAOutput(input *streamanalytics.FunctionOutput) []interface{} {
+	if input == nil {
+		return []interface{}{}
+	}
+
+	var variableType string
+	if input.DataType != nil {
+		variableType = *input.DataType
+	}
+
+	return []interface{}{
+		map[string]interface{}{
+			"type": variableType,
+		},
+	}
+}
diff --git a/internal/services/streamanalytics/stream_analytics_function_javascript_uda_resource_test.go b/internal/services/streamanalytics/stream_analytics_function_javascript_uda_resource_test.go
new file mode 100644
index 000000000000..dde194e5fbaa
--- /dev/null
+++ b/internal/services/streamanalytics/stream_analytics_function_javascript_uda_resource_test.go
@@ -0,0 +1,279 @@
+package streamanalytics_test
+
+import (
+	"context"
+	"fmt"
+	"testing"
+
+	"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
+	"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
+	"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
+	"github.com/hashicorp/terraform-provider-azurerm/internal/services/streamanalytics/parse"
+	"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
+	"github.com/hashicorp/terraform-provider-azurerm/utils"
+)
+
+type StreamAnalyticsFunctionJavaScriptUDAResource struct{}
+
+func TestAccStreamAnalyticsFunctionJavaScriptUDA_basic(t *testing.T) {
+	data := acceptance.BuildTestData(t, "azurerm_stream_analytics_function_javascript_uda", "test")
+	r := StreamAnalyticsFunctionJavaScriptUDAResource{}
+
+	data.ResourceTest(t, r, []acceptance.TestStep{
+		{
+			Config: r.basic(data),
+			Check: acceptance.ComposeTestCheckFunc(
+				check.That(data.ResourceName).ExistsInAzure(r),
+			),
+		},
+		data.ImportStep(),
+	})
+}
+
+func TestAccStreamAnalyticsFunctionJavaScriptUDA_requiresImport(t *testing.T) {
+	data := acceptance.BuildTestData(t, "azurerm_stream_analytics_function_javascript_uda", "test")
+	r := StreamAnalyticsFunctionJavaScriptUDAResource{}
+
+	data.ResourceTest(t, r, []acceptance.TestStep{
+		{
+			Config: r.basic(data),
+			Check: acceptance.ComposeTestCheckFunc(
+				check.That(data.ResourceName).ExistsInAzure(r),
+			),
+		},
+		data.RequiresImportErrorStep(r.requiresImport),
+	})
+}
+
+func TestAccStreamAnalyticsFunctionJavaScriptUDA_inputs(t *testing.T) {
+	data := acceptance.BuildTestData(t, "azurerm_stream_analytics_function_javascript_uda", "test")
+	r := StreamAnalyticsFunctionJavaScriptUDAResource{}
+
+	data.ResourceTest(t, r, []acceptance.TestStep{
+		{
+			Config: r.basic(data),
+			Check: acceptance.ComposeTestCheckFunc(
+				check.That(data.ResourceName).ExistsInAzure(r),
+			),
+		},
+		data.ImportStep(),
+		{
+			Config: r.complete(data),
+			Check: acceptance.ComposeTestCheckFunc(
+				check.That(data.ResourceName).ExistsInAzure(r),
+			),
+		},
+		data.ImportStep(),
+		{
+			Config: r.basic(data),
+			Check: acceptance.ComposeTestCheckFunc(
+				check.That(data.ResourceName).ExistsInAzure(r),
+			),
+		},
+		data.ImportStep(),
+	})
+}
+
+func TestAccStreamAnalyticsFunctionJavaScriptUDA_update(t *testing.T) {
+	data := acceptance.BuildTestData(t, "azurerm_stream_analytics_function_javascript_uda", "test")
+	r := StreamAnalyticsFunctionJavaScriptUDAResource{}
+
+	data.ResourceTest(t, r, []acceptance.TestStep{
+		{
+			Config: r.basic(data),
+			Check: acceptance.ComposeTestCheckFunc(
+				check.That(data.ResourceName).ExistsInAzure(r),
+			),
+		},
+		data.ImportStep(),
+		{
+			Config: r.update(data),
+			Check: acceptance.ComposeTestCheckFunc(
+				check.That(data.ResourceName).ExistsInAzure(r),
+			),
+		},
+		data.ImportStep(),
+	})
+}
+
+func (r StreamAnalyticsFunctionJavaScriptUDAResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
+	id, err := parse.FunctionID(state.ID)
+	if err != nil {
+		return nil, err
+	}
+
+	resp, err := client.StreamAnalytics.FunctionsClient.Get(ctx, id.ResourceGroup, id.StreamingjobName, id.Name)
+	if err != nil {
+		if utils.ResponseWasNotFound(resp.Response) {
+			return utils.Bool(false), nil
+		}
+		return nil, fmt.Errorf("retrieving %s : %+v", *id, err)
+	}
+
+	return utils.Bool(true), nil
+}
+
+func (r StreamAnalyticsFunctionJavaScriptUDAResource) basic(data acceptance.TestData) string {
+	return fmt.Sprintf(`
+%s
+
+resource "azurerm_stream_analytics_function_javascript_uda" "test" {
+  name                    = "acctestinput-%d"
+  stream_analytics_job_id = azurerm_stream_analytics_job.test.id
+
+  script = <<SCRIPT
+function main() {
+    this.init = function () {
+        this.state = 0;
+    }
+
+    this.accumulate = function (value, timestamp) {
+        this.state += value;
+    }
+
+    this.computeResult = function () {
+        return this.state;
+    }
+}
+SCRIPT
+
+
+  input {
+    type = "bigint"
+  }
+
+  output {
+    type = "bigint"
+  }
+}
+`, r.template(data), data.RandomInteger)
+}
+
+func (r StreamAnalyticsFunctionJavaScriptUDAResource) requiresImport(data acceptance.TestData) string {
+	return fmt.Sprintf(`
+%s
+
+resource "azurerm_stream_analytics_function_javascript_uda" "import" {
+  name                    = azurerm_stream_analytics_function_javascript_uda.test.name
+  stream_analytics_job_id = azurerm_stream_analytics_function_javascript_uda.test.stream_analytics_job_id
+  script                  = azurerm_stream_analytics_function_javascript_uda.test.script
+
+  input {
+    type = azurerm_stream_analytics_function_javascript_uda.test.input.0.type
+  }
+
+  output {
+    type = azurerm_stream_analytics_function_javascript_uda.test.output.0.type
+  }
+}
+`, r.basic(data))
+}
+
+func (r StreamAnalyticsFunctionJavaScriptUDAResource) complete(data acceptance.TestData) string {
+	return fmt.Sprintf(`
+%s
+
+resource "azurerm_stream_analytics_function_javascript_uda" "test" {
+  name                    = "acctestinput-%d"
+  stream_analytics_job_id = azurerm_stream_analytics_job.test.id
+
+  script = <<SCRIPT
+function main() {
+    this.init = function () {
+        this.state = 0;
+    }
+
+    this.accumulate = function (value, timestamp) {
+        this.state += value;
+    }
+
+    this.computeResult = function () {
+        return this.state;
+    }
+}
+SCRIPT
+
+
+  input {
+    type = "bigint"
+  }
+
+  input {
+    type = "float"
+  }
+
+  output {
+    type = "bigint"
+  }
+}
+`, r.template(data), data.RandomInteger)
+}
+
+func (r StreamAnalyticsFunctionJavaScriptUDAResource) update(data acceptance.TestData) string {
+	return fmt.Sprintf(`
+%s
+
+resource "azurerm_stream_analytics_function_javascript_uda" "test" {
+  name                    = "acctestinput-%d"
+  stream_analytics_job_id = azurerm_stream_analytics_job.test.id
+
+  script = <<SCRIPT
+function main() {
+    this.init = function () {
+        this.state = 0;
+    }
+
+    this.accumulate = function (value) {
+        this.state += value;
+    }
+
+    this.computeResult = function () {
+        return this.state;
+    }
+}
+SCRIPT
+
+
+  input {
+    type = "float"
+  }
+
+  output {
+    type = "float"
+  }
+}
+`, r.template(data), data.RandomInteger)
+}
+
+func (r StreamAnalyticsFunctionJavaScriptUDAResource) template(data acceptance.TestData) string {
+	return fmt.Sprintf(`
+provider "azurerm" {
+  features {}
+}
+
+resource "azurerm_resource_group" "test" {
+  name     = "acctestRG-%d"
+  location = "%s"
+}
+
+resource "azurerm_stream_analytics_job" "test" {
+  name                                     = "acctestjob-%d"
+  resource_group_name                      = azurerm_resource_group.test.name
+  location                                 = azurerm_resource_group.test.location
+  compatibility_level                      = "1.0"
+  data_locale                              = "en-GB"
+  events_late_arrival_max_delay_in_seconds = 60
+  events_out_of_order_max_delay_in_seconds = 50
+  events_out_of_order_policy               = "Adjust"
+  output_error_policy                      = "Drop"
+  streaming_units                          = 3
+
+  transformation_query = <<QUERY
+    SELECT *
+    INTO [YourOutputAlias]
+    FROM [YourInputAlias]
+QUERY
+
+}
+`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
+}
diff --git a/internal/services/streamanalytics/validate/function_name.go b/internal/services/streamanalytics/validate/function_name.go
new file mode 100644
index 000000000000..0b14f5d137ec
--- /dev/null
+++ b/internal/services/streamanalytics/validate/function_name.go
@@ -0,0 +1,16 @@
+package validate
+
+import (
+	"fmt"
+	"regexp"
+)
+
+func FunctionName(v interface{}, _ string) (warnings []string, errors []error) {
+	input := v.(string)
+
+	if !regexp.MustCompile(`^[a-zA-Z0-9-]{3,63}$`).MatchString(input) {
+		errors = append(errors, fmt.Errorf("%s contain only letters, numbers and hyphens. The value must be between 3 and 63 characters long", input))
+	}
+
+	return warnings, errors
+}
diff --git a/internal/services/streamanalytics/validate/function_name_test.go b/internal/services/streamanalytics/validate/function_name_test.go
new file mode 100644
index 000000000000..db696806a474
--- /dev/null
+++ b/internal/services/streamanalytics/validate/function_name_test.go
@@ -0,0 +1,32 @@
+package validate
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestFunctionName(t *testing.T) {
+	testCases := []struct {
+		input       string
+		shouldError bool
+	}{
+		{"", true},
+		{"ABC", false},
+		{"abc", false},
+		{"a-b", false},
+		{"ab-", false},
+		{"ab-1", false},
+		{"ab#-1", false},
+		{strings.Repeat("s", 3), false},
+		{strings.Repeat("s", 63), false},
+		{strings.Repeat("s", 64), true},
+	}
+
+	for _, test := range testCases {
+		_, es := FunctionName(test.input, "name")
+
+		if test.shouldError && len(es) == 0 {
+			t.Fatalf("Expected validating name %q to fail", test.input)
+		}
+	}
+}
diff --git a/website/docs/r/stream_analytics_function_javascript_uda.html.markdown b/website/docs/r/stream_analytics_function_javascript_uda.html.markdown
new file mode 100644
index 000000000000..9d27ff3edcdd
--- /dev/null
+++ b/website/docs/r/stream_analytics_function_javascript_uda.html.markdown
@@ -0,0 +1,102 @@
+---
+subcategory: "Stream Analytics"
+layout: "azurerm"
+page_title: "Azure Resource Manager: azurerm_stream_analytics_function_javascript_uda"
+description: |-
+  Manages a JavaScript UDA Function within a Stream Analytics Streaming Job.
+---
+
+# azurerm_stream_analytics_function_javascript_uda
+
+Manages a JavaScript UDA Function within a Stream Analytics Streaming Job.
+
+## Example Usage
+
+```hcl
+data "azurerm_resource_group" "example" {
+  name = "example-resources"
+}
+
+data "azurerm_stream_analytics_job" "example" {
+  name                = "example-job"
+  resource_group_name = azurerm_resource_group.example.name
+}
+
+resource "azurerm_stream_analytics_function_javascript_uda" "example" {
+  name                    = "example-javascript-function"
+  stream_analytics_job_id = data.azurerm_stream_analytics_job.example.id
+
+  script = <<SCRIPT
+function main() {
+    this.init = function () {
+        this.state = 0;
+    }
+
+    this.accumulate = function (value, timestamp) {
+        this.state += value;
+    }
+
+    this.computeResult = function () {
+        return this.state;
+    }
+}
+SCRIPT
+
+  input {
+    type = "bigint"
+  }
+
+  output {
+    type = "bigint"
+  }
+}
+```
+
+## Argument Reference
+
+The following arguments are supported:
+
+* `name` - (Required) The name of the JavaScript UDA Function. Changing this forces a new resource to be created.
+
+* `stream_analytics_job_id` - (Required) The resource ID of the Stream Analytics Job where this Function should be created. Changing this forces a new resource to be created.
+
+* `input` - (Required) One or more `input` blocks as defined below.
+
+* `output` - (Required) An `output` block as defined below.
+
+* `script` - (Required) The JavaScript of this UDA Function.
+
+---
+
+An `input` block supports the following:
+
+* `type` - The input data type of this JavaScript Function. Possible values include `any`, `array`, `bigint`, `datetime`, `float`, `nvarchar(max)` and `record`.
+
+---
+
+An `output` block supports the following:
+
+* `type` - The output data type from this JavaScript Function. Possible values include `any`, `array`, `bigint`, `datetime`, `float`, `nvarchar(max)` and `record`.
+
+## Attributes Reference
+
+The following attributes are exported in addition to the arguments listed above:
+
+* `id` - The ID of the Stream Analytics JavaScript UDA Function.
+
+## Timeouts
+
+The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions:
+
+* `create` - (Defaults to 30 minutes) Used when creating the Stream Analytics JavaScript UDA Function.
+* `update` - (Defaults to 30 minutes) Used when updating the Stream Analytics JavaScript UDA Function.
+* `read` - (Defaults to 5 minutes) Used when retrieving the Stream Analytics JavaScript UDA Function.
+* `delete` - (Defaults to 30 minutes) Used when deleting the Stream Analytics JavaScript UDA Function.
+
+## Import
+
+Stream Analytics JavaScript UDA Functions can be imported using the `resource id`, e.g.
+
+```shell
+terraform import azurerm_stream_analytics_function_javascript_uda.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.StreamAnalytics/streamingjobs/job1/functions/func1
+```