diff --git a/examples/mongodbatlas_stream_instance/main.tf b/examples/mongodbatlas_stream_instance/main.tf index 3d2f9087ef..03926bea81 100644 --- a/examples/mongodbatlas_stream_instance/main.tf +++ b/examples/mongodbatlas_stream_instance/main.tf @@ -10,4 +10,7 @@ resource "mongodbatlas_stream_instance" "example" { region = "VIRGINIA_USA" cloud_provider = "AWS" } -} \ No newline at end of file + stream_config = { + tier = "SP30" + } +} diff --git a/internal/service/streaminstance/data_source_stream_instance.go b/internal/service/streaminstance/data_source_stream_instance.go index 277f8fe4e4..a5ff091f15 100644 --- a/internal/service/streaminstance/data_source_stream_instance.go +++ b/internal/service/streaminstance/data_source_stream_instance.go @@ -60,6 +60,14 @@ func DSAttributes(withArguments bool) map[string]schema.Attribute { ElementType: types.StringType, Computed: true, }, + "stream_config": schema.SingleNestedAttribute{ + Computed: true, + Attributes: map[string]schema.Attribute{ + "tier": schema.StringAttribute{ + Computed: true, + }, + }, + }, } } diff --git a/internal/service/streaminstance/data_source_stream_instance_test.go b/internal/service/streaminstance/data_source_stream_instance_test.go index 8948e62dec..40e57618f7 100644 --- a/internal/service/streaminstance/data_source_stream_instance_test.go +++ b/internal/service/streaminstance/data_source_stream_instance_test.go @@ -24,7 +24,10 @@ func TestAccStreamDSStreamInstance_basic(t *testing.T) { Steps: []resource.TestStep{ { Config: streamInstanceDataSourceConfig(orgID, projectName, instanceName, region, cloudProvider), - Check: streamInstanceAttributeChecks(dataSourceName, orgID, projectName, instanceName, region, cloudProvider), + Check: resource.ComposeTestCheckFunc( + streamInstanceAttributeChecks(dataSourceName, instanceName, region, cloudProvider), + resource.TestCheckResourceAttr(dataSourceName, "stream_config.tier", "SP30"), + ), }, }, }) diff --git a/internal/service/streaminstance/model_stream_instance.go b/internal/service/streaminstance/model_stream_instance.go index aff5afa185..55725bb4c5 100644 --- a/internal/service/streaminstance/model_stream_instance.go +++ b/internal/service/streaminstance/model_stream_instance.go @@ -16,14 +16,24 @@ func NewStreamInstanceCreateReq(ctx context.Context, plan *TFStreamInstanceModel if diags := plan.DataProcessRegion.As(ctx, dataProcessRegion, basetypes.ObjectAsOptions{}); diags.HasError() { return nil, diags } - return &admin.StreamsTenant{ + streamTenant := &admin.StreamsTenant{ GroupId: plan.ProjectID.ValueStringPointer(), Name: plan.InstanceName.ValueStringPointer(), DataProcessRegion: &admin.StreamsDataProcessRegion{ CloudProvider: dataProcessRegion.CloudProvider.ValueString(), Region: dataProcessRegion.Region.ValueString(), }, - }, nil + } + if !plan.StreamConfig.IsNull() && !plan.StreamConfig.IsUnknown() { + streamConfig := new(TFInstanceStreamConfigSpecModel) + if diags := plan.StreamConfig.As(ctx, streamConfig, basetypes.ObjectAsOptions{}); diags.HasError() { + return nil, diags + } + streamTenant.StreamConfig = &admin.StreamConfig{ + Tier: streamConfig.Tier.ValueStringPointer(), + } + } + return streamTenant, nil } func NewStreamInstanceUpdateReq(ctx context.Context, plan *TFStreamInstanceModel) (*admin.StreamsDataProcessRegion, diag.Diagnostics) { @@ -49,6 +59,15 @@ func NewTFStreamInstance(ctx context.Context, apiResp *admin.StreamsTenant) (*TF dataProcessRegion = returnedProcessRegion diags.Append(diagsProcessRegion...) } + var streamConfig = types.ObjectNull(StreamConfigObjectType.AttrTypes) + apiStreamConfig := apiResp.StreamConfig + if apiStreamConfig != nil && apiStreamConfig.Tier != nil { + returnedStreamConfig, diagsStreamConfig := types.ObjectValueFrom(ctx, StreamConfigObjectType.AttrTypes, TFInstanceStreamConfigSpecModel{ + Tier: types.StringPointerValue(apiStreamConfig.Tier), + }) + streamConfig = returnedStreamConfig + diags.Append(diagsStreamConfig...) + } if diags.HasError() { return nil, diags } @@ -58,6 +77,7 @@ func NewTFStreamInstance(ctx context.Context, apiResp *admin.StreamsTenant) (*TF InstanceName: types.StringPointerValue(apiResp.Name), ProjectID: types.StringPointerValue(apiResp.GroupId), DataProcessRegion: dataProcessRegion, + StreamConfig: streamConfig, Hostnames: hostnames, }, nil } diff --git a/internal/service/streaminstance/model_stream_instance_test.go b/internal/service/streaminstance/model_stream_instance_test.go index b543428495..abfafc5a56 100644 --- a/internal/service/streaminstance/model_stream_instance_test.go +++ b/internal/service/streaminstance/model_stream_instance_test.go @@ -16,6 +16,7 @@ const ( cloudProvider = "AWS" region = "VIRGINIA_USA" instanceName = "InstanceName" + tier = "SP30" ) var hostnames = &[]string{"atlas-stream.virginia-usa.a.query.mongodb-dev.net"} @@ -36,6 +37,9 @@ func TestStreamInstanceSDKToTFModel(t *testing.T) { CloudProvider: cloudProvider, Region: region, }, + StreamConfig: &admin.StreamConfig{ + Tier: admin.PtrString(tier), + }, GroupId: admin.PtrString(dummyProjectID), Hostnames: hostnames, Name: admin.PtrString(instanceName), @@ -46,10 +50,11 @@ func TestStreamInstanceSDKToTFModel(t *testing.T) { ProjectID: types.StringValue(dummyProjectID), Hostnames: tfHostnamesList(t, hostnames), InstanceName: types.StringValue(instanceName), + StreamConfig: tfStreamConfigObject(t, tier), }, }, { - name: "Empty hostnames and dataProcessRegion in response", // should never happen, but verifying it is handled gracefully + name: "Empty hostnames, streamConfig and dataProcessRegion in response", // should never happen, but verifying it is handled gracefully SDKResp: &admin.StreamsTenant{ Id: admin.PtrString(dummyStreamInstanceID), GroupId: admin.PtrString(dummyProjectID), @@ -61,6 +66,7 @@ func TestStreamInstanceSDKToTFModel(t *testing.T) { ProjectID: types.StringValue(dummyProjectID), Hostnames: types.ListNull(types.StringType), InstanceName: types.StringValue(instanceName), + StreamConfig: types.ObjectNull(streaminstance.StreamConfigObjectType.AttrTypes), }, }, } @@ -100,6 +106,9 @@ func TestStreamInstancesSDKToTFModel(t *testing.T) { GroupId: admin.PtrString(dummyProjectID), Hostnames: hostnames, Name: admin.PtrString(instanceName), + StreamConfig: &admin.StreamConfig{ + Tier: admin.PtrString(tier), + }, }, }, TotalCount: admin.PtrInt(1), @@ -121,6 +130,7 @@ func TestStreamInstancesSDKToTFModel(t *testing.T) { ProjectID: types.StringValue(dummyProjectID), Hostnames: tfHostnamesList(t, hostnames), InstanceName: types.StringValue(instanceName), + StreamConfig: tfStreamConfigObject(t, tier), }, }, }, @@ -168,6 +178,26 @@ func TestStreamInstanceTFToSDKCreateModel(t *testing.T) { testCases := []tfToSDKCreateModelTestCase{ { name: "Complete TF state", + tfModel: &streaminstance.TFStreamInstanceModel{ + DataProcessRegion: tfRegionObject(t, cloudProvider, region), + ProjectID: types.StringValue(dummyProjectID), + InstanceName: types.StringValue(instanceName), + StreamConfig: tfStreamConfigObject(t, tier), + }, + expectedSDKReq: &admin.StreamsTenant{ + DataProcessRegion: &admin.StreamsDataProcessRegion{ + CloudProvider: cloudProvider, + Region: region, + }, + GroupId: admin.PtrString(dummyProjectID), + Name: admin.PtrString(instanceName), + StreamConfig: &admin.StreamConfig{ + Tier: admin.PtrString(tier), + }, + }, + }, + { + name: "TF State without StreamConfig", tfModel: &streaminstance.TFStreamInstanceModel{ DataProcessRegion: tfRegionObject(t, cloudProvider, region), ProjectID: types.StringValue(dummyProjectID), @@ -246,6 +276,17 @@ func tfRegionObject(t *testing.T, cloudProvider, region string) types.Object { return dataProcessRegion } +func tfStreamConfigObject(t *testing.T, tier string) types.Object { + t.Helper() + streamConfig, diags := types.ObjectValueFrom(context.Background(), streaminstance.StreamConfigObjectType.AttrTypes, streaminstance.TFInstanceStreamConfigSpecModel{ + Tier: types.StringValue(tier), + }) + if diags.HasError() { + t.Errorf("failed to create terraform data process region model: %s", diags.Errors()[0].Summary()) + } + return streamConfig +} + func tfHostnamesList(t *testing.T, hostnames *[]string) types.List { t.Helper() resultList, diags := types.ListValueFrom(context.Background(), types.StringType, hostnames) diff --git a/internal/service/streaminstance/resource_stream_instance.go b/internal/service/streaminstance/resource_stream_instance.go index fc8c980d5f..11f3eaf94f 100644 --- a/internal/service/streaminstance/resource_stream_instance.go +++ b/internal/service/streaminstance/resource_stream_instance.go @@ -37,6 +37,7 @@ type TFStreamInstanceModel struct { InstanceName types.String `tfsdk:"instance_name"` ProjectID types.String `tfsdk:"project_id"` DataProcessRegion types.Object `tfsdk:"data_process_region"` + StreamConfig types.Object `tfsdk:"stream_config"` Hostnames types.List `tfsdk:"hostnames"` } @@ -45,11 +46,19 @@ type TFInstanceProcessRegionSpecModel struct { Region types.String `tfsdk:"region"` } +type TFInstanceStreamConfigSpecModel struct { + Tier types.String `tfsdk:"tier"` +} + var ProcessRegionObjectType = types.ObjectType{AttrTypes: map[string]attr.Type{ "cloud_provider": types.StringType, "region": types.StringType, }} +var StreamConfigObjectType = types.ObjectType{AttrTypes: map[string]attr.Type{ + "tier": types.StringType, +}} + func (r *streamInstanceRS) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { resp.Schema = schema.Schema{ Attributes: map[string]schema.Attribute{ @@ -83,6 +92,16 @@ func (r *streamInstanceRS) Schema(ctx context.Context, req resource.SchemaReques ElementType: types.StringType, Computed: true, }, + "stream_config": schema.SingleNestedAttribute{ + Optional: true, + Computed: true, + Attributes: map[string]schema.Attribute{ + "tier": schema.StringAttribute{ + Optional: true, + Computed: true, + }, + }, + }, }, } } diff --git a/internal/service/streaminstance/resource_stream_instance_migration_test.go b/internal/service/streaminstance/resource_stream_instance_migration_test.go index 86bff01b15..079bb4500d 100644 --- a/internal/service/streaminstance/resource_stream_instance_migration_test.go +++ b/internal/service/streaminstance/resource_stream_instance_migration_test.go @@ -27,7 +27,7 @@ func TestAccMigrationStreamRSStreamInstance_basic(t *testing.T) { { ExternalProviders: mig.ExternalProviders(), Config: acc.StreamInstanceConfig(orgID, projectName, instanceName, region, cloudProvider), - Check: streamInstanceAttributeChecks(resourceName, orgID, projectName, instanceName, region, cloudProvider), + Check: streamInstanceAttributeChecks(resourceName, instanceName, region, cloudProvider), }, { ProtoV6ProviderFactories: acc.TestAccProviderV6Factories, diff --git a/internal/service/streaminstance/resource_stream_instance_test.go b/internal/service/streaminstance/resource_stream_instance_test.go index a7cad8c1aa..033c375894 100644 --- a/internal/service/streaminstance/resource_stream_instance_test.go +++ b/internal/service/streaminstance/resource_stream_instance_test.go @@ -25,7 +25,10 @@ func TestAccStreamRSStreamInstance_basic(t *testing.T) { Steps: []resource.TestStep{ { Config: acc.StreamInstanceConfig(orgID, projectName, instanceName, region, cloudProvider), // as of now there are no values that can be updated because only one region is supported - Check: streamInstanceAttributeChecks(resourceName, orgID, projectName, instanceName, region, cloudProvider), + Check: resource.ComposeTestCheckFunc( + streamInstanceAttributeChecks(resourceName, instanceName, region, cloudProvider), + resource.TestCheckResourceAttr(resourceName, "stream_config.tier", "SP30"), + ), }, { ResourceName: resourceName, @@ -37,7 +40,36 @@ func TestAccStreamRSStreamInstance_basic(t *testing.T) { }) } -func streamInstanceAttributeChecks(resourceName, orgID, projectName, instanceName, region, cloudProvider string) resource.TestCheckFunc { +func TestAccStreamRSStreamInstance_withStreamConfig(t *testing.T) { + var ( + resourceName = "mongodbatlas_stream_instance.test" + orgID = os.Getenv("MONGODB_ATLAS_ORG_ID") + projectName = acc.RandomProjectName() + instanceName = acc.RandomName() + ) + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acc.PreCheckBetaFlag(t); acc.PreCheckBasic(t) }, + ProtoV6ProviderFactories: acc.TestAccProviderV6Factories, + CheckDestroy: acc.CheckDestroyStreamInstance, + Steps: []resource.TestStep{ + { + Config: acc.StreamInstanceWithStreamConfigConfig(orgID, projectName, instanceName, region, cloudProvider), // as of now there are no values that can be updated because only one region is supported + Check: resource.ComposeTestCheckFunc( + streamInstanceAttributeChecks(resourceName, instanceName, region, cloudProvider), + resource.TestCheckResourceAttr(resourceName, "stream_config.tier", "SP30"), + ), + }, + { + ResourceName: resourceName, + ImportStateIdFunc: checkStreamInstanceImportStateIDFunc(resourceName), + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func streamInstanceAttributeChecks(resourceName, instanceName, region, cloudProvider string) resource.TestCheckFunc { resourceChecks := []resource.TestCheckFunc{ checkSearchInstanceExists(), resource.TestCheckResourceAttrSet(resourceName, "id"), diff --git a/internal/testutil/acc/stream_instance.go b/internal/testutil/acc/stream_instance.go index 1589bece46..cbb5cad72d 100644 --- a/internal/testutil/acc/stream_instance.go +++ b/internal/testutil/acc/stream_instance.go @@ -25,6 +25,27 @@ func StreamInstanceConfig(orgID, projectName, instanceName, region, cloudProvide `, orgID, projectName, instanceName, region, cloudProvider) } +func StreamInstanceWithStreamConfigConfig(orgID, projectName, instanceName, region, cloudProvider string) string { + return fmt.Sprintf(` + resource "mongodbatlas_project" "test" { + org_id = %[1]q + name = %[2]q + } + + resource "mongodbatlas_stream_instance" "test" { + project_id = mongodbatlas_project.test.id + instance_name = %[3]q + data_process_region = { + region = %[4]q + cloud_provider = %[5]q + } + stream_config = { + tier = "SP30" + } + } + `, orgID, projectName, instanceName, region, cloudProvider) +} + func CheckDestroyStreamInstance(state *terraform.State) error { if projectDestroyedErr := CheckDestroyProject(state); projectDestroyedErr != nil { return projectDestroyedErr diff --git a/website/docs/d/stream_instance.html.markdown b/website/docs/d/stream_instance.html.markdown index d62f6399da..d835f194ba 100644 --- a/website/docs/d/stream_instance.html.markdown +++ b/website/docs/d/stream_instance.html.markdown @@ -30,6 +30,7 @@ data "mongodbatlas_stream_instance" "example" { * `data_process_region` - Defines the cloud service provider and region where MongoDB Cloud performs stream processing. See [data process region](#data-process-region). * `hostnames` - List that contains the hostnames assigned to the stream instance. +* `stream_config` - Defines the configuration options for an Atlas Stream Processing Instance. See [stream config](#stream-config) ### Data Process Region @@ -37,5 +38,9 @@ data "mongodbatlas_stream_instance" "example" { * `cloud_provider` - Label that identifies the cloud service provider where MongoDB Cloud performs stream processing. The [MongoDB Atlas API](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) describes the valid values. * `region` - Name of the cloud provider region hosting Atlas Stream Processing. The [MongoDB Atlas API](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) describes the valid values. +### Stream Config + +* `tier` - Selected tier for the Stream Instance. Configures Memory / VCPU allowances. The [MongoDB Atlas API](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) describes the valid values. + To learn more, see: [MongoDB Atlas API - Stream Instance](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) Documentation. The [Terraform Provider Examples Section](https://github.com/mongodb/terraform-provider-mongodbatlas/blob/master/examples/mongodbatlas_stream_instance/atlas-streams-user-journey.md) also contains details on the overall support for Atlas Streams Processing in Terraform. diff --git a/website/docs/d/stream_instances.html.markdown b/website/docs/d/stream_instances.html.markdown index f6c68eaaec..534350b6a7 100644 --- a/website/docs/d/stream_instances.html.markdown +++ b/website/docs/d/stream_instances.html.markdown @@ -41,11 +41,16 @@ In addition to all arguments above, it also exports the following attributes: * `instance_name` - Human-readable label that identifies the stream instance. * `data_process_region` - Defines the cloud service provider and region where MongoDB Cloud performs stream processing. See [data process region](#data-process-region). * `hostnames` - List that contains the hostnames assigned to the stream instance. +* `stream_config` - Defines the configuration options for an Atlas Stream Processing Instance. See [stream config](#stream-config) ### Data Process Region * `cloud_provider` - Label that identifies the cloud service provider where MongoDB Cloud performs stream processing. The [MongoDB Atlas API](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) describes the valid values. * `region` - Name of the cloud provider region hosting Atlas Stream Processing. The [MongoDB Atlas API](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) describes the valid values. +### Stream Config + +* `tier` - Selected tier for the Stream Instance. Configures Memory / VCPU allowances. The [MongoDB Atlas API](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) describes the valid values. + To learn more, see: [MongoDB Atlas API - Stream Instance](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) Documentation. The [Terraform Provider Examples Section](https://github.com/mongodb/terraform-provider-mongodbatlas/blob/master/examples/mongodbatlas_stream_instance/atlas-streams-user-journey.md) also contains details on the overall support for Atlas Streams Processing in Terraform. diff --git a/website/docs/r/stream_instance.html.markdown b/website/docs/r/stream_instance.html.markdown index 17f4a0b51f..08d109fbe5 100644 --- a/website/docs/r/stream_instance.html.markdown +++ b/website/docs/r/stream_instance.html.markdown @@ -30,12 +30,19 @@ resource "mongodbatlas_stream_instance" "test" { * `project_id` - (Required) Unique 24-hexadecimal digit string that identifies your project. * `instance_name` - (Required) Human-readable label that identifies the stream instance. * `data_process_region` - (Required) Cloud service provider and region where MongoDB Cloud performs stream processing. See [data process region](#data-process-region). +* `stream_config` - (Optional) Configuration options for an Atlas Stream Processing Instance. See [stream config](#stream-config) + ### Data Process Region * `cloud_provider` - (Required) Label that identifies the cloud service provider where MongoDB Cloud performs stream processing. The [MongoDB Atlas API](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) describes the valid values. * `region` - (Required) Name of the cloud provider region hosting Atlas Stream Processing. The [MongoDB Atlas API](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) describes the valid values. +### Stream Config + +* `tier` - (Required) Selected tier for the Stream Instance. Configures Memory / VCPU allowances. The [MongoDB Atlas API](https://www.mongodb.com/docs/atlas/reference/api-resources-spec/#tag/Streams/operation/createStreamInstance) describes the valid values. + + ## Attributes Reference In addition to all arguments above, the following attributes are exported: