Skip to content

feat: Adds encryption_at_rest_provider to mongodbatlas_search_deployment resource and data source #3152

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Mar 18, 2025
7 changes: 7 additions & 0 deletions .changelog/3152.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```release-note:enhancement
resource/mongodbatlas_search_deployment: Adds `encryption_at_rest_provider` computed attribute
```

```release-note:enhancement
data-source/mongodbatlas_search_deployment: Adds `encryption_at_rest_provider` computed attribute
```
1 change: 1 addition & 0 deletions docs/data-sources/search_deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ output "mongodbatlas_search_deployment_id" {

### Read-Only

- `encryption_at_rest_provider` (String) Cloud service provider that manages your customer keys to provide an additional layer of Encryption At Rest for the cluster.
- `id` (String) Unique 24-hexadecimal digit string that identifies the search deployment.
- `specs` (Attributes List) List of settings that configure the search nodes for your cluster. This list is currently limited to defining a single element. (see [below for nested schema](#nestedatt--specs))
- `state_name` (String) Human-readable label that indicates the current operating condition of this search deployment.
Expand Down
1 change: 1 addition & 0 deletions docs/resources/search_deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ output "mongodbatlas_search_deployment_id" {

### Read-Only

- `encryption_at_rest_provider` (String) Cloud service provider that manages your customer keys to provide an additional layer of Encryption At Rest for the cluster.
- `id` (String) Unique 24-hexadecimal digit string that identifies the search deployment.
- `state_name` (String) Human-readable label that indicates the current operating condition of this search deployment.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ func testAccAdvancedClusterFlexUpgrade(t *testing.T, instanceSize string, includ
}
if includeDedicated {
steps = append(steps, resource.TestStep{
Config: acc.ConvertAdvancedClusterToPreviewProviderV2(t, true, configBasicDedicated(projectID, clusterName, defaultZoneName)),
Config: acc.ConvertAdvancedClusterToPreviewProviderV2(t, true, acc.ConfigBasicDedicated(projectID, clusterName, defaultZoneName)),
Check: checksBasicDedicated(projectID, clusterName),
})
}
Expand Down Expand Up @@ -178,7 +178,7 @@ func TestAccMockableAdvancedCluster_tenantUpgrade(t *testing.T) {
Check: checkTenant(true, projectID, clusterName),
},
{
Config: acc.ConvertAdvancedClusterToPreviewProviderV2(t, true, configBasicDedicated(projectID, clusterName, defaultZoneName)),
Config: acc.ConvertAdvancedClusterToPreviewProviderV2(t, true, acc.ConfigBasicDedicated(projectID, clusterName, defaultZoneName)),
Check: checksBasicDedicated(projectID, clusterName),
},
acc.TestStepImportCluster(resourceName),
Expand Down Expand Up @@ -1664,33 +1664,6 @@ func checkTenant(isAcc bool, projectID, name string) resource.TestCheckFunc {
pluralChecks...)
}

func configBasicDedicated(projectID, name, zoneName string) string {
zoneNameLine := ""
if zoneName != "" {
zoneNameLine = fmt.Sprintf("zone_name = %q", zoneName)
}
return fmt.Sprintf(`
resource "mongodbatlas_advanced_cluster" "test" {
project_id = %[1]q
name = %[2]q
cluster_type = "REPLICASET"

replication_specs {
region_configs {
priority = 7
provider_name = "AWS"
region_name = "US_EAST_1"
electable_specs {
node_count = 3
instance_size = "M10"
}
}
%[3]s
}
}
`, projectID, name, zoneNameLine) + dataSourcesTFNewSchema
}

func checksBasicDedicated(projectID, name string) resource.TestCheckFunc {
originalChecks := checkTenant(true, projectID, name)
checkMap := map[string]string{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func TestMigEncryptionAtRest_basicAWS(t *testing.T) {
}
useDatasource = mig.IsProviderVersionAtLeast("1.19.0") // data source introduced in this version
useRequirePrivateNetworking = mig.IsProviderVersionAtLeast("1.28.0") // require_private_networking introduced in this version
useEnabledForSearchNodes = mig.IsProviderVersionAtLeast("1.30.0") // enabled_for_search_nodes introduced in this version
useEnabledForSearchNodes = mig.IsProviderVersionAtLeast("1.30.0") // TODO: confirm version enabled_for_search_nodes introduced in this version
)

resource.Test(t, resource.TestCase{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ func (d *searchDeploymentDS) Read(ctx context.Context, req datasource.ReadReques
return
}

connV2 := d.Client.AtlasV2
// TODO: update before merging to master: connV2 := d.Client.AtlasV2
connV2 := d.Client.AtlasPreview
projectID := searchDeploymentConfig.ProjectID.ValueString()
clusterName := searchDeploymentConfig.ClusterName.ValueString()
deploymentResp, _, err := connV2.AtlasSearchApi.GetAtlasSearchDeployment(ctx, projectID, clusterName).Execute()
Expand All @@ -56,10 +57,11 @@ func (d *searchDeploymentDS) Read(ctx context.Context, req datasource.ReadReques

func convertToDSModel(inputModel *TFSearchDeploymentRSModel) TFSearchDeploymentDSModel {
return TFSearchDeploymentDSModel{
ID: inputModel.ID,
ClusterName: inputModel.ClusterName,
ProjectID: inputModel.ProjectID,
Specs: inputModel.Specs,
StateName: inputModel.StateName,
ID: inputModel.ID,
ClusterName: inputModel.ClusterName,
ProjectID: inputModel.ProjectID,
Specs: inputModel.Specs,
StateName: inputModel.StateName,
EncryptionAtRestProvider: inputModel.EncryptionAtRestProvider,
}
}
14 changes: 14 additions & 0 deletions internal/service/searchdeployment/data_source_schema.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package searchdeployment

import (
"github.com/hashicorp/terraform-plugin-framework/types"
)

type TFSearchDeploymentDSModel struct {
Copy link
Member

Choose a reason for hiding this comment

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

nit: You can consider refactoring to use DataSourceSchemaFromResource

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But DataSourceSchemaFromResource is for the resource schema, not the TF models? I tried to use TFSearchDeploymentRSModel everywhere, but the resource model has the timeout attribute, and it should not be in the data source

ID types.String `tfsdk:"id"`
ClusterName types.String `tfsdk:"cluster_name"`
ProjectID types.String `tfsdk:"project_id"`
Specs types.List `tfsdk:"specs"`
StateName types.String `tfsdk:"state_name"`
EncryptionAtRestProvider types.String `tfsdk:"encryption_at_rest_provider"`
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"go.mongodb.org/atlas-sdk/v20250219001/admin"

// TODO: update before merging to master: "go.mongodb.org/atlas-sdk/v20250219001/admin"
"github.com/mongodb/atlas-sdk-go/admin"
)

func NewSearchDeploymentReq(ctx context.Context, searchDeploymentPlan *TFSearchDeploymentRSModel) admin.ApiSearchDeploymentRequest {
Expand All @@ -27,10 +29,11 @@ func NewSearchDeploymentReq(ctx context.Context, searchDeploymentPlan *TFSearchD

func NewTFSearchDeployment(ctx context.Context, clusterName string, deployResp *admin.ApiSearchDeploymentResponse, timeout *timeouts.Value, allowMultipleSpecs bool) (*TFSearchDeploymentRSModel, diag.Diagnostics) {
result := TFSearchDeploymentRSModel{
ID: types.StringPointerValue(deployResp.Id),
ClusterName: types.StringValue(clusterName),
ProjectID: types.StringPointerValue(deployResp.GroupId),
StateName: types.StringPointerValue(deployResp.StateName),
ID: types.StringPointerValue(deployResp.Id),
ClusterName: types.StringValue(clusterName),
ProjectID: types.StringPointerValue(deployResp.GroupId),
StateName: types.StringPointerValue(deployResp.StateName),
EncryptionAtRestProvider: types.StringPointerValue(deployResp.EncryptionAtRestProvider),
}

if timeout != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/service/searchdeployment"
"go.mongodb.org/atlas-sdk/v20250219001/admin"

// TODO: update before merging to master: "go.mongodb.org/atlas-sdk/v20250219001/admin"
"github.com/mongodb/atlas-sdk-go/admin"
)

type sdkToTFModelTestCase struct {
Expand All @@ -24,6 +26,7 @@ const (
clusterName = "Cluster0"
instanceSize = "S20_HIGHCPU_NVME"
nodeCount = 2
earProvider = "AWS"
)

func TestSearchDeploymentSDKToTFModel(t *testing.T) {
Expand All @@ -41,13 +44,15 @@ func TestSearchDeploymentSDKToTFModel(t *testing.T) {
NodeCount: nodeCount,
},
},
EncryptionAtRestProvider: admin.PtrString(earProvider),
},
expectedTFModel: &searchdeployment.TFSearchDeploymentRSModel{
ID: types.StringValue(dummyDeploymentID),
ClusterName: types.StringValue(clusterName),
ProjectID: types.StringValue(dummyProjectID),
StateName: types.StringValue(stateName),
Specs: tfSpecsList(t, instanceSize, nodeCount),
ID: types.StringValue(dummyDeploymentID),
ClusterName: types.StringValue(clusterName),
ProjectID: types.StringValue(dummyProjectID),
StateName: types.StringValue(stateName),
Specs: tfSpecsList(t, instanceSize, nodeCount),
EncryptionAtRestProvider: types.StringValue(earProvider),
},
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ func (r *searchDeploymentRS) Create(ctx context.Context, req resource.CreateRequ
return
}

connV2 := r.Client.AtlasV2
// TODO: update before merging to master: connV2 := d.Client.AtlasV2
connV2 := r.Client.AtlasPreview
projectID := searchDeploymentPlan.ProjectID.ValueString()
clusterName := searchDeploymentPlan.ClusterName.ValueString()
searchDeploymentReq := NewSearchDeploymentReq(ctx, &searchDeploymentPlan)
Expand Down Expand Up @@ -91,7 +92,8 @@ func (r *searchDeploymentRS) Read(ctx context.Context, req resource.ReadRequest,
return
}

connV2 := r.Client.AtlasV2
// TODO: update before merging to master: connV2 := d.Client.AtlasV2
connV2 := r.Client.AtlasPreview
projectID := searchDeploymentPlan.ProjectID.ValueString()
clusterName := searchDeploymentPlan.ClusterName.ValueString()
deploymentResp, getResp, err := connV2.AtlasSearchApi.GetAtlasSearchDeployment(ctx, projectID, clusterName).Execute()
Expand Down Expand Up @@ -119,7 +121,8 @@ func (r *searchDeploymentRS) Update(ctx context.Context, req resource.UpdateRequ
return
}

connV2 := r.Client.AtlasV2
// TODO: update before merging to master: connV2 := d.Client.AtlasV2
connV2 := r.Client.AtlasPreview
projectID := searchDeploymentPlan.ProjectID.ValueString()
clusterName := searchDeploymentPlan.ClusterName.ValueString()
searchDeploymentReq := NewSearchDeploymentReq(ctx, &searchDeploymentPlan)
Expand Down Expand Up @@ -154,7 +157,8 @@ func (r *searchDeploymentRS) Delete(ctx context.Context, req resource.DeleteRequ
return
}

connV2 := r.Client.AtlasV2
// TODO: update before merging to master: connV2 := d.Client.AtlasV2
connV2 := r.Client.AtlasPreview
projectID := searchDeploymentState.ProjectID.ValueString()
clusterName := searchDeploymentState.ClusterName.ValueString()
if _, _, err := connV2.AtlasSearchApi.DeleteAtlasSearchDeployment(ctx, projectID, clusterName).Execute(); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@ import (
func TestMigSearchDeployment_basic(t *testing.T) {
var (
resourceName = "mongodbatlas_search_deployment.test"
orgID = os.Getenv("MONGODB_ATLAS_ORG_ID")
projectName = acc.RandomProjectName()
projectID = os.Getenv("MONGODB_ATLAS_PROJECT_EAR_PE_AWS_ID") // to use RequirePrivateNetworking, Atlas Project is required to have FF enabled
clusterName = acc.RandomClusterName()
instanceSize = "S30_HIGHCPU_NVME"
searchNodeCount = 3
config = configBasic(orgID, projectName, clusterName, instanceSize, searchNodeCount)
config = configBasic(projectID, clusterName, instanceSize, searchNodeCount)
)
mig.SkipIfVersionBelow(t, "1.13.0")
mig.SkipIfVersionBelow(t, "1.30.0") // TODO: confirm version enabled_for_search_nodes introduced in this version
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { mig.PreCheckBasic(t) },
CheckDestroy: checkDestroy,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,17 +63,22 @@ func ResourceSchema(ctx context.Context) schema.Schema {
Update: true,
Delete: true,
}),
"encryption_at_rest_provider": schema.StringAttribute{
Computed: true,
MarkdownDescription: "Cloud service provider that manages your customer keys to provide an additional layer of Encryption At Rest for the cluster.",
},
},
}
}

type TFSearchDeploymentRSModel struct {
ID types.String `tfsdk:"id"`
ClusterName types.String `tfsdk:"cluster_name"`
ProjectID types.String `tfsdk:"project_id"`
Specs types.List `tfsdk:"specs"`
StateName types.String `tfsdk:"state_name"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
ID types.String `tfsdk:"id"`
ClusterName types.String `tfsdk:"cluster_name"`
ProjectID types.String `tfsdk:"project_id"`
Specs types.List `tfsdk:"specs"`
StateName types.String `tfsdk:"state_name"`
Timeouts timeouts.Value `tfsdk:"timeouts"`
EncryptionAtRestProvider types.String `tfsdk:"encryption_at_rest_provider"`
}

type TFSearchNodeSpecModel struct {
Expand Down
Loading
Loading