Skip to content
Open
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
10 changes: 10 additions & 0 deletions .changelog/3818.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
```release-note:enhancement
resource/mongodbatlas_stream_privatelink_endpoint: Adds support for GCP Confluent
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
resource/mongodbatlas_stream_privatelink_endpoint: Adds support for GCP Confluent
resource/mongodbatlas_stream_privatelink_endpoint: Adds support for GCP Confluent

Is it missing a ``` ?


```release-note:enhancement
data-source/mongodbatlas_stream_privatelink_endpoint: Adds support for GCP Confluent
```

```release-note:enhancement
data-source/mongodbatlas_stream_privatelink_endpoints: Adds support for GCP Confluent
```
44 changes: 43 additions & 1 deletion docs/data-sources/stream_privatelink_endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,45 @@ output "privatelink_endpoint_id" {
}
```

### GCP Confluent Privatelink
```terraform
resource "mongodbatlas_stream_privatelink_endpoint" "gcp_confluent" {
project_id = var.project_id

provider_name = "GCP"
vendor = "CONFLUENT"
region = var.gcp_region

dns_domain = var.confluent_dns_domain
dns_sub_domain = var.confluent_dns_subdomains

service_attachment_uris = [
"projects/my-project/regions/us-west1/serviceAttachments/confluent-attachment-1",
"projects/my-project/regions/us-west1/serviceAttachments/confluent-attachment-2"
]
}

data "mongodbatlas_stream_privatelink_endpoint" "gcp_confluent" {
project_id = var.project_id
id = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.id
}

output "privatelink_endpoint_id" {
description = "The ID of the MongoDB Atlas Stream Private Link Endpoint"
value = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.id
}

output "privatelink_endpoint_state" {
description = "The state of the MongoDB Atlas Stream Private Link Endpoint"
value = data.mongodbatlas_stream_privatelink_endpoint.gcp_confluent.state
}

output "service_attachment_uris" {
description = "The GCP service attachment URIs used for the private link"
value = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.service_attachment_uris
}
```

<!-- schema generated by tfplugindocs -->
## Schema

Expand All @@ -274,8 +313,9 @@ output "privatelink_endpoint_id" {
- `interface_endpoint_id` (String) Interface endpoint ID that is created from the specified service endpoint ID.
- `interface_endpoint_name` (String) Name of interface endpoint that is created from the specified service endpoint ID.
- `provider_account_id` (String) Account ID from the cloud provider.
- `provider_name` (String) Provider where the endpoint is deployed. Valid values are AWS and AZURE.
- `provider_name` (String) Provider where the endpoint is deployed. Valid values are AWS, AZURE, and GCP.
- `region` (String) The region of the Provider’s cluster. See [AZURE](https://www.mongodb.com/docs/atlas/reference/microsoft-azure/#stream-processing-instances) and [AWS](https://www.mongodb.com/docs/atlas/reference/amazon-aws/#stream-processing-instances) supported regions. When the vendor is `CONFLUENT`, this is the domain name of Confluent cluster. When the vendor is `MSK`, this is computed by the API from the provided `arn`.
- `service_attachment_uris` (List of String) List of GCP service attachment URIs for Confluent vendor. Required for GCP provider with CONFLUENT vendor.
- `service_endpoint_id` (String) For AZURE EVENTHUB, this is the [namespace endpoint ID](https://learn.microsoft.com/en-us/rest/api/eventhub/namespaces/get). For AWS CONFLUENT cluster, this is the [VPC Endpoint service name](https://docs.confluent.io/cloud/current/networking/private-links/aws-privatelink.html).
- `state` (String) Status of the connection.
- `vendor` (String) Vendor that manages the endpoint. The following are the vendor values per provider:
Expand All @@ -284,4 +324,6 @@ output "privatelink_endpoint_id" {

* **Azure**: EVENTHUB and CONFLUENT

* **GCP**: CONFLUENT

For more information see: [MongoDB Atlas API - Streams Privatelink](https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/operation/operation-createprivatelinkconnection) Documentation.
44 changes: 43 additions & 1 deletion docs/data-sources/stream_privatelink_endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,45 @@ output "privatelink_endpoint_id" {
}
```

### GCP Confluent Privatelink
```terraform
resource "mongodbatlas_stream_privatelink_endpoint" "gcp_confluent" {
project_id = var.project_id

provider_name = "GCP"
vendor = "CONFLUENT"
region = var.gcp_region

dns_domain = var.confluent_dns_domain
dns_sub_domain = var.confluent_dns_subdomains

service_attachment_uris = [
"projects/my-project/regions/us-west1/serviceAttachments/confluent-attachment-1",
"projects/my-project/regions/us-west1/serviceAttachments/confluent-attachment-2"
]
}

data "mongodbatlas_stream_privatelink_endpoint" "gcp_confluent" {
project_id = var.project_id
id = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.id
}

output "privatelink_endpoint_id" {
description = "The ID of the MongoDB Atlas Stream Private Link Endpoint"
value = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.id
}

output "privatelink_endpoint_state" {
description = "The state of the MongoDB Atlas Stream Private Link Endpoint"
value = data.mongodbatlas_stream_privatelink_endpoint.gcp_confluent.state
}

output "service_attachment_uris" {
description = "The GCP service attachment URIs used for the private link"
value = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.service_attachment_uris
}
```

<!-- schema generated by tfplugindocs -->
## Schema

Expand Down Expand Up @@ -282,8 +321,9 @@ Read-Only:
- `interface_endpoint_name` (String) Name of interface endpoint that is created from the specified service endpoint ID.
- `project_id` (String) Unique 24-hexadecimal digit string that identifies your project. Use the [/groups](#tag/Projects/operation/listProjects) endpoint to retrieve all projects to which the authenticated user has access.<br>**NOTE**: Groups and projects are synonymous terms. Your group id is the same as your project id. For existing groups, your group or project id remains the same. The resource and corresponding endpoints use the term groups.
- `provider_account_id` (String) Account ID from the cloud provider.
- `provider_name` (String) Provider where the endpoint is deployed. Valid values are AWS and AZURE.
- `provider_name` (String) Provider where the endpoint is deployed. Valid values are AWS, AZURE, and GCP.
- `region` (String) The region of the Provider’s cluster. See [AZURE](https://www.mongodb.com/docs/atlas/reference/microsoft-azure/#stream-processing-instances) and [AWS](https://www.mongodb.com/docs/atlas/reference/amazon-aws/#stream-processing-instances) supported regions. When the vendor is `CONFLUENT`, this is the domain name of Confluent cluster. When the vendor is `MSK`, this is computed by the API from the provided `arn`.
- `service_attachment_uris` (List of String) List of GCP service attachment URIs for Confluent vendor. Required for GCP provider with CONFLUENT vendor.
- `service_endpoint_id` (String) For AZURE EVENTHUB, this is the [namespace endpoint ID](https://learn.microsoft.com/en-us/rest/api/eventhub/namespaces/get). For AWS CONFLUENT cluster, this is the [VPC Endpoint service name](https://docs.confluent.io/cloud/current/networking/private-links/aws-privatelink.html).
- `state` (String) Status of the connection.
- `vendor` (String) Vendor that manages the endpoint. The following are the vendor values per provider:
Expand All @@ -292,4 +332,6 @@ Read-Only:

* **Azure**: EVENTHUB and CONFLUENT

* **GCP**: CONFLUENT

For more information see: [MongoDB Atlas API - Streams Privatelink](https://www.mongodb.com/docs/api/doc/atlas-admin-api-v2/operation/operation-createprivatelinkconnection) Documentation.
45 changes: 44 additions & 1 deletion docs/resources/stream_privatelink_endpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,51 @@ output "privatelink_endpoint_id" {
}
```

### GCP Confluent Privatelink
```terraform
resource "mongodbatlas_stream_privatelink_endpoint" "gcp_confluent" {
project_id = var.project_id

provider_name = "GCP"
vendor = "CONFLUENT"
region = var.gcp_region

dns_domain = var.confluent_dns_domain
dns_sub_domain = var.confluent_dns_subdomains

service_attachment_uris = [
"projects/my-project/regions/us-west1/serviceAttachments/confluent-attachment-1",
"projects/my-project/regions/us-west1/serviceAttachments/confluent-attachment-2"
]
}

data "mongodbatlas_stream_privatelink_endpoint" "gcp_confluent" {
project_id = var.project_id
id = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.id
}

output "privatelink_endpoint_id" {
description = "The ID of the MongoDB Atlas Stream Private Link Endpoint"
value = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.id
}

output "privatelink_endpoint_state" {
description = "The state of the MongoDB Atlas Stream Private Link Endpoint"
value = data.mongodbatlas_stream_privatelink_endpoint.gcp_confluent.state
}

output "service_attachment_uris" {
description = "The GCP service attachment URIs used for the private link"
value = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.service_attachment_uris
}
```

### Further Examples
- [AWS Confluent PrivateLink](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/v2.1.0/examples/mongodbatlas_stream_privatelink_endpoint/confluent_serverless)
- [Confluent Dedicated Cluster](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/v2.1.0/examples/mongodbatlas_stream_privatelink_endpoint/confluent_dedicated_cluster)
- [AWS MSK PrivateLink](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/v2.1.0/examples/mongodbatlas_stream_privatelink_endpoint/aws_msk_cluster)
- [AWS S3 PrivateLink](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/v2.1.0/examples/mongodbatlas_stream_privatelink_endpoint/s3)
- [GCP Confluent PrivateLink](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/v2.1.0/examples/mongodbatlas_stream_privatelink_endpoint/gcp_confluent)
- [Azure PrivateLink](https://github.com/mongodb/terraform-provider-mongodbatlas/tree/v2.1.0/examples/mongodbatlas_stream_privatelink_endpoint/azure)

<!-- schema generated by tfplugindocs -->
Expand All @@ -266,13 +306,15 @@ output "privatelink_endpoint_id" {
### Required

- `project_id` (String) Unique 24-hexadecimal digit string that identifies your project. Use the [/groups](#tag/Projects/operation/listProjects) endpoint to retrieve all projects to which the authenticated user has access.<br>**NOTE**: Groups and projects are synonymous terms. Your group id is the same as your project id. For existing groups, your group or project id remains the same. The resource and corresponding endpoints use the term groups.
- `provider_name` (String) Provider where the endpoint is deployed. Valid values are AWS and AZURE.
- `provider_name` (String) Provider where the endpoint is deployed. Valid values are AWS, AZURE, and GCP.
- `vendor` (String) Vendor that manages the endpoint. The following are the vendor values per provider:

* **AWS**: MSK, CONFLUENT, and S3

* **Azure**: EVENTHUB and CONFLUENT

* **GCP**: CONFLUENT

### Optional

- `arn` (String) Amazon Resource Name (ARN). Required for AWS Provider and MSK vendor.
Expand All @@ -283,6 +325,7 @@ output "privatelink_endpoint_id" {
* AZURE provider with EVENTHUB or CONFLUENT vendor.
- `dns_sub_domain` (List of String) Sub-Domain name of Confluent cluster. These are typically your availability zones. Required for AWS Provider and CONFLUENT vendor. If your AWS CONFLUENT cluster doesn't use subdomains, you must set this to the empty array [].
- `region` (String) The region of the Provider’s cluster. See [AZURE](https://www.mongodb.com/docs/atlas/reference/microsoft-azure/#stream-processing-instances) and [AWS](https://www.mongodb.com/docs/atlas/reference/amazon-aws/#stream-processing-instances) supported regions. When the vendor is `CONFLUENT`, this is the domain name of Confluent cluster. When the vendor is `MSK`, this is computed by the API from the provided `arn`.
- `service_attachment_uris` (List of String) List of GCP service attachment URIs for Confluent vendor. Required for GCP provider with CONFLUENT vendor.
- `service_endpoint_id` (String) For AZURE EVENTHUB, this is the [namespace endpoint ID](https://learn.microsoft.com/en-us/rest/api/eventhub/namespaces/get). For AWS CONFLUENT cluster, this is the [VPC Endpoint service name](https://docs.confluent.io/cloud/current/networking/private-links/aws-privatelink.html).

### Read-Only
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# MongoDB Atlas Provider - GCP Confluent Privatelink for Atlas Streams

This example shows how to use GCP Private Service Connect for Atlas Streams with Confluent Cloud.

You must set the following variables:

- `project_id`: Unique 24-hexadecimal digit string that identifies your project
- `atlas_client_id`: MongoDB Atlas Service Account Client ID
- `atlas_client_secret`: MongoDB Atlas Service Account Client Secret
- `gcp_region`: GCP region where your Confluent cluster is located
- `confluent_dns_domain`: DNS domain for your Confluent cluster
- `confluent_dns_subdomains`: List of DNS subdomains for your Confluent cluster
- `service_attachment_uris`: List of GCP service attachment URIs from your Confluent Cloud cluster
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
resource "mongodbatlas_stream_privatelink_endpoint" "gcp_confluent" {
project_id = var.project_id

provider_name = "GCP"
vendor = "CONFLUENT"
region = var.gcp_region

dns_domain = var.confluent_dns_domain
dns_sub_domain = var.confluent_dns_subdomains

service_attachment_uris = [
"projects/my-project/regions/us-west1/serviceAttachments/confluent-attachment-1",
"projects/my-project/regions/us-west1/serviceAttachments/confluent-attachment-2"
]
}

data "mongodbatlas_stream_privatelink_endpoint" "gcp_confluent" {
project_id = var.project_id
id = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.id
}

output "privatelink_endpoint_id" {
description = "The ID of the MongoDB Atlas Stream Private Link Endpoint"
value = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.id
}

output "privatelink_endpoint_state" {
description = "The state of the MongoDB Atlas Stream Private Link Endpoint"
value = data.mongodbatlas_stream_privatelink_endpoint.gcp_confluent.state
}

output "service_attachment_uris" {
description = "The GCP service attachment URIs used for the private link"
value = mongodbatlas_stream_privatelink_endpoint.gcp_confluent.service_attachment_uris
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
variable "project_id" {
description = "The MongoDB Atlas project ID"
type = string
}

variable "gcp_region" {
description = "The GCP region where resources will be created"
type = string
default = "us-west1"
}

variable "confluent_dns_domain" {
description = "The DNS domain for the Confluent cluster"
type = string
default = "example.confluent.cloud"
}

variable "confluent_dns_subdomains" {
description = "List of DNS subdomains for the Confluent cluster"
type = list(string)
default = ["subdomain1", "subdomain2"]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = ">= 1.0"
required_providers {
mongodbatlas = {
source = "mongodb/mongodbatlas"
version = "~> 2.1"
}
}
}
37 changes: 35 additions & 2 deletions internal/service/streamprivatelinkendpoint/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const (
VendorConfluent = "CONFLUENT"
VendorMSK = "MSK"
VendorS3 = "S3"
ProviderGCP = "GCP"
)

func NewTFModel(ctx context.Context, projectID string, apiResp *admin.StreamsPrivateLinkConnection) (*TFModel, diag.Diagnostics) {
Expand All @@ -39,15 +40,37 @@ func NewTFModel(ctx context.Context, projectID string, apiResp *admin.StreamsPri
}
result.DnsSubDomain = subdomain

serviceAttachmentUris, diagsServiceAttachment := types.ListValueFrom(ctx, types.StringType, apiResp.GetGcpServiceAttachmentUris())
if diagsServiceAttachment.HasError() {
return nil, diagsServiceAttachment
}
result.ServiceAttachmentUris = serviceAttachmentUris

return result, nil
}

func NewAtlasReq(ctx context.Context, plan *TFModel) (*admin.StreamsPrivateLinkConnection, diag.Diagnostics) {
diags := diag.Diagnostics{}

if plan.Vendor.ValueString() == VendorConfluent {
if plan.ServiceEndpointId.IsNull() {
diags.AddError(fmt.Sprintf("service_endpoint_id is required for vendor %s", VendorConfluent), "")
provider := plan.Provider.ValueString()

// Validate that exactly one of service_endpoint_id or service_attachment_uris is provided
hasServiceEndpointID := !plan.ServiceEndpointId.IsNull() && plan.ServiceEndpointId.ValueString() != ""
hasServiceAttachmentUris := !plan.ServiceAttachmentUris.IsNull() && len(plan.ServiceAttachmentUris.Elements()) > 0

if !hasServiceEndpointID && !hasServiceAttachmentUris {
diags.AddError("Either service_endpoint_id or service_attachment_uris must be provided for CONFLUENT vendor", "")
}
if hasServiceEndpointID && hasServiceAttachmentUris {
diags.AddError("Only one of service_endpoint_id or service_attachment_uris can be provided", "")
}

if provider == ProviderGCP && !hasServiceAttachmentUris {
diags.AddError(fmt.Sprintf("service_attachment_uris is required for provider %s with vendor %s", ProviderGCP, VendorConfluent), "")
}
if provider != ProviderGCP && !hasServiceEndpointID {
diags.AddError(fmt.Sprintf("service_endpoint_id is required for provider %s with vendor %s", provider, VendorConfluent), "")
}
if plan.DnsDomain.IsNull() {
diags.AddError(fmt.Sprintf("dns_domain is required for vendor %s", VendorConfluent), "")
Expand Down Expand Up @@ -97,6 +120,16 @@ func NewAtlasReq(ctx context.Context, plan *TFModel) (*admin.StreamsPrivateLinkC
}
result.DnsSubDomain = &dnsSubdomains
}

if !plan.ServiceAttachmentUris.IsNull() {
var serviceAttachmentUris []string
diags := plan.ServiceAttachmentUris.ElementsAs(ctx, &serviceAttachmentUris, false)
if diags.HasError() {
return nil, diags
}
result.GcpServiceAttachmentUris = &serviceAttachmentUris
}

return result, nil
}

Expand Down
Loading