Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
76a9fac
Add field to resource
marcabreracast Apr 1, 2026
b3559ce
Add functionality to read and import
marcabreracast Apr 1, 2026
fcbf3fa
Add field to singular data source
marcabreracast Apr 1, 2026
deee4f9
Add field to plural data source
marcabreracast Apr 1, 2026
c391d97
Add acceptance tests
marcabreracast Apr 1, 2026
ebbb7e5
Update nil check
marcabreracast Apr 1, 2026
de1e4ed
Add changelog
marcabreracast Apr 1, 2026
ce9eb6f
Add fields to resource and data sources docs
marcabreracast Apr 7, 2026
50e5ddc
Add field for test
marcabreracast Apr 7, 2026
d7635ec
Fix typo in docs
marcabreracast Apr 7, 2026
0c7f891
Address doc comments
marcabreracast Apr 8, 2026
a435f94
Add acceptance test for private endpoint field in Data Federation
marcabreracast Apr 8, 2026
d0bc750
Update test so it creates VPC from scratch and avoids CI conflict
marcabreracast Apr 8, 2026
782f39e
Remove additional fields to avoid permission issue
marcabreracast Apr 8, 2026
3ca2e0c
Increase waiting time to avoid flakiness
marcabreracast Apr 9, 2026
7bda453
Move test above internal functions
marcabreracast Apr 9, 2026
7f39bec
Remove specific aws provider declaration from test
marcabreracast Apr 9, 2026
46b452b
Add comment clarifying waiting behaviour
marcabreracast Apr 9, 2026
2f36c2d
Add note to docs to clarify sleep behaviour
marcabreracast Apr 9, 2026
76d38cc
Rephrase note
marcabreracast Apr 9, 2026
ab1c745
Add example
marcabreracast Apr 9, 2026
317a5d2
Add more outputs
marcabreracast Apr 10, 2026
9d63c9e
Clarify AWS/Atlas regions in var description
marcabreracast Apr 10, 2026
172a7f2
Remove base url
marcabreracast Apr 10, 2026
ca40685
Fix typo in output
marcabreracast Apr 10, 2026
0da4f9e
Add default values for vars
marcabreracast Apr 10, 2026
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
11 changes: 11 additions & 0 deletions .changelog/4358.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
```release-note:enhancement
Comment thread
marcabreracast marked this conversation as resolved.
resource/mongodbatlas_federated_database_instance: Adds `private_endpoint_hostnames` attribute
```

```release-note:enhancement
data-source/mongodbatlas_federated_database_instance: Adds `private_endpoint_hostnames` attribute
```

```release-note:enhancement
data-source/mongodbatlas_federated_database_instances: Adds `private_endpoint_hostnames` attribute
```
3 changes: 3 additions & 0 deletions docs/data-sources/federated_database_instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ In addition to all arguments above, the following attributes are exported:

* `id` - The Terraform's unique identifier used internally for state management.
* `hostnames` - The list of hostnames assigned to the Federated Database Instance. Each string in the array is a hostname assigned to the Federated Database Instance.
* `private_endpoint_hostnames` - The list of private endpoint hostnames assigned to the Federated Database Instance.
Comment thread
marcabreracast marked this conversation as resolved.
* `private_endpoint_hostnames.#.hostname` - Human-readable label that identifies the host.
* `private_endpoint_hostnames.#.private_endpoint` - Human-readable label that identifies the private endpoint.
* `state` - Current state of the Federated Database Instance:
* `ACTIVE` - The Federated Database Instance is active and verified. You can query the data stores associated with the Federated Database Instance.
* `DELETED` - The Federated Database Instance was deleted.
Expand Down
3 changes: 3 additions & 0 deletions docs/data-sources/federated_database_instances.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ In addition to all arguments above, the following attributes are exported:

* `id` - The Terraform's unique identifier used internally for state management.
* `hostnames` - The list of hostnames assigned to the Federated Database Instance. Each string in the array is a hostname assigned to the Federated Database Instance.
* `private_endpoint_hostnames` - The list of private endpoint hostnames assigned to the Federated Database Instance.
* `private_endpoint_hostnames.#.hostname` - Human-readable label that identifies the host.
* `private_endpoint_hostnames.#.private_endpoint` - Human-readable label that identifies the private endpoint.
* `state` - Current state of the Federated Database Instance:
* `ACTIVE` - The Federated Database Instance is active and verified. You can query the data stores associated with the Federated Database Instance.
* `DELETED` - The Federated Database Instance was deleted.
Expand Down
3 changes: 3 additions & 0 deletions docs/resources/federated_database_instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ In addition to all arguments above, the following attributes are exported:

* `id` - The Terraform's unique identifier used internally for state management.
* `hostnames` - The list of hostnames assigned to the Federated Database Instance. Each string in the array is a hostname assigned to the Federated Database Instance.
* `private_endpoint_hostnames` - The list of private endpoint hostnames assigned to the Federated Database Instance.
* `private_endpoint_hostnames.#.hostname` - Human-readable label that identifies the host.
* `private_endpoint_hostnames.#.private_endpoint` - Human-readable label that identifies the private endpoint.
* `state` - Current state of the Federated Database Instance:
* `ACTIVE` - The Federated Database Instance is active and verified. You can query the data stores associated with the Federated Database Instance.
* `DELETED` - The Federated Database Instance was deleted.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,22 @@ func DataSource() *schema.Resource {
Type: schema.TypeString,
},
},
"private_endpoint_hostnames": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"hostname": {
Type: schema.TypeString,
Computed: true,
},
"private_endpoint": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"cloud_provider_config": cloudProviderConfig(true),
"data_process_region": {
Type: schema.TypeList,
Expand Down Expand Up @@ -320,6 +336,10 @@ func dataSourceMongoDBAtlasFederatedDatabaseInstanceRead(ctx context.Context, d
return diag.FromErr(fmt.Errorf(errorFederatedDatabaseInstanceSetting, "hostnames", name, err))
}

if err := d.Set("private_endpoint_hostnames", flattenPrivateEndpointHostnames(dataFederationInstance.GetPrivateEndpointHostnames())); err != nil {
Comment thread
marcabreracast marked this conversation as resolved.
return diag.FromErr(fmt.Errorf(errorFederatedDatabaseInstanceSetting, "private_endpoint_hostnames", name, err))
}

d.SetId(conversion.EncodeStateID(map[string]string{
"project_id": projectID,
"name": dataFederationInstance.GetName(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestAccFederatedDatabaseInstanceDS_s3Bucket(t *testing.T) {
checkAttributes(&federatedInstance, name),
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
resource.TestCheckResourceAttr(resourceName, "name", name),
resource.TestCheckResourceAttr(resourceName, "private_endpoint_hostnames.#", "0"),
),
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@ func PluralDataSource() *schema.Resource {
Type: schema.TypeString,
},
},
"private_endpoint_hostnames": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"hostname": {
Type: schema.TypeString,
Computed: true,
},
"private_endpoint": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"cloud_provider_config": cloudProviderConfig(true),
"data_process_region": {
Type: schema.TypeList,
Expand Down Expand Up @@ -100,14 +116,15 @@ func flattenFederatedDatabaseInstances(d *schema.ResourceData, projectID string,

for i := range federatedDatabaseInstances {
federatedDatabaseInstancesMap[i] = map[string]any{
"project_id": projectID,
"name": federatedDatabaseInstances[i].GetName(),
"state": federatedDatabaseInstances[i].GetState(),
"hostnames": federatedDatabaseInstances[i].GetHostnames(),
"cloud_provider_config": flattenCloudProviderConfig(d, federatedDatabaseInstances[i].CloudProviderConfig),
"data_process_region": flattenDataProcessRegion(federatedDatabaseInstances[i].DataProcessRegion),
"storage_databases": flattenDataFederationDatabase(federatedDatabaseInstances[i].Storage.GetDatabases()),
"storage_stores": flattenDataFederationStores(federatedDatabaseInstances[i].Storage.GetStores()),
"project_id": projectID,
"name": federatedDatabaseInstances[i].GetName(),
"state": federatedDatabaseInstances[i].GetState(),
"hostnames": federatedDatabaseInstances[i].GetHostnames(),
"cloud_provider_config": flattenCloudProviderConfig(d, federatedDatabaseInstances[i].CloudProviderConfig),
"data_process_region": flattenDataProcessRegion(federatedDatabaseInstances[i].DataProcessRegion),
"storage_databases": flattenDataFederationDatabase(federatedDatabaseInstances[i].Storage.GetDatabases()),
"storage_stores": flattenDataFederationStores(federatedDatabaseInstances[i].Storage.GetStores()),
"private_endpoint_hostnames": flattenPrivateEndpointHostnames(federatedDatabaseInstances[i].GetPrivateEndpointHostnames()),
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func TestAccFederatedDatabaseInstanceDSPlural_basic(t *testing.T) {
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(resourceName, "project_id"),
resource.TestCheckResourceAttrSet(resourceName, "results.#"),
resource.TestCheckResourceAttr(resourceName, "results.0.private_endpoint_hostnames.#", "0"),
),
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ func Resource() *schema.Resource {
Type: schema.TypeString,
},
},
"private_endpoint_hostnames": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"hostname": {
Type: schema.TypeString,
Computed: true,
},
"private_endpoint": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
Comment thread
marcabreracast marked this conversation as resolved.
Comment thread
marcabreracast marked this conversation as resolved.
// Optional-only behavior from the API, but keeping O+C to avoid behavior changes.
"cloud_provider_config": cloudProviderConfig(false),
"data_process_region": {
Expand Down Expand Up @@ -397,6 +413,10 @@ func resourceRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Di
return diag.FromErr(fmt.Errorf(errorFederatedDatabaseInstanceSetting, "hostnames", name, err))
}

if err := d.Set("private_endpoint_hostnames", flattenPrivateEndpointHostnames(dataFederationInstance.GetPrivateEndpointHostnames())); err != nil {
return diag.FromErr(fmt.Errorf(errorFederatedDatabaseInstanceSetting, "private_endpoint_hostnames", name, err))
}

d.SetId(conversion.EncodeStateID(map[string]string{
"project_id": projectID,
"name": name,
Expand Down Expand Up @@ -514,6 +534,10 @@ func resourceImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*s
return nil, fmt.Errorf(errorFederatedDatabaseInstanceSetting, "hostnames", name, err)
}

if err := d.Set("private_endpoint_hostnames", flattenPrivateEndpointHostnames(dataFederationInstance.GetPrivateEndpointHostnames())); err != nil {
return nil, fmt.Errorf(errorFederatedDatabaseInstanceSetting, "private_endpoint_hostnames", name, err)
}

d.SetId(conversion.EncodeStateID(map[string]string{
"project_id": projectID,
"name": *dataFederationInstance.Name,
Expand Down Expand Up @@ -863,6 +887,17 @@ func flattenDataFederationStores(stores []admin.DataLakeStoreSettings) []map[str
return store
}

func flattenPrivateEndpointHostnames(privateEndpointHostnames []admin.PrivateEndpointHostname) []map[string]any {
result := make([]map[string]any, len(privateEndpointHostnames))
for i, h := range privateEndpointHostnames {
result[i] = map[string]any{
"hostname": h.GetHostname(),
"private_endpoint": h.GetPrivateEndpoint(),
}
}
return result
}

func newReadPreferenceField(atlasReadPreference *admin.DataLakeAtlasStoreReadPreference) []map[string]any {
if atlasReadPreference == nil {
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"maps"
"os"
"testing"
"time"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
Expand All @@ -31,6 +32,7 @@ func TestAccFederatedDatabaseInstance_basic(t *testing.T) {
"storage_stores.0.read_preference.0.tag_sets.#": "2",
"storage_stores.0.read_preference.0.tag_sets.0.tags.#": "2",
"storage_databases.0.collections.0.data_sources.0.database": "sample_airbnb",
"private_endpoint_hostnames.#": "0",
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Do we have any test where this is set?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Agree, first double check on which scenario it is populated and from there see feasibility of capturing within a test

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added a test in a435f94 to fully create a private endpoint from scratch. Note that because the creation takes some time, I had to take a similar approach to what we're doing in encryptionatrest resource test, where we wait for the value to be populated.

}
setChecks := []string{"project_id", "storage_stores.0.read_preference.0.tag_sets.#"}
firstStepChecks := acc.AddAttrChecks(resourceName, nil, valueChecks)
Expand Down Expand Up @@ -595,6 +597,92 @@ data "mongodbatlas_federated_database_instance" "test" {
`, federatedInstanceName, projectName, orgID)
}

func TestAccFederatedDatabaseInstance_withPrivateEndpoint(t *testing.T) {
Comment thread
EspenAlbert marked this conversation as resolved.
Outdated
var (
Comment thread
EspenAlbert marked this conversation as resolved.
Outdated
projectID = acc.ProjectIDExecution(t)
name = acc.RandomName()
)

resource.Test(t, resource.TestCase{
PreCheck: func() { acc.PreCheckBasic(t); acc.PreCheckAwsEnvBasic(t) },
ExternalProviders: acc.ExternalProvidersOnlyAWS(),
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
CheckDestroy: acc.CheckDestroyFederatedDatabaseInstance,
Steps: []resource.TestStep{
{
Config: configWithPrivateEndpoint(projectID, name),
},
{
PreConfig: waitForStatusUpdate,
Comment thread
EspenAlbert marked this conversation as resolved.
Outdated
RefreshState: true,
Comment thread
EspenAlbert marked this conversation as resolved.
Outdated
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "private_endpoint_hostnames.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "private_endpoint_hostnames.0.hostname"),
resource.TestCheckResourceAttrSet(resourceName, "private_endpoint_hostnames.0.private_endpoint"),
),
},
},
})
}

func waitForStatusUpdate() {
time.Sleep(2 * time.Minute)
}

func configWithPrivateEndpoint(projectID, name string) string {
return fmt.Sprintf(`
provider "aws" {
Comment thread
EspenAlbert marked this conversation as resolved.
Outdated
region = "us-east-1"
}

resource "aws_vpc" "test" {
Comment thread
EspenAlbert marked this conversation as resolved.
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
}

resource "aws_subnet" "test" {
vpc_id = aws_vpc.test.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
}

data "aws_security_group" "default" {
name = "default"
vpc_id = aws_vpc.test.id
}

resource "aws_vpc_endpoint" "test" {
vpc_id = aws_vpc.test.id
service_name = "com.amazonaws.vpce.us-east-1.vpce-svc-0a7247db33497082e"
vpc_endpoint_type = "Interface"
subnet_ids = [aws_subnet.test.id]
security_group_ids = [data.aws_security_group.default.id]
}

resource "mongodbatlas_privatelink_endpoint_service_data_federation_online_archive" "test" {
project_id = %[1]q
endpoint_id = aws_vpc_endpoint.test.id
provider_name = "AWS"
comment = "Terraform Acceptance Test"
customer_endpoint_dns_name = aws_vpc_endpoint.test.dns_entry[0].dns_name
region = "US_EAST_1"
}

resource "mongodbatlas_federated_database_instance" "test" {
project_id = %[1]q
name = %[2]q

data_process_region {
cloud_provider = "AWS"
region = "VIRGINIA_USA"
}

depends_on = [mongodbatlas_privatelink_endpoint_service_data_federation_online_archive.test]
}
`, projectID, name)
}

func configFirstStepsUpdate(federatedInstanceName, projectName, orgID string) string {
return fmt.Sprintf(`

Expand Down