github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_db_instance_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"regexp"
     7  	"strings"
     8  
     9  	"math/rand"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/hashicorp/terraform/helper/acctest"
    14  	"github.com/hashicorp/terraform/helper/resource"
    15  	"github.com/hashicorp/terraform/terraform"
    16  
    17  	"github.com/aws/aws-sdk-go/aws"
    18  	"github.com/aws/aws-sdk-go/aws/awserr"
    19  	"github.com/aws/aws-sdk-go/service/rds"
    20  )
    21  
    22  func TestAccAWSDBInstance_basic(t *testing.T) {
    23  	var v rds.DBInstance
    24  
    25  	resource.Test(t, resource.TestCase{
    26  		PreCheck:     func() { testAccPreCheck(t) },
    27  		Providers:    testAccProviders,
    28  		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
    29  		Steps: []resource.TestStep{
    30  			{
    31  				Config: testAccAWSDBInstanceConfig,
    32  				Check: resource.ComposeTestCheckFunc(
    33  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
    34  					testAccCheckAWSDBInstanceAttributes(&v),
    35  					resource.TestCheckResourceAttr(
    36  						"aws_db_instance.bar", "allocated_storage", "10"),
    37  					resource.TestCheckResourceAttr(
    38  						"aws_db_instance.bar", "engine", "mysql"),
    39  					resource.TestCheckResourceAttr(
    40  						"aws_db_instance.bar", "license_model", "general-public-license"),
    41  					resource.TestCheckResourceAttr(
    42  						"aws_db_instance.bar", "instance_class", "db.t1.micro"),
    43  					resource.TestCheckResourceAttr(
    44  						"aws_db_instance.bar", "name", "baz"),
    45  					resource.TestCheckResourceAttr(
    46  						"aws_db_instance.bar", "username", "foo"),
    47  					resource.TestCheckResourceAttr(
    48  						"aws_db_instance.bar", "parameter_group_name", "default.mysql5.6"),
    49  					resource.TestCheckResourceAttrSet("aws_db_instance.bar", "hosted_zone_id"),
    50  				),
    51  			},
    52  		},
    53  	})
    54  }
    55  
    56  func TestAccAWSDBInstance_kmsKey(t *testing.T) {
    57  	var v rds.DBInstance
    58  	keyRegex := regexp.MustCompile("^arn:aws:kms:")
    59  
    60  	ri := rand.New(rand.NewSource(time.Now().UnixNano())).Int()
    61  	config := fmt.Sprintf(testAccAWSDBInstanceConfigKmsKeyId, ri)
    62  
    63  	resource.Test(t, resource.TestCase{
    64  		PreCheck:     func() { testAccPreCheck(t) },
    65  		Providers:    testAccProviders,
    66  		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
    67  		Steps: []resource.TestStep{
    68  			{
    69  				Config: config,
    70  				Check: resource.ComposeTestCheckFunc(
    71  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
    72  					testAccCheckAWSDBInstanceAttributes(&v),
    73  					resource.TestMatchResourceAttr(
    74  						"aws_db_instance.bar", "kms_key_id", keyRegex),
    75  				),
    76  			},
    77  		},
    78  	})
    79  }
    80  
    81  func TestAccAWSDBInstance_subnetGroup(t *testing.T) {
    82  	var v rds.DBInstance
    83  	rName := acctest.RandString(10)
    84  
    85  	resource.Test(t, resource.TestCase{
    86  		PreCheck:     func() { testAccPreCheck(t) },
    87  		Providers:    testAccProviders,
    88  		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
    89  		Steps: []resource.TestStep{
    90  			{
    91  				Config: testAccAWSDBInstanceConfigWithSubnetGroup(rName),
    92  				Check: resource.ComposeTestCheckFunc(
    93  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
    94  					resource.TestCheckResourceAttr(
    95  						"aws_db_instance.bar", "db_subnet_group_name", "foo-"+rName),
    96  				),
    97  			},
    98  			{
    99  				Config: testAccAWSDBInstanceConfigWithSubnetGroupUpdated(rName),
   100  				Check: resource.ComposeTestCheckFunc(
   101  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
   102  					resource.TestCheckResourceAttr(
   103  						"aws_db_instance.bar", "db_subnet_group_name", "bar-"+rName),
   104  				),
   105  			},
   106  		},
   107  	})
   108  }
   109  
   110  func TestAccAWSDBInstance_optionGroup(t *testing.T) {
   111  	var v rds.DBInstance
   112  
   113  	rName := fmt.Sprintf("tf-option-test-%d", acctest.RandInt())
   114  
   115  	resource.Test(t, resource.TestCase{
   116  		PreCheck:     func() { testAccPreCheck(t) },
   117  		Providers:    testAccProviders,
   118  		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
   119  		Steps: []resource.TestStep{
   120  			{
   121  				Config: testAccAWSDBInstanceConfigWithOptionGroup(rName),
   122  				Check: resource.ComposeTestCheckFunc(
   123  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
   124  					testAccCheckAWSDBInstanceAttributes(&v),
   125  					resource.TestCheckResourceAttr(
   126  						"aws_db_instance.bar", "option_group_name", rName),
   127  				),
   128  			},
   129  		},
   130  	})
   131  }
   132  
   133  func TestAccAWSDBInstanceReplica(t *testing.T) {
   134  	var s, r rds.DBInstance
   135  
   136  	resource.Test(t, resource.TestCase{
   137  		PreCheck:     func() { testAccPreCheck(t) },
   138  		Providers:    testAccProviders,
   139  		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
   140  		Steps: []resource.TestStep{
   141  			{
   142  				Config: testAccReplicaInstanceConfig(rand.New(rand.NewSource(time.Now().UnixNano())).Int()),
   143  				Check: resource.ComposeTestCheckFunc(
   144  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &s),
   145  					testAccCheckAWSDBInstanceExists("aws_db_instance.replica", &r),
   146  					testAccCheckAWSDBInstanceReplicaAttributes(&s, &r),
   147  				),
   148  			},
   149  		},
   150  	})
   151  }
   152  
   153  func TestAccAWSDBInstanceNoSnapshot(t *testing.T) {
   154  	var snap rds.DBInstance
   155  
   156  	resource.Test(t, resource.TestCase{
   157  		PreCheck:     func() { testAccPreCheck(t) },
   158  		Providers:    testAccProviders,
   159  		CheckDestroy: testAccCheckAWSDBInstanceNoSnapshot,
   160  		Steps: []resource.TestStep{
   161  			{
   162  				Config: testAccSnapshotInstanceConfig(),
   163  				Check: resource.ComposeTestCheckFunc(
   164  					testAccCheckAWSDBInstanceExists("aws_db_instance.snapshot", &snap),
   165  				),
   166  			},
   167  		},
   168  	})
   169  }
   170  
   171  func TestAccAWSDBInstanceSnapshot(t *testing.T) {
   172  	var snap rds.DBInstance
   173  	rInt := acctest.RandInt()
   174  
   175  	resource.Test(t, resource.TestCase{
   176  		PreCheck:  func() { testAccPreCheck(t) },
   177  		Providers: testAccProviders,
   178  		// testAccCheckAWSDBInstanceSnapshot verifies a database snapshot is
   179  		// created, and subequently deletes it
   180  		CheckDestroy: testAccCheckAWSDBInstanceSnapshot(rInt),
   181  		Steps: []resource.TestStep{
   182  			{
   183  				Config: testAccSnapshotInstanceConfigWithSnapshot(rInt),
   184  				Check: resource.ComposeTestCheckFunc(
   185  					testAccCheckAWSDBInstanceExists("aws_db_instance.snapshot", &snap),
   186  				),
   187  			},
   188  		},
   189  	})
   190  }
   191  
   192  func TestAccAWSDBInstance_enhancedMonitoring(t *testing.T) {
   193  	var dbInstance rds.DBInstance
   194  	rName := acctest.RandString(5)
   195  
   196  	resource.Test(t, resource.TestCase{
   197  		PreCheck:     func() { testAccPreCheck(t) },
   198  		Providers:    testAccProviders,
   199  		CheckDestroy: testAccCheckAWSDBInstanceNoSnapshot,
   200  		Steps: []resource.TestStep{
   201  			{
   202  				Config: testAccSnapshotInstanceConfig_enhancedMonitoring(rName),
   203  				Check: resource.ComposeTestCheckFunc(
   204  					testAccCheckAWSDBInstanceExists("aws_db_instance.enhanced_monitoring", &dbInstance),
   205  					resource.TestCheckResourceAttr(
   206  						"aws_db_instance.enhanced_monitoring", "monitoring_interval", "5"),
   207  				),
   208  			},
   209  		},
   210  	})
   211  }
   212  
   213  // Regression test for https://github.com/hashicorp/terraform/issues/3760 .
   214  // We apply a plan, then change just the iops. If the apply succeeds, we
   215  // consider this a pass, as before in 3760 the request would fail
   216  func TestAccAWS_separate_DBInstance_iops_update(t *testing.T) {
   217  	var v rds.DBInstance
   218  
   219  	rName := acctest.RandString(5)
   220  
   221  	resource.Test(t, resource.TestCase{
   222  		PreCheck:     func() { testAccPreCheck(t) },
   223  		Providers:    testAccProviders,
   224  		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
   225  		Steps: []resource.TestStep{
   226  			{
   227  				Config: testAccSnapshotInstanceConfig_iopsUpdate(rName, 1000),
   228  				Check: resource.ComposeTestCheckFunc(
   229  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
   230  					testAccCheckAWSDBInstanceAttributes(&v),
   231  				),
   232  			},
   233  
   234  			{
   235  				Config: testAccSnapshotInstanceConfig_iopsUpdate(rName, 2000),
   236  				Check: resource.ComposeTestCheckFunc(
   237  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
   238  					testAccCheckAWSDBInstanceAttributes(&v),
   239  				),
   240  			},
   241  		},
   242  	})
   243  }
   244  
   245  func TestAccAWSDBInstance_portUpdate(t *testing.T) {
   246  	var v rds.DBInstance
   247  
   248  	rName := acctest.RandString(5)
   249  
   250  	resource.Test(t, resource.TestCase{
   251  		PreCheck:     func() { testAccPreCheck(t) },
   252  		Providers:    testAccProviders,
   253  		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
   254  		Steps: []resource.TestStep{
   255  			{
   256  				Config: testAccSnapshotInstanceConfig_mysqlPort(rName),
   257  				Check: resource.ComposeTestCheckFunc(
   258  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
   259  					resource.TestCheckResourceAttr(
   260  						"aws_db_instance.bar", "port", "3306"),
   261  				),
   262  			},
   263  
   264  			{
   265  				Config: testAccSnapshotInstanceConfig_updateMysqlPort(rName),
   266  				Check: resource.ComposeTestCheckFunc(
   267  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
   268  					resource.TestCheckResourceAttr(
   269  						"aws_db_instance.bar", "port", "3305"),
   270  				),
   271  			},
   272  		},
   273  	})
   274  }
   275  
   276  func TestAccAWSDBInstance_MSSQL_TZ(t *testing.T) {
   277  	var v rds.DBInstance
   278  
   279  	resource.Test(t, resource.TestCase{
   280  		PreCheck:     func() { testAccPreCheck(t) },
   281  		Providers:    testAccProviders,
   282  		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
   283  		Steps: []resource.TestStep{
   284  			{
   285  				Config: testAccAWSDBMSSQL_timezone,
   286  				Check: resource.ComposeTestCheckFunc(
   287  					testAccCheckAWSDBInstanceExists("aws_db_instance.mssql", &v),
   288  					testAccCheckAWSDBInstanceAttributes_MSSQL(&v, ""),
   289  					resource.TestCheckResourceAttr(
   290  						"aws_db_instance.mssql", "allocated_storage", "20"),
   291  					resource.TestCheckResourceAttr(
   292  						"aws_db_instance.mssql", "engine", "sqlserver-ex"),
   293  				),
   294  			},
   295  
   296  			{
   297  				Config: testAccAWSDBMSSQL_timezone_AKST,
   298  				Check: resource.ComposeTestCheckFunc(
   299  					testAccCheckAWSDBInstanceExists("aws_db_instance.mssql", &v),
   300  					testAccCheckAWSDBInstanceAttributes_MSSQL(&v, "Alaskan Standard Time"),
   301  					resource.TestCheckResourceAttr(
   302  						"aws_db_instance.mssql", "allocated_storage", "20"),
   303  					resource.TestCheckResourceAttr(
   304  						"aws_db_instance.mssql", "engine", "sqlserver-ex"),
   305  				),
   306  			},
   307  		},
   308  	})
   309  }
   310  
   311  func TestAccAWSDBInstance_MinorVersion(t *testing.T) {
   312  	var v rds.DBInstance
   313  
   314  	resource.Test(t, resource.TestCase{
   315  		PreCheck:     func() { testAccPreCheck(t) },
   316  		Providers:    testAccProviders,
   317  		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
   318  		Steps: []resource.TestStep{
   319  			{
   320  				Config: testAccAWSDBInstanceConfigAutoMinorVersion,
   321  				Check: resource.ComposeTestCheckFunc(
   322  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
   323  				),
   324  			},
   325  		},
   326  	})
   327  }
   328  
   329  // See https://github.com/hashicorp/terraform/issues/11881
   330  func TestAccAWSDBInstance_diffSuppressInitialState(t *testing.T) {
   331  	var v rds.DBInstance
   332  	rInt := acctest.RandInt()
   333  
   334  	resource.Test(t, resource.TestCase{
   335  		PreCheck:     func() { testAccPreCheck(t) },
   336  		Providers:    testAccProviders,
   337  		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
   338  		Steps: []resource.TestStep{
   339  			{
   340  				Config: testAccAWSDBInstanceConfigSuppressInitialState(rInt),
   341  				Check: resource.ComposeTestCheckFunc(
   342  					testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v),
   343  				),
   344  			},
   345  		},
   346  	})
   347  }
   348  
   349  func testAccCheckAWSDBInstanceDestroy(s *terraform.State) error {
   350  	conn := testAccProvider.Meta().(*AWSClient).rdsconn
   351  
   352  	for _, rs := range s.RootModule().Resources {
   353  		if rs.Type != "aws_db_instance" {
   354  			continue
   355  		}
   356  
   357  		// Try to find the Group
   358  		var err error
   359  		resp, err := conn.DescribeDBInstances(
   360  			&rds.DescribeDBInstancesInput{
   361  				DBInstanceIdentifier: aws.String(rs.Primary.ID),
   362  			})
   363  
   364  		if ae, ok := err.(awserr.Error); ok && ae.Code() == "DBInstanceNotFound" {
   365  			continue
   366  		}
   367  
   368  		if err == nil {
   369  			if len(resp.DBInstances) != 0 &&
   370  				*resp.DBInstances[0].DBInstanceIdentifier == rs.Primary.ID {
   371  				return fmt.Errorf("DB Instance still exists")
   372  			}
   373  		}
   374  
   375  		// Verify the error
   376  		newerr, ok := err.(awserr.Error)
   377  		if !ok {
   378  			return err
   379  		}
   380  		if newerr.Code() != "DBInstanceNotFound" {
   381  			return err
   382  		}
   383  	}
   384  
   385  	return nil
   386  }
   387  
   388  func testAccCheckAWSDBInstanceAttributes(v *rds.DBInstance) resource.TestCheckFunc {
   389  	return func(s *terraform.State) error {
   390  
   391  		if *v.Engine != "mysql" {
   392  			return fmt.Errorf("bad engine: %#v", *v.Engine)
   393  		}
   394  
   395  		if *v.EngineVersion == "" {
   396  			return fmt.Errorf("bad engine_version: %#v", *v.EngineVersion)
   397  		}
   398  
   399  		if *v.BackupRetentionPeriod != 0 {
   400  			return fmt.Errorf("bad backup_retention_period: %#v", *v.BackupRetentionPeriod)
   401  		}
   402  
   403  		return nil
   404  	}
   405  }
   406  
   407  func testAccCheckAWSDBInstanceAttributes_MSSQL(v *rds.DBInstance, tz string) resource.TestCheckFunc {
   408  	return func(s *terraform.State) error {
   409  
   410  		if *v.Engine != "sqlserver-ex" {
   411  			return fmt.Errorf("bad engine: %#v", *v.Engine)
   412  		}
   413  
   414  		rtz := ""
   415  		if v.Timezone != nil {
   416  			rtz = *v.Timezone
   417  		}
   418  
   419  		if tz != rtz {
   420  			return fmt.Errorf("Expected (%s) Timezone for MSSQL test, got (%s)", tz, rtz)
   421  		}
   422  
   423  		return nil
   424  	}
   425  }
   426  
   427  func testAccCheckAWSDBInstanceReplicaAttributes(source, replica *rds.DBInstance) resource.TestCheckFunc {
   428  	return func(s *terraform.State) error {
   429  
   430  		if replica.ReadReplicaSourceDBInstanceIdentifier != nil && *replica.ReadReplicaSourceDBInstanceIdentifier != *source.DBInstanceIdentifier {
   431  			return fmt.Errorf("bad source identifier for replica, expected: '%s', got: '%s'", *source.DBInstanceIdentifier, *replica.ReadReplicaSourceDBInstanceIdentifier)
   432  		}
   433  
   434  		return nil
   435  	}
   436  }
   437  
   438  func testAccCheckAWSDBInstanceSnapshot(rInt int) resource.TestCheckFunc {
   439  	return func(s *terraform.State) error {
   440  		for _, rs := range s.RootModule().Resources {
   441  			if rs.Type != "aws_db_instance" {
   442  				continue
   443  			}
   444  
   445  			awsClient := testAccProvider.Meta().(*AWSClient)
   446  			conn := awsClient.rdsconn
   447  
   448  			var err error
   449  			log.Printf("[INFO] Trying to locate the DBInstance Final Snapshot")
   450  			snapshot_identifier := fmt.Sprintf("foobarbaz-test-terraform-final-snapshot-%d", rInt)
   451  			_, snapErr := conn.DescribeDBSnapshots(
   452  				&rds.DescribeDBSnapshotsInput{
   453  					DBSnapshotIdentifier: aws.String(snapshot_identifier),
   454  				})
   455  
   456  			if snapErr != nil {
   457  				newerr, _ := snapErr.(awserr.Error)
   458  				if newerr.Code() == "DBSnapshotNotFound" {
   459  					return fmt.Errorf("Snapshot %s not found", snapshot_identifier)
   460  				}
   461  			} else { // snapshot was found,
   462  				// verify we have the tags copied to the snapshot
   463  				instanceARN, err := buildRDSARN(snapshot_identifier, testAccProvider.Meta().(*AWSClient).partition, testAccProvider.Meta().(*AWSClient).accountid, testAccProvider.Meta().(*AWSClient).region)
   464  				// tags have a different ARN, just swapping :db: for :snapshot:
   465  				tagsARN := strings.Replace(instanceARN, ":db:", ":snapshot:", 1)
   466  				if err != nil {
   467  					return fmt.Errorf("Error building ARN for tags check with ARN (%s): %s", tagsARN, err)
   468  				}
   469  				resp, err := conn.ListTagsForResource(&rds.ListTagsForResourceInput{
   470  					ResourceName: aws.String(tagsARN),
   471  				})
   472  				if err != nil {
   473  					return fmt.Errorf("Error retrieving tags for ARN (%s): %s", tagsARN, err)
   474  				}
   475  
   476  				if resp.TagList == nil || len(resp.TagList) == 0 {
   477  					return fmt.Errorf("Tag list is nil or zero: %s", resp.TagList)
   478  				}
   479  
   480  				var found bool
   481  				for _, t := range resp.TagList {
   482  					if *t.Key == "Name" && *t.Value == "tf-tags-db" {
   483  						found = true
   484  					}
   485  				}
   486  				if !found {
   487  					return fmt.Errorf("Expected to find tag Name (%s), but wasn't found. Tags: %s", "tf-tags-db", resp.TagList)
   488  				}
   489  				// end tag search
   490  
   491  				log.Printf("[INFO] Deleting the Snapshot %s", snapshot_identifier)
   492  				_, snapDeleteErr := conn.DeleteDBSnapshot(
   493  					&rds.DeleteDBSnapshotInput{
   494  						DBSnapshotIdentifier: aws.String(snapshot_identifier),
   495  					})
   496  				if snapDeleteErr != nil {
   497  					return err
   498  				}
   499  			} // end snapshot was found
   500  
   501  			resp, err := conn.DescribeDBInstances(
   502  				&rds.DescribeDBInstancesInput{
   503  					DBInstanceIdentifier: aws.String(rs.Primary.ID),
   504  				})
   505  
   506  			if err != nil {
   507  				newerr, _ := err.(awserr.Error)
   508  				if newerr.Code() != "DBInstanceNotFound" {
   509  					return err
   510  				}
   511  
   512  			} else {
   513  				if len(resp.DBInstances) != 0 &&
   514  					*resp.DBInstances[0].DBInstanceIdentifier == rs.Primary.ID {
   515  					return fmt.Errorf("DB Instance still exists")
   516  				}
   517  			}
   518  		}
   519  
   520  		return nil
   521  	}
   522  }
   523  
   524  func testAccCheckAWSDBInstanceNoSnapshot(s *terraform.State) error {
   525  	conn := testAccProvider.Meta().(*AWSClient).rdsconn
   526  
   527  	for _, rs := range s.RootModule().Resources {
   528  		if rs.Type != "aws_db_instance" {
   529  			continue
   530  		}
   531  
   532  		var err error
   533  		resp, err := conn.DescribeDBInstances(
   534  			&rds.DescribeDBInstancesInput{
   535  				DBInstanceIdentifier: aws.String(rs.Primary.ID),
   536  			})
   537  
   538  		if err != nil {
   539  			newerr, _ := err.(awserr.Error)
   540  			if newerr.Code() != "DBInstanceNotFound" {
   541  				return err
   542  			}
   543  
   544  		} else {
   545  			if len(resp.DBInstances) != 0 &&
   546  				*resp.DBInstances[0].DBInstanceIdentifier == rs.Primary.ID {
   547  				return fmt.Errorf("DB Instance still exists")
   548  			}
   549  		}
   550  
   551  		snapshot_identifier := "foobarbaz-test-terraform-final-snapshot-2"
   552  		_, snapErr := conn.DescribeDBSnapshots(
   553  			&rds.DescribeDBSnapshotsInput{
   554  				DBSnapshotIdentifier: aws.String(snapshot_identifier),
   555  			})
   556  
   557  		if snapErr != nil {
   558  			newerr, _ := snapErr.(awserr.Error)
   559  			if newerr.Code() != "DBSnapshotNotFound" {
   560  				return fmt.Errorf("Snapshot %s found and it shouldn't have been", snapshot_identifier)
   561  			}
   562  		}
   563  	}
   564  
   565  	return nil
   566  }
   567  
   568  func testAccCheckAWSDBInstanceExists(n string, v *rds.DBInstance) resource.TestCheckFunc {
   569  	return func(s *terraform.State) error {
   570  		rs, ok := s.RootModule().Resources[n]
   571  		if !ok {
   572  			return fmt.Errorf("Not found: %s", n)
   573  		}
   574  
   575  		if rs.Primary.ID == "" {
   576  			return fmt.Errorf("No DB Instance ID is set")
   577  		}
   578  
   579  		conn := testAccProvider.Meta().(*AWSClient).rdsconn
   580  
   581  		opts := rds.DescribeDBInstancesInput{
   582  			DBInstanceIdentifier: aws.String(rs.Primary.ID),
   583  		}
   584  
   585  		resp, err := conn.DescribeDBInstances(&opts)
   586  
   587  		if err != nil {
   588  			return err
   589  		}
   590  
   591  		if len(resp.DBInstances) != 1 ||
   592  			*resp.DBInstances[0].DBInstanceIdentifier != rs.Primary.ID {
   593  			return fmt.Errorf("DB Instance not found")
   594  		}
   595  
   596  		*v = *resp.DBInstances[0]
   597  
   598  		return nil
   599  	}
   600  }
   601  
   602  // Database names cannot collide, and deletion takes so long, that making the
   603  // name a bit random helps so able we can kill a test that's just waiting for a
   604  // delete and not be blocked on kicking off another one.
   605  var testAccAWSDBInstanceConfig = `
   606  resource "aws_db_instance" "bar" {
   607  	allocated_storage = 10
   608  	engine = "MySQL"
   609  	engine_version = "5.6.21"
   610  	instance_class = "db.t1.micro"
   611  	name = "baz"
   612  	password = "barbarbarbar"
   613  	username = "foo"
   614  
   615  
   616  	# Maintenance Window is stored in lower case in the API, though not strictly 
   617  	# documented. Terraform will downcase this to match (as opposed to throw a 
   618  	# validation error).
   619  	maintenance_window = "Fri:09:00-Fri:09:30"
   620  	skip_final_snapshot = true
   621  
   622  	backup_retention_period = 0
   623  
   624  	parameter_group_name = "default.mysql5.6"
   625  }`
   626  
   627  var testAccAWSDBInstanceConfigKmsKeyId = `
   628  resource "aws_kms_key" "foo" {
   629      description = "Terraform acc test %s"
   630      policy = <<POLICY
   631  {
   632    "Version": "2012-10-17",
   633    "Id": "kms-tf-1",
   634    "Statement": [
   635      {
   636        "Sid": "Enable IAM User Permissions",
   637        "Effect": "Allow",
   638        "Principal": {
   639          "AWS": "*"
   640        },
   641        "Action": "kms:*",
   642        "Resource": "*"
   643      }
   644    ]
   645  }
   646  POLICY
   647  }
   648  
   649  resource "aws_db_instance" "bar" {
   650  	allocated_storage = 10
   651  	engine = "MySQL"
   652  	engine_version = "5.6.21"
   653  	instance_class = "db.m3.medium"
   654  	name = "baz"
   655  	password = "barbarbarbar"
   656  	username = "foo"
   657  
   658  
   659  	# Maintenance Window is stored in lower case in the API, though not strictly
   660  	# documented. Terraform will downcase this to match (as opposed to throw a
   661  	# validation error).
   662  	maintenance_window = "Fri:09:00-Fri:09:30"
   663  
   664  	backup_retention_period = 0
   665  	storage_encrypted = true
   666  	kms_key_id = "${aws_kms_key.foo.arn}"
   667  
   668  	skip_final_snapshot = true
   669  
   670  	parameter_group_name = "default.mysql5.6"
   671  }
   672  `
   673  
   674  func testAccAWSDBInstanceConfigWithOptionGroup(rName string) string {
   675  	return fmt.Sprintf(`
   676  resource "aws_db_option_group" "bar" {
   677  	name = "%s"
   678  	option_group_description = "Test option group for terraform"
   679  	engine_name = "mysql"
   680  	major_engine_version = "5.6"
   681  }
   682  
   683  resource "aws_db_instance" "bar" {
   684  	identifier = "foobarbaz-test-terraform-%d"
   685  
   686  	allocated_storage = 10
   687  	engine = "MySQL"
   688  	instance_class = "db.m1.small"
   689  	name = "baz"
   690  	password = "barbarbarbar"
   691  	username = "foo"
   692  
   693  	backup_retention_period = 0
   694  	skip_final_snapshot = true
   695  
   696  	parameter_group_name = "default.mysql5.6"
   697  	option_group_name = "${aws_db_option_group.bar.name}"
   698  }`, rName, acctest.RandInt())
   699  }
   700  
   701  func testAccReplicaInstanceConfig(val int) string {
   702  	return fmt.Sprintf(`
   703  	resource "aws_db_instance" "bar" {
   704  		identifier = "foobarbaz-test-terraform-%d"
   705  
   706  		allocated_storage = 5
   707  		engine = "mysql"
   708  		engine_version = "5.6.21"
   709  		instance_class = "db.t1.micro"
   710  		name = "baz"
   711  		password = "barbarbarbar"
   712  		username = "foo"
   713  
   714  		backup_retention_period = 1
   715  		skip_final_snapshot = true
   716  
   717  		parameter_group_name = "default.mysql5.6"
   718  	}
   719  	
   720  	resource "aws_db_instance" "replica" {
   721  		identifier = "tf-replica-db-%d"
   722  		backup_retention_period = 0
   723  		replicate_source_db = "${aws_db_instance.bar.identifier}"
   724  		allocated_storage = "${aws_db_instance.bar.allocated_storage}"
   725  		engine = "${aws_db_instance.bar.engine}"
   726  		engine_version = "${aws_db_instance.bar.engine_version}"
   727  		instance_class = "${aws_db_instance.bar.instance_class}"
   728  		password = "${aws_db_instance.bar.password}"
   729  		username = "${aws_db_instance.bar.username}"
   730  		skip_final_snapshot = true
   731  		tags {
   732  			Name = "tf-replica-db"
   733  		}
   734  	}
   735  	`, val, val)
   736  }
   737  
   738  func testAccSnapshotInstanceConfig() string {
   739  	return fmt.Sprintf(`
   740  provider "aws" {
   741    region = "us-east-1"
   742  }
   743  resource "aws_db_instance" "snapshot" {
   744  	identifier = "tf-test-%d"
   745  
   746  	allocated_storage = 5
   747  	engine = "mysql"
   748  	engine_version = "5.6.21"
   749  	instance_class = "db.t1.micro"
   750  	name = "baz"
   751  	password = "barbarbarbar"
   752  	username = "foo"
   753  	security_group_names = ["default"]
   754  	backup_retention_period = 1
   755  
   756  	publicly_accessible = true
   757  
   758  	parameter_group_name = "default.mysql5.6"
   759  
   760  	skip_final_snapshot = true
   761  	final_snapshot_identifier = "foobarbaz-test-terraform-final-snapshot-1"
   762  }`, acctest.RandInt())
   763  }
   764  
   765  func testAccSnapshotInstanceConfigWithSnapshot(rInt int) string {
   766  	return fmt.Sprintf(`
   767  provider "aws" {
   768    region = "us-east-1"
   769  }
   770  resource "aws_db_instance" "snapshot" {
   771  	identifier = "tf-snapshot-%d"
   772  
   773  	allocated_storage = 5
   774  	engine = "mysql"
   775  	engine_version = "5.6.21"
   776  	instance_class = "db.t1.micro"
   777  	name = "baz"
   778  	password = "barbarbarbar"
   779  	publicly_accessible = true
   780  	username = "foo"
   781      	security_group_names = ["default"]
   782  	backup_retention_period = 1
   783  
   784  	parameter_group_name = "default.mysql5.6"
   785  
   786  	copy_tags_to_snapshot = true
   787  	final_snapshot_identifier = "foobarbaz-test-terraform-final-snapshot-%d"
   788  	tags {
   789  		Name = "tf-tags-db"
   790  	}
   791  }
   792  `, rInt, rInt)
   793  }
   794  
   795  func testAccSnapshotInstanceConfig_enhancedMonitoring(rName string) string {
   796  	return fmt.Sprintf(`
   797  resource "aws_iam_role" "enhanced_policy_role" {
   798      name = "enhanced-monitoring-role-%s"
   799      assume_role_policy = <<EOF
   800  {
   801    "Version": "2012-10-17",
   802    "Statement": [
   803      {
   804        "Sid": "",
   805        "Effect": "Allow",
   806        "Principal": {
   807          "Service": "monitoring.rds.amazonaws.com"
   808        },
   809        "Action": "sts:AssumeRole"
   810      }
   811    ]
   812  }
   813  EOF
   814  
   815  }
   816  
   817  resource "aws_iam_policy_attachment" "test-attach" {
   818      name = "enhanced-monitoring-attachment"
   819      roles = [
   820          "${aws_iam_role.enhanced_policy_role.name}",
   821      ]
   822  
   823      policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole"
   824  }
   825  
   826  resource "aws_db_instance" "enhanced_monitoring" {
   827  	identifier = "foobarbaz-enhanced-monitoring-%s"
   828  	depends_on = ["aws_iam_policy_attachment.test-attach"]
   829  
   830  	allocated_storage = 5
   831  	engine = "mysql"
   832  	engine_version = "5.6.21"
   833  	instance_class = "db.m3.medium"
   834  	name = "baz"
   835  	password = "barbarbarbar"
   836  	username = "foo"
   837  	backup_retention_period = 1
   838  
   839  	parameter_group_name = "default.mysql5.6"
   840  
   841  	monitoring_role_arn = "${aws_iam_role.enhanced_policy_role.arn}"
   842  	monitoring_interval = "5"
   843  
   844  	skip_final_snapshot = true
   845  }`, rName, rName)
   846  }
   847  
   848  func testAccSnapshotInstanceConfig_iopsUpdate(rName string, iops int) string {
   849  	return fmt.Sprintf(`
   850  resource "aws_db_instance" "bar" {
   851    identifier           = "mydb-rds-%s"
   852    engine               = "mysql"
   853    engine_version       = "5.6.23"
   854    instance_class       = "db.t2.micro"
   855    name                 = "mydb"
   856    username             = "foo"
   857    password             = "barbarbar"
   858    parameter_group_name = "default.mysql5.6"
   859    skip_final_snapshot = true
   860  
   861    apply_immediately = true
   862  
   863    storage_type      = "io1"
   864    allocated_storage = 200
   865    iops              = %d
   866  }`, rName, iops)
   867  }
   868  
   869  func testAccSnapshotInstanceConfig_mysqlPort(rName string) string {
   870  	return fmt.Sprintf(`
   871  resource "aws_db_instance" "bar" {
   872    identifier           = "mydb-rds-%s"
   873    engine               = "mysql"
   874    engine_version       = "5.6.23"
   875    instance_class       = "db.t2.micro"
   876    name                 = "mydb"
   877    username             = "foo"
   878    password             = "barbarbar"
   879    parameter_group_name = "default.mysql5.6"
   880    port = 3306
   881    allocated_storage = 10
   882    skip_final_snapshot = true
   883  
   884    apply_immediately = true
   885  }`, rName)
   886  }
   887  
   888  func testAccSnapshotInstanceConfig_updateMysqlPort(rName string) string {
   889  	return fmt.Sprintf(`
   890  resource "aws_db_instance" "bar" {
   891    identifier           = "mydb-rds-%s"
   892    engine               = "mysql"
   893    engine_version       = "5.6.23"
   894    instance_class       = "db.t2.micro"
   895    name                 = "mydb"
   896    username             = "foo"
   897    password             = "barbarbar"
   898    parameter_group_name = "default.mysql5.6"
   899    port = 3305
   900    allocated_storage = 10
   901    skip_final_snapshot = true
   902  
   903    apply_immediately = true
   904  }`, rName)
   905  }
   906  
   907  func testAccAWSDBInstanceConfigWithSubnetGroup(rName string) string {
   908  	return fmt.Sprintf(`
   909  resource "aws_vpc" "foo" {
   910  	cidr_block = "10.1.0.0/16"
   911  }
   912  
   913  resource "aws_subnet" "foo" {
   914  	cidr_block = "10.1.1.0/24"
   915  	availability_zone = "us-west-2a"
   916  	vpc_id = "${aws_vpc.foo.id}"
   917  	tags {
   918  		Name = "tf-dbsubnet-test-1"
   919  	}
   920  }
   921  
   922  resource "aws_subnet" "bar" {
   923  	cidr_block = "10.1.2.0/24"
   924  	availability_zone = "us-west-2b"
   925  	vpc_id = "${aws_vpc.foo.id}"
   926  	tags {
   927  		Name = "tf-dbsubnet-test-2"
   928  	}
   929  }
   930  
   931  resource "aws_db_subnet_group" "foo" {
   932  	name = "foo-%s"
   933  	subnet_ids = ["${aws_subnet.foo.id}", "${aws_subnet.bar.id}"]
   934  	tags {
   935  		Name = "tf-dbsubnet-group-test"
   936  	}
   937  }
   938  
   939  resource "aws_db_instance" "bar" {
   940    identifier           = "mydb-rds-%s"
   941    engine               = "mysql"
   942    engine_version       = "5.6.23"
   943    instance_class       = "db.t2.micro"
   944    name                 = "mydb"
   945    username             = "foo"
   946    password             = "barbarbar"
   947    parameter_group_name = "default.mysql5.6"
   948    db_subnet_group_name = "${aws_db_subnet_group.foo.name}"
   949    port = 3305
   950    allocated_storage = 10
   951    skip_final_snapshot = true
   952  
   953  	backup_retention_period = 0
   954    apply_immediately = true
   955  }`, rName, rName)
   956  }
   957  
   958  func testAccAWSDBInstanceConfigWithSubnetGroupUpdated(rName string) string {
   959  	return fmt.Sprintf(`
   960  resource "aws_vpc" "foo" {
   961  	cidr_block = "10.1.0.0/16"
   962  }
   963  
   964  resource "aws_vpc" "bar" {
   965  	cidr_block = "10.10.0.0/16"
   966  }
   967  
   968  resource "aws_subnet" "foo" {
   969  	cidr_block = "10.1.1.0/24"
   970  	availability_zone = "us-west-2a"
   971  	vpc_id = "${aws_vpc.foo.id}"
   972  	tags {
   973  		Name = "tf-dbsubnet-test-1"
   974  	}
   975  }
   976  
   977  resource "aws_subnet" "bar" {
   978  	cidr_block = "10.1.2.0/24"
   979  	availability_zone = "us-west-2b"
   980  	vpc_id = "${aws_vpc.foo.id}"
   981  	tags {
   982  		Name = "tf-dbsubnet-test-2"
   983  	}
   984  }
   985  
   986  resource "aws_subnet" "test" {
   987  	cidr_block = "10.10.3.0/24"
   988  	availability_zone = "us-west-2b"
   989  	vpc_id = "${aws_vpc.bar.id}"
   990  	tags {
   991  		Name = "tf-dbsubnet-test-3"
   992  	}
   993  }
   994  
   995  resource "aws_subnet" "another_test" {
   996  	cidr_block = "10.10.4.0/24"
   997  	availability_zone = "us-west-2a"
   998  	vpc_id = "${aws_vpc.bar.id}"
   999  	tags {
  1000  		Name = "tf-dbsubnet-test-4"
  1001  	}
  1002  }
  1003  
  1004  resource "aws_db_subnet_group" "foo" {
  1005  	name = "foo-%s"
  1006  	subnet_ids = ["${aws_subnet.foo.id}", "${aws_subnet.bar.id}"]
  1007  	tags {
  1008  		Name = "tf-dbsubnet-group-test"
  1009  	}
  1010  }
  1011  
  1012  resource "aws_db_subnet_group" "bar" {
  1013  	name = "bar-%s"
  1014  	subnet_ids = ["${aws_subnet.test.id}", "${aws_subnet.another_test.id}"]
  1015  	tags {
  1016  		Name = "tf-dbsubnet-group-test-updated"
  1017  	}
  1018  }
  1019  
  1020  resource "aws_db_instance" "bar" {
  1021    identifier           = "mydb-rds-%s"
  1022    engine               = "mysql"
  1023    engine_version       = "5.6.23"
  1024    instance_class       = "db.t2.micro"
  1025    name                 = "mydb"
  1026    username             = "foo"
  1027    password             = "barbarbar"
  1028    parameter_group_name = "default.mysql5.6"
  1029    db_subnet_group_name = "${aws_db_subnet_group.bar.name}"
  1030    port = 3305
  1031    allocated_storage = 10
  1032    skip_final_snapshot = true
  1033  
  1034  	backup_retention_period = 0
  1035  
  1036    apply_immediately = true
  1037  }`, rName, rName, rName)
  1038  }
  1039  
  1040  const testAccAWSDBMSSQL_timezone = `
  1041  provider "aws" {
  1042    region = "us-west-2"
  1043  }
  1044  
  1045  resource "aws_vpc" "foo" {
  1046    cidr_block           = "10.1.0.0/16"
  1047    enable_dns_hostnames = true
  1048  	tags {
  1049  		Name = "tf-rds-mssql-timezone-test"
  1050  	}
  1051  }
  1052  
  1053  resource "aws_db_subnet_group" "rds_one" {
  1054    name        = "rds_one_db"
  1055    description = "db subnets for rds_one"
  1056  
  1057    subnet_ids = ["${aws_subnet.main.id}", "${aws_subnet.other.id}"]
  1058  }
  1059  
  1060  resource "aws_subnet" "main" {
  1061    vpc_id            = "${aws_vpc.foo.id}"
  1062    availability_zone = "us-west-2a"
  1063    cidr_block        = "10.1.1.0/24"
  1064  }
  1065  
  1066  resource "aws_subnet" "other" {
  1067    vpc_id            = "${aws_vpc.foo.id}"
  1068    availability_zone = "us-west-2b"
  1069    cidr_block        = "10.1.2.0/24"
  1070  }
  1071  
  1072  resource "aws_db_instance" "mssql" {
  1073    #identifier = "tf-test-mssql"
  1074  
  1075    db_subnet_group_name = "${aws_db_subnet_group.rds_one.name}"
  1076  
  1077    instance_class          = "db.t2.micro"
  1078    allocated_storage       = 20
  1079    username                = "somecrazyusername"
  1080    password                = "somecrazypassword"
  1081    engine                  = "sqlserver-ex"
  1082    backup_retention_period = 0
  1083    skip_final_snapshot = true
  1084  
  1085    #publicly_accessible = true
  1086  
  1087    vpc_security_group_ids = ["${aws_security_group.rds-mssql.id}"]
  1088  }
  1089  
  1090  resource "aws_security_group" "rds-mssql" {
  1091    name = "tf-rds-mssql-test"
  1092  
  1093    description = "TF Testing"
  1094    vpc_id      = "${aws_vpc.foo.id}"
  1095  }
  1096  
  1097  resource "aws_security_group_rule" "rds-mssql-1" {
  1098    type        = "egress"
  1099    from_port   = 0
  1100    to_port     = 0
  1101    protocol    = "-1"
  1102    cidr_blocks = ["0.0.0.0/0"]
  1103  
  1104    security_group_id = "${aws_security_group.rds-mssql.id}"
  1105  }
  1106  `
  1107  
  1108  const testAccAWSDBMSSQL_timezone_AKST = `
  1109  provider "aws" {
  1110    region = "us-west-2"
  1111  }
  1112  
  1113  resource "aws_vpc" "foo" {
  1114    cidr_block           = "10.1.0.0/16"
  1115    enable_dns_hostnames = true
  1116  	tags {
  1117  		Name = "tf-rds-mssql-timezone-test"
  1118  	}
  1119  }
  1120  
  1121  resource "aws_db_subnet_group" "rds_one" {
  1122    name        = "rds_one_db"
  1123    description = "db subnets for rds_one"
  1124  
  1125    subnet_ids = ["${aws_subnet.main.id}", "${aws_subnet.other.id}"]
  1126  }
  1127  
  1128  resource "aws_subnet" "main" {
  1129    vpc_id            = "${aws_vpc.foo.id}"
  1130    availability_zone = "us-west-2a"
  1131    cidr_block        = "10.1.1.0/24"
  1132  }
  1133  
  1134  resource "aws_subnet" "other" {
  1135    vpc_id            = "${aws_vpc.foo.id}"
  1136    availability_zone = "us-west-2b"
  1137    cidr_block        = "10.1.2.0/24"
  1138  }
  1139  
  1140  resource "aws_db_instance" "mssql" {
  1141    #identifier = "tf-test-mssql"
  1142  
  1143    db_subnet_group_name = "${aws_db_subnet_group.rds_one.name}"
  1144  
  1145    instance_class          = "db.t2.micro"
  1146    allocated_storage       = 20
  1147    username                = "somecrazyusername"
  1148    password                = "somecrazypassword"
  1149    engine                  = "sqlserver-ex"
  1150    backup_retention_period = 0
  1151    skip_final_snapshot = true
  1152  
  1153    #publicly_accessible = true
  1154  
  1155    vpc_security_group_ids = ["${aws_security_group.rds-mssql.id}"]
  1156    timezone               = "Alaskan Standard Time"
  1157  }
  1158  
  1159  resource "aws_security_group" "rds-mssql" {
  1160    name = "tf-rds-mssql-test"
  1161  
  1162    description = "TF Testing"
  1163    vpc_id      = "${aws_vpc.foo.id}"
  1164  }
  1165  
  1166  resource "aws_security_group_rule" "rds-mssql-1" {
  1167    type        = "egress"
  1168    from_port   = 0
  1169    to_port     = 0
  1170    protocol    = "-1"
  1171    cidr_blocks = ["0.0.0.0/0"]
  1172  
  1173    security_group_id = "${aws_security_group.rds-mssql.id}"
  1174  }
  1175  `
  1176  
  1177  var testAccAWSDBInstanceConfigAutoMinorVersion = fmt.Sprintf(`
  1178  resource "aws_db_instance" "bar" {
  1179    identifier = "foobarbaz-test-terraform-%d"
  1180  	allocated_storage = 10
  1181  	engine = "MySQL"
  1182  	engine_version = "5.6"
  1183  	instance_class = "db.t1.micro"
  1184  	name = "baz"
  1185  	password = "barbarbarbar"
  1186  	username = "foo"
  1187  	skip_final_snapshot = true
  1188  }
  1189  `, acctest.RandInt())
  1190  
  1191  func testAccAWSDBInstanceConfigSuppressInitialState(rInt int) string {
  1192  	return fmt.Sprintf(`
  1193  resource "aws_db_instance" "bar" {
  1194    identifier = "foobarbaz-test-terraform-%d"
  1195  	allocated_storage = 10
  1196  	engine = "MySQL"
  1197  	instance_class = "db.t1.micro"
  1198  	name = "baz"
  1199  	password = "barbarbarbar"
  1200  	username = "foo"
  1201  	skip_final_snapshot = true
  1202  }
  1203  
  1204  data "template_file" "test" {
  1205    template = ""
  1206    vars = {
  1207      test_var = "${aws_db_instance.bar.engine_version}"
  1208    }
  1209  }
  1210  `, rInt)
  1211  }