diff --git a/modules/endpoint/README.md b/modules/endpoint/README.md
new file mode 100644
index 000000000..0d7bcfedd
--- /dev/null
+++ b/modules/endpoint/README.md
@@ -0,0 +1,42 @@
+# Google Cloud Data Fusion Module
+
+This module allows simple management of ['Google Cloud Endpoints'](https://cloud.google.com/endpoints/) services. It supports creating ['OpenAPI'](https://cloud.google.com/endpoints/docs/openapi) or ['gRPC'](https://cloud.google.com/endpoints/docs/grpc/about-grpc).
+
+## Examples
+
+### OpenAPI
+
+```hcl
+module "endpoint" {
+ source = "../../modules/endpoint"
+ project_id = local.project_id
+ service_name = local.service_name
+ openapi_config = local.openapi_config
+ iam_roles = ["servicemanagement.serviceController"]
+ iam_members = {
+ "servicemanagement.serviceController" = ["serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com"]
+ }
+}
+```
+
+
+## Variables
+
+| name | description | type | required | default |
+|---|---|:---: |:---:|:---:|
+| service_name | The name of the service. Usually of the form '$apiname.endpoints.$projectid.cloud.goog'. | string | ✓ | |
+| *grpc_config* | The path to the full text of the Service Config YAML file. | string | | null |
+| *iam_members* | Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the instance are preserved. | map(list(string)) | | {} |
+| *iam_roles* | Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. | list(string) | | [] |
+| *openapi_config* | The path to the full text of the OpenAPI YAML configuration. Either this, or both of grpc_config and protoc_output_base64 must be specified. | string | | null |
+| *project_id* | The project ID that the service belongs to. | string | | null |
+| *protoc_output_base64* | The path to the full contents of the Service Descriptor File generated by protoc. | string | | null |
+
+## Outputs
+
+| name | description | sensitive |
+|---|---|:---:|
+| endpoint_service | The Endpoint service resource. | |
+| endpoints | A list of Endpoint objects. | |
+| service_name | The name of the service.. | |
+
diff --git a/modules/endpoint/main.tf b/modules/endpoint/main.tf
new file mode 100644
index 000000000..dbe26a079
--- /dev/null
+++ b/modules/endpoint/main.tf
@@ -0,0 +1,46 @@
+/**
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+locals {
+ iam_roles_bindings = {
+ for k in var.iam_roles : k => lookup(var.iam_members, k, [])
+ }
+}
+
+resource "google_endpoints_service" "default" {
+ project = var.project_id
+ service_name = var.service_name
+
+ openapi_config = var.openapi_config != null ? file(var.openapi_config) : null
+ grpc_config = var.grpc_config != null ? file(var.grpc_config) : null
+
+ protoc_output_base64 = var.protoc_output_base64 != null ? base64encode(file(var.protoc_output_base64)) : null
+}
+
+resource "google_project_service" "default" {
+ project = var.project_id
+ service = google_endpoints_service.default.service_name
+ disable_on_destroy = true
+ disable_dependent_services = true
+}
+
+resource "google_endpoints_service_iam_binding" "default" {
+ for_each = local.iam_roles_bindings
+
+ service_name = google_endpoints_service.default.service_name
+ role = "roles/${each.key}"
+ members = each.value
+}
\ No newline at end of file
diff --git a/modules/endpoint/outputs.tf b/modules/endpoint/outputs.tf
new file mode 100644
index 000000000..4c7df9e54
--- /dev/null
+++ b/modules/endpoint/outputs.tf
@@ -0,0 +1,30 @@
+/**
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+output "service_name" {
+ description = "The name of the service.."
+ value = google_endpoints_service.default.service_name
+}
+
+output "endpoint_service" {
+ description = "The Endpoint service resource."
+ value = google_endpoints_service.default
+}
+
+output "endpoints" {
+ description = "A list of Endpoint objects."
+ value = google_endpoints_service.default.endpoints
+}
\ No newline at end of file
diff --git a/modules/endpoint/variables.tf b/modules/endpoint/variables.tf
new file mode 100644
index 000000000..20d3fa539
--- /dev/null
+++ b/modules/endpoint/variables.tf
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+variable "grpc_config" {
+ description = "The path to the full text of the Service Config YAML file."
+ type = string
+ default = null
+}
+
+variable "iam_roles" {
+ description = "Authoritative for a given role. Updates the IAM policy to grant a role to a list of members."
+ type = list(string)
+ default = []
+}
+
+variable "iam_members" {
+ description = "Authoritative for a given role. Updates the IAM policy to grant a role to a list of members. Other roles within the IAM policy for the instance are preserved."
+ type = map(list(string))
+ default = {}
+}
+
+variable "openapi_config" {
+ description = "The path to the full text of the OpenAPI YAML configuration. Either this, or both of grpc_config and protoc_output_base64 must be specified."
+ type = string
+ default = null
+}
+
+variable "project_id" {
+ description = "The project ID that the service belongs to."
+ type = string
+ default = null
+}
+
+variable "protoc_output_base64" {
+ description = "The path to the full contents of the Service Descriptor File generated by protoc."
+ type = string
+ default = null
+}
+
+variable "service_name" {
+ description = "The name of the service. Usually of the form '$apiname.endpoints.$projectid.cloud.goog'."
+ type = string
+}
\ No newline at end of file
diff --git a/modules/endpoint/versions.tf b/modules/endpoint/versions.tf
new file mode 100644
index 000000000..bc4c2a9d7
--- /dev/null
+++ b/modules/endpoint/versions.tf
@@ -0,0 +1,19 @@
+/**
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+terraform {
+ required_version = ">= 0.12.6"
+}