diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0b9e9b3a..797b0085 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@
All notable changes to this project will be documented in this file.
## [Unreleased]
+- new 'Cloud Endpoints' module
## [2.1.0] - 2020-06-22
diff --git a/README.md b/README.md
index 789c9842..db02b66e 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ The current list of modules supports most of the core foundational and networkin
Currently available modules:
- **foundational** - [folders](./modules/folders), [log sinks](./modules/logging-sinks), [organization](./modules/organization), [project](./modules/project), [service accounts](./modules/iam-service-accounts)
-- **networking** - [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC peering](./modules/net-vpc-peering), [VPN static](./modules/net-vpn-static), [VPN dynamic](./modules/net-vpn-dynamic), [VPN HA](./modules/net-vpn-ha), [NAT](./modules/net-cloudnat), [address reservation](./modules/net-address), [DNS](./modules/dns), [L4 ILB](./modules/net-ilb), [Service Directory](./modules/service-directory)
+- **networking** - [VPC](./modules/net-vpc), [VPC firewall](./modules/net-vpc-firewall), [VPC peering](./modules/net-vpc-peering), [VPN static](./modules/net-vpn-static), [VPN dynamic](./modules/net-vpn-dynamic), [VPN HA](./modules/net-vpn-ha), [NAT](./modules/net-cloudnat), [address reservation](./modules/net-address), [DNS](./modules/dns), [L4 ILB](./modules/net-ilb), [Service Directory](./modules/service-directory), [Cloud Endpoints](./modules/cloudenpoints)
- **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [GKE cluster](./modules/gke-cluster), [GKE nodepool](./modules/gke-nodepool), [COS container](./modules/cos-container) (coredns, mysql, onprem, squid)
- **data** - [GCS](./modules/gcs), [BigQuery dataset](./modules/bigquery-dataset), [Pub/Sub](./modules/pubsub), [Datafusion](./modules/datafusion), [Bigtable instance](./modules/bigtable-instance)
- **security** - [KMS](./modules/kms), [SecretManager](./modules/secret-manager)
diff --git a/modules/README.md b/modules/README.md
index a831c734..d94f6dc0 100644
--- a/modules/README.md
+++ b/modules/README.md
@@ -21,6 +21,7 @@ Specific modules also offer support for non-authoritative bindings (e.g. `google
- [address reservation](./net-address)
- [Cloud DNS](./dns)
- [Cloud NAT](./net-cloudnat)
+- [Cloud Endpoints](./endpoints)
- [L4 Internal Load Balancer](./net-ilb)
- [Service Directory](./service-directory)
- [VPC](./net-vpc)
diff --git a/modules/endpoints/README.md b/modules/endpoints/README.md
new file mode 100644
index 00000000..f57952e4
--- /dev/null
+++ b/modules/endpoints/README.md
@@ -0,0 +1,44 @@
+# Google Cloud Endpoints
+
+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) endpoints.
+
+## Examples
+
+### OpenAPI
+
+```hcl
+module "endpoint" {
+ source = "../../modules/endpoint"
+ project_id = "my-project"
+ service_name = "YOUR-API.endpoints.YOUR-PROJECT-ID.cloud.goog"
+ openapi_config = { "yaml_path" = "openapi.yaml" }
+ grpc_config = null
+ iam_roles = ["servicemanagement.serviceController"]
+ iam_members = {
+ "servicemanagement.serviceController" = ["serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com"]
+ }
+}
+```
+
+[Here](https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/endpoints/getting-started/openapi.yaml) you can find an example of an openapi.yaml file. Once created the endpoint, remember to activate the service at project level.
+
+
+## Variables
+
+| name | description | type | required | default |
+|---|---|:---: |:---:|:---:|
+| grpc_config | The configuration for a gRPC enpoint. Either this or openapi_config must be specified. | object({...})
| ✓ | |
+| openapi_config | The configuration for an OpenAPI endopoint. Either this or grpc_config must be specified. | object({...})
| ✓ | |
+| service_name | The name of the service. Usually of the form '$apiname.endpoints.$projectid.cloud.goog'. | string
| ✓ | |
+| *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)
| | []
|
+| *project_id* | The project ID that the service belongs to. | string
| | null
|
+
+## Outputs
+
+| name | description | sensitive |
+|---|---|:---:|
+| endpoints | A list of Endpoint objects. | |
+| endpoints_service | The Endpoint service resource. | |
+| service_name | The name of the service.. | |
+
diff --git a/modules/endpoints/main.tf b/modules/endpoints/main.tf
new file mode 100644
index 00000000..1b9cedbe
--- /dev/null
+++ b/modules/endpoints/main.tf
@@ -0,0 +1,36 @@
+/**
+ * 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.yaml_path) : null
+ grpc_config = var.grpc_config != null ? file(var.grpc_config.yaml_path) : null
+ protoc_output_base64 = var.grpc_config != null ? base64encode(file(var.grpc_config.protoc_output_path)) : null
+}
+
+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
+}
diff --git a/modules/endpoints/outputs.tf b/modules/endpoints/outputs.tf
new file mode 100644
index 00000000..e4da1de6
--- /dev/null
+++ b/modules/endpoints/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 "endpoints_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
+}
diff --git a/modules/endpoints/variables.tf b/modules/endpoints/variables.tf
new file mode 100644
index 00000000..76fb8b8b
--- /dev/null
+++ b/modules/endpoints/variables.tf
@@ -0,0 +1,53 @@
+/**
+ * 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 configuration for a gRPC enpoint. Either this or openapi_config must be specified."
+ type = object({
+ yaml_path = string
+ protoc_output_path = string
+ })
+}
+
+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 configuration for an OpenAPI endopoint. Either this or grpc_config must be specified."
+ type = object({
+ yaml_path = string
+ })
+}
+
+variable "project_id" {
+ description = "The project ID that the service belongs to."
+ type = string
+ default = null
+}
+
+variable "service_name" {
+ description = "The name of the service. Usually of the form '$apiname.endpoints.$projectid.cloud.goog'."
+ type = string
+}
diff --git a/modules/endpoints/versions.tf b/modules/endpoints/versions.tf
new file mode 100644
index 00000000..bc4c2a9d
--- /dev/null
+++ b/modules/endpoints/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"
+}