Add `name_prefix` to RDS resources (#13232)
Adds `name_prefix` (or, in some cases, `identifier_prefix`) support to all AWS RDS resources.
This commit is contained in:
parent
e7c3e8df68
commit
d25c310468
|
@ -101,11 +101,19 @@ func resourceAwsDbInstance() *schema.Resource {
|
||||||
},
|
},
|
||||||
|
|
||||||
"identifier": {
|
"identifier": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ConflictsWith: []string{"identifier_prefix"},
|
||||||
|
ValidateFunc: validateRdsIdentifier,
|
||||||
|
},
|
||||||
|
"identifier_prefix": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Computed: true,
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
ValidateFunc: validateRdsId,
|
ValidateFunc: validateRdsIdentifierPrefix,
|
||||||
},
|
},
|
||||||
|
|
||||||
"instance_class": {
|
"instance_class": {
|
||||||
|
@ -336,10 +344,16 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
|
||||||
conn := meta.(*AWSClient).rdsconn
|
conn := meta.(*AWSClient).rdsconn
|
||||||
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
|
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
|
||||||
|
|
||||||
identifier := d.Get("identifier").(string)
|
var identifier string
|
||||||
// Generate a unique ID for the user
|
if v, ok := d.GetOk("identifier"); ok {
|
||||||
if identifier == "" {
|
identifier = v.(string)
|
||||||
identifier = resource.PrefixedUniqueId("tf-")
|
} else {
|
||||||
|
if v, ok := d.GetOk("identifier_prefix"); ok {
|
||||||
|
identifier = resource.PrefixedUniqueId(v.(string))
|
||||||
|
} else {
|
||||||
|
identifier = resource.UniqueId()
|
||||||
|
}
|
||||||
|
|
||||||
// SQL Server identifier size is max 15 chars, so truncate
|
// SQL Server identifier size is max 15 chars, so truncate
|
||||||
if engine := d.Get("engine").(string); engine != "" {
|
if engine := d.Get("engine").(string); engine != "" {
|
||||||
if strings.Contains(strings.ToLower(engine), "sqlserver") {
|
if strings.Contains(strings.ToLower(engine), "sqlserver") {
|
||||||
|
|
|
@ -53,6 +53,46 @@ func TestAccAWSDBInstance_basic(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBInstance_namePrefix(t *testing.T) {
|
||||||
|
var v rds.DBInstance
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSDBInstanceDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSDBInstanceConfig_namePrefix,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSDBInstanceExists("aws_db_instance.test", &v),
|
||||||
|
testAccCheckAWSDBInstanceAttributes(&v),
|
||||||
|
resource.TestMatchResourceAttr(
|
||||||
|
"aws_db_instance.test", "identifier", regexp.MustCompile("^tf-test-")),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBInstance_generatedName(t *testing.T) {
|
||||||
|
var v rds.DBInstance
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSDBInstanceDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSDBInstanceConfig_generatedName,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSDBInstanceExists("aws_db_instance.test", &v),
|
||||||
|
testAccCheckAWSDBInstanceAttributes(&v),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccAWSDBInstance_kmsKey(t *testing.T) {
|
func TestAccAWSDBInstance_kmsKey(t *testing.T) {
|
||||||
var v rds.DBInstance
|
var v rds.DBInstance
|
||||||
keyRegex := regexp.MustCompile("^arn:aws:kms:")
|
keyRegex := regexp.MustCompile("^arn:aws:kms:")
|
||||||
|
@ -613,8 +653,8 @@ resource "aws_db_instance" "bar" {
|
||||||
username = "foo"
|
username = "foo"
|
||||||
|
|
||||||
|
|
||||||
# Maintenance Window is stored in lower case in the API, though not strictly
|
# Maintenance Window is stored in lower case in the API, though not strictly
|
||||||
# documented. Terraform will downcase this to match (as opposed to throw a
|
# documented. Terraform will downcase this to match (as opposed to throw a
|
||||||
# validation error).
|
# validation error).
|
||||||
maintenance_window = "Fri:09:00-Fri:09:30"
|
maintenance_window = "Fri:09:00-Fri:09:30"
|
||||||
skip_final_snapshot = true
|
skip_final_snapshot = true
|
||||||
|
@ -628,6 +668,39 @@ resource "aws_db_instance" "bar" {
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
|
const testAccAWSDBInstanceConfig_namePrefix = `
|
||||||
|
resource "aws_db_instance" "test" {
|
||||||
|
allocated_storage = 10
|
||||||
|
engine = "MySQL"
|
||||||
|
identifier_prefix = "tf-test-"
|
||||||
|
instance_class = "db.t1.micro"
|
||||||
|
password = "password"
|
||||||
|
username = "root"
|
||||||
|
security_group_names = ["default"]
|
||||||
|
publicly_accessible = true
|
||||||
|
skip_final_snapshot = true
|
||||||
|
|
||||||
|
timeouts {
|
||||||
|
create = "30m"
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
|
const testAccAWSDBInstanceConfig_generatedName = `
|
||||||
|
resource "aws_db_instance" "test" {
|
||||||
|
allocated_storage = 10
|
||||||
|
engine = "MySQL"
|
||||||
|
instance_class = "db.t1.micro"
|
||||||
|
password = "password"
|
||||||
|
username = "root"
|
||||||
|
security_group_names = ["default"]
|
||||||
|
publicly_accessible = true
|
||||||
|
skip_final_snapshot = true
|
||||||
|
|
||||||
|
timeouts {
|
||||||
|
create = "30m"
|
||||||
|
}
|
||||||
|
}`
|
||||||
|
|
||||||
var testAccAWSDBInstanceConfigKmsKeyId = `
|
var testAccAWSDBInstanceConfigKmsKeyId = `
|
||||||
resource "aws_kms_key" "foo" {
|
resource "aws_kms_key" "foo" {
|
||||||
description = "Terraform acc test %s"
|
description = "Terraform acc test %s"
|
||||||
|
@ -720,7 +793,7 @@ func testAccReplicaInstanceConfig(val int) string {
|
||||||
|
|
||||||
parameter_group_name = "default.mysql5.6"
|
parameter_group_name = "default.mysql5.6"
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_db_instance" "replica" {
|
resource "aws_db_instance" "replica" {
|
||||||
identifier = "tf-replica-db-%d"
|
identifier = "tf-replica-db-%d"
|
||||||
backup_retention_period = 0
|
backup_retention_period = 0
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
@ -31,10 +30,19 @@ func resourceAwsDbOptionGroup() *schema.Resource {
|
||||||
Computed: true,
|
Computed: true,
|
||||||
},
|
},
|
||||||
"name": &schema.Schema{
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ConflictsWith: []string{"name_prefix"},
|
||||||
|
ValidateFunc: validateDbOptionGroupName,
|
||||||
|
},
|
||||||
|
"name_prefix": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Required: true,
|
ValidateFunc: validateDbOptionGroupNamePrefix,
|
||||||
ValidateFunc: validateDbOptionGroupName,
|
|
||||||
},
|
},
|
||||||
"engine_name": &schema.Schema{
|
"engine_name": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
@ -48,8 +56,9 @@ func resourceAwsDbOptionGroup() *schema.Resource {
|
||||||
},
|
},
|
||||||
"option_group_description": &schema.Schema{
|
"option_group_description": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
Default: "Managed by Terraform",
|
||||||
},
|
},
|
||||||
|
|
||||||
"option": &schema.Schema{
|
"option": &schema.Schema{
|
||||||
|
@ -107,11 +116,20 @@ func resourceAwsDbOptionGroupCreate(d *schema.ResourceData, meta interface{}) er
|
||||||
rdsconn := meta.(*AWSClient).rdsconn
|
rdsconn := meta.(*AWSClient).rdsconn
|
||||||
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
|
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
|
||||||
|
|
||||||
|
var groupName string
|
||||||
|
if v, ok := d.GetOk("name"); ok {
|
||||||
|
groupName = v.(string)
|
||||||
|
} else if v, ok := d.GetOk("name_prefix"); ok {
|
||||||
|
groupName = resource.PrefixedUniqueId(v.(string))
|
||||||
|
} else {
|
||||||
|
groupName = resource.UniqueId()
|
||||||
|
}
|
||||||
|
|
||||||
createOpts := &rds.CreateOptionGroupInput{
|
createOpts := &rds.CreateOptionGroupInput{
|
||||||
EngineName: aws.String(d.Get("engine_name").(string)),
|
EngineName: aws.String(d.Get("engine_name").(string)),
|
||||||
MajorEngineVersion: aws.String(d.Get("major_engine_version").(string)),
|
MajorEngineVersion: aws.String(d.Get("major_engine_version").(string)),
|
||||||
OptionGroupDescription: aws.String(d.Get("option_group_description").(string)),
|
OptionGroupDescription: aws.String(d.Get("option_group_description").(string)),
|
||||||
OptionGroupName: aws.String(d.Get("name").(string)),
|
OptionGroupName: aws.String(groupName),
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +139,7 @@ func resourceAwsDbOptionGroupCreate(d *schema.ResourceData, meta interface{}) er
|
||||||
return fmt.Errorf("Error creating DB Option Group: %s", err)
|
return fmt.Errorf("Error creating DB Option Group: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId(d.Get("name").(string))
|
d.SetId(groupName)
|
||||||
log.Printf("[INFO] DB Option Group ID: %s", d.Id())
|
log.Printf("[INFO] DB Option Group ID: %s", d.Id())
|
||||||
|
|
||||||
return resourceAwsDbOptionGroupUpdate(d, meta)
|
return resourceAwsDbOptionGroupUpdate(d, meta)
|
||||||
|
@ -343,28 +361,3 @@ func buildRDSOptionGroupARN(identifier, partition, accountid, region string) (st
|
||||||
arn := fmt.Sprintf("arn:%s:rds:%s:%s:og:%s", partition, region, accountid, identifier)
|
arn := fmt.Sprintf("arn:%s:rds:%s:%s:og:%s", partition, region, accountid, identifier)
|
||||||
return arn, nil
|
return arn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateDbOptionGroupName(v interface{}, k string) (ws []string, errors []error) {
|
|
||||||
value := v.(string)
|
|
||||||
if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"first character of %q must be a letter", k))
|
|
||||||
}
|
|
||||||
if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"only alphanumeric characters and hyphens allowed in %q", k))
|
|
||||||
}
|
|
||||||
if regexp.MustCompile(`--`).MatchString(value) {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q cannot contain two consecutive hyphens", k))
|
|
||||||
}
|
|
||||||
if regexp.MustCompile(`-$`).MatchString(value) {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q cannot end with a hyphen", k))
|
|
||||||
}
|
|
||||||
if len(value) > 255 {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q cannot be greater than 255 characters", k))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package aws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
|
@ -34,6 +35,66 @@ func TestAccAWSDBOptionGroup_basic(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBOptionGroup_namePrefix(t *testing.T) {
|
||||||
|
var v rds.OptionGroup
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSDBOptionGroup_namePrefix,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSDBOptionGroupExists("aws_db_option_group.test", &v),
|
||||||
|
testAccCheckAWSDBOptionGroupAttributes(&v),
|
||||||
|
resource.TestMatchResourceAttr(
|
||||||
|
"aws_db_option_group.test", "name", regexp.MustCompile("^tf-test-")),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBOptionGroup_generatedName(t *testing.T) {
|
||||||
|
var v rds.OptionGroup
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSDBOptionGroup_generatedName,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSDBOptionGroupExists("aws_db_option_group.test", &v),
|
||||||
|
testAccCheckAWSDBOptionGroupAttributes(&v),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBOptionGroup_defaultDescription(t *testing.T) {
|
||||||
|
var v rds.OptionGroup
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSDBOptionGroupDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccAWSDBOptionGroup_defaultDescription(acctest.RandInt()),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSDBOptionGroupExists("aws_db_option_group.test", &v),
|
||||||
|
resource.TestCheckResourceAttr(
|
||||||
|
"aws_db_option_group.test", "option_group_description", "Managed by Terraform"),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccAWSDBOptionGroup_basicDestroyWithInstance(t *testing.T) {
|
func TestAccAWSDBOptionGroup_basicDestroyWithInstance(t *testing.T) {
|
||||||
rName := fmt.Sprintf("option-group-test-terraform-%s", acctest.RandString(5))
|
rName := fmt.Sprintf("option-group-test-terraform-%s", acctest.RandString(5))
|
||||||
|
|
||||||
|
@ -160,42 +221,6 @@ func testAccCheckAWSDBOptionGroupAttributes(v *rds.OptionGroup) resource.TestChe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResourceAWSDBOptionGroupName_validation(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
Value string
|
|
||||||
ErrCount int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
Value: "testing123!",
|
|
||||||
ErrCount: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: "1testing123",
|
|
||||||
ErrCount: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: "testing--123",
|
|
||||||
ErrCount: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: "testing123-",
|
|
||||||
ErrCount: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: randomString(256),
|
|
||||||
ErrCount: 1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
|
||||||
_, errors := validateDbOptionGroupName(tc.Value, "aws_db_option_group_name")
|
|
||||||
|
|
||||||
if len(errors) != tc.ErrCount {
|
|
||||||
t.Fatalf("Expected the DB Option Group Name to trigger a validation error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckAWSDBOptionGroupExists(n string, v *rds.OptionGroup) resource.TestCheckFunc {
|
func testAccCheckAWSDBOptionGroupExists(n string, v *rds.OptionGroup) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
rs, ok := s.RootModule().Resources[n]
|
rs, ok := s.RootModule().Resources[n]
|
||||||
|
@ -387,3 +412,30 @@ resource "aws_db_option_group" "bar" {
|
||||||
}
|
}
|
||||||
`, r)
|
`, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const testAccAWSDBOptionGroup_namePrefix = `
|
||||||
|
resource "aws_db_option_group" "test" {
|
||||||
|
name_prefix = "tf-test-"
|
||||||
|
option_group_description = "Test option group for terraform"
|
||||||
|
engine_name = "mysql"
|
||||||
|
major_engine_version = "5.6"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccAWSDBOptionGroup_generatedName = `
|
||||||
|
resource "aws_db_option_group" "test" {
|
||||||
|
option_group_description = "Test option group for terraform"
|
||||||
|
engine_name = "mysql"
|
||||||
|
major_engine_version = "5.6"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
func testAccAWSDBOptionGroup_defaultDescription(n int) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "aws_db_option_group" "test" {
|
||||||
|
name = "tf-test-%d"
|
||||||
|
engine_name = "mysql"
|
||||||
|
major_engine_version = "5.6"
|
||||||
|
}
|
||||||
|
`, n)
|
||||||
|
}
|
||||||
|
|
|
@ -32,10 +32,19 @@ func resourceAwsDbParameterGroup() *schema.Resource {
|
||||||
Computed: true,
|
Computed: true,
|
||||||
},
|
},
|
||||||
"name": &schema.Schema{
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ConflictsWith: []string{"name_prefix"},
|
||||||
|
ValidateFunc: validateDbParamGroupName,
|
||||||
|
},
|
||||||
|
"name_prefix": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Required: true,
|
ValidateFunc: validateDbParamGroupNamePrefix,
|
||||||
ValidateFunc: validateDbParamGroupName,
|
|
||||||
},
|
},
|
||||||
"family": &schema.Schema{
|
"family": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
@ -81,8 +90,17 @@ func resourceAwsDbParameterGroupCreate(d *schema.ResourceData, meta interface{})
|
||||||
rdsconn := meta.(*AWSClient).rdsconn
|
rdsconn := meta.(*AWSClient).rdsconn
|
||||||
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
|
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
|
||||||
|
|
||||||
|
var groupName string
|
||||||
|
if v, ok := d.GetOk("name"); ok {
|
||||||
|
groupName = v.(string)
|
||||||
|
} else if v, ok := d.GetOk("name_prefix"); ok {
|
||||||
|
groupName = resource.PrefixedUniqueId(v.(string))
|
||||||
|
} else {
|
||||||
|
groupName = resource.UniqueId()
|
||||||
|
}
|
||||||
|
|
||||||
createOpts := rds.CreateDBParameterGroupInput{
|
createOpts := rds.CreateDBParameterGroupInput{
|
||||||
DBParameterGroupName: aws.String(d.Get("name").(string)),
|
DBParameterGroupName: aws.String(groupName),
|
||||||
DBParameterGroupFamily: aws.String(d.Get("family").(string)),
|
DBParameterGroupFamily: aws.String(d.Get("family").(string)),
|
||||||
Description: aws.String(d.Get("description").(string)),
|
Description: aws.String(d.Get("description").(string)),
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
|
|
|
@ -3,6 +3,7 @@ package aws
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -290,6 +291,44 @@ func TestAccAWSDBParameterGroup_basic(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBParameterGroup_namePrefix(t *testing.T) {
|
||||||
|
var v rds.DBParameterGroup
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSDBParameterGroupDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccDBParameterGroupConfig_namePrefix,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSDBParameterGroupExists("aws_db_parameter_group.test", &v),
|
||||||
|
resource.TestMatchResourceAttr(
|
||||||
|
"aws_db_parameter_group.test", "name", regexp.MustCompile("^tf-test-")),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBParameterGroup_generatedName(t *testing.T) {
|
||||||
|
var v rds.DBParameterGroup
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSDBParameterGroupDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccDBParameterGroupConfig_generatedName,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSDBParameterGroupExists("aws_db_parameter_group.test", &v),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccAWSDBParameterGroup_withApplyMethod(t *testing.T) {
|
func TestAccAWSDBParameterGroup_withApplyMethod(t *testing.T) {
|
||||||
var v rds.DBParameterGroup
|
var v rds.DBParameterGroup
|
||||||
|
|
||||||
|
@ -671,3 +710,16 @@ resource "aws_db_parameter_group" "large" {
|
||||||
parameter { name = "tx_isolation" value = "REPEATABLE-READ" }
|
parameter { name = "tx_isolation" value = "REPEATABLE-READ" }
|
||||||
}`, n)
|
}`, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const testAccDBParameterGroupConfig_namePrefix = `
|
||||||
|
resource "aws_db_parameter_group" "test" {
|
||||||
|
name_prefix = "tf-test-"
|
||||||
|
family = "mysql5.6"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const testAccDBParameterGroupConfig_generatedName = `
|
||||||
|
resource "aws_db_parameter_group" "test" {
|
||||||
|
family = "mysql5.6"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
|
@ -3,7 +3,6 @@ package aws
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -31,10 +30,19 @@ func resourceAwsDbSubnetGroup() *schema.Resource {
|
||||||
},
|
},
|
||||||
|
|
||||||
"name": &schema.Schema{
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ConflictsWith: []string{"name_prefix"},
|
||||||
|
ValidateFunc: validateDbSubnetGroupName,
|
||||||
|
},
|
||||||
|
"name_prefix": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Required: true,
|
ValidateFunc: validateDbSubnetGroupNamePrefix,
|
||||||
ValidateFunc: validateSubnetGroupName,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"description": &schema.Schema{
|
"description": &schema.Schema{
|
||||||
|
@ -65,8 +73,17 @@ func resourceAwsDbSubnetGroupCreate(d *schema.ResourceData, meta interface{}) er
|
||||||
subnetIds[i] = aws.String(subnetId.(string))
|
subnetIds[i] = aws.String(subnetId.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var groupName string
|
||||||
|
if v, ok := d.GetOk("name"); ok {
|
||||||
|
groupName = v.(string)
|
||||||
|
} else if v, ok := d.GetOk("name_prefix"); ok {
|
||||||
|
groupName = resource.PrefixedUniqueId(v.(string))
|
||||||
|
} else {
|
||||||
|
groupName = resource.UniqueId()
|
||||||
|
}
|
||||||
|
|
||||||
createOpts := rds.CreateDBSubnetGroupInput{
|
createOpts := rds.CreateDBSubnetGroupInput{
|
||||||
DBSubnetGroupName: aws.String(d.Get("name").(string)),
|
DBSubnetGroupName: aws.String(groupName),
|
||||||
DBSubnetGroupDescription: aws.String(d.Get("description").(string)),
|
DBSubnetGroupDescription: aws.String(d.Get("description").(string)),
|
||||||
SubnetIds: subnetIds,
|
SubnetIds: subnetIds,
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
|
@ -238,20 +255,3 @@ func buildRDSsubgrpARN(identifier, partition, accountid, region string) (string,
|
||||||
return arn, nil
|
return arn, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateSubnetGroupName(v interface{}, k string) (ws []string, errors []error) {
|
|
||||||
value := v.(string)
|
|
||||||
if !regexp.MustCompile(`^[ .0-9a-z-_]+$`).MatchString(value) {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"only lowercase alphanumeric characters, hyphens, underscores, periods, and spaces allowed in %q", k))
|
|
||||||
}
|
|
||||||
if len(value) > 255 {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q cannot be longer than 255 characters", k))
|
|
||||||
}
|
|
||||||
if regexp.MustCompile(`(?i)^default$`).MatchString(value) {
|
|
||||||
errors = append(errors, fmt.Errorf(
|
|
||||||
"%q is not allowed as %q", "Default", k))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package aws
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/acctest"
|
"github.com/hashicorp/terraform/helper/acctest"
|
||||||
|
@ -43,6 +44,46 @@ func TestAccAWSDBSubnetGroup_basic(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBSubnetGroup_namePrefix(t *testing.T) {
|
||||||
|
var v rds.DBSubnetGroup
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckDBSubnetGroupDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccDBSubnetGroupConfig_namePrefix,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckDBSubnetGroupExists(
|
||||||
|
"aws_db_subnet_group.test", &v),
|
||||||
|
resource.TestMatchResourceAttr(
|
||||||
|
"aws_db_subnet_group.test", "name", regexp.MustCompile("^tf_test-")),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBSubnetGroup_generatedName(t *testing.T) {
|
||||||
|
var v rds.DBSubnetGroup
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckDBSubnetGroupDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: testAccDBSubnetGroupConfig_generatedName,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckDBSubnetGroupExists(
|
||||||
|
"aws_db_subnet_group.test", &v),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// Regression test for https://github.com/hashicorp/terraform/issues/2603 and
|
// Regression test for https://github.com/hashicorp/terraform/issues/2603 and
|
||||||
// https://github.com/hashicorp/terraform/issues/2664
|
// https://github.com/hashicorp/terraform/issues/2664
|
||||||
func TestAccAWSDBSubnetGroup_withUndocumentedCharacters(t *testing.T) {
|
func TestAccAWSDBSubnetGroup_withUndocumentedCharacters(t *testing.T) {
|
||||||
|
@ -105,38 +146,6 @@ func TestAccAWSDBSubnetGroup_updateDescription(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResourceAWSDBSubnetGroupNameValidation(t *testing.T) {
|
|
||||||
cases := []struct {
|
|
||||||
Value string
|
|
||||||
ErrCount int
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
Value: "tEsting",
|
|
||||||
ErrCount: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: "testing?",
|
|
||||||
ErrCount: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: "default",
|
|
||||||
ErrCount: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Value: randomString(300),
|
|
||||||
ErrCount: 1,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range cases {
|
|
||||||
_, errors := validateSubnetGroupName(tc.Value, "aws_db_subnet_group")
|
|
||||||
|
|
||||||
if len(errors) != tc.ErrCount {
|
|
||||||
t.Fatalf("Expected the DB Subnet Group name to trigger a validation error")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testAccCheckDBSubnetGroupDestroy(s *terraform.State) error {
|
func testAccCheckDBSubnetGroupDestroy(s *terraform.State) error {
|
||||||
conn := testAccProvider.Meta().(*AWSClient).rdsconn
|
conn := testAccProvider.Meta().(*AWSClient).rdsconn
|
||||||
|
|
||||||
|
@ -263,6 +272,49 @@ resource "aws_db_subnet_group" "foo" {
|
||||||
}`, rName)
|
}`, rName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const testAccDBSubnetGroupConfig_namePrefix = `
|
||||||
|
resource "aws_vpc" "test" {
|
||||||
|
cidr_block = "10.1.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "a" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.1.1.0/24"
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "b" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.1.2.0/24"
|
||||||
|
availability_zone = "us-west-2b"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_db_subnet_group" "test" {
|
||||||
|
name_prefix = "tf_test-"
|
||||||
|
subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"]
|
||||||
|
}`
|
||||||
|
|
||||||
|
const testAccDBSubnetGroupConfig_generatedName = `
|
||||||
|
resource "aws_vpc" "test" {
|
||||||
|
cidr_block = "10.1.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "a" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.1.1.0/24"
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "b" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.1.2.0/24"
|
||||||
|
availability_zone = "us-west-2b"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_db_subnet_group" "test" {
|
||||||
|
subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"]
|
||||||
|
}`
|
||||||
|
|
||||||
const testAccDBSubnetGroupConfig_withUnderscoresAndPeriodsAndSpaces = `
|
const testAccDBSubnetGroupConfig_withUnderscoresAndPeriodsAndSpaces = `
|
||||||
resource "aws_vpc" "main" {
|
resource "aws_vpc" "main" {
|
||||||
cidr_block = "192.168.0.0/16"
|
cidr_block = "192.168.0.0/16"
|
||||||
|
|
|
@ -36,10 +36,19 @@ func resourceAwsRDSCluster() *schema.Resource {
|
||||||
},
|
},
|
||||||
|
|
||||||
"cluster_identifier": {
|
"cluster_identifier": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ConflictsWith: []string{"cluster_identifier_prefix"},
|
||||||
|
ValidateFunc: validateRdsIdentifier,
|
||||||
|
},
|
||||||
|
"cluster_identifier_prefix": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
ValidateFunc: validateRdsId,
|
ValidateFunc: validateRdsIdentifierPrefix,
|
||||||
},
|
},
|
||||||
|
|
||||||
"cluster_members": {
|
"cluster_members": {
|
||||||
|
@ -225,6 +234,19 @@ func resourceAwsRDSClusterCreate(d *schema.ResourceData, meta interface{}) error
|
||||||
conn := meta.(*AWSClient).rdsconn
|
conn := meta.(*AWSClient).rdsconn
|
||||||
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
|
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
|
||||||
|
|
||||||
|
var identifier string
|
||||||
|
if v, ok := d.GetOk("cluster_identifier"); ok {
|
||||||
|
identifier = v.(string)
|
||||||
|
} else {
|
||||||
|
if v, ok := d.GetOk("cluster_identifier_prefix"); ok {
|
||||||
|
identifier = resource.PrefixedUniqueId(v.(string))
|
||||||
|
} else {
|
||||||
|
identifier = resource.PrefixedUniqueId("tf-")
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set("cluster_identifier", identifier)
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := d.GetOk("snapshot_identifier"); ok {
|
if _, ok := d.GetOk("snapshot_identifier"); ok {
|
||||||
opts := rds.RestoreDBClusterFromSnapshotInput{
|
opts := rds.RestoreDBClusterFromSnapshotInput{
|
||||||
DBClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)),
|
DBClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)),
|
||||||
|
|
|
@ -24,10 +24,19 @@ func resourceAwsRDSClusterInstance() *schema.Resource {
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
"identifier": {
|
"identifier": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ConflictsWith: []string{"identifier_prefix"},
|
||||||
|
ValidateFunc: validateRdsIdentifier,
|
||||||
|
},
|
||||||
|
"identifier_prefix": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
ValidateFunc: validateRdsId,
|
ValidateFunc: validateRdsIdentifierPrefix,
|
||||||
},
|
},
|
||||||
|
|
||||||
"db_subnet_group_name": {
|
"db_subnet_group_name": {
|
||||||
|
@ -162,10 +171,14 @@ func resourceAwsRDSClusterInstanceCreate(d *schema.ResourceData, meta interface{
|
||||||
createOpts.DBParameterGroupName = aws.String(attr.(string))
|
createOpts.DBParameterGroupName = aws.String(attr.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
if v := d.Get("identifier").(string); v != "" {
|
if v, ok := d.GetOk("identifier"); ok {
|
||||||
createOpts.DBInstanceIdentifier = aws.String(v)
|
createOpts.DBInstanceIdentifier = aws.String(v.(string))
|
||||||
} else {
|
} else {
|
||||||
createOpts.DBInstanceIdentifier = aws.String(resource.UniqueId())
|
if v, ok := d.GetOk("identifier_prefix"); ok {
|
||||||
|
createOpts.DBInstanceIdentifier = aws.String(resource.PrefixedUniqueId(v.(string)))
|
||||||
|
} else {
|
||||||
|
createOpts.DBInstanceIdentifier = aws.String(resource.PrefixedUniqueId("tf-"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if attr, ok := d.GetOk("db_subnet_group_name"); ok {
|
if attr, ok := d.GetOk("db_subnet_group_name"); ok {
|
||||||
|
|
|
@ -46,6 +46,48 @@ func TestAccAWSRDSClusterInstance_basic(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSRDSClusterInstance_namePrefix(t *testing.T) {
|
||||||
|
var v rds.DBInstance
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSClusterDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSClusterInstanceConfig_namePrefix(acctest.RandInt()),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSClusterInstanceExists("aws_rds_cluster_instance.test", &v),
|
||||||
|
testAccCheckAWSDBClusterInstanceAttributes(&v),
|
||||||
|
resource.TestMatchResourceAttr(
|
||||||
|
"aws_rds_cluster_instance.test", "identifier", regexp.MustCompile("^tf-cluster-instance-")),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSRDSClusterInstance_generatedName(t *testing.T) {
|
||||||
|
var v rds.DBInstance
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSClusterDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSClusterInstanceConfig_generatedName(acctest.RandInt()),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSClusterInstanceExists("aws_rds_cluster_instance.test", &v),
|
||||||
|
testAccCheckAWSDBClusterInstanceAttributes(&v),
|
||||||
|
resource.TestMatchResourceAttr(
|
||||||
|
"aws_rds_cluster_instance.test", "identifier", regexp.MustCompile("^tf-")),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccAWSRDSClusterInstance_kmsKey(t *testing.T) {
|
func TestAccAWSRDSClusterInstance_kmsKey(t *testing.T) {
|
||||||
var v rds.DBInstance
|
var v rds.DBInstance
|
||||||
keyRegex := regexp.MustCompile("^arn:aws:kms:")
|
keyRegex := regexp.MustCompile("^arn:aws:kms:")
|
||||||
|
@ -256,6 +298,83 @@ resource "aws_db_parameter_group" "bar" {
|
||||||
`, n, n, n)
|
`, n, n, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccAWSClusterInstanceConfig_namePrefix(n int) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "aws_rds_cluster_instance" "test" {
|
||||||
|
identifier_prefix = "tf-cluster-instance-"
|
||||||
|
cluster_identifier = "${aws_rds_cluster.test.id}"
|
||||||
|
instance_class = "db.r3.large"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_rds_cluster" "test" {
|
||||||
|
cluster_identifier = "tf-aurora-cluster-%d"
|
||||||
|
master_username = "root"
|
||||||
|
master_password = "password"
|
||||||
|
db_subnet_group_name = "${aws_db_subnet_group.test.name}"
|
||||||
|
skip_final_snapshot = true
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_vpc" "test" {
|
||||||
|
cidr_block = "10.0.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "a" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.0.0.0/24"
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "b" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.0.1.0/24"
|
||||||
|
availability_zone = "us-west-2b"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_db_subnet_group" "test" {
|
||||||
|
name = "tf-test-%d"
|
||||||
|
subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"]
|
||||||
|
}
|
||||||
|
`, n, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccAWSClusterInstanceConfig_generatedName(n int) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "aws_rds_cluster_instance" "test" {
|
||||||
|
cluster_identifier = "${aws_rds_cluster.test.id}"
|
||||||
|
instance_class = "db.r3.large"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_rds_cluster" "test" {
|
||||||
|
cluster_identifier = "tf-aurora-cluster-%d"
|
||||||
|
master_username = "root"
|
||||||
|
master_password = "password"
|
||||||
|
db_subnet_group_name = "${aws_db_subnet_group.test.name}"
|
||||||
|
skip_final_snapshot = true
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_vpc" "test" {
|
||||||
|
cidr_block = "10.0.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "a" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.0.0.0/24"
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "b" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.0.1.0/24"
|
||||||
|
availability_zone = "us-west-2b"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_db_subnet_group" "test" {
|
||||||
|
name = "tf-test-%d"
|
||||||
|
subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"]
|
||||||
|
}
|
||||||
|
`, n, n)
|
||||||
|
}
|
||||||
|
|
||||||
func testAccAWSClusterInstanceConfigKmsKey(n int) string {
|
func testAccAWSClusterInstanceConfigKmsKey(n int) string {
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,19 @@ func resourceAwsRDSClusterParameterGroup() *schema.Resource {
|
||||||
Computed: true,
|
Computed: true,
|
||||||
},
|
},
|
||||||
"name": &schema.Schema{
|
"name": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ConflictsWith: []string{"name_prefix"},
|
||||||
|
ValidateFunc: validateDbParamGroupName,
|
||||||
|
},
|
||||||
|
"name_prefix": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
Required: true,
|
ValidateFunc: validateDbParamGroupNamePrefix,
|
||||||
ValidateFunc: validateDbParamGroupName,
|
|
||||||
},
|
},
|
||||||
"family": &schema.Schema{
|
"family": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
@ -86,8 +95,17 @@ func resourceAwsRDSClusterParameterGroupCreate(d *schema.ResourceData, meta inte
|
||||||
rdsconn := meta.(*AWSClient).rdsconn
|
rdsconn := meta.(*AWSClient).rdsconn
|
||||||
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
|
tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
|
||||||
|
|
||||||
|
var groupName string
|
||||||
|
if v, ok := d.GetOk("name"); ok {
|
||||||
|
groupName = v.(string)
|
||||||
|
} else if v, ok := d.GetOk("name_prefix"); ok {
|
||||||
|
groupName = resource.PrefixedUniqueId(v.(string))
|
||||||
|
} else {
|
||||||
|
groupName = resource.UniqueId()
|
||||||
|
}
|
||||||
|
|
||||||
createOpts := rds.CreateDBClusterParameterGroupInput{
|
createOpts := rds.CreateDBClusterParameterGroupInput{
|
||||||
DBClusterParameterGroupName: aws.String(d.Get("name").(string)),
|
DBClusterParameterGroupName: aws.String(groupName),
|
||||||
DBParameterGroupFamily: aws.String(d.Get("family").(string)),
|
DBParameterGroupFamily: aws.String(d.Get("family").(string)),
|
||||||
Description: aws.String(d.Get("description").(string)),
|
Description: aws.String(d.Get("description").(string)),
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
|
|
|
@ -3,6 +3,7 @@ package aws
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -90,6 +91,44 @@ func TestAccAWSDBClusterParameterGroup_basic(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBClusterParameterGroup_namePrefix(t *testing.T) {
|
||||||
|
var v rds.DBClusterParameterGroup
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSDBClusterParameterGroupDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSDBClusterParameterGroupConfig_namePrefix,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSDBClusterParameterGroupExists("aws_rds_cluster_parameter_group.test", &v),
|
||||||
|
resource.TestMatchResourceAttr(
|
||||||
|
"aws_rds_cluster_parameter_group.test", "name", regexp.MustCompile("^tf-test-")),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSDBClusterParameterGroup_generatedName(t *testing.T) {
|
||||||
|
var v rds.DBClusterParameterGroup
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSDBClusterParameterGroupDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSDBClusterParameterGroupConfig_generatedName,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSDBClusterParameterGroupExists("aws_rds_cluster_parameter_group.test", &v),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccAWSDBClusterParameterGroup_disappears(t *testing.T) {
|
func TestAccAWSDBClusterParameterGroup_disappears(t *testing.T) {
|
||||||
var v rds.DBClusterParameterGroup
|
var v rds.DBClusterParameterGroup
|
||||||
|
|
||||||
|
@ -365,3 +404,15 @@ func testAccAWSDBClusterParameterGroupOnlyConfig(name string) string {
|
||||||
family = "aurora5.6"
|
family = "aurora5.6"
|
||||||
}`, name)
|
}`, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const testAccAWSDBClusterParameterGroupConfig_namePrefix = `
|
||||||
|
resource "aws_rds_cluster_parameter_group" "test" {
|
||||||
|
name_prefix = "tf-test-"
|
||||||
|
family = "aurora5.6"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
const testAccAWSDBClusterParameterGroupConfig_generatedName = `
|
||||||
|
resource "aws_rds_cluster_parameter_group" "test" {
|
||||||
|
family = "aurora5.6"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
|
@ -40,6 +40,46 @@ func TestAccAWSRDSCluster_basic(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAWSRDSCluster_namePrefix(t *testing.T) {
|
||||||
|
var v rds.DBCluster
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSClusterDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSClusterConfig_namePrefix(acctest.RandInt()),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSClusterExists("aws_rds_cluster.test", &v),
|
||||||
|
resource.TestMatchResourceAttr(
|
||||||
|
"aws_rds_cluster.test", "cluster_identifier", regexp.MustCompile("^tf-test-")),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccAWSRDSCluster_generatedName(t *testing.T) {
|
||||||
|
var v rds.DBCluster
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testAccCheckAWSClusterDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: testAccAWSClusterConfig_generatedName(acctest.RandInt()),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testAccCheckAWSClusterExists("aws_rds_cluster.test", &v),
|
||||||
|
resource.TestMatchResourceAttr(
|
||||||
|
"aws_rds_cluster.test", "cluster_identifier", regexp.MustCompile("^tf-")),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccAWSRDSCluster_takeFinalSnapshot(t *testing.T) {
|
func TestAccAWSRDSCluster_takeFinalSnapshot(t *testing.T) {
|
||||||
var v rds.DBCluster
|
var v rds.DBCluster
|
||||||
rInt := acctest.RandInt()
|
rInt := acctest.RandInt()
|
||||||
|
@ -322,6 +362,71 @@ resource "aws_rds_cluster" "default" {
|
||||||
}`, n)
|
}`, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testAccAWSClusterConfig_namePrefix(n int) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "aws_rds_cluster" "test" {
|
||||||
|
cluster_identifier_prefix = "tf-test-"
|
||||||
|
master_username = "root"
|
||||||
|
master_password = "password"
|
||||||
|
db_subnet_group_name = "${aws_db_subnet_group.test.name}"
|
||||||
|
skip_final_snapshot = true
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_vpc" "test" {
|
||||||
|
cidr_block = "10.0.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "a" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.0.0.0/24"
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "b" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.0.1.0/24"
|
||||||
|
availability_zone = "us-west-2b"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_db_subnet_group" "test" {
|
||||||
|
name = "tf-test-%d"
|
||||||
|
subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"]
|
||||||
|
}
|
||||||
|
`, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccAWSClusterConfig_generatedName(n int) string {
|
||||||
|
return fmt.Sprintf(`
|
||||||
|
resource "aws_rds_cluster" "test" {
|
||||||
|
master_username = "root"
|
||||||
|
master_password = "password"
|
||||||
|
db_subnet_group_name = "${aws_db_subnet_group.test.name}"
|
||||||
|
skip_final_snapshot = true
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_vpc" "test" {
|
||||||
|
cidr_block = "10.0.0.0/16"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "a" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.0.0.0/24"
|
||||||
|
availability_zone = "us-west-2a"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_subnet" "b" {
|
||||||
|
vpc_id = "${aws_vpc.test.id}"
|
||||||
|
cidr_block = "10.0.1.0/24"
|
||||||
|
availability_zone = "us-west-2b"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "aws_db_subnet_group" "test" {
|
||||||
|
name = "tf-test-%d"
|
||||||
|
subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"]
|
||||||
|
}
|
||||||
|
`, n)
|
||||||
|
}
|
||||||
|
|
||||||
func testAccAWSClusterConfigWithFinalSnapshot(n int) string {
|
func testAccAWSClusterConfigWithFinalSnapshot(n int) string {
|
||||||
return fmt.Sprintf(`
|
return fmt.Sprintf(`
|
||||||
resource "aws_rds_cluster" "default" {
|
resource "aws_rds_cluster" "default" {
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
func validateRdsId(v interface{}, k string) (ws []string, errors []error) {
|
func validateRdsIdentifier(v interface{}, k string) (ws []string, errors []error) {
|
||||||
value := v.(string)
|
value := v.(string)
|
||||||
if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) {
|
if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) {
|
||||||
errors = append(errors, fmt.Errorf(
|
errors = append(errors, fmt.Errorf(
|
||||||
|
@ -33,6 +33,23 @@ func validateRdsId(v interface{}, k string) (ws []string, errors []error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateRdsIdentifierPrefix(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
value := v.(string)
|
||||||
|
if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"only lowercase alphanumeric characters and hyphens allowed in %q", k))
|
||||||
|
}
|
||||||
|
if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"first character of %q must be a letter", k))
|
||||||
|
}
|
||||||
|
if regexp.MustCompile(`--`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot contain two consecutive hyphens", k))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func validateElastiCacheClusterId(v interface{}, k string) (ws []string, errors []error) {
|
func validateElastiCacheClusterId(v interface{}, k string) (ws []string, errors []error) {
|
||||||
value := v.(string)
|
value := v.(string)
|
||||||
if (len(value) < 1) || (len(value) > 20) {
|
if (len(value) < 1) || (len(value) > 20) {
|
||||||
|
@ -103,7 +120,27 @@ func validateDbParamGroupName(v interface{}, k string) (ws []string, errors []er
|
||||||
"%q cannot be greater than 255 characters", k))
|
"%q cannot be greater than 255 characters", k))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateDbParamGroupNamePrefix(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
value := v.(string)
|
||||||
|
if !regexp.MustCompile(`^[0-9a-z-]+$`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"only lowercase alphanumeric characters and hyphens allowed in %q", k))
|
||||||
|
}
|
||||||
|
if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"first character of %q must be a letter", k))
|
||||||
|
}
|
||||||
|
if regexp.MustCompile(`--`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot contain two consecutive hyphens", k))
|
||||||
|
}
|
||||||
|
if len(value) > 255 {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot be greater than 226 characters", k))
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateStreamViewType(v interface{}, k string) (ws []string, errors []error) {
|
func validateStreamViewType(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
@ -1041,3 +1078,79 @@ func validateApiGatewayUsagePlanQuotaSettings(v map[string]interface{}) (errors
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateDbSubnetGroupName(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
value := v.(string)
|
||||||
|
if !regexp.MustCompile(`^[ .0-9a-z-_]+$`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"only lowercase alphanumeric characters, hyphens, underscores, periods, and spaces allowed in %q", k))
|
||||||
|
}
|
||||||
|
if len(value) > 255 {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot be longer than 255 characters", k))
|
||||||
|
}
|
||||||
|
if regexp.MustCompile(`(?i)^default$`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q is not allowed as %q", "Default", k))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateDbSubnetGroupNamePrefix(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
value := v.(string)
|
||||||
|
if !regexp.MustCompile(`^[ .0-9a-z-_]+$`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"only lowercase alphanumeric characters, hyphens, underscores, periods, and spaces allowed in %q", k))
|
||||||
|
}
|
||||||
|
if len(value) > 229 {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot be longer than 229 characters", k))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateDbOptionGroupName(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
value := v.(string)
|
||||||
|
if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"first character of %q must be a letter", k))
|
||||||
|
}
|
||||||
|
if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"only alphanumeric characters and hyphens allowed in %q", k))
|
||||||
|
}
|
||||||
|
if regexp.MustCompile(`--`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot contain two consecutive hyphens", k))
|
||||||
|
}
|
||||||
|
if regexp.MustCompile(`-$`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot end with a hyphen", k))
|
||||||
|
}
|
||||||
|
if len(value) > 255 {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot be greater than 255 characters", k))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func validateDbOptionGroupNamePrefix(v interface{}, k string) (ws []string, errors []error) {
|
||||||
|
value := v.(string)
|
||||||
|
if !regexp.MustCompile(`^[a-z]`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"first character of %q must be a letter", k))
|
||||||
|
}
|
||||||
|
if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"only alphanumeric characters and hyphens allowed in %q", k))
|
||||||
|
}
|
||||||
|
if regexp.MustCompile(`--`).MatchString(value) {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot contain two consecutive hyphens", k))
|
||||||
|
}
|
||||||
|
if len(value) > 229 {
|
||||||
|
errors = append(errors, fmt.Errorf(
|
||||||
|
"%q cannot be greater than 229 characters", k))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -1785,3 +1785,131 @@ func TestValidateElbNamePrefix(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateDbSubnetGroupName(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Value string
|
||||||
|
ErrCount int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Value: "tEsting",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "testing?",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "default",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: randomString(300),
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
_, errors := validateDbSubnetGroupName(tc.Value, "aws_db_subnet_group")
|
||||||
|
|
||||||
|
if len(errors) != tc.ErrCount {
|
||||||
|
t.Fatalf("Expected the DB Subnet Group name to trigger a validation error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateDbSubnetGroupNamePrefix(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Value string
|
||||||
|
ErrCount int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Value: "tEsting",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "testing?",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: randomString(230),
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
_, errors := validateDbSubnetGroupNamePrefix(tc.Value, "aws_db_subnet_group")
|
||||||
|
|
||||||
|
if len(errors) != tc.ErrCount {
|
||||||
|
t.Fatalf("Expected the DB Subnet Group name prefix to trigger a validation error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateDbOptionGroupName(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Value string
|
||||||
|
ErrCount int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Value: "testing123!",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "1testing123",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "testing--123",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "testing123-",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: randomString(256),
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
_, errors := validateDbOptionGroupName(tc.Value, "aws_db_option_group_name")
|
||||||
|
|
||||||
|
if len(errors) != tc.ErrCount {
|
||||||
|
t.Fatalf("Expected the DB Option Group Name to trigger a validation error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateDbOptionGroupNamePrefix(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
Value string
|
||||||
|
ErrCount int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Value: "testing123!",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "1testing123",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: "testing--123",
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Value: randomString(230),
|
||||||
|
ErrCount: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
_, errors := validateDbOptionGroupNamePrefix(tc.Value, "aws_db_option_group_name")
|
||||||
|
|
||||||
|
if len(errors) != tc.ErrCount {
|
||||||
|
t.Fatalf("Expected the DB Option Group name prefix to trigger a validation error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -55,7 +55,8 @@ The following arguments are supported:
|
||||||
* `allocated_storage` - (Required unless a `snapshot_identifier` or `replicate_source_db` is provided) The allocated storage in gigabytes.
|
* `allocated_storage` - (Required unless a `snapshot_identifier` or `replicate_source_db` is provided) The allocated storage in gigabytes.
|
||||||
* `engine` - (Required unless a `snapshot_identifier` or `replicate_source_db` is provided) The database engine to use.
|
* `engine` - (Required unless a `snapshot_identifier` or `replicate_source_db` is provided) The database engine to use.
|
||||||
* `engine_version` - (Optional) The engine version to use.
|
* `engine_version` - (Optional) The engine version to use.
|
||||||
* `identifier` - (Optional) The name of the RDS instance, if omitted, Terraform will assign a random, unique name
|
* `identifier` - (Optional, Forces new resource) The name of the RDS instance, if omitted, Terraform will assign a random, unique identifier.
|
||||||
|
* `identifier_prefix` - (Optional, Forces new resource) Creates a unique identifier beginning with the specified prefix. Conflicts with `identifer`.
|
||||||
* `instance_class` - (Required) The instance type of the RDS instance.
|
* `instance_class` - (Required) The instance type of the RDS instance.
|
||||||
* `storage_type` - (Optional) One of "standard" (magnetic), "gp2" (general
|
* `storage_type` - (Optional) One of "standard" (magnetic), "gp2" (general
|
||||||
purpose SSD), or "io1" (provisioned IOPS SSD). The default is "io1" if
|
purpose SSD), or "io1" (provisioned IOPS SSD). The default is "io1" if
|
||||||
|
@ -156,7 +157,7 @@ On Oracle instances the following is exported additionally:
|
||||||
|
|
||||||
- `create` - (Default `40 minutes`) Used for Creating Instances, Replicas, and
|
- `create` - (Default `40 minutes`) Used for Creating Instances, Replicas, and
|
||||||
restoring from Snapshots
|
restoring from Snapshots
|
||||||
- `update` - (Default `80 minutes`) Used for Database modifications
|
- `update` - (Default `80 minutes`) Used for Database modifications
|
||||||
- `delete` - (Default `40 minutes`) Used for destroying databases. This includes
|
- `delete` - (Default `40 minutes`) Used for destroying databases. This includes
|
||||||
the time required to take snapshots
|
the time required to take snapshots
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,9 @@ resource "aws_db_option_group" "bar" {
|
||||||
|
|
||||||
The following arguments are supported:
|
The following arguments are supported:
|
||||||
|
|
||||||
* `name` - (Required) The name of the Option group to be created.
|
* `name` - (Optional, Forces new resource) The name of the option group. If omitted, Terraform will assign a random, unique name.
|
||||||
* `option_group_description` - (Required) The description of the option group.
|
* `name_prefix` - (Optional, Forces new resource) Creates a unique name beginning with the specified prefix. Conflicts with `name`.
|
||||||
|
* `option_group_description` - (Optional) The description of the option group. Defaults to "Managed by Terraform".
|
||||||
* `engine_name` - (Required) Specifies the name of the engine that this option group should be associated with..
|
* `engine_name` - (Required) Specifies the name of the engine that this option group should be associated with..
|
||||||
* `major_engine_version` - (Required) Specifies the major version of the engine that this option group should be associated with.
|
* `major_engine_version` - (Required) Specifies the major version of the engine that this option group should be associated with.
|
||||||
* `option` - (Optional) A list of Options to apply.
|
* `option` - (Optional) A list of Options to apply.
|
||||||
|
@ -70,4 +71,4 @@ DB Option groups can be imported using the `name`, e.g.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ terraform import aws_db_option_group.bar mysql-option-group
|
$ terraform import aws_db_option_group.bar mysql-option-group
|
||||||
```
|
```
|
||||||
|
|
|
@ -31,7 +31,8 @@ resource "aws_db_parameter_group" "default" {
|
||||||
|
|
||||||
The following arguments are supported:
|
The following arguments are supported:
|
||||||
|
|
||||||
* `name` - (Required) The name of the DB parameter group.
|
* `name` - (Optional, Forces new resource) The name of the DB parameter group. If omitted, Terraform will assign a random, unique name.
|
||||||
|
* `name_prefix` - (Optional, Forces new resource) Creates a unique name beginning with the specified prefix. Conflicts with `name`.
|
||||||
* `family` - (Required) The family of the DB parameter group.
|
* `family` - (Required) The family of the DB parameter group.
|
||||||
* `description` - (Optional) The description of the DB parameter group. Defaults to "Managed by Terraform".
|
* `description` - (Optional) The description of the DB parameter group. Defaults to "Managed by Terraform".
|
||||||
* `parameter` - (Optional) A list of DB parameters to apply.
|
* `parameter` - (Optional) A list of DB parameters to apply.
|
||||||
|
@ -58,4 +59,4 @@ DB Parameter groups can be imported using the `name`, e.g.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ terraform import aws_db_parameter_group.rds_pg rds-pg
|
$ terraform import aws_db_parameter_group.rds_pg rds-pg
|
||||||
```
|
```
|
||||||
|
|
|
@ -27,7 +27,8 @@ resource "aws_db_subnet_group" "default" {
|
||||||
|
|
||||||
The following arguments are supported:
|
The following arguments are supported:
|
||||||
|
|
||||||
* `name` - (Required) The name of the DB subnet group.
|
* `name` - (Optional, Forces new resource) The name of the DB subnet group. If omitted, Terraform will assign a random, unique name.
|
||||||
|
* `name_prefix` - (Optional, Forces new resource) Creates a unique name beginning with the specified prefix. Conflicts with `name`.
|
||||||
* `description` - (Optional) The description of the DB subnet group. Defaults to "Managed by Terraform".
|
* `description` - (Optional) The description of the DB subnet group. Defaults to "Managed by Terraform".
|
||||||
* `subnet_ids` - (Required) A list of VPC subnet IDs.
|
* `subnet_ids` - (Required) A list of VPC subnet IDs.
|
||||||
* `tags` - (Optional) A mapping of tags to assign to the resource.
|
* `tags` - (Optional) A mapping of tags to assign to the resource.
|
||||||
|
@ -46,4 +47,4 @@ DB Subnet groups can be imported using the `name`, e.g.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ terraform import aws_db_subnet_group.default production-subnet-group
|
$ terraform import aws_db_subnet_group.default production-subnet-group
|
||||||
```
|
```
|
||||||
|
|
|
@ -53,8 +53,8 @@ the [AWS official documentation](https://docs.aws.amazon.com/AmazonRDS/latest/Co
|
||||||
|
|
||||||
The following arguments are supported:
|
The following arguments are supported:
|
||||||
|
|
||||||
* `cluster_identifier` - (Required) The Cluster Identifier. Must be a lower case
|
* `cluster_identifier` - (Optional, Forces new resources) The cluster identifier. If omitted, Terraform will assign a random, unique identifier.
|
||||||
string.
|
* `cluster_identifier_prefix` - (Optional, Forces new resource) Creates a unique cluster identifier beginning with the specified prefix. Conflicts with `cluster_identifer`.
|
||||||
* `database_name` - (Optional) The name for your database of up to 8 alpha-numeric
|
* `database_name` - (Optional) The name for your database of up to 8 alpha-numeric
|
||||||
characters. If you do not provide a name, Amazon RDS will not create a
|
characters. If you do not provide a name, Amazon RDS will not create a
|
||||||
database in the DB cluster you are creating
|
database in the DB cluster you are creating
|
||||||
|
|
|
@ -47,8 +47,8 @@ the [AWS official documentation](https://docs.aws.amazon.com/AmazonRDS/latest/Co
|
||||||
|
|
||||||
The following arguments are supported:
|
The following arguments are supported:
|
||||||
|
|
||||||
* `identifier` - (Optional) The Instance Identifier. Must be a lower case
|
* `identifier` - (Optional, Forces new resource) The indentifier for the RDS instance, if omitted, Terraform will assign a random, unique identifier.
|
||||||
string. If omitted, a unique identifier will be generated.
|
* `identifier_prefix` - (Optional, Forces new resource) Creates a unique identifier beginning with the specified prefix. Conflicts with `identifer`.
|
||||||
* `cluster_identifier` - (Required) The identifier of the [`aws_rds_cluster`](/docs/providers/aws/r/rds_cluster.html) in which to launch this instance.
|
* `cluster_identifier` - (Required) The identifier of the [`aws_rds_cluster`](/docs/providers/aws/r/rds_cluster.html) in which to launch this instance.
|
||||||
* `instance_class` - (Required) The instance class to use. For details on CPU
|
* `instance_class` - (Required) The instance class to use. For details on CPU
|
||||||
and memory, see [Scaling Aurora DB Instances][4]. Aurora currently
|
and memory, see [Scaling Aurora DB Instances][4]. Aurora currently
|
||||||
|
|
|
@ -32,9 +32,10 @@ resource "aws_rds_cluster_parameter_group" "default" {
|
||||||
|
|
||||||
The following arguments are supported:
|
The following arguments are supported:
|
||||||
|
|
||||||
* `name` - (Required) The name of the DB cluster parameter group.
|
* `name` - (Optional, Forces new resource) The name of the DB cluster parameter group. If omitted, Terraform will assign a random, unique name.
|
||||||
|
* `name_prefix` - (Optional, Forces new resource) Creates a unique name beginning with the specified prefix. Conflicts with `name`.
|
||||||
* `family` - (Required) The family of the DB cluster parameter group.
|
* `family` - (Required) The family of the DB cluster parameter group.
|
||||||
* `description` - (Required) The description of the DB cluster parameter group.
|
* `description` - (Optional) The description of the DB cluster parameter group. Defaults to "Managed by Terraform".
|
||||||
* `parameter` - (Optional) A list of DB parameters to apply.
|
* `parameter` - (Optional) A list of DB parameters to apply.
|
||||||
* `tags` - (Optional) A mapping of tags to assign to the resource.
|
* `tags` - (Optional) A mapping of tags to assign to the resource.
|
||||||
|
|
||||||
|
@ -60,4 +61,4 @@ RDS Cluster Parameter Groups can be imported using the `name`, e.g.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ terraform import aws_rds_cluster_parameter_group.cluster_pg production-pg-1
|
$ terraform import aws_rds_cluster_parameter_group.cluster_pg production-pg-1
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in New Issue