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