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