diff --git a/.changelog/43809.txt b/.changelog/43809.txt new file mode 100644 index 000000000000..a81513115f9a --- /dev/null +++ b/.changelog/43809.txt @@ -0,0 +1,7 @@ +```release-note:new-resource +aws_odb_cloud_autonomous_vm_cluster +``` + +```release-note:new-data-source +aws_odb_cloud_autonomous_vm_cluster +``` \ No newline at end of file diff --git a/.changelog/44272.txt b/.changelog/44272.txt new file mode 100644 index 000000000000..c4394c9254e1 --- /dev/null +++ b/.changelog/44272.txt @@ -0,0 +1,3 @@ +```release-note:new-data-source +aws_billing_views +``` diff --git a/.changelog/44310.txt b/.changelog/44310.txt new file mode 100644 index 000000000000..eb1f41bde34c --- /dev/null +++ b/.changelog/44310.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_sagemaker_endpoint_configuration: Fix panic when empty `async_inference_config.output_config.notification_config` block is specified +``` diff --git a/CHANGELOG.md b/CHANGELOG.md index 42d12d2d1f62..e98b16f4ba17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,15 +2,24 @@ FEATURES: +* **New Data Source:** `aws_billing_views` ([#44272](https://github.com/hashicorp/terraform-provider-aws/issues/44272)) +* **New Data Source:** `aws_odb_cloud_autonomous_vm_cluster` ([#43809](https://github.com/hashicorp/terraform-provider-aws/issues/43809)) * **New Data Source:** `aws_odb_cloud_exadata_infrastructure` ([#43650](https://github.com/hashicorp/terraform-provider-aws/issues/43650)) +* **New Data Source:** `aws_odb_network` ([#43715](https://github.com/hashicorp/terraform-provider-aws/issues/43715)) * **New Resource:** `aws_controltower_baseline` ([#42397](https://github.com/hashicorp/terraform-provider-aws/issues/42397)) +* **New Resource:** `aws_odb_cloud_autonomous_vm_cluster` ([#43809](https://github.com/hashicorp/terraform-provider-aws/issues/43809)) * **New Resource:** `aws_odb_cloud_exadata_infrastructure` ([#43650](https://github.com/hashicorp/terraform-provider-aws/issues/43650)) +* **New Resource:** `aws_odb_network` ([#43715](https://github.com/hashicorp/terraform-provider-aws/issues/43715)) ENHANCEMENTS: * resource/aws_rds_global_cluster: Remove provider-side conflict between `source_db_cluster_identifier` and `engine` arguments ([#44252](https://github.com/hashicorp/terraform-provider-aws/issues/44252)) * resource/aws_scheduler_schedule: Add `action_after_completion` argument ([#44264](https://github.com/hashicorp/terraform-provider-aws/issues/44264)) +BUG FIXES: + +* resource/aws_sagemaker_endpoint_configuration: Fix panic when empty `async_inference_config.output_config.notification_config` block is specified ([#44310](https://github.com/hashicorp/terraform-provider-aws/issues/44310)) + ## 6.13.0 (September 11, 2025) ENHANCEMENTS: diff --git a/examples/odb/autonomous_vm_cluster.tf b/examples/odb/autonomous_vm_cluster.tf new file mode 100644 index 000000000000..920237d77c56 --- /dev/null +++ b/examples/odb/autonomous_vm_cluster.tf @@ -0,0 +1,51 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# Autonomous VM Cluster with default maintenance window and minimum parameters +resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_minimum_parameters" { + cloud_exadata_infrastructure_id = "" # refer your exadata infra id + odb_network_id = "" # refer_your_odb_net_id + display_name = "Ofake-avmc-my_avmc" + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + # ids of db server. refer your exa infra. This is a manadatory fileld. Refer your cloud exadata infrastructure for db server id + db_servers = [""] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + preference = "NO_PREFERENCE" + } + +} + +# Autonomous VM Cluster with all parameters +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + description = "my first avmc" + time_zone = "UTC" + cloud_exadata_infrastructure_id = "" + odb_network_id = "" + display_name = "Ofake_my avmc" + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = ["", ""] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + days_of_week = [{ name = "MONDAY" }, { name = "TUESDAY" }] + hours_of_day = [4, 16] + lead_time_in_weeks = 3 + months = [{ name = "FEBRUARY" }, { name = "MAY" }, { name = "AUGUST" }, { name = "NOVEMBER" }] + preference = "CUSTOM_PREFERENCE" + weeks_of_month = [2, 4] + } + tags = { + "env" = "dev" + } + +} diff --git a/internal/service/acm/sweep.go b/internal/service/acm/sweep.go index d8e4fe21f51e..90d8ff84b51c 100644 --- a/internal/service/acm/sweep.go +++ b/internal/service/acm/sweep.go @@ -9,7 +9,9 @@ import ( "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/acm" + awstypes "github.com/aws/aws-sdk-go-v2/service/acm/types" "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/enum" "github.com/hashicorp/terraform-provider-aws/internal/sweep" "github.com/hashicorp/terraform-provider-aws/internal/sweep/awsv2" ) @@ -48,7 +50,12 @@ func sweepCertificates(region string) error { conn := client.ACMClient(ctx) var sweepResources []sweep.Sweepable - input := acm.ListCertificatesInput{} + input := acm.ListCertificatesInput{ + Includes: &awstypes.Filters{ + // By default, ListCertificates only returns RSA_1024 and RSA_2048 certificates + KeyTypes: enum.EnumValues[awstypes.KeyAlgorithm](), + }, + } pages := acm.NewListCertificatesPaginator(conn, &input) for pages.HasMorePages() { page, err := pages.NextPage(ctx) diff --git a/internal/service/apigateway/sweep.go b/internal/service/apigateway/sweep.go index 145b106f66b1..7445e252906d 100644 --- a/internal/service/apigateway/sweep.go +++ b/internal/service/apigateway/sweep.go @@ -305,7 +305,7 @@ func sweepDomainNames(region string) error { for _, v := range page.Items { r := resourceDomainName() d := r.Data(nil) - d.SetId(aws.ToString(v.DomainName)) + d.SetId(domainNameCreateResourceID(aws.ToString(v.DomainName), aws.ToString(v.DomainNameId))) sweepResources = append(sweepResources, sweep.NewSweepResource(r, d, client)) } diff --git a/internal/service/athena/data_catalog.go b/internal/service/athena/data_catalog.go index 2a8a35ca4aba..7824b3a24410 100644 --- a/internal/service/athena/data_catalog.go +++ b/internal/service/athena/data_catalog.go @@ -198,6 +198,9 @@ func resourceDataCatalogDelete(ctx context.Context, d *schema.ResourceData, meta if errs.IsA[*types.ResourceNotFoundException](err) { return diags } + if errs.IsAErrorMessageContains[*types.InvalidRequestException](err, "was not found") { + return diags + } if err != nil { return sdkdiag.AppendErrorf(diags, "deleting Athena Data Catalog (%s): %s", d.Id(), err) diff --git a/internal/service/billing/service_package_gen.go b/internal/service/billing/service_package_gen.go index 84aedd7d64f0..5e30758bd55f 100644 --- a/internal/service/billing/service_package_gen.go +++ b/internal/service/billing/service_package_gen.go @@ -26,6 +26,12 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*inttypes.S Name: "Service Account", Region: unique.Make(inttypes.ResourceRegionDisabled()), }, + { + Factory: newDataSourceViews, + TypeName: "aws_billing_views", + Name: "Views", + Region: unique.Make(inttypes.ResourceRegionDisabled()), + }, } } diff --git a/internal/service/billing/views_data_source.go b/internal/service/billing/views_data_source.go new file mode 100644 index 000000000000..fdc4ebe17101 --- /dev/null +++ b/internal/service/billing/views_data_source.go @@ -0,0 +1,110 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package billing + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/service/billing" + awstypes "github.com/aws/aws-sdk-go-v2/service/billing/types" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/smerr" +) + +// @FrameworkDataSource("aws_billing_views", name="Views") +func newDataSourceViews(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceViews{}, nil +} + +const ( + DSNameViews = "Views Data Source" +) + +type dataSourceViews struct { + framework.DataSourceWithModel[dataSourceViewsModel] +} + +func (d *dataSourceViews) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + "billing_view_types": schema.ListAttribute{ + CustomType: fwtypes.ListOfStringEnumType[awstypes.BillingViewType](), + Optional: true, + ElementType: types.StringType, + }, + "billing_view": framework.ResourceComputedListOfObjectsAttribute[dataSourceBillingViewModel](ctx, nil, nil), + }, + } +} + +func (d *dataSourceViews) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + conn := d.Meta().BillingClient(ctx) + + var data dataSourceViewsModel + smerr.EnrichAppend(ctx, &resp.Diagnostics, req.Config.Get(ctx, &data)) + if resp.Diagnostics.HasError() { + return + } + + var billingViewTypes []awstypes.BillingViewType + smerr.EnrichAppend(ctx, &resp.Diagnostics, data.BillingViewTypes.ElementsAs(ctx, &billingViewTypes, false)) + if resp.Diagnostics.HasError() { + return + } + + out, err := findViewsByViewTypes(ctx, conn, billingViewTypes) + if err != nil { + smerr.AddError(ctx, &resp.Diagnostics, err, smerr.ID, data.BillingViewTypes.String()) + return + } + + smerr.EnrichAppend(ctx, &resp.Diagnostics, flex.Flatten(ctx, out, &data.BillingView, flex.WithFieldNamePrefix("Views")), smerr.ID, data.BillingViewTypes.String()) + if resp.Diagnostics.HasError() { + return + } + + smerr.EnrichAppend(ctx, &resp.Diagnostics, resp.State.Set(ctx, &data), smerr.ID, data.BillingViewTypes.String()) +} + +func findViewsByViewTypes(ctx context.Context, conn *billing.Client, billingViewTypes []awstypes.BillingViewType) ([]awstypes.BillingViewListElement, error) { + input := billing.ListBillingViewsInput{} + if len(billingViewTypes) > 0 { + input.BillingViewTypes = billingViewTypes + } + + return findViews(ctx, conn, &input) +} + +func findViews(ctx context.Context, conn *billing.Client, input *billing.ListBillingViewsInput) ([]awstypes.BillingViewListElement, error) { + var results []awstypes.BillingViewListElement + + paginator := billing.NewListBillingViewsPaginator(conn, input) + for paginator.HasMorePages() { + page, err := paginator.NextPage(ctx) + if err != nil { + return nil, err + } + results = append(results, page.BillingViews...) + } + + return results, nil +} + +type dataSourceViewsModel struct { + BillingViewTypes fwtypes.ListOfStringEnum[awstypes.BillingViewType] `tfsdk:"billing_view_types"` + BillingView fwtypes.ListNestedObjectValueOf[dataSourceBillingViewModel] `tfsdk:"billing_view"` +} + +type dataSourceBillingViewModel struct { + ARN types.String `tfsdk:"arn"` + BillingViewType types.String `tfsdk:"billing_view_type"` + Description types.String `tfsdk:"description"` + Name types.String `tfsdk:"name"` + OwnerAccountId types.String `tfsdk:"owner_account_id"` +} diff --git a/internal/service/billing/views_data_source_test.go b/internal/service/billing/views_data_source_test.go new file mode 100644 index 000000000000..4058dea241a5 --- /dev/null +++ b/internal/service/billing/views_data_source_test.go @@ -0,0 +1,60 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package billing_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/names" +) + +func TestAccBillingViewsDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + + dataSourceName := "data.aws_billing_views.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.BillingServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccViewsDataSourceConfig_basic(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "billing_view.#", "1"), + acctest.CheckResourceAttrGlobalARN(ctx, dataSourceName, "billing_view.0.arn", "billing", "billingview/primary"), + resource.TestCheckResourceAttr(dataSourceName, "billing_view.0.billing_view_type", "PRIMARY"), + resource.TestCheckResourceAttr(dataSourceName, "billing_view.0.name", "Primary View"), + ), + }, + { + Config: testAccViewsDataSourceConfig_noArguments(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckTypeSetElemNestedAttrs(dataSourceName, "billing_view.*", map[string]string{ + "billing_view_type": "PRIMARY", + names.AttrName: "Primary View", + }), + ), + }, + }, + }) +} + +func testAccViewsDataSourceConfig_basic() string { + return ` +data "aws_billing_views" "test" { + billing_view_types = ["PRIMARY"] +} +` +} + +func testAccViewsDataSourceConfig_noArguments() string { + return ` +data "aws_billing_views" "test" {} +` +} diff --git a/internal/service/iam/sweep.go b/internal/service/iam/sweep.go index 15cf6ef25709..16622a6c92cd 100644 --- a/internal/service/iam/sweep.go +++ b/internal/service/iam/sweep.go @@ -59,6 +59,7 @@ func RegisterSweepers() { Dependencies: []string{ "aws_auditmanager_assessment", "aws_batch_compute_environment", + "aws_bedrockagent_agent", "aws_cloudformation_stack_set_instance", "aws_cognito_user_pool", "aws_config_configuration_aggregator", @@ -661,6 +662,7 @@ func roleNameFilter(name string) bool { // exhaustive list. prefixes := []string{ "another_rds", + "AmazonBedrockExecutionRoleForAgents", // Required role name prefix "AmazonComprehendServiceRole-", "aws_batch_service_role", "aws_elastictranscoder_pipeline_tf_test", diff --git a/internal/service/odb/cloud_autonomous_vm_cluster.go b/internal/service/odb/cloud_autonomous_vm_cluster.go new file mode 100644 index 000000000000..e330f78fe481 --- /dev/null +++ b/internal/service/odb/cloud_autonomous_vm_cluster.go @@ -0,0 +1,650 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package odb + +import ( + "context" + "errors" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/odb" + odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" + "github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" + "github.com/hashicorp/terraform-plugin-framework-validators/listvalidator" + "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" + "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/float64planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/int32planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/listplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/setplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" + "github.com/hashicorp/terraform-plugin-framework/schema/validator" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/enum" + "github.com/hashicorp/terraform-provider-aws/internal/errs" + "github.com/hashicorp/terraform-provider-aws/internal/errs/fwdiag" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// Function annotations are used for resource registration to the Provider. DO NOT EDIT. +// @FrameworkResource("aws_odb_cloud_autonomous_vm_cluster", name="Cloud Autonomous Vm Cluster") +// @Tags(identifierAttribute="arn") +func newResourceCloudAutonomousVmCluster(_ context.Context) (resource.ResourceWithConfigure, error) { + r := &resourceCloudAutonomousVmCluster{} + r.SetDefaultCreateTimeout(24 * time.Hour) + r.SetDefaultUpdateTimeout(24 * time.Hour) + r.SetDefaultDeleteTimeout(24 * time.Hour) + + return r, nil +} + +const ( + ResNameCloudAutonomousVmCluster = "Cloud Autonomous Vm Cluster" +) + +var ResourceCloudAutonomousVMCluster = newResourceCloudAutonomousVmCluster + +type resourceCloudAutonomousVmCluster struct { + framework.ResourceWithModel[cloudAutonomousVmClusterResourceModel] + framework.WithTimeouts + framework.WithImportByID +} + +func (r *resourceCloudAutonomousVmCluster) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { + status := fwtypes.StringEnumType[odbtypes.ResourceStatus]() + licenseModel := fwtypes.StringEnumType[odbtypes.LicenseModel]() + computeModel := fwtypes.StringEnumType[odbtypes.ComputeModel]() + stringLengthBetween1And255Validator := []validator.String{ + stringvalidator.LengthBetween(1, 255), + } + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + names.AttrARN: framework.ARNAttributeComputedOnly(), + names.AttrID: framework.IDAttribute(), + "cloud_exadata_infrastructure_id": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "Exadata infrastructure id. Changing this will force terraform to create new resource.", + }, + "autonomous_data_storage_percentage": schema.Float32Attribute{ + Computed: true, + Description: "The progress of the current operation on the Autonomous VM cluster, as a percentage.", + }, + "autonomous_data_storage_size_in_tbs": schema.Float64Attribute{ + Required: true, + PlanModifiers: []planmodifier.Float64{ + float64planmodifier.RequiresReplace(), + }, + Description: "The data storage size allocated for Autonomous Databases in the Autonomous VM cluster, in TB. Changing this will force terraform to create new resource.", + }, + "available_autonomous_data_storage_size_in_tbs": schema.Float64Attribute{ + Computed: true, + Description: "The available data storage space for Autonomous Databases in the Autonomous VM cluster, in TB.", + }, + "available_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that you can create with the currently available storage.", + }, + "available_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores available for allocation to Autonomous Databases", + }, + "compute_model": schema.StringAttribute{ + CustomType: computeModel, + Computed: true, + Description: "The compute model of the Autonomous VM cluster: ECPU or OCPU.", + }, + "cpu_core_count": schema.Int32Attribute{ + Computed: true, + Description: "The total number of CPU cores in the Autonomous VM cluster.", + }, + "cpu_core_count_per_node": schema.Int32Attribute{ + Required: true, + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + Description: "The number of CPU cores enabled per node in the Autonomous VM cluster.", + }, + "cpu_percentage": schema.Float32Attribute{ + Computed: true, + Description: "The percentage of total CPU cores currently in use in the Autonomous VM cluster.", + }, + names.AttrCreatedAt: schema.StringAttribute{ + Computed: true, + CustomType: timetypes.RFC3339Type{}, + Description: "The date and time when the Autonomous VM cluster was created.", + }, + "data_storage_size_in_gbs": schema.Float64Attribute{ + Computed: true, + Description: "The total data storage allocated to the Autonomous VM cluster, in GB.", + }, + "data_storage_size_in_tbs": schema.Float64Attribute{ + Computed: true, + Description: "The total data storage allocated to the Autonomous VM cluster, in TB.", + }, + "odb_node_storage_size_in_gbs": schema.Int32Attribute{ + Computed: true, + Description: " The local node storage allocated to the Autonomous VM cluster, in gigabytes (GB)", + }, + "db_servers": schema.SetAttribute{ + Required: true, + CustomType: fwtypes.SetOfStringType, + ElementType: types.StringType, + PlanModifiers: []planmodifier.Set{ + setplanmodifier.RequiresReplace(), + }, + Description: "The database servers in the Autonomous VM cluster. Changing this will force terraform to create new resource.", + }, + names.AttrDescription: schema.StringAttribute{ + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "The description of the Autonomous VM cluster.", + }, + names.AttrDisplayName: schema.StringAttribute{ + Required: true, + Validators: stringLengthBetween1And255Validator, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "The display name of the Autonomous VM cluster. Changing this will force terraform to create new resource.", + }, + names.AttrDomain: schema.StringAttribute{ + Computed: true, + Description: "The domain name of the Autonomous VM cluster.", + }, + "exadata_storage_in_tbs_lowest_scaled_value": schema.Float64Attribute{ + Computed: true, + Description: "The minimum value to which you can scale down the Exadata storage, in TB.", + }, + "hostname": schema.StringAttribute{ + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.UseStateForUnknown(), + }, + Description: "The hostname of the Autonomous VM cluster.", + }, + "is_mtls_enabled_vm_cluster": schema.BoolAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.Bool{ + boolplanmodifier.RequiresReplace(), + boolplanmodifier.UseStateForUnknown(), + }, + Description: "Indicates whether mutual TLS (mTLS) authentication is enabled for the Autonomous VM cluster. Changing this will force terraform to create new resource. ", + }, + "license_model": schema.StringAttribute{ + CustomType: licenseModel, + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + stringplanmodifier.UseStateForUnknown(), + }, + Description: "The license model for the Autonomous VM cluster. Valid values are LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE . Changing this will force terraform to create new resource.", + }, + "max_acds_lowest_scaled_value": schema.Int32Attribute{ + Computed: true, + Description: "The minimum value to which you can scale down the maximum number of Autonomous CDBs.", + }, + "memory_per_oracle_compute_unit_in_gbs": schema.Int32Attribute{ + Required: true, + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + Description: "The amount of memory allocated per Oracle Compute Unit, in GB. Changing this will force terraform to create new resource.", + }, + "memory_size_in_gbs": schema.Int32Attribute{ + Computed: true, + Description: "The total amount of memory allocated to the Autonomous VM cluster, in gigabytes(GB).", + }, + "node_count": schema.Int32Attribute{ + Computed: true, + Description: "The number of database server nodes in the Autonomous VM cluster.", + }, + "non_provisionable_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that can't be provisioned because of resource constraints.", + }, + "oci_resource_anchor_name": schema.StringAttribute{ + Computed: true, + Description: "The name of the OCI resource anchor associated with this Autonomous VM cluster.", + }, + "oci_url": schema.StringAttribute{ + Computed: true, + Description: "The URL for accessing the OCI console page for this Autonomous VM cluster.", + }, + "ocid": schema.StringAttribute{ + Computed: true, + Description: "The Oracle Cloud Identifier (OCID) of the Autonomous VM cluster.", + }, + "odb_network_id": schema.StringAttribute{ + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + Description: "The unique identifier of the ODB network associated with this Autonomous VM Cluster. Changing this will force terraform to create new resource.", + }, + "percent_progress": schema.Float32Attribute{ + Computed: true, + Description: `The progress of the current operation on the Autonomous VM cluster, as a percentage.`, + }, + "provisionable_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that can be provisioned in the Autonomous VM cluster.", + }, + "provisioned_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs currently provisioned in the Autonomous VM cluster.", + }, + "provisioned_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPUs provisioned in the Autonomous VM cluster.", + }, + "reclaimable_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores that can be reclaimed from terminated or scaled-down Autonomous Databases.", + }, + "reserved_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores reserved for system operations and redundancy.", + }, + "scan_listener_port_non_tls": schema.Int32Attribute{ + Required: true, + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + Description: "The SCAN listener port for non-TLS (TCP) protocol. The default is 1521. Changing this will force terraform to create new resource.", + }, + "scan_listener_port_tls": schema.Int32Attribute{ + Required: true, + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + Description: "The SCAN listener port for TLS (TCP) protocol. The default is 2484. Changing this will force terraform to create new resource.", + }, + "shape": schema.StringAttribute{ + Computed: true, + Description: "The shape of the Exadata infrastructure for the Autonomous VM cluster.", + }, + names.AttrStatus: schema.StringAttribute{ + CustomType: status, + Computed: true, + Description: "The status of the Autonomous VM cluster. Possible values include CREATING, AVAILABLE , UPDATING , DELETING , DELETED , FAILED ", + }, + names.AttrStatusReason: schema.StringAttribute{ + Computed: true, + Description: "Additional information about the current status of the Autonomous VM cluster.", + }, + "time_zone": schema.StringAttribute{ + Optional: true, + Computed: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + stringplanmodifier.UseStateForUnknown(), + }, + Description: "The time zone of the Autonomous VM cluster. Changing this will force terraform to create new resource.", + }, + "total_container_databases": schema.Int32Attribute{ + Required: true, + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + Description: "The total number of Autonomous Container Databases that can be created with the allocated local storage. Changing this will force terraform to create new resource.", + }, + "time_ords_certificate_expires": schema.StringAttribute{ + Computed: true, + CustomType: timetypes.RFC3339Type{}, + }, + "time_database_ssl_certificate_expires": schema.StringAttribute{ + Computed: true, + CustomType: timetypes.RFC3339Type{}, + Description: "The expiration date and time of the database SSL certificate.", + }, + names.AttrTags: tftags.TagsAttribute(), + names.AttrTagsAll: tftags.TagsAttributeComputedOnly(), + }, + Blocks: map[string]schema.Block{ + names.AttrTimeouts: timeouts.Block(ctx, timeouts.Opts{ + Create: true, + Update: true, + Delete: true, + }), + "maintenance_window": schema.ListNestedBlock{ + CustomType: fwtypes.NewListNestedObjectTypeOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel](ctx), + Validators: []validator.List{ + listvalidator.SizeAtMost(1), + listvalidator.IsRequired(), + }, + PlanModifiers: []planmodifier.List{ + listplanmodifier.RequiresReplace(), + }, + Description: "The maintenance window of the Autonomous VM cluster.", + + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "days_of_week": schema.SetAttribute{ + ElementType: fwtypes.NewObjectTypeOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel](ctx), + Optional: true, + Description: "The days of the week when maintenance can be performed.", + PlanModifiers: []planmodifier.Set{ + setplanmodifier.RequiresReplace(), + }, + }, + "hours_of_day": schema.SetAttribute{ + ElementType: types.Int64Type, + Optional: true, + Description: "The hours of the day when maintenance can be performed.", + PlanModifiers: []planmodifier.Set{ + setplanmodifier.RequiresReplace(), + }, + }, + "lead_time_in_weeks": schema.Int32Attribute{ + Optional: true, + Description: "The lead time in weeks before the maintenance window.", + PlanModifiers: []planmodifier.Int32{ + int32planmodifier.RequiresReplace(), + }, + }, + "months": schema.SetAttribute{ + ElementType: fwtypes.NewObjectTypeOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel](ctx), + Optional: true, + Description: "The months when maintenance can be performed.", + PlanModifiers: []planmodifier.Set{ + setplanmodifier.RequiresReplace(), + }, + }, + "preference": schema.StringAttribute{ + Required: true, + CustomType: fwtypes.StringEnumType[odbtypes.PreferenceType](), + Description: "The preference for the maintenance window scheduling.", + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, + "weeks_of_month": schema.SetAttribute{ + ElementType: types.Int64Type, + Optional: true, + Description: "Indicates whether to skip release updates during maintenance.", + PlanModifiers: []planmodifier.Set{ + setplanmodifier.RequiresReplace(), + }, + }, + }, + }, + }, + }, + } +} + +func (r *resourceCloudAutonomousVmCluster) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { + conn := r.Meta().ODBClient(ctx) + var plan cloudAutonomousVmClusterResourceModel + resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...) + if resp.Diagnostics.HasError() { + return + } + + input := odb.CreateCloudAutonomousVmClusterInput{ + Tags: getTagsIn(ctx), + } + resp.Diagnostics.Append(flex.Expand(ctx, plan, &input)...) + if resp.Diagnostics.HasError() { + return + } + + out, err := conn.CreateCloudAutonomousVmCluster(ctx, &input) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionCreating, ResNameCloudAutonomousVmCluster, plan.DisplayName.ValueString(), err), + err.Error(), + ) + return + } + if out == nil || out.CloudAutonomousVmClusterId == nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionCreating, ResNameCloudAutonomousVmCluster, plan.DisplayName.ValueString(), nil), + errors.New("empty output").Error(), + ) + return + } + + createTimeout := r.CreateTimeout(ctx, plan.Timeouts) + createdAVMC, err := waitCloudAutonomousVmClusterCreated(ctx, conn, *out.CloudAutonomousVmClusterId, createTimeout) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root(names.AttrID), aws.ToString(out.CloudAutonomousVmClusterId))...) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionWaitingForCreation, ResNameCloudAutonomousVmCluster, plan.DisplayName.ValueString(), err), + err.Error(), + ) + return + } + resp.Diagnostics.Append(flex.Flatten(ctx, createdAVMC, &plan)...) + resp.Diagnostics.Append(resp.State.Set(ctx, plan)...) +} + +func (r *resourceCloudAutonomousVmCluster) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { + conn := r.Meta().ODBClient(ctx) + + var state cloudAutonomousVmClusterResourceModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + out, err := FindCloudAutonomousVmClusterByID(ctx, conn, state.CloudAutonomousVmClusterId.ValueString()) + + if tfresource.NotFound(err) { + resp.Diagnostics.Append(fwdiag.NewResourceNotFoundWarningDiagnostic(err)) + resp.State.RemoveResource(ctx) + return + } + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionReading, ResNameCloudAutonomousVmCluster, state.DisplayName.ValueString(), err), + err.Error(), + ) + return + } + resp.Diagnostics.Append(flex.Flatten(ctx, out, &state)...) + if resp.Diagnostics.HasError() { + return + } + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (r *resourceCloudAutonomousVmCluster) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { + conn := r.Meta().ODBClient(ctx) + + var state cloudAutonomousVmClusterResourceModel + resp.Diagnostics.Append(req.State.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + + input := odb.DeleteCloudAutonomousVmClusterInput{ + CloudAutonomousVmClusterId: state.CloudAutonomousVmClusterId.ValueStringPointer(), + } + + _, err := conn.DeleteCloudAutonomousVmCluster(ctx, &input) + + if err != nil { + if errs.IsA[*odbtypes.ResourceNotFoundException](err) { + return + } + + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionDeleting, ResNameCloudAutonomousVmCluster, state.CloudAutonomousVmClusterId.ValueString(), err), + err.Error(), + ) + return + } + deleteTimeout := r.DeleteTimeout(ctx, state.Timeouts) + _, err = waitCloudAutonomousVmClusterDeleted(ctx, conn, state.CloudAutonomousVmClusterId.ValueString(), deleteTimeout) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionWaitingForDeletion, ResNameCloudAutonomousVmCluster, state.CloudAutonomousVmClusterId.ValueString(), err), + err.Error(), + ) + return + } +} + +func waitCloudAutonomousVmClusterCreated(ctx context.Context, conn *odb.Client, id string, timeout time.Duration) (*odbtypes.CloudAutonomousVmCluster, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(odbtypes.ResourceStatusProvisioning), + Target: enum.Slice(odbtypes.ResourceStatusAvailable, odbtypes.ResourceStatusFailed), + Refresh: statusCloudAutonomousVmCluster(ctx, conn, id), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + if out, ok := outputRaw.(*odbtypes.CloudAutonomousVmCluster); ok { + return out, err + } + + return nil, err +} + +func waitCloudAutonomousVmClusterDeleted(ctx context.Context, conn *odb.Client, id string, timeout time.Duration) (*odbtypes.CloudAutonomousVmCluster, error) { + stateConf := &retry.StateChangeConf{ + Pending: enum.Slice(odbtypes.ResourceStatusTerminating), + Target: []string{}, + Refresh: statusCloudAutonomousVmCluster(ctx, conn, id), + Timeout: timeout, + } + + outputRaw, err := stateConf.WaitForStateContext(ctx) + if out, ok := outputRaw.(*odbtypes.CloudAutonomousVmCluster); ok { + return out, err + } + + return nil, err +} + +func statusCloudAutonomousVmCluster(ctx context.Context, conn *odb.Client, id string) retry.StateRefreshFunc { + return func() (any, string, error) { + out, err := FindCloudAutonomousVmClusterByID(ctx, conn, id) + if tfresource.NotFound(err) { + return nil, "", nil + } + + if err != nil { + return nil, "", err + } + + return out, string(out.Status), nil + } +} + +func FindCloudAutonomousVmClusterByID(ctx context.Context, conn *odb.Client, id string) (*odbtypes.CloudAutonomousVmCluster, error) { + input := odb.GetCloudAutonomousVmClusterInput{ + CloudAutonomousVmClusterId: aws.String(id), + } + out, err := conn.GetCloudAutonomousVmCluster(ctx, &input) + if err != nil { + if errs.IsA[*odbtypes.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: &input, + } + } + return nil, err + } + + if out == nil || out.CloudAutonomousVmCluster == nil { + return nil, tfresource.NewEmptyResultError(&input) + } + + return out.CloudAutonomousVmCluster, nil +} + +type cloudAutonomousVmClusterResourceModel struct { + framework.WithRegionModel + CloudAutonomousVmClusterArn types.String `tfsdk:"arn"` + CloudAutonomousVmClusterId types.String `tfsdk:"id"` + CloudExadataInfrastructureId types.String `tfsdk:"cloud_exadata_infrastructure_id"` + AutonomousDataStoragePercentage types.Float32 `tfsdk:"autonomous_data_storage_percentage"` + AutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"autonomous_data_storage_size_in_tbs"` + AvailableAutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"available_autonomous_data_storage_size_in_tbs"` + AvailableContainerDatabases types.Int32 `tfsdk:"available_container_databases"` + AvailableCpus types.Float32 `tfsdk:"available_cpus"` + ComputeModel fwtypes.StringEnum[odbtypes.ComputeModel] `tfsdk:"compute_model"` + CpuCoreCount types.Int32 `tfsdk:"cpu_core_count"` + CpuCoreCountPerNode types.Int32 `tfsdk:"cpu_core_count_per_node"` + CpuPercentage types.Float32 `tfsdk:"cpu_percentage"` + CreatedAt timetypes.RFC3339 `tfsdk:"created_at" ` + DataStorageSizeInGBs types.Float64 `tfsdk:"data_storage_size_in_gbs"` + DataStorageSizeInTBs types.Float64 `tfsdk:"data_storage_size_in_tbs"` + DbNodeStorageSizeInGBs types.Int32 `tfsdk:"odb_node_storage_size_in_gbs"` + DbServers fwtypes.SetValueOf[types.String] `tfsdk:"db_servers"` + Description types.String `tfsdk:"description"` + DisplayName types.String `tfsdk:"display_name"` + Domain types.String `tfsdk:"domain"` + ExadataStorageInTBsLowestScaledValue types.Float64 `tfsdk:"exadata_storage_in_tbs_lowest_scaled_value"` + Hostname types.String `tfsdk:"hostname"` + IsMtlsEnabledVmCluster types.Bool `tfsdk:"is_mtls_enabled_vm_cluster"` + LicenseModel fwtypes.StringEnum[odbtypes.LicenseModel] `tfsdk:"license_model"` + MaxAcdsLowestScaledValue types.Int32 `tfsdk:"max_acds_lowest_scaled_value"` + MemoryPerOracleComputeUnitInGBs types.Int32 `tfsdk:"memory_per_oracle_compute_unit_in_gbs"` + MemorySizeInGBs types.Int32 `tfsdk:"memory_size_in_gbs"` + NodeCount types.Int32 `tfsdk:"node_count"` + NonProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"non_provisionable_autonomous_container_databases"` + OciResourceAnchorName types.String `tfsdk:"oci_resource_anchor_name"` + OciUrl types.String `tfsdk:"oci_url"` + Ocid types.String `tfsdk:"ocid"` + OdbNetworkId types.String `tfsdk:"odb_network_id"` + PercentProgress types.Float32 `tfsdk:"percent_progress"` + ProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"provisionable_autonomous_container_databases"` + ProvisionedAutonomousContainerDatabases types.Int32 `tfsdk:"provisioned_autonomous_container_databases"` + ProvisionedCpus types.Float32 `tfsdk:"provisioned_cpus"` + ReclaimableCpus types.Float32 `tfsdk:"reclaimable_cpus"` + ReservedCpus types.Float32 `tfsdk:"reserved_cpus"` + ScanListenerPortNonTls types.Int32 `tfsdk:"scan_listener_port_non_tls"` + ScanListenerPortTls types.Int32 `tfsdk:"scan_listener_port_tls"` + Shape types.String `tfsdk:"shape"` + Status fwtypes.StringEnum[odbtypes.ResourceStatus] `tfsdk:"status"` + StatusReason types.String `tfsdk:"status_reason"` + TimeZone types.String `tfsdk:"time_zone"` + TotalContainerDatabases types.Int32 `tfsdk:"total_container_databases"` + Timeouts timeouts.Value `tfsdk:"timeouts"` + Tags tftags.Map `tfsdk:"tags"` + TagsAll tftags.Map `tfsdk:"tags_all"` + TimeOrdsCertificateExpires timetypes.RFC3339 `tfsdk:"time_ords_certificate_expires"` + TimeDatabaseSslCertificateExpires timetypes.RFC3339 `tfsdk:"time_database_ssl_certificate_expires"` + MaintenanceWindow fwtypes.ListNestedObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"maintenance_window" ` +} + +type cloudAutonomousVmClusterMaintenanceWindowResourceModel struct { + DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"days_of_week"` + HoursOfDay fwtypes.SetValueOf[types.Int64] `tfsdk:"hours_of_day"` + LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` + Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowResourceModel] `tfsdk:"months"` + Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` + WeeksOfMonth fwtypes.SetValueOf[types.Int64] `tfsdk:"weeks_of_month"` +} + +type dayWeekNameAutonomousVmClusterMaintenanceWindowResourceModel struct { + Name fwtypes.StringEnum[odbtypes.DayOfWeekName] `tfsdk:"name"` +} + +type monthNameAutonomousVmClusterMaintenanceWindowResourceModel struct { + Name fwtypes.StringEnum[odbtypes.MonthName] `tfsdk:"name"` +} diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go new file mode 100644 index 000000000000..d21456c05544 --- /dev/null +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source.go @@ -0,0 +1,346 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package odb + +import ( + "context" + + "github.com/aws/aws-sdk-go-v2/service/odb" + odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" + "github.com/hashicorp/terraform-plugin-framework-timetypes/timetypes" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/framework" + "github.com/hashicorp/terraform-provider-aws/internal/framework/flex" + fwtypes "github.com/hashicorp/terraform-provider-aws/internal/framework/types" + tftags "github.com/hashicorp/terraform-provider-aws/internal/tags" + "github.com/hashicorp/terraform-provider-aws/names" +) + +// Function annotations are used for datasource registration to the Provider. DO NOT EDIT. +// @FrameworkDataSource("aws_odb_cloud_autonomous_vm_cluster", name="Cloud Autonomous Vm Cluster") +// @Tags(identifierAttribute="arn") +func newDataSourceCloudAutonomousVmCluster(context.Context) (datasource.DataSourceWithConfigure, error) { + return &dataSourceCloudAutonomousVmCluster{}, nil +} + +const ( + DSNameCloudAutonomousVmCluster = "Cloud Autonomous Vm Cluster Data Source" +) + +type dataSourceCloudAutonomousVmCluster struct { + framework.DataSourceWithModel[cloudAutonomousVmClusterDataSourceModel] +} + +func (d *dataSourceCloudAutonomousVmCluster) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) { + status := fwtypes.StringEnumType[odbtypes.ResourceStatus]() + licenseModel := fwtypes.StringEnumType[odbtypes.LicenseModel]() + computeModel := fwtypes.StringEnumType[odbtypes.ComputeModel]() + resp.Schema = schema.Schema{ + Attributes: map[string]schema.Attribute{ + names.AttrARN: framework.ARNAttributeComputedOnly(), + + names.AttrID: schema.StringAttribute{ + Required: true, + Description: "Unique ID of the Autonomous VM cluster.", + }, + "cloud_exadata_infrastructure_id": schema.StringAttribute{ + Computed: true, + Description: "Cloud exadata infrastructure id associated with this cloud autonomous VM cluster.", + }, + "autonomous_data_storage_percentage": schema.Float32Attribute{ + Computed: true, + Description: "The percentage of data storage currently in use for Autonomous Databases in the Autonomous VM cluster.", + }, + "autonomous_data_storage_size_in_tbs": schema.Float64Attribute{ + Computed: true, + Description: "The data storage size allocated for Autonomous Databases in the Autonomous VM cluster, in TB.", + }, + "available_autonomous_data_storage_size_in_tbs": schema.Float64Attribute{ + Computed: true, + Description: "The available data storage space for Autonomous Databases in the Autonomous VM cluster, in TB.", + }, + "available_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that you can create with the currently available storage.", + }, + "available_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores available for allocation to Autonomous Databases.", + }, + "compute_model": schema.StringAttribute{ + CustomType: computeModel, + Computed: true, + Description: " The compute model of the Autonomous VM cluster: ECPU or OCPU.", + }, + "cpu_core_count": schema.Int32Attribute{ + Computed: true, + Description: "The total number of CPU cores in the Autonomous VM cluster.", + }, + "cpu_core_count_per_node": schema.Int32Attribute{ + Computed: true, + Description: "The number of CPU cores enabled per node in the Autonomous VM cluster.", + }, + "cpu_percentage": schema.Float32Attribute{ + Computed: true, + Description: "he percentage of total CPU cores currently in use in the Autonomous VM cluster.", + }, + names.AttrCreatedAt: schema.StringAttribute{ + Computed: true, + CustomType: timetypes.RFC3339Type{}, + Description: "The date and time when the Autonomous VM cluster was created.", + }, + "data_storage_size_in_gbs": schema.Float64Attribute{ + Computed: true, + Description: "The total data storage allocated to the Autonomous VM cluster, in GB.", + }, + "data_storage_size_in_tbs": schema.Float64Attribute{ + Computed: true, + Description: "The total data storage allocated to the Autonomous VM cluster, in TB.", + }, + "odb_node_storage_size_in_gbs": schema.Int32Attribute{ + Computed: true, + Description: "The local node storage allocated to the Autonomous VM cluster, in gigabytes (GB).", + }, + "db_servers": schema.SetAttribute{ + Computed: true, + CustomType: fwtypes.SetOfStringType, + ElementType: types.StringType, + Description: "The list of database servers associated with the Autonomous VM cluster.", + }, + names.AttrDescription: schema.StringAttribute{ + Computed: true, + Description: "The user-provided description of the Autonomous VM cluster.", + }, + names.AttrDisplayName: schema.StringAttribute{ + Computed: true, + Description: "The display name of the Autonomous VM cluster.", + }, + names.AttrDomain: schema.StringAttribute{ + Computed: true, + Description: "The domain name of the Autonomous VM cluster.", + }, + "exadata_storage_in_tbs_lowest_scaled_value": schema.Float64Attribute{ + Computed: true, + Description: "The minimum value to which you can scale down the Exadata storage, in TB.", + }, + "hostname": schema.StringAttribute{ + Computed: true, + Description: "The hostname of the Autonomous VM cluster.", + }, + "is_mtls_enabled_vm_cluster": schema.BoolAttribute{ + Computed: true, + Description: " Indicates whether mutual TLS (mTLS) authentication is enabled for the Autonomous VM cluster.", + }, + "license_model": schema.StringAttribute{ + CustomType: licenseModel, + Computed: true, + Description: "The Oracle license model that applies to the Autonomous VM cluster. Valid values are LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE .", + }, + "max_acds_lowest_scaled_value": schema.Int32Attribute{ + Computed: true, + Description: "The minimum value to which you can scale down the maximum number of Autonomous CDBs.", + }, + "memory_per_oracle_compute_unit_in_gbs": schema.Int32Attribute{ + Computed: true, + Description: "The amount of memory allocated per Oracle Compute Unit, in GB.", + }, + "memory_size_in_gbs": schema.Int32Attribute{ + Computed: true, + Description: "The total amount of memory allocated to the Autonomous VM cluster, in gigabytes (GB).", + }, + "node_count": schema.Int32Attribute{ + Computed: true, + Description: "The number of database server nodes in the Autonomous VM cluster.", + }, + "non_provisionable_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that can't be provisioned because of resource constraints.", + }, + "oci_resource_anchor_name": schema.StringAttribute{ + Computed: true, + Description: "The name of the OCI resource anchor associated with this Autonomous VM cluster.", + }, + "oci_url": schema.StringAttribute{ + Computed: true, + Description: "The URL for accessing the OCI console page for this Autonomous VM cluster.", + }, + "ocid": schema.StringAttribute{ + Computed: true, + Description: "The Oracle Cloud Identifier (OCID) of the Autonomous VM cluster.", + }, + "odb_network_id": schema.StringAttribute{ + Computed: true, + Description: "The unique identifier of the ODB network associated with this Autonomous VM cluster.", + }, + "percent_progress": schema.Float32Attribute{ + Computed: true, + Description: "The progress of the current operation on the Autonomous VM cluster, as a percentage.", + }, + "provisionable_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs that can be provisioned in the Autonomous VM cluster.", + }, + "provisioned_autonomous_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The number of Autonomous CDBs currently provisioned in the Autonomous VM cluster.", + }, + "provisioned_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores currently provisioned in the Autonomous VM cluster.", + }, + "reclaimable_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores that can be reclaimed from terminated or scaled-down Autonomous Databases.", + }, + "reserved_cpus": schema.Float32Attribute{ + Computed: true, + Description: "The number of CPU cores reserved for system operations and redundancy.", + }, + "scan_listener_port_non_tls": schema.Int32Attribute{ + Computed: true, + Description: "The SCAN listener port for non-TLS (TCP) protocol. The default is 1521.", + }, + "scan_listener_port_tls": schema.Int32Attribute{ + Computed: true, + Description: "The SCAN listener port for TLS (TCP) protocol. The default is 2484.", + }, + "shape": schema.StringAttribute{ + Computed: true, + Description: "The shape of the Exadata infrastructure for the Autonomous VM cluster.", + }, + names.AttrStatus: schema.StringAttribute{ + CustomType: status, + Computed: true, + Description: "The status of the Autonomous VM cluster.", + }, + names.AttrStatusReason: schema.StringAttribute{ + Computed: true, + Description: "Additional information about the current status of the Autonomous VM cluster.", + }, + "time_database_ssl_certificate_expires": schema.StringAttribute{ + Computed: true, + CustomType: timetypes.RFC3339Type{}, + Description: "The expiration date and time of the database SSL certificate.", + }, + "time_ords_certificate_expires": schema.StringAttribute{ + Computed: true, + CustomType: timetypes.RFC3339Type{}, + Description: "The expiration date and time of the Oracle REST Data Services (ORDS)certificate .", + }, + "time_zone": schema.StringAttribute{ + Computed: true, + Description: "The time zone of the Autonomous VM cluster.", + }, + "total_container_databases": schema.Int32Attribute{ + Computed: true, + Description: "The total number of Autonomous Container Databases that can be created with the allocated local storage.", + }, + names.AttrTags: tftags.TagsAttributeComputedOnly(), + "maintenance_window": schema.ListAttribute{ + Computed: true, + CustomType: fwtypes.NewListNestedObjectTypeOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel](ctx), + Description: "The maintenance window for the Autonomous VM cluster.", + }, + }, + } +} + +func (d *dataSourceCloudAutonomousVmCluster) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + conn := d.Meta().ODBClient(ctx) + var data cloudAutonomousVmClusterDataSourceModel + resp.Diagnostics.Append(req.Config.Get(ctx, &data)...) + if resp.Diagnostics.HasError() { + return + } + input := odb.GetCloudAutonomousVmClusterInput{ + CloudAutonomousVmClusterId: data.CloudAutonomousVmClusterId.ValueStringPointer(), + } + + out, err := conn.GetCloudAutonomousVmCluster(ctx, &input) + if err != nil { + resp.Diagnostics.AddError( + create.ProblemStandardMessage(names.ODB, create.ErrActionReading, DSNameCloudAutonomousVmCluster, data.CloudAutonomousVmClusterId.ValueString(), err), + err.Error(), + ) + return + } + resp.Diagnostics.Append(flex.Flatten(ctx, out.CloudAutonomousVmCluster, &data)...) + if resp.Diagnostics.HasError() { + return + } + + resp.Diagnostics.Append(resp.State.Set(ctx, &data)...) +} + +type cloudAutonomousVmClusterDataSourceModel struct { + framework.WithRegionModel + CloudAutonomousVmClusterArn types.String `tfsdk:"arn"` + CloudAutonomousVmClusterId types.String `tfsdk:"id"` + CloudExadataInfrastructureId types.String `tfsdk:"cloud_exadata_infrastructure_id"` + AutonomousDataStoragePercentage types.Float32 `tfsdk:"autonomous_data_storage_percentage"` + AutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"autonomous_data_storage_size_in_tbs"` + AvailableAutonomousDataStorageSizeInTBs types.Float64 `tfsdk:"available_autonomous_data_storage_size_in_tbs"` + AvailableContainerDatabases types.Int32 `tfsdk:"available_container_databases"` + AvailableCpus types.Float32 `tfsdk:"available_cpus"` + ComputeModel fwtypes.StringEnum[odbtypes.ComputeModel] `tfsdk:"compute_model"` + CpuCoreCount types.Int32 `tfsdk:"cpu_core_count"` + CpuCoreCountPerNode types.Int32 `tfsdk:"cpu_core_count_per_node"` + CpuPercentage types.Float32 `tfsdk:"cpu_percentage"` + CreatedAt timetypes.RFC3339 `tfsdk:"created_at" ` + DataStorageSizeInGBs types.Float64 `tfsdk:"data_storage_size_in_gbs"` + DataStorageSizeInTBs types.Float64 `tfsdk:"data_storage_size_in_tbs"` + DbNodeStorageSizeInGBs types.Int32 `tfsdk:"odb_node_storage_size_in_gbs"` + DbServers fwtypes.SetValueOf[types.String] `tfsdk:"db_servers"` + Description types.String `tfsdk:"description"` + DisplayName types.String `tfsdk:"display_name"` + Domain types.String `tfsdk:"domain"` + ExadataStorageInTBsLowestScaledValue types.Float64 `tfsdk:"exadata_storage_in_tbs_lowest_scaled_value"` + Hostname types.String `tfsdk:"hostname"` + IsMtlsEnabledVmCluster types.Bool `tfsdk:"is_mtls_enabled_vm_cluster"` + LicenseModel fwtypes.StringEnum[odbtypes.LicenseModel] `tfsdk:"license_model"` + MaxAcdsLowestScaledValue types.Int32 `tfsdk:"max_acds_lowest_scaled_value"` + MemoryPerOracleComputeUnitInGBs types.Int32 `tfsdk:"memory_per_oracle_compute_unit_in_gbs"` + MemorySizeInGBs types.Int32 `tfsdk:"memory_size_in_gbs"` + NodeCount types.Int32 `tfsdk:"node_count"` + NonProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"non_provisionable_autonomous_container_databases"` + OciResourceAnchorName types.String `tfsdk:"oci_resource_anchor_name"` + OciUrl types.String `tfsdk:"oci_url"` + Ocid types.String `tfsdk:"ocid"` + OdbNetworkId types.String `tfsdk:"odb_network_id"` + PercentProgress types.Float32 `tfsdk:"percent_progress"` + ProvisionableAutonomousContainerDatabases types.Int32 `tfsdk:"provisionable_autonomous_container_databases"` + ProvisionedAutonomousContainerDatabases types.Int32 `tfsdk:"provisioned_autonomous_container_databases"` + ProvisionedCpus types.Float32 `tfsdk:"provisioned_cpus"` + ReclaimableCpus types.Float32 `tfsdk:"reclaimable_cpus"` + ReservedCpus types.Float32 `tfsdk:"reserved_cpus"` + ScanListenerPortNonTls types.Int32 `tfsdk:"scan_listener_port_non_tls"` + ScanListenerPortTls types.Int32 `tfsdk:"scan_listener_port_tls"` + Shape types.String `tfsdk:"shape"` + Status fwtypes.StringEnum[odbtypes.ResourceStatus] `tfsdk:"status"` + StatusReason types.String `tfsdk:"status_reason"` + TimeDatabaseSslCertificateExpires timetypes.RFC3339 `tfsdk:"time_database_ssl_certificate_expires"` + TimeOrdsCertificateExpires timetypes.RFC3339 `tfsdk:"time_ords_certificate_expires" ` + TimeZone types.String `tfsdk:"time_zone"` + TotalContainerDatabases types.Int32 `tfsdk:"total_container_databases"` + MaintenanceWindow fwtypes.ListNestedObjectValueOf[cloudAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"maintenance_window" ` + Tags tftags.Map `tfsdk:"tags"` +} +type cloudAutonomousVmClusterMaintenanceWindowDataSourceModel struct { + DaysOfWeek fwtypes.SetNestedObjectValueOf[dayWeekNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"days_of_week"` + HoursOfDay fwtypes.SetValueOf[types.Int64] `tfsdk:"hours_of_day"` + LeadTimeInWeeks types.Int32 `tfsdk:"lead_time_in_weeks"` + Months fwtypes.SetNestedObjectValueOf[monthNameAutonomousVmClusterMaintenanceWindowDataSourceModel] `tfsdk:"months"` + Preference fwtypes.StringEnum[odbtypes.PreferenceType] `tfsdk:"preference"` + WeeksOfMonth fwtypes.SetValueOf[types.Int64] `tfsdk:"weeks_of_month"` +} +type dayWeekNameAutonomousVmClusterMaintenanceWindowDataSourceModel struct { + Name fwtypes.StringEnum[odbtypes.DayOfWeekName] `tfsdk:"name"` +} + +type monthNameAutonomousVmClusterMaintenanceWindowDataSourceModel struct { + Name fwtypes.StringEnum[odbtypes.MonthName] `tfsdk:"name"` +} diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go new file mode 100644 index 000000000000..172ffd5f3831 --- /dev/null +++ b/internal/service/odb/cloud_autonomous_vm_cluster_data_source_test.go @@ -0,0 +1,191 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package odb_test + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go-v2/service/odb" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + tfodb "github.com/hashicorp/terraform-provider-aws/internal/service/odb" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +type autonomousVMClusterDSTest struct { + exaInfraDisplayNamePrefix string + odbNetDisplayNamePrefix string + autonomousVmClusterDisplayNamePrefix string +} + +var autonomousVMClusterDSTestEntity = autonomousVMClusterDSTest{ + exaInfraDisplayNamePrefix: "Ofake-exa", + odbNetDisplayNamePrefix: "odb-net", + autonomousVmClusterDisplayNamePrefix: "Ofake-avmc", +} + +func TestAccODBCloudAutonomousVmClusterDataSource_basic(t *testing.T) { + ctx := acctest.Context(t) + + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + avmcResource := "aws_odb_cloud_autonomous_vm_cluster.test" + avmcDataSource := "data.aws_odb_cloud_autonomous_vm_cluster.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + autonomousVMClusterDSTestEntity.testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ODBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: autonomousVMClusterDSTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: autonomousVMClusterDSTestEntity.avmcBasic(), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(avmcResource, names.AttrID, avmcDataSource, names.AttrID), + ), + }, + }, + }) +} + +func (autonomousVMClusterDSTest) testAccCheckCloudAutonomousVmClusterDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_odb_cloud_autonomous_vm_cluster" { + continue + } + + _, err := tfodb.FindCloudAutonomousVmClusterByID(ctx, conn, rs.Primary.ID) + if tfresource.NotFound(err) { + return nil + } + if err != nil { + return create.Error(names.ODB, create.ErrActionCheckingDestroyed, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, err) + } + + return create.Error(names.ODB, create.ErrActionCheckingDestroyed, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, errors.New("not destroyed")) + } + + return nil + } +} +func (autonomousVMClusterDSTest) testAccPreCheck(ctx context.Context, t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + input := odb.ListCloudAutonomousVmClustersInput{} + _, err := conn.ListCloudAutonomousVmClusters(ctx, &input) + if acctest.PreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) + } + if err != nil { + t.Fatalf("unexpected PreCheck error: %s", err) + } +} + +func (autonomousVMClusterDSTest) avmcBasic() string { + exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) + odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) + avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) + domain := acctest.RandomDomainName() + emailAddress := acctest.RandomEmailAddress(domain) + exaInfraRes := autonomousVMClusterDSTestEntity.exaInfra(exaInfraDisplayName, emailAddress) + odbNetRes := autonomousVMClusterDSTestEntity.oracleDBNetwork(odbNetworkDisplayName) + res := fmt.Sprintf(` +%s + +%s + +data "aws_odb_db_servers_list" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id +} + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id = aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + preference = "NO_PREFERENCE" + } + tags = { + "env" = "dev" + } + +} + + +data "aws_odb_cloud_autonomous_vm_cluster" "test" { + id = aws_odb_cloud_autonomous_vm_cluster.test.id + +} +`, exaInfraRes, odbNetRes, avmcDisplayName) + + return res +} + +func (autonomousVMClusterDSTest) oracleDBNetwork(odbNetName string) string { + networkRes := fmt.Sprintf(` + + + + +resource "aws_odb_network" "test" { + display_name = %[1]q + availability_zone_id = "use1-az6" + client_subnet_cidr = "10.2.0.0/24" + backup_subnet_cidr = "10.2.1.0/24" + s3_access = "DISABLED" + zero_etl_access = "DISABLED" +} + + +`, odbNetName) + return networkRes +} + +func (autonomousVMClusterDSTest) exaInfra(exaInfraName, emailAddress string) string { + exaInfraRes := fmt.Sprintf(` + + + + +resource "aws_odb_cloud_exadata_infrastructure" "test" { + display_name = %[1]q + shape = "Exadata.X9M" + storage_count = 3 + compute_count = 2 + availability_zone_id = "use1-az6" + customer_contacts_to_send_to_oci = ["%[2]s"] + maintenance_window { + custom_action_timeout_in_mins = 16 + is_custom_action_timeout_enabled = true + patching_mode = "ROLLING" + preference = "NO_PREFERENCE" + } +} + + +`, exaInfraName, emailAddress) + return exaInfraRes +} diff --git a/internal/service/odb/cloud_autonomous_vm_cluster_test.go b/internal/service/odb/cloud_autonomous_vm_cluster_test.go new file mode 100644 index 000000000000..b9ef4784286e --- /dev/null +++ b/internal/service/odb/cloud_autonomous_vm_cluster_test.go @@ -0,0 +1,481 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package odb_test + +import ( + "context" + "errors" + "fmt" + "strings" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/odb" + odbtypes "github.com/aws/aws-sdk-go-v2/service/odb/types" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + sdkacctest "github.com/hashicorp/terraform-plugin-testing/helper/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "github.com/hashicorp/terraform-provider-aws/internal/acctest" + "github.com/hashicorp/terraform-provider-aws/internal/conns" + "github.com/hashicorp/terraform-provider-aws/internal/create" + "github.com/hashicorp/terraform-provider-aws/internal/errs" + tfodb "github.com/hashicorp/terraform-provider-aws/internal/service/odb" + "github.com/hashicorp/terraform-provider-aws/internal/tfresource" + "github.com/hashicorp/terraform-provider-aws/names" +) + +type autonomousVMClusterResourceTest struct { + exaInfraDisplayNamePrefix string + odbNetDisplayNamePrefix string + autonomousVmClusterDisplayNamePrefix string +} + +var autonomousVMClusterResourceTestEntity = autonomousVMClusterResourceTest{ + exaInfraDisplayNamePrefix: "Ofake-exa", + odbNetDisplayNamePrefix: "oracleDB-net", + autonomousVmClusterDisplayNamePrefix: "Ofake-avmc", +} + +func TestAccODBCloudAutonomousVmCluster_basic(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var cloudAVMC odbtypes.CloudAutonomousVmCluster + + resourceName := "aws_odb_cloud_autonomous_vm_cluster.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + autonomousVMClusterResourceTestEntity.testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ODBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: autonomousVMClusterResourceTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: autonomousVMClusterResourceTestEntity.avmcBasic(), + Check: resource.ComposeAggregateTestCheckFunc( + autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &cloudAVMC), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccODBCloudAutonomousVmCluster_withAllParams(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var cloudAVMC odbtypes.CloudAutonomousVmCluster + + resourceName := "aws_odb_cloud_autonomous_vm_cluster.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + //acctest.PreCheckPartitionHasService(t, names.ODBServiceID) + autonomousVMClusterResourceTestEntity.testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ODBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: autonomousVMClusterResourceTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: autonomousVMClusterResourceTestEntity.avmcAllParamsConfig(), + Check: resource.ComposeAggregateTestCheckFunc( + autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &cloudAVMC), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccODBCloudAutonomousVmCluster_tagging(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var avmc1, avmc2 odbtypes.CloudAutonomousVmCluster + resourceName := "aws_odb_cloud_autonomous_vm_cluster.test" + withoutTag, withTag := autonomousVMClusterResourceTestEntity.avmcNoTagWithTag() + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + autonomousVMClusterResourceTestEntity.testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ODBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: autonomousVMClusterResourceTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), + + Steps: []resource.TestStep{ + { + Config: withoutTag, + + Check: resource.ComposeAggregateTestCheckFunc( + autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &avmc1), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: withTag, + Check: resource.ComposeAggregateTestCheckFunc( + autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &avmc2), + resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"), + resource.TestCheckResourceAttr(resourceName, "tags.env", "dev"), + resource.ComposeTestCheckFunc(func(state *terraform.State) error { + if strings.Compare(*(avmc1.CloudAutonomousVmClusterId), *(avmc2.CloudAutonomousVmClusterId)) != 0 { + return errors.New("shouldn't create a new autonomous vm cluster") + } + return nil + }), + ), + }, + }, + }) +} + +func TestAccODBCloudAutonomousVmCluster_disappears(t *testing.T) { + ctx := acctest.Context(t) + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var cloudautonomousvmcluster odbtypes.CloudAutonomousVmCluster + resourceName := "aws_odb_cloud_autonomous_vm_cluster.test" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(ctx, t) + autonomousVMClusterResourceTestEntity.testAccPreCheck(ctx, t) + }, + ErrorCheck: acctest.ErrorCheck(t, names.ODBServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: autonomousVMClusterResourceTestEntity.testAccCheckCloudAutonomousVmClusterDestroy(ctx), + Steps: []resource.TestStep{ + { + Config: autonomousVMClusterResourceTestEntity.avmcBasic(), + Check: resource.ComposeAggregateTestCheckFunc( + autonomousVMClusterResourceTestEntity.checkCloudAutonomousVmClusterExists(ctx, resourceName, &cloudautonomousvmcluster), + acctest.CheckFrameworkResourceDisappears(ctx, acctest.Provider, tfodb.ResourceCloudAutonomousVMCluster, resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func (autonomousVMClusterResourceTest) testAccPreCheck(ctx context.Context, t *testing.T) { + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + input := odb.ListCloudAutonomousVmClustersInput{} + _, err := conn.ListCloudAutonomousVmClusters(ctx, &input) + if acctest.PreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) + } + if err != nil { + t.Fatalf("unexpected PreCheck error: %s", err) + } +} +func (autonomousVMClusterResourceTest) testAccCheckCloudAutonomousVmClusterDestroy(ctx context.Context) resource.TestCheckFunc { + return func(s *terraform.State) error { + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_odb_cloud_autonomous_vm_cluster" { + continue + } + + _, err := autonomousVMClusterResourceTestEntity.findAVMC(ctx, conn, rs.Primary.ID) + if tfresource.NotFound(err) { + return nil + } + if err != nil { + return create.Error(names.ODB, create.ErrActionCheckingDestroyed, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, err) + } + + return create.Error(names.ODB, create.ErrActionCheckingDestroyed, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, errors.New("not destroyed")) + } + + return nil + } +} + +func (autonomousVMClusterResourceTest) checkCloudAutonomousVmClusterExists(ctx context.Context, name string, cloudAutonomousVMCluster *odbtypes.CloudAutonomousVmCluster) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, name, errors.New("not found")) + } + + if rs.Primary.ID == "" { + return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, name, errors.New("not set")) + } + + conn := acctest.Provider.Meta().(*conns.AWSClient).ODBClient(ctx) + resp, err := autonomousVMClusterResourceTestEntity.findAVMC(ctx, conn, rs.Primary.ID) + if err != nil { + return create.Error(names.ODB, create.ErrActionCheckingExistence, tfodb.ResNameCloudAutonomousVmCluster, rs.Primary.ID, err) + } + + *cloudAutonomousVMCluster = *resp + + return nil + } +} + +func (autonomousVMClusterResourceTest) findAVMC(ctx context.Context, conn *odb.Client, id string) (*odbtypes.CloudAutonomousVmCluster, error) { + input := odb.GetCloudAutonomousVmClusterInput{ + CloudAutonomousVmClusterId: aws.String(id), + } + out, err := conn.GetCloudAutonomousVmCluster(ctx, &input) + if err != nil { + if errs.IsA[*odbtypes.ResourceNotFoundException](err) { + return nil, &retry.NotFoundError{ + LastError: err, + LastRequest: &input, + } + } + return nil, err + } + + if out == nil || out.CloudAutonomousVmCluster == nil { + return nil, tfresource.NewEmptyResultError(&input) + } + + return out.CloudAutonomousVmCluster, nil +} + +func (autonomousVMClusterResourceTest) avmcBasic() string { + exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) + odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) + avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) + domain := acctest.RandomDomainName() + emailAddress := acctest.RandomEmailAddress(domain) + exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName, emailAddress) + odbNetRes := autonomousVMClusterResourceTestEntity.oracleDBNetwork(odbNetworkDisplayName) + res := fmt.Sprintf(` +%s + +%s + +data "aws_odb_db_servers_list" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id +} + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id = aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + preference = "NO_PREFERENCE" + } + +} + + + + +`, exaInfraRes, odbNetRes, avmcDisplayName) + + return res +} + +func (autonomousVMClusterResourceTest) avmcNoTagWithTag() (string, string) { + exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) + odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) + avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) + domain := acctest.RandomDomainName() + emailAddress := acctest.RandomEmailAddress(domain) + exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName, emailAddress) + odbNetRes := autonomousVMClusterResourceTestEntity.oracleDBNetwork(odbNetworkDisplayName) + noTag := fmt.Sprintf(` +%s + +%s + +data "aws_odb_db_servers_list" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id +} + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id = aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + preference = "NO_PREFERENCE" + } + +} + + + + +`, exaInfraRes, odbNetRes, avmcDisplayName) + withTag := fmt.Sprintf(` +%s + +%s + +data "aws_odb_db_servers_list" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id +} + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id = aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + preference = "NO_PREFERENCE" + } + tags = { + "env" = "dev" + } + +} + + + + +`, exaInfraRes, odbNetRes, avmcDisplayName) + + return noTag, withTag +} + +func (autonomousVMClusterResourceTest) avmcAllParamsConfig() string { + exaInfraDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.exaInfraDisplayNamePrefix) + odbNetworkDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.odbNetDisplayNamePrefix) + avmcDisplayName := sdkacctest.RandomWithPrefix(autonomousVMClusterDSTestEntity.autonomousVmClusterDisplayNamePrefix) + domain := acctest.RandomDomainName() + emailAddress := acctest.RandomEmailAddress(domain) + exaInfraRes := autonomousVMClusterResourceTestEntity.exaInfra(exaInfraDisplayName, emailAddress) + odbNetRes := autonomousVMClusterResourceTestEntity.oracleDBNetwork(odbNetworkDisplayName) + res := fmt.Sprintf(` +%s + +%s + +data "aws_odb_db_servers_list" "test" { + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id +} + +resource "aws_odb_cloud_autonomous_vm_cluster" "test" { + description = "my first avmc" + time_zone = "UTC" + cloud_exadata_infrastructure_id = aws_odb_cloud_exadata_infrastructure.test.id + odb_network_id = aws_odb_network.test.id + display_name = %[3]q + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = [for db_server in data.aws_odb_db_servers_list.test.db_servers : db_server.id] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + days_of_week = [{ name = "MONDAY" }, { name = "TUESDAY" }] + hours_of_day = [4, 16] + lead_time_in_weeks = 3 + months = [{ name = "FEBRUARY" }, { name = "MAY" }, { name = "AUGUST" }, { name = "NOVEMBER" }] + preference = "CUSTOM_PREFERENCE" + weeks_of_month = [2, 4] + } + tags = { + "env" = "dev" + } + +} + + + + +`, exaInfraRes, odbNetRes, avmcDisplayName) + + return res +} + +func (autonomousVMClusterResourceTest) oracleDBNetwork(odbNetName string) string { + networkRes := fmt.Sprintf(` + + + + +resource "aws_odb_network" "test" { + display_name = %[1]q + availability_zone_id = "use1-az6" + client_subnet_cidr = "10.2.0.0/24" + backup_subnet_cidr = "10.2.1.0/24" + s3_access = "DISABLED" + zero_etl_access = "DISABLED" +} + + +`, odbNetName) + return networkRes +} + +func (autonomousVMClusterResourceTest) exaInfra(exaDisplayName, emailAddress string) string { + resource := fmt.Sprintf(` +resource "aws_odb_cloud_exadata_infrastructure" "test" { + display_name = %[1]q + shape = "Exadata.X9M" + storage_count = 3 + compute_count = 2 + availability_zone_id = "use1-az6" + customer_contacts_to_send_to_oci = [{ email = "%[2]s" }] + maintenance_window { + custom_action_timeout_in_mins = 16 + is_custom_action_timeout_enabled = true + patching_mode = "ROLLING" + preference = "NO_PREFERENCE" + } +} +`, exaDisplayName, emailAddress) + + return resource +} diff --git a/internal/service/odb/service_package_gen.go b/internal/service/odb/service_package_gen.go index 952fb1922304..ccb059cc69d8 100644 --- a/internal/service/odb/service_package_gen.go +++ b/internal/service/odb/service_package_gen.go @@ -19,6 +19,15 @@ type servicePackage struct{} func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*inttypes.ServicePackageFrameworkDataSource { return []*inttypes.ServicePackageFrameworkDataSource{ + { + Factory: newDataSourceCloudAutonomousVmCluster, + TypeName: "aws_odb_cloud_autonomous_vm_cluster", + Name: "Cloud Autonomous Vm Cluster", + Tags: unique.Make(inttypes.ServicePackageResourceTags{ + IdentifierAttribute: names.AttrARN, + }), + Region: unique.Make(inttypes.ResourceRegionDefault()), + }, { Factory: newDataSourceCloudExadataInfrastructure, TypeName: "aws_odb_cloud_exadata_infrastructure", @@ -42,6 +51,15 @@ func (p *servicePackage) FrameworkDataSources(ctx context.Context) []*inttypes.S func (p *servicePackage) FrameworkResources(ctx context.Context) []*inttypes.ServicePackageFrameworkResource { return []*inttypes.ServicePackageFrameworkResource{ + { + Factory: newResourceCloudAutonomousVmCluster, + TypeName: "aws_odb_cloud_autonomous_vm_cluster", + Name: "Cloud Autonomous Vm Cluster", + Tags: unique.Make(inttypes.ServicePackageResourceTags{ + IdentifierAttribute: names.AttrARN, + }), + Region: unique.Make(inttypes.ResourceRegionDefault()), + }, { Factory: newResourceCloudExadataInfrastructure, TypeName: "aws_odb_cloud_exadata_infrastructure", diff --git a/internal/service/sagemaker/endpoint_configuration.go b/internal/service/sagemaker/endpoint_configuration.go index 544ed48baefd..c64f2ad67fc0 100644 --- a/internal/service/sagemaker/endpoint_configuration.go +++ b/internal/service/sagemaker/endpoint_configuration.go @@ -1107,6 +1107,9 @@ func expandEndpointConfigNotificationConfig(configured []any) *awstypes.AsyncInf if len(configured) == 0 { return nil } + if configured[0] == nil { + return &awstypes.AsyncInferenceNotificationConfig{} + } m := configured[0].(map[string]any) diff --git a/internal/service/sagemaker/endpoint_configuration_test.go b/internal/service/sagemaker/endpoint_configuration_test.go index 50b6d1dbb26a..753f82681527 100644 --- a/internal/service/sagemaker/endpoint_configuration_test.go +++ b/internal/service/sagemaker/endpoint_configuration_test.go @@ -769,6 +769,24 @@ func TestAccSageMakerEndpointConfiguration_Async_notif(t *testing.T) { ImportState: true, ImportStateVerify: true, }, + { + Config: testAccEndpointConfigurationConfig_asyncNotifEmpty(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckEndpointConfigurationExists(ctx, resourceName), + resource.TestCheckResourceAttr(resourceName, names.AttrName, rName), + resource.TestCheckResourceAttr(resourceName, "async_inference_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "async_inference_config.0.client_config.#", "0"), + resource.TestCheckResourceAttr(resourceName, "async_inference_config.0.output_config.#", "1"), + resource.TestCheckResourceAttrSet(resourceName, "async_inference_config.0.output_config.0.s3_output_path"), + resource.TestCheckResourceAttr(resourceName, "async_inference_config.0.output_config.0.notification_config.#", "1"), + resource.TestCheckResourceAttr(resourceName, "async_inference_config.0.output_config.0.notification_config.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, }, }) } @@ -1523,6 +1541,46 @@ resource "aws_sagemaker_endpoint_configuration" "test" { `, rName)) } +func testAccEndpointConfigurationConfig_asyncNotifEmpty(rName string) string { + return acctest.ConfigCompose(testAccEndpointConfigurationConfig_base(rName), fmt.Sprintf(` +resource "aws_s3_bucket" "test" { + bucket = %[1]q + force_destroy = true +} + +resource "aws_sns_topic" "test" { + name = %[1]q +} + +resource "aws_kms_key" "test" { + description = %[1]q + deletion_window_in_days = 7 + enable_key_rotation = true +} + +resource "aws_sagemaker_endpoint_configuration" "test" { + name = %[1]q + + production_variants { + variant_name = "variant-1" + model_name = aws_sagemaker_model.test.name + initial_instance_count = 2 + instance_type = "ml.t2.medium" + initial_variant_weight = 1 + } + + async_inference_config { + output_config { + s3_output_path = "s3://${aws_s3_bucket.test.bucket}/" + kms_key_id = aws_kms_key.test.arn + + notification_config {} + } + } +} +`, rName)) +} + func testAccEndpointConfigurationConfig_asyncNotifInferenceIn(rName string) string { return acctest.ConfigCompose(testAccEndpointConfigurationConfig_base(rName), fmt.Sprintf(` resource "aws_s3_bucket" "test" { diff --git a/website/docs/d/billing_views.html.markdown b/website/docs/d/billing_views.html.markdown new file mode 100644 index 000000000000..7933857e18ef --- /dev/null +++ b/website/docs/d/billing_views.html.markdown @@ -0,0 +1,53 @@ +--- +subcategory: "Billing" +layout: "aws" +page_title: "AWS: aws_billing_views" +description: |- + Retrieve a list of AWS Billing Views. +--- + +# Data Source: aws_billing_views + +Provides details about an AWS Billing Views. + +## Example Usage + +### Basic Usage + +```terraform +data "aws_billing_views" "example" { + billing_view_types = ["PRIMARY"] +} + +output "primary_view_arn_by_types" { + value = data.aws_billing_views.example.billing_view[0].arn +} +``` + +```terraform +data "aws_billing_views" "example" {} + +output "view_arns" { + value = [for view in data.aws_billing_views.example.billing_view : view.arn] +} + +output "primary_view_arn_by_name" { + value = [for view in data.aws_billing_views.example.billing_view : view.arn if view.name == "Primary View"][0] +} +``` + +## Argument Reference + +The following arguments are optional: + +* `billing_view_types` - (Optional) List of billing view types to retrieve. Valid values are `PRIMARY`, `BILLING_GROUP`, `CUSTOM`. + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `billing_view` - List of billing view objects with the following attributes: + * `arn` - ARN of the billing view. + * `description` - Description of the billing view. + * `name` - Name of the billing view. + * `owner_account_id` - Account ID of the billing view owner. diff --git a/website/docs/d/odb_cloud_autonomous_vm_cluster.html.markdown b/website/docs/d/odb_cloud_autonomous_vm_cluster.html.markdown new file mode 100644 index 000000000000..93994d0b85e6 --- /dev/null +++ b/website/docs/d/odb_cloud_autonomous_vm_cluster.html.markdown @@ -0,0 +1,84 @@ +--- +subcategory: "Oracle Database@AWS" +layout: "AWS: aws_odb_cloud_autonomous_vm_cluster" +page_title: "AWS: aws_odb_cloud_autonomous_vm_cluster" +description: |- + Terraform data source for managing cloud autonomous vm cluster resource in AWS for Oracle Database@AWS. +--- + +# Data Source: aws_odb_cloud_autonomous_vm_cluster + +Terraform data source for managing cloud autonomous vm cluster resource in AWS for Oracle Database@AWS. + +You can find out more about Oracle Database@AWS from [User Guide](https://docs.aws.amazon.com/odb/latest/UserGuide/what-is-odb.html). + +## Example Usage + +### Basic Usage + +```terraform +data "aws_odb_cloud_autonomous_vm_cluster" "example" { + id = "example" +} +``` + +## Argument Reference + +The following arguments are optional: + +* `id` - (Required) The unique identifier of the cloud autonomous vm cluster. +* `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference). + +## Attribute Reference + +This data source exports the following attributes in addition to the arguments above: + +* `arn` - The Amazon Resource Name (ARN) for the Exadata infrastructure. +* `cloud_exadata_infrastructure_id` - Cloud exadata infrastructure id associated with this cloud autonomous VM cluster. +* `autonomous_data_storage_percentage` - The percentage of data storage currently in use for Autonomous Databases in the Autonomous VM cluster. +* `autonomous_data_storage_size_in_tbs` - The data storage size allocated for Autonomous Databases in the Autonomous VM cluster, in TB. +* `available_autonomous_data_storage_size_in_tbs` - The available data storage space for Autonomous Databases in the Autonomous VM cluster, in TB. +* `available_container_databases` - The number of Autonomous CDBs that you can create with the currently available storage. +* `available_cpus` - The number of CPU cores available for allocation to Autonomous Databases. +* `compute_model` - The compute model of the Autonomous VM cluster: ECPU or OCPU. +* `cpu_core_count` - The total number of CPU cores in the Autonomous VM cluster. +* `cpu_core_count_per_node` - The number of CPU cores enabled per node in the Autonomous VM cluster. +* `cpu_percentage` - he percentage of total CPU cores currently in use in the Autonomous VM cluster. +* `created_at` - The date and time when the Autonomous VM cluster was created. +* `data_storage_size_in_gbs` - The total data storage allocated to the Autonomous VM cluster, in GB. +* `data_storage_size_in_tbs` - The total data storage allocated to the Autonomous VM cluster, in TB. +* `odb_node_storage_size_in_gbs` - The local node storage allocated to the Autonomous VM cluster, in gigabytes (GB). +* `db_servers` - The list of database servers associated with the Autonomous VM cluster. +* `description` - The user-provided description of the Autonomous VM cluster. +* `display_name` - The display name of the Autonomous VM cluster. +* `domain` - The domain name of the Autonomous VM cluster. +* `exadata_storage_in_tbs_lowest_scaled_value` - The minimum value to which you can scale down the Exadata storage, in TB. +* `hostname` - The hostname of the Autonomous VM cluster. +* `is_mtls_enabled_vm_cluster` - Indicates whether mutual TLS (mTLS) authentication is enabled for the Autonomous VM cluster. +* `license_model` - The Oracle license model that applies to the Autonomous VM cluster. Valid values are LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE. +* `max_acds_lowest_scaled_value` - The minimum value to which you can scale down the maximum number of Autonomous CDBs. +* `memory_per_oracle_compute_unit_in_gbs` - The amount of memory allocated per Oracle Compute Unit, in GB. +* `memory_size_in_gbs` - The total amount of memory allocated to the Autonomous VM cluster, in gigabytes (GB). +* `node_count` - The number of database server nodes in the Autonomous VM cluster. +* `non_provisionable_autonomous_container_databases` - The number of Autonomous CDBs that can't be provisioned because of resource constraints. +* `oci_resource_anchor_name` - The name of the OCI resource anchor associated with this Autonomous VM cluster. +* `oci_url` - The URL for accessing the OCI console page for this Autonomous VM cluster. +* `ocid` - The Oracle Cloud Identifier (OCID) of the Autonomous VM cluster. +* `odb_network_id` - The unique identifier of the ODB network associated with this Autonomous VM cluster. +* `percent_progress` - The progress of the current operation on the Autonomous VM cluster, as a percentage. +* `provisionable_autonomous_container_databases` - The number of Autonomous CDBs that can be provisioned in the Autonomous VM cluster. +* `provisioned_autonomous_container_databases` - The number of Autonomous CDBs currently provisioned in the Autonomous VM cluster. +* `provisioned_cpus` - The number of CPU cores currently provisioned in the Autonomous VM cluster. +* `reclaimable_cpus` - The number of CPU cores that can be reclaimed from terminated or scaled-down Autonomous Databases. +* `reserved_cpus` - The number of CPU cores reserved for system operations and redundancy. +* `scan_listener_port_non_tls` - The SCAN listener port for non-TLS (TCP) protocol. The default is 1521. +* `scan_listener_port_tls` - The SCAN listener port for TLS (TCP) protocol. The default is 2484. +* `shape` - The shape of the Exadata infrastructure for the Autonomous VM cluster. +* `status` - The status of the Autonomous VM cluster. +* `status_reason` - Additional information about the current status of the Autonomous VM cluster. +* `time_database_ssl_certificate_expires` - The expiration date and time of the database SSL certificate. +* `time_ords_certificate_expires` - The expiration date and time of the Oracle REST Data Services (ORDS)certificate. +* `time_zone` - The time zone of the Autonomous VM cluster. +* `total_container_databases` - The total number of Autonomous Container Databases that can be created with the allocated local storage. +* `tags` - A map of tags to assign to the exadata infrastructure. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. +* `maintenance_window` - The maintenance window for the Autonomous VM cluster. diff --git a/website/docs/r/autoscaling_group.html.markdown b/website/docs/r/autoscaling_group.html.markdown index bbe33e98dc50..e62672f5fcee 100644 --- a/website/docs/r/autoscaling_group.html.markdown +++ b/website/docs/r/autoscaling_group.html.markdown @@ -684,7 +684,7 @@ This configuration block supports the following: - `instance_warmup` - (Optional) Number of seconds until a newly launched instance is configured and ready to use. Default behavior is to use the Auto Scaling Group's health check grace period. - `max_healthy_percentage` - (Optional) Amount of capacity in the Auto Scaling group that can be in service and healthy, or pending, to support your workload when an instance refresh is in place, as a percentage of the desired capacity of the Auto Scaling group. Values must be between `100` and `200`, defaults to `100`. - `min_healthy_percentage` - (Optional) Amount of capacity in the Auto Scaling group that must remain healthy during an instance refresh to allow the operation to continue, as a percentage of the desired capacity of the Auto Scaling group. Defaults to `90`. - - `skip_matching` - (Optional) Replace instances that already have your desired configuration. Defaults to `false`. + - `skip_matching` - (Optional) Skip replacing instances that already have your desired configuration. Defaults to `false`. - `auto_rollback` - (Optional) Automatically rollback if instance refresh fails. Defaults to `false`. This option may only be set to `true` when specifying a `launch_template` or `mixed_instances_policy`. - `alarm_specification` - (Optional) Alarm Specification for Instance Refresh. - `alarms` - (Required) List of Cloudwatch alarms. If any of these alarms goes into ALARM state, Instance Refresh is failed. diff --git a/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown new file mode 100644 index 000000000000..391a2b013a5b --- /dev/null +++ b/website/docs/r/odb_cloud_autonomous_vm_cluster.html.markdown @@ -0,0 +1,168 @@ +--- +subcategory: "Oracle Database@AWS" +layout: "AWS: aws_odb_cloud_autonomous_vm_cluster" +page_title: "AWS: aws_odb_cloud_autonomous_vm_cluster" +description: |- + Terraform resource managing cloud autonomous vm cluster in AWS for Oracle Database@AWS. +--- + +# Resource: aws_odb_cloud_autonomous_vm_cluster + +Terraform resource managing cloud autonomous vm cluster in AWS for Oracle Database@AWS. + +You can find out more about Oracle Database@AWS from [User Guide](https://docs.aws.amazon.com/odb/latest/UserGuide/what-is-odb.html). + +## Example Usage + +### Basic Usage + +```terraform +resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_minimum_parameters" { + cloud_exadata_infrastructure_id = "" # refer your exadata infra id + odb_network_id = "" # refer_your_odb_net_id + display_name = "Ofake-avmc-my_avmc" + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + # ids of db server. refer your exa infra. This is a manadatory fileld. Refer your cloud exadata infrastructure for db server id + db_servers = [""] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + preference = "NO_PREFERENCE" + } + +} + + +resource "aws_odb_cloud_autonomous_vm_cluster" "avmc_with_all_params" { + description = "my first avmc" + time_zone = "UTC" + cloud_exadata_infrastructure_id = "" + odb_network_id = "" + display_name = "Ofake_my avmc" + autonomous_data_storage_size_in_tbs = 5 + memory_per_oracle_compute_unit_in_gbs = 2 + total_container_databases = 1 + cpu_core_count_per_node = 40 + license_model = "LICENSE_INCLUDED" + db_servers = ["", ""] + scan_listener_port_tls = 8561 + scan_listener_port_non_tls = 1024 + maintenance_window { + days_of_week = [{ name = "MONDAY" }, { name = "TUESDAY" }] + hours_of_day = [4, 16] + lead_time_in_weeks = 3 + months = [{ name = "FEBRUARY" }, { name = "MAY" }, { name = "AUGUST" }, { name = "NOVEMBER" }] + preference = "CUSTOM_PREFERENCE" + weeks_of_month = [2, 4] + } + tags = { + "env" = "dev" + } + +} + +``` + +## Argument Reference + +The following arguments are required: + +* `cloud_exadata_infrastructure_id` - (Required) Exadata infrastructure id. Changing this will force terraform to create new resource. +* `autonomous_data_storage_size_in_tbs` - (Required) The data storage size allocated for Autonomous Databases in the Autonomous VM cluster, in TB. Changing this will force terraform to create new resource. +* `cpu_core_count_per_node` - (Required) The number of CPU cores enabled per node in the Autonomous VM cluster. Changing this will force terraform to create new resource. +* `db_servers` - (Required) The database servers in the Autonomous VM cluster. Changing this will force terraform to create new resource. +* `display_name` - (Required) The display name of the Autonomous VM cluster. Changing this will force terraform to create new resource. +* `memory_per_oracle_compute_unit_in_gbs` - (Required) The amount of memory allocated per Oracle Compute Unit, in GB. Changing this will force terraform to create new resource. +* `odb_network_id` - (Required) The unique identifier of the ODB network associated with this Autonomous VM Cluster. Changing this will force terraform to create new resource. +* `scan_listener_port_non_tls` - (Required) The SCAN listener port for non-TLS (TCP) protocol. The default is 1521. Changing this will force terraform to create new resource. +* `scan_listener_port_tls` - (Required) The SCAN listener port for TLS (TCP) protocol. The default is 2484. Changing this will force terraform to create new resource. +* `total_container_databases` - (Required) The total number of Autonomous Container Databases that can be created with the allocated local storage. Changing this will force terraform to create new resource. +* `maintenance_window` - (Required) The maintenance window of the Autonomous VM cluster. Changing this will force terraform to create new resource. + +The following arguments are optional: + +* `description` - (Optional) The description of the Autonomous VM cluster. +* `is_mtls_enabled_vm_cluster` - (Optional) Indicates whether mutual TLS (mTLS) authentication is enabled for the Autonomous VM cluster. Changing this will force terraform to create new resource. +* `license_model` - (Optional) The license model for the Autonomous VM cluster. Valid values are LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE. Changing this will force terraform to create new resource. +* `time_zone` - (Optional) The time zone of the Autonomous VM cluster. Changing this will force terraform to create new resource. +* `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference). +* `tags` - (Optional) A map of tags to assign to the exadata infrastructure. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. + +### maintenance_window + +* `preference` - (Required) The preference for the maintenance window scheduling. Changing this will force terraform to create new resource. +* `days_of_week` - (Optional) The days of the week when maintenance can be performed. Changing this will force terraform to create new resource. +* `hours_of_day` - (Optional) The hours of the day when maintenance can be performed. Changing this will force terraform to create new resource. +* `lead_time_in_weeks` - (Optional) The lead time in weeks before the maintenance window. Changing this will force terraform to create new resource. +* `months` - (Optional) The months when maintenance can be performed. Changing this will force terraform to create new resource. +* `weeks_of_month` - (Optional) Indicates whether to skip release updates during maintenance. Changing this will force terraform to create new resource. + +## Attribute Reference + +This resource exports the following attributes in addition to the arguments above: + +* `arn` - The Amazon Resource Name (ARN) for the Exadata infrastructure. +* `autonomous_data_storage_percentage` - The progress of the current operation on the Autonomous VM cluster, as a percentage. +* `available_autonomous_data_storage_size_in_tbs` - The available data storage space for Autonomous Databases in the Autonomous VM cluster, in TB. +* `available_container_databases` - The number of Autonomous CDBs that you can create with the currently available storage. +* `available_cpus` - The number of CPU cores available for allocation to Autonomous Databases. +* `compute_model` - The compute model of the Autonomous VM cluster: ECPU or OCPU. +* `cpu_core_count` - The total number of CPU cores in the Autonomous VM cluster. +* `cpu_percentage` - The percentage of total CPU cores currently in use in the Autonomous VM cluster. +* `created_at` - The date and time when the Autonomous VM cluster was created. +* `data_storage_size_in_gbs` - The total data storage allocated to the Autonomous VM cluster, in GB. +* `data_storage_size_in_tbs` - The total data storage allocated to the Autonomous VM cluster, in TB. +* `odb_node_storage_size_in_gbs` - The local node storage allocated to the Autonomous VM cluster, in gigabytes (GB). +* `domain` - The domain name of the Autonomous VM cluster. +* `exadata_storage_in_tbs_lowest_scaled_value` - The minimum value to which you can scale down the Exadata storage, in TB. +* `hostname` - The hostname of the Autonomous VM cluster. +* `license_model` - The license model for the Autonomous VM cluster. Valid values are LICENSE_INCLUDED or BRING_YOUR_OWN_LICENSE. +* `max_acds_lowest_scaled_value` - The minimum value to which you can scale down the maximum number of Autonomous CDBs. +* `memory_size_in_gbs` - The total amount of memory allocated to the Autonomous VM cluster, in gigabytes(GB). +* `node_count` - The number of database server nodes in the Autonomous VM cluster. +* `non_provisionable_autonomous_container_databases` - The number of Autonomous CDBs that can't be provisioned because of resource constraints. +* `oci_resource_anchor_name` - The name of the OCI resource anchor associated with this Autonomous VM cluster. +* `oci_url` - The URL for accessing the OCI console page for this Autonomous VM cluster. +* `ocid` - The Oracle Cloud Identifier (OCID) of the Autonomous VM cluster. +* `percent_progress` - The progress of the current operation on the Autonomous VM cluster, as a percentage. +* `provisionable_autonomous_container_databases` - The number of Autonomous CDBs that can be provisioned in the Autonomous VM cluster. +* `provisioned_autonomous_container_databases` - The number of Autonomous CDBs currently provisioned in the Autonomous VM cluster. +* `provisioned_cpus` - The number of CPUs provisioned in the Autonomous VM cluster. +* `reclaimable_cpus` - The number of CPU cores that can be reclaimed from terminated or scaled-down Autonomous Databases. +* `reserved_cpus` - The number of CPU cores reserved for system operations and redundancy. +* `shape` - The shape of the Exadata infrastructure for the Autonomous VM cluster. +* `status` - The status of the Autonomous VM cluster. Possible values include CREATING, AVAILABLE, UPDATING, DELETING, DELETED, FAILED. +* `status_reason` - Additional information about the current status of the Autonomous VM cluster. +* `time_zone` - The time zone of the Autonomous VM cluster. +* `time_ords_certificate_expires` - The expiration date and time of the ORDS certificate. +* `time_database_ssl_certificate_expires` - The expiration date and time of the database SSL certificate. +* `tags_all` - The combined set of user-defined and provider-defined tags. + +## Timeouts + +[Configuration options](https://developer.hashicorp.com/terraform/language/resources/syntax#operation-timeouts): + +* `create` - (Default `24h`) +* `update` - (Default `24h`) +* `delete` - (Default `24h`) + +## Import + +In Terraform v1.5.0 and later, use an [`import` block](https://developer.hashicorp.com/terraform/language/import) to import OpenSearch Ingestion Pipeline using the `id`. For example: + +```terraform +import { + to = aws_odb_cloud_autonomous_vm_cluster.example + id = "example" +} +``` + +Using `terraform import`, import cloud autonomous vm cluster `id`. For example: + +```console +% terraform import aws_odb_cloud_autonomous_vm_cluster.example example +```