diff --git a/aws/data_source_aws_neptune_orderable_db_instance.go b/aws/data_source_aws_neptune_orderable_db_instance.go new file mode 100644 index 00000000000..d9a1c6a3cb2 --- /dev/null +++ b/aws/data_source_aws_neptune_orderable_db_instance.go @@ -0,0 +1,242 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/neptune" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceAwsNeptuneOrderableDbInstance() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsNeptuneOrderableDbInstanceRead, + 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, + }, + + "max_iops_per_db_instance": { + Type: schema.TypeInt, + Computed: true, + }, + + "max_iops_per_gib": { + Type: schema.TypeFloat, + Computed: true, + }, + + "max_storage_size": { + Type: schema.TypeInt, + Computed: true, + }, + + "min_iops_per_db_instance": { + Type: schema.TypeInt, + Computed: true, + }, + + "min_iops_per_gib": { + Type: schema.TypeFloat, + Computed: true, + }, + + "min_storage_size": { + Type: schema.TypeInt, + Computed: true, + }, + + "multi_az_capable": { + Type: schema.TypeBool, + Computed: true, + }, + + "preferred_db_instance_classes": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "read_replica_capable": { + Type: schema.TypeBool, + Computed: true, + }, + + "storage_type": { + Type: schema.TypeString, + Computed: true, + }, + + "supports_enhanced_monitoring": { + Type: schema.TypeBool, + Computed: true, + }, + + "supports_iam_database_authentication": { + Type: schema.TypeBool, + Computed: true, + }, + + "supports_iops": { + Type: schema.TypeBool, + Computed: true, + }, + + "supports_performance_insights": { + Type: schema.TypeBool, + Computed: true, + }, + + "supports_storage_encryption": { + Type: schema.TypeBool, + Computed: true, + }, + + "vpc": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, + }, + } +} + +func dataSourceAwsNeptuneOrderableDbInstanceRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).neptuneconn + + input := &neptune.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 Neptune Orderable DB Instance Options: %v", input) + + var instanceClassResults []*neptune.OrderableDBInstanceOption + err := conn.DescribeOrderableDBInstanceOptionsPages(input, func(resp *neptune.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 Neptune orderable DB instance options: %w", err) + } + + if len(instanceClassResults) == 0 { + return fmt.Errorf("no Neptune Orderable DB Instance options found matching criteria; try different search") + } + + // preferred classes + var found *neptune.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 Neptune 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 Neptune 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("max_iops_per_db_instance", found.MaxIopsPerDbInstance) + d.Set("max_iops_per_gib", found.MaxIopsPerGib) + d.Set("max_storage_size", found.MaxStorageSize) + d.Set("min_iops_per_db_instance", found.MinIopsPerDbInstance) + d.Set("min_iops_per_gib", found.MinIopsPerGib) + d.Set("min_storage_size", found.MinStorageSize) + d.Set("multi_az_capable", found.MultiAZCapable) + d.Set("read_replica_capable", found.ReadReplicaCapable) + d.Set("storage_type", found.StorageType) + d.Set("supports_enhanced_monitoring", found.SupportsEnhancedMonitoring) + d.Set("supports_iam_database_authentication", found.SupportsIAMDatabaseAuthentication) + d.Set("supports_iops", found.SupportsIops) + d.Set("supports_performance_insights", found.SupportsPerformanceInsights) + d.Set("supports_storage_encryption", found.SupportsStorageEncryption) + d.Set("vpc", found.Vpc) + + return nil +} diff --git a/aws/data_source_aws_neptune_orderable_db_instance_test.go b/aws/data_source_aws_neptune_orderable_db_instance_test.go new file mode 100644 index 00000000000..0516229fe39 --- /dev/null +++ b/aws/data_source_aws_neptune_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/neptune" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccAWSNeptuneOrderableDbInstanceDataSource_basic(t *testing.T) { + dataSourceName := "data.aws_neptune_orderable_db_instance.test" + engine := "neptune" + engineVersion := "1.0.2.2" + licenseModel := "amazon-license" + class := "db.t3.medium" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSNeptuneOrderableDbInstance(t) }, + Providers: testAccProviders, + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: testAccAWSNeptuneOrderableDbInstanceDataSourceConfigBasic(class, engine, engineVersion, licenseModel), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "engine", engine), + resource.TestCheckResourceAttr(dataSourceName, "engine_version", engineVersion), + resource.TestCheckResourceAttr(dataSourceName, "license_model", licenseModel), + resource.TestCheckResourceAttr(dataSourceName, "db_instance_class", class), + ), + }, + }, + }) +} + +func TestAccAWSNeptuneOrderableDbInstanceDataSource_preferred(t *testing.T) { + dataSourceName := "data.aws_neptune_orderable_db_instance.test" + engine := "neptune" + engineVersion := "1.0.3.0" + licenseModel := "amazon-license" + preferredOption := "db.r4.2xlarge" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSNeptuneOrderableDbInstance(t) }, + Providers: testAccProviders, + CheckDestroy: nil, + Steps: []resource.TestStep{ + { + Config: testAccAWSNeptuneOrderableDbInstanceDataSourceConfigPreferred(engine, engineVersion, licenseModel, preferredOption), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "engine", engine), + resource.TestCheckResourceAttr(dataSourceName, "engine_version", engineVersion), + resource.TestCheckResourceAttr(dataSourceName, "license_model", licenseModel), + resource.TestCheckResourceAttr(dataSourceName, "db_instance_class", preferredOption), + ), + }, + }, + }) +} + +func testAccPreCheckAWSNeptuneOrderableDbInstance(t *testing.T) { + conn := testAccProvider.Meta().(*AWSClient).neptuneconn + + input := &neptune.DescribeOrderableDBInstanceOptionsInput{ + Engine: aws.String("mysql"), + } + + _, 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 testAccAWSNeptuneOrderableDbInstanceDataSourceConfigBasic(class, engine, version, license string) string { + return fmt.Sprintf(` +data "aws_neptune_orderable_db_instance" "test" { + db_instance_class = %q + engine = %q + engine_version = %q + license_model = %q +} +`, class, engine, version, license) +} + +func testAccAWSNeptuneOrderableDbInstanceDataSourceConfigPreferred(engine, version, license, preferredOption string) string { + return fmt.Sprintf(` +data "aws_neptune_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 a62f3bb7dec..cf5b64e86c0 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -286,6 +286,7 @@ func Provider() *schema.Provider { "aws_msk_cluster": dataSourceAwsMskCluster(), "aws_msk_configuration": dataSourceAwsMskConfiguration(), "aws_nat_gateway": dataSourceAwsNatGateway(), + "aws_neptune_orderable_db_instance": dataSourceAwsNeptuneOrderableDbInstance(), "aws_network_acls": dataSourceAwsNetworkAcls(), "aws_network_interface": dataSourceAwsNetworkInterface(), "aws_network_interfaces": dataSourceAwsNetworkInterfaces(), diff --git a/website/docs/d/neptune_orderable_db_instance.markdown b/website/docs/d/neptune_orderable_db_instance.markdown new file mode 100644 index 00000000000..cc74ed78320 --- /dev/null +++ b/website/docs/d/neptune_orderable_db_instance.markdown @@ -0,0 +1,55 @@ +--- +subcategory: "Neptune" +layout: "aws" +page_title: "AWS: aws_neptune_orderable_db_instance" +description: |- + Information about Neptune orderable DB instances. +--- + +# Data Source: aws_neptune_orderable_db_instance + +Information about Neptune orderable DB instances. + +## Example Usage + +```hcl +data "aws_neptune_orderable_db_instance" "test" { + engine = "neptune" + engine_version = "1.0.3.0" + license_model = "amazon-license" + storage_type = "aurora" + + 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 `neptune`. +* `db_instance_class` - (Optional) DB instance class. Examples of classes are `db.r5.large`, `db.r5.xlarge`, `db.r4.large`, `db.r5.4xlarge`, `db.r5.12xlarge`, `db.r4.xlarge`, and `db.t3.medium`. +* `engine_version` - (Optional) Version of the DB engine. For example, `1.0.1.0`, `1.0.1.2`, `1.0.2.2`, and `1.0.3.0`. +* `license_model` - (Optional) License model. For example, `amazon-license`. +* `preferred_db_instance_classes` - (Optional) Ordered list of preferred Neptune 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 attributes are exported: + +* `availability_zones` - Availability zones where the instance is available. +* `max_iops_per_db_instance` - Maximum total provisioned IOPS for a DB instance. +* `max_iops_per_gib` - Maximum provisioned IOPS per GiB for a DB instance. +* `max_storage_size` - Maximum storage size for a DB instance. +* `min_iops_per_db_instance` - Minimum total provisioned IOPS for a DB instance. +* `min_iops_per_gib` - Minimum provisioned IOPS per GiB for a DB instance. +* `min_storage_size` - Minimum storage size for a DB instance. +* `multi_az_capable` - Whether a DB instance is Multi-AZ capable. +* `read_replica_capable` - Whether a DB instance can have a read replica. +* `storage_type` - The storage type for a DB instance. +* `supports_enhanced_monitoring` - Whether a DB instance supports Enhanced Monitoring at intervals from 1 to 60 seconds. +* `supports_iam_database_authentication` - Whether a DB instance supports IAM database authentication. +* `supports_iops` - Whether a DB instance supports provisioned IOPS. +* `supports_performance_insights` - Whether a DB instance supports Performance Insights. +* `supports_storage_encryption` - Whether a DB instance supports encrypted storage.