diff --git a/aws/data_source_aws_docdb_orderable_db_instance.go b/aws/data_source_aws_docdb_orderable_db_instance.go new file mode 100644 index 00000000000..73c29db3139 --- /dev/null +++ b/aws/data_source_aws_docdb_orderable_db_instance.go @@ -0,0 +1,158 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/docdb" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceAwsDocdbOrderableDbInstance() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsDocdbOrderableDbInstanceRead, + Schema: map[string]*schema.Schema{ + "availability_zones": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "db_instance_class": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "engine": { + Type: schema.TypeString, + Required: true, + }, + + "engine_version": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "license_model": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "preferred_db_instance_classes": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "vpc": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + }, + } +} + +func dataSourceAwsDocdbOrderableDbInstanceRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).docdbconn + + input := &docdb.DescribeOrderableDBInstanceOptionsInput{} + + if v, ok := d.GetOk("db_instance_class"); ok { + input.DBInstanceClass = aws.String(v.(string)) + } + + if v, ok := d.GetOk("engine"); ok { + input.Engine = aws.String(v.(string)) + } + + if v, ok := d.GetOk("engine_version"); ok { + input.EngineVersion = aws.String(v.(string)) + } + + if v, ok := d.GetOk("license_model"); ok { + input.LicenseModel = aws.String(v.(string)) + } + + if v, ok := d.GetOk("vpc"); ok { + input.Vpc = aws.Bool(v.(bool)) + } + + log.Printf("[DEBUG] Reading DocDB Orderable DB Instance Options: %v", input) + var instanceClassResults []*docdb.OrderableDBInstanceOption + + err := conn.DescribeOrderableDBInstanceOptionsPages(input, func(resp *docdb.DescribeOrderableDBInstanceOptionsOutput, lastPage bool) bool { + for _, instanceOption := range resp.OrderableDBInstanceOptions { + if instanceOption == nil { + continue + } + + instanceClassResults = append(instanceClassResults, instanceOption) + } + return !lastPage + }) + + if err != nil { + return fmt.Errorf("error reading DocDB orderable DB instance options: %w", err) + } + + if len(instanceClassResults) == 0 { + return fmt.Errorf("no DocDB Orderable DB Instance options found matching criteria; try different search") + } + + // preferred classes + var found *docdb.OrderableDBInstanceOption + if l := d.Get("preferred_db_instance_classes").([]interface{}); len(l) > 0 { + for _, elem := range l { + preferredInstanceClass, ok := elem.(string) + + if !ok { + continue + } + + for _, instanceClassResult := range instanceClassResults { + if preferredInstanceClass == aws.StringValue(instanceClassResult.DBInstanceClass) { + found = instanceClassResult + break + } + } + + if found != nil { + break + } + } + } + + if found == nil && len(instanceClassResults) > 1 { + return fmt.Errorf("multiple DocDB DB Instance Classes (%v) match the criteria; try a different search", instanceClassResults) + } + + if found == nil && len(instanceClassResults) == 1 { + found = instanceClassResults[0] + } + + if found == nil { + return fmt.Errorf("no DocDB DB Instance Classes match the criteria; try a different search") + } + + d.SetId(aws.StringValue(found.DBInstanceClass)) + + d.Set("db_instance_class", found.DBInstanceClass) + + var availabilityZones []string + for _, az := range found.AvailabilityZones { + availabilityZones = append(availabilityZones, aws.StringValue(az.Name)) + } + d.Set("availability_zones", availabilityZones) + + d.Set("engine", found.Engine) + d.Set("engine_version", found.EngineVersion) + d.Set("license_model", found.LicenseModel) + d.Set("vpc", found.Vpc) + + return nil +} diff --git a/aws/data_source_aws_docdb_orderable_db_instance_test.go b/aws/data_source_aws_docdb_orderable_db_instance_test.go new file mode 100644 index 00000000000..1f26a5b0563 --- /dev/null +++ b/aws/data_source_aws_docdb_orderable_db_instance_test.go @@ -0,0 +1,101 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/docdb" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccAWSDocdbOrderableDbInstanceDataSource_basic(t *testing.T) { + dataSourceName := "data.aws_docdb_orderable_db_instance.test" + class := "db.t3.medium" + engine := "docdb" + engineVersion := "3.6.0" + license := "na" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSDocdbOrderableDbInstance(t) }, + Providers: testAccProviders, + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: testAccAWSDocdbOrderableDbInstanceDataSourceConfigBasic(class, engine, engineVersion, license), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "db_instance_class", class), + resource.TestCheckResourceAttr(dataSourceName, "engine", engine), + resource.TestCheckResourceAttr(dataSourceName, "engine_version", engineVersion), + resource.TestCheckResourceAttr(dataSourceName, "license_model", license), + ), + }, + }, + }) +} + +func TestAccAWSDocdbOrderableDbInstanceDataSource_preferred(t *testing.T) { + dataSourceName := "data.aws_docdb_orderable_db_instance.test" + engine := "docdb" + engineVersion := "3.6.0" + license := "na" + preferredOption := "db.r5.large" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSDocdbOrderableDbInstance(t) }, + Providers: testAccProviders, + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: testAccAWSDocdbOrderableDbInstanceDataSourceConfigPreferred(engine, engineVersion, license, preferredOption), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "engine", engine), + resource.TestCheckResourceAttr(dataSourceName, "engine_version", engineVersion), + resource.TestCheckResourceAttr(dataSourceName, "license_model", license), + resource.TestCheckResourceAttr(dataSourceName, "db_instance_class", preferredOption), + ), + }, + }, + }) +} + +func testAccPreCheckAWSDocdbOrderableDbInstance(t *testing.T) { + conn := testAccProvider.Meta().(*AWSClient).docdbconn + + input := &docdb.DescribeOrderableDBInstanceOptionsInput{ + Engine: aws.String("docdb"), + } + + _, err := conn.DescribeOrderableDBInstanceOptions(input) + + if testAccPreCheckSkipError(err) { + t.Skipf("skipping acceptance testing: %s", err) + } + + if err != nil { + t.Fatalf("unexpected PreCheck error: %s", err) + } +} + +func testAccAWSDocdbOrderableDbInstanceDataSourceConfigBasic(class, engine, version, license string) string { + return fmt.Sprintf(` +data "aws_docdb_orderable_db_instance" "test" { + db_instance_class = %q + engine = %q + engine_version = %q + license_model = %q +} +`, class, engine, version, license) +} + +func testAccAWSDocdbOrderableDbInstanceDataSourceConfigPreferred(engine, version, license, preferredOption string) string { + return fmt.Sprintf(` +data "aws_docdb_orderable_db_instance" "test" { + engine = %q + engine_version = %q + license_model = %q + + preferred_db_instance_classes = ["db.xyz.xlarge", %q, "db.t3.small"] +} +`, engine, version, license, preferredOption) +} diff --git a/aws/provider.go b/aws/provider.go index cb1a6840c75..73abac74e9c 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -202,6 +202,7 @@ func Provider() *schema.Provider { "aws_db_snapshot": dataSourceAwsDbSnapshot(), "aws_db_subnet_group": dataSourceAwsDbSubnetGroup(), "aws_directory_service_directory": dataSourceAwsDirectoryServiceDirectory(), + "aws_docdb_orderable_db_instance": dataSourceAwsDocdbOrderableDbInstance(), "aws_dx_gateway": dataSourceAwsDxGateway(), "aws_dynamodb_table": dataSourceAwsDynamoDbTable(), "aws_ebs_default_kms_key": dataSourceAwsEbsDefaultKmsKey(), diff --git a/website/docs/d/docdb_orderable_db_instance.markdown b/website/docs/d/docdb_orderable_db_instance.markdown new file mode 100644 index 00000000000..9241ec48a0f --- /dev/null +++ b/website/docs/d/docdb_orderable_db_instance.markdown @@ -0,0 +1,40 @@ +--- +subcategory: "DocumentDB" +layout: "aws" +page_title: "AWS: aws_docdb_orderable_db_instance" +description: |- + Information about DocumentDB orderable DB instances. +--- + +# Data Source: aws_docdb_orderable_db_instance + +Information about DocumentDB orderable DB instances. + +## Example Usage + +```hcl +data "aws_docdb_orderable_db_instance" "test" { + engine = "docdb" + engine_version = "3.6.0" + license_model = "na" + + preferred_db_instance_classes = ["db.r5.large", "db.r4.large", "db.t3.medium"] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `engine` - (Required) DB engine. Engine values include `docdb`. +* `db_instance_class` - (Optional) DB instance class. Examples of classes are `db.r5.12xlarge`, `db.r5.24xlarge`, `db.r5.2xlarge`, `db.r5.4xlarge`, `db.r5.large`, `db.r5.xlarge`, and `db.t3.medium`. +* `engine_version` - (Optional) Version of the DB engine. For example, `3.6.0`. +* `license_model` - (Optional) License model. Examples of license models are `general-public-license`, `na`, `bring-your-own-license`, and `amazon-license`. +* `preferred_db_instance_classes` - (Optional) Ordered list of preferred DocumentDB DB instance classes. The first match in this list will be returned. If no preferred matches are found and the original search returned more than one result, an error is returned. +* `vpc` - (Optional) Boolean that indicates whether to show only VPC or non-VPC offerings. + +## Attribute Reference + +In addition to all arguments above, the following attribute is exported: + +* `availability_zones` - Availability zones where the instance is available.