github.com/joshgarnett/terraform@v0.5.4-0.20160219181435-92dc20bb3594/builtin/providers/aws/resource_aws_db_instance_test.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 7 "math/rand" 8 "testing" 9 "time" 10 11 "github.com/hashicorp/terraform/helper/acctest" 12 "github.com/hashicorp/terraform/helper/resource" 13 "github.com/hashicorp/terraform/terraform" 14 15 "github.com/aws/aws-sdk-go/aws" 16 "github.com/aws/aws-sdk-go/aws/awserr" 17 "github.com/aws/aws-sdk-go/service/rds" 18 ) 19 20 func TestAccAWSDBInstance_basic(t *testing.T) { 21 var v rds.DBInstance 22 23 resource.Test(t, resource.TestCase{ 24 PreCheck: func() { testAccPreCheck(t) }, 25 Providers: testAccProviders, 26 CheckDestroy: testAccCheckAWSDBInstanceDestroy, 27 Steps: []resource.TestStep{ 28 resource.TestStep{ 29 Config: testAccAWSDBInstanceConfig, 30 Check: resource.ComposeTestCheckFunc( 31 testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &v), 32 testAccCheckAWSDBInstanceAttributes(&v), 33 resource.TestCheckResourceAttr( 34 "aws_db_instance.bar", "allocated_storage", "10"), 35 resource.TestCheckResourceAttr( 36 "aws_db_instance.bar", "engine", "mysql"), 37 resource.TestCheckResourceAttr( 38 "aws_db_instance.bar", "license_model", "general-public-license"), 39 resource.TestCheckResourceAttr( 40 "aws_db_instance.bar", "instance_class", "db.t1.micro"), 41 resource.TestCheckResourceAttr( 42 "aws_db_instance.bar", "name", "baz"), 43 resource.TestCheckResourceAttr( 44 "aws_db_instance.bar", "username", "foo"), 45 resource.TestCheckResourceAttr( 46 "aws_db_instance.bar", "parameter_group_name", "default.mysql5.6"), 47 ), 48 }, 49 }, 50 }) 51 } 52 53 func TestAccAWSDBInstanceReplica(t *testing.T) { 54 var s, r rds.DBInstance 55 56 resource.Test(t, resource.TestCase{ 57 PreCheck: func() { testAccPreCheck(t) }, 58 Providers: testAccProviders, 59 CheckDestroy: testAccCheckAWSDBInstanceDestroy, 60 Steps: []resource.TestStep{ 61 resource.TestStep{ 62 Config: testAccReplicaInstanceConfig(rand.New(rand.NewSource(time.Now().UnixNano())).Int()), 63 Check: resource.ComposeTestCheckFunc( 64 testAccCheckAWSDBInstanceExists("aws_db_instance.bar", &s), 65 testAccCheckAWSDBInstanceExists("aws_db_instance.replica", &r), 66 testAccCheckAWSDBInstanceReplicaAttributes(&s, &r), 67 ), 68 }, 69 }, 70 }) 71 } 72 73 func TestAccAWSDBInstanceSnapshot(t *testing.T) { 74 var snap rds.DBInstance 75 76 resource.Test(t, resource.TestCase{ 77 PreCheck: func() { testAccPreCheck(t) }, 78 Providers: testAccProviders, 79 // testAccCheckAWSDBInstanceSnapshot verifies a database snapshot is 80 // created, and subequently deletes it 81 CheckDestroy: testAccCheckAWSDBInstanceSnapshot, 82 Steps: []resource.TestStep{ 83 resource.TestStep{ 84 Config: testAccSnapshotInstanceConfig(), 85 Check: resource.ComposeTestCheckFunc( 86 testAccCheckAWSDBInstanceExists("aws_db_instance.snapshot", &snap), 87 ), 88 }, 89 }, 90 }) 91 } 92 93 func TestAccAWSDBInstanceNoSnapshot(t *testing.T) { 94 var nosnap rds.DBInstance 95 96 resource.Test(t, resource.TestCase{ 97 PreCheck: func() { testAccPreCheck(t) }, 98 Providers: testAccProviders, 99 CheckDestroy: testAccCheckAWSDBInstanceNoSnapshot, 100 Steps: []resource.TestStep{ 101 resource.TestStep{ 102 Config: testAccNoSnapshotInstanceConfig, 103 Check: resource.ComposeTestCheckFunc( 104 testAccCheckAWSDBInstanceExists("aws_db_instance.no_snapshot", &nosnap), 105 ), 106 }, 107 }, 108 }) 109 } 110 111 func testAccCheckAWSDBInstanceDestroy(s *terraform.State) error { 112 conn := testAccProvider.Meta().(*AWSClient).rdsconn 113 114 for _, rs := range s.RootModule().Resources { 115 if rs.Type != "aws_db_instance" { 116 continue 117 } 118 119 // Try to find the Group 120 var err error 121 resp, err := conn.DescribeDBInstances( 122 &rds.DescribeDBInstancesInput{ 123 DBInstanceIdentifier: aws.String(rs.Primary.ID), 124 }) 125 126 if ae, ok := err.(awserr.Error); ok && ae.Code() == "DBInstanceNotFound" { 127 continue 128 } 129 130 if err == nil { 131 if len(resp.DBInstances) != 0 && 132 *resp.DBInstances[0].DBInstanceIdentifier == rs.Primary.ID { 133 return fmt.Errorf("DB Instance still exists") 134 } 135 } 136 137 // Verify the error 138 newerr, ok := err.(awserr.Error) 139 if !ok { 140 return err 141 } 142 if newerr.Code() != "InvalidDBInstance.NotFound" { 143 return err 144 } 145 } 146 147 return nil 148 } 149 150 func testAccCheckAWSDBInstanceAttributes(v *rds.DBInstance) resource.TestCheckFunc { 151 return func(s *terraform.State) error { 152 153 if *v.Engine != "mysql" { 154 return fmt.Errorf("bad engine: %#v", *v.Engine) 155 } 156 157 if *v.EngineVersion == "" { 158 return fmt.Errorf("bad engine_version: %#v", *v.EngineVersion) 159 } 160 161 if *v.BackupRetentionPeriod != 0 { 162 return fmt.Errorf("bad backup_retention_period: %#v", *v.BackupRetentionPeriod) 163 } 164 165 return nil 166 } 167 } 168 169 func testAccCheckAWSDBInstanceReplicaAttributes(source, replica *rds.DBInstance) resource.TestCheckFunc { 170 return func(s *terraform.State) error { 171 172 if replica.ReadReplicaSourceDBInstanceIdentifier != nil && *replica.ReadReplicaSourceDBInstanceIdentifier != *source.DBInstanceIdentifier { 173 return fmt.Errorf("bad source identifier for replica, expected: '%s', got: '%s'", *source.DBInstanceIdentifier, *replica.ReadReplicaSourceDBInstanceIdentifier) 174 } 175 176 return nil 177 } 178 } 179 180 func testAccCheckAWSDBInstanceSnapshot(s *terraform.State) error { 181 conn := testAccProvider.Meta().(*AWSClient).rdsconn 182 183 for _, rs := range s.RootModule().Resources { 184 if rs.Type != "aws_db_instance" { 185 continue 186 } 187 188 var err error 189 resp, err := conn.DescribeDBInstances( 190 &rds.DescribeDBInstancesInput{ 191 DBInstanceIdentifier: aws.String(rs.Primary.ID), 192 }) 193 194 if err != nil { 195 newerr, _ := err.(awserr.Error) 196 if newerr.Code() != "DBInstanceNotFound" { 197 return err 198 } 199 200 } else { 201 if len(resp.DBInstances) != 0 && 202 *resp.DBInstances[0].DBInstanceIdentifier == rs.Primary.ID { 203 return fmt.Errorf("DB Instance still exists") 204 } 205 } 206 207 log.Printf("[INFO] Trying to locate the DBInstance Final Snapshot") 208 snapshot_identifier := "foobarbaz-test-terraform-final-snapshot-1" 209 _, snapErr := conn.DescribeDBSnapshots( 210 &rds.DescribeDBSnapshotsInput{ 211 DBSnapshotIdentifier: aws.String(snapshot_identifier), 212 }) 213 214 if snapErr != nil { 215 newerr, _ := snapErr.(awserr.Error) 216 if newerr.Code() == "DBSnapshotNotFound" { 217 return fmt.Errorf("Snapshot %s not found", snapshot_identifier) 218 } 219 } else { 220 log.Printf("[INFO] Deleting the Snapshot %s", snapshot_identifier) 221 _, snapDeleteErr := conn.DeleteDBSnapshot( 222 &rds.DeleteDBSnapshotInput{ 223 DBSnapshotIdentifier: aws.String(snapshot_identifier), 224 }) 225 if snapDeleteErr != nil { 226 return err 227 } 228 } 229 } 230 231 return nil 232 } 233 234 func testAccCheckAWSDBInstanceNoSnapshot(s *terraform.State) error { 235 conn := testAccProvider.Meta().(*AWSClient).rdsconn 236 237 for _, rs := range s.RootModule().Resources { 238 if rs.Type != "aws_db_instance" { 239 continue 240 } 241 242 var err error 243 resp, err := conn.DescribeDBInstances( 244 &rds.DescribeDBInstancesInput{ 245 DBInstanceIdentifier: aws.String(rs.Primary.ID), 246 }) 247 248 if err != nil { 249 newerr, _ := err.(awserr.Error) 250 if newerr.Code() != "DBInstanceNotFound" { 251 return err 252 } 253 254 } else { 255 if len(resp.DBInstances) != 0 && 256 *resp.DBInstances[0].DBInstanceIdentifier == rs.Primary.ID { 257 return fmt.Errorf("DB Instance still exists") 258 } 259 } 260 261 snapshot_identifier := "foobarbaz-test-terraform-final-snapshot-2" 262 _, snapErr := conn.DescribeDBSnapshots( 263 &rds.DescribeDBSnapshotsInput{ 264 DBSnapshotIdentifier: aws.String(snapshot_identifier), 265 }) 266 267 if snapErr != nil { 268 newerr, _ := snapErr.(awserr.Error) 269 if newerr.Code() != "DBSnapshotNotFound" { 270 return fmt.Errorf("Snapshot %s found and it shouldn't have been", snapshot_identifier) 271 } 272 } 273 } 274 275 return nil 276 } 277 278 func testAccCheckAWSDBInstanceExists(n string, v *rds.DBInstance) resource.TestCheckFunc { 279 return func(s *terraform.State) error { 280 rs, ok := s.RootModule().Resources[n] 281 if !ok { 282 return fmt.Errorf("Not found: %s", n) 283 } 284 285 if rs.Primary.ID == "" { 286 return fmt.Errorf("No DB Instance ID is set") 287 } 288 289 conn := testAccProvider.Meta().(*AWSClient).rdsconn 290 291 opts := rds.DescribeDBInstancesInput{ 292 DBInstanceIdentifier: aws.String(rs.Primary.ID), 293 } 294 295 resp, err := conn.DescribeDBInstances(&opts) 296 297 if err != nil { 298 return err 299 } 300 301 if len(resp.DBInstances) != 1 || 302 *resp.DBInstances[0].DBInstanceIdentifier != rs.Primary.ID { 303 return fmt.Errorf("DB Instance not found") 304 } 305 306 *v = *resp.DBInstances[0] 307 308 return nil 309 } 310 } 311 312 // Database names cannot collide, and deletion takes so long, that making the 313 // name a bit random helps so able we can kill a test that's just waiting for a 314 // delete and not be blocked on kicking off another one. 315 var testAccAWSDBInstanceConfig = fmt.Sprintf(` 316 resource "aws_db_instance" "bar" { 317 identifier = "foobarbaz-test-terraform-%d" 318 319 allocated_storage = 10 320 engine = "MySQL" 321 engine_version = "5.6.21" 322 instance_class = "db.t1.micro" 323 name = "baz" 324 password = "barbarbarbar" 325 username = "foo" 326 327 328 # Maintenance Window is stored in lower case in the API, though not strictly 329 # documented. Terraform will downcase this to match (as opposed to throw a 330 # validation error). 331 maintenance_window = "Fri:09:00-Fri:09:30" 332 333 backup_retention_period = 0 334 335 parameter_group_name = "default.mysql5.6" 336 }`, rand.New(rand.NewSource(time.Now().UnixNano())).Int()) 337 338 func testAccReplicaInstanceConfig(val int) string { 339 return fmt.Sprintf(` 340 resource "aws_db_instance" "bar" { 341 identifier = "foobarbaz-test-terraform-%d" 342 343 allocated_storage = 5 344 engine = "mysql" 345 engine_version = "5.6.21" 346 instance_class = "db.t1.micro" 347 name = "baz" 348 password = "barbarbarbar" 349 username = "foo" 350 351 backup_retention_period = 1 352 353 parameter_group_name = "default.mysql5.6" 354 } 355 356 resource "aws_db_instance" "replica" { 357 identifier = "tf-replica-db-%d" 358 backup_retention_period = 0 359 replicate_source_db = "${aws_db_instance.bar.identifier}" 360 allocated_storage = "${aws_db_instance.bar.allocated_storage}" 361 engine = "${aws_db_instance.bar.engine}" 362 engine_version = "${aws_db_instance.bar.engine_version}" 363 instance_class = "${aws_db_instance.bar.instance_class}" 364 password = "${aws_db_instance.bar.password}" 365 username = "${aws_db_instance.bar.username}" 366 tags { 367 Name = "tf-replica-db" 368 } 369 } 370 `, val, val) 371 } 372 373 func testAccSnapshotInstanceConfig() string { 374 return fmt.Sprintf(` 375 provider "aws" { 376 region = "us-east-1" 377 } 378 resource "aws_db_instance" "snapshot" { 379 identifier = "tf-snapshot-%d" 380 381 allocated_storage = 5 382 engine = "mysql" 383 engine_version = "5.6.21" 384 instance_class = "db.t1.micro" 385 name = "baz" 386 password = "barbarbarbar" 387 username = "foo" 388 security_group_names = ["default"] 389 backup_retention_period = 1 390 391 parameter_group_name = "default.mysql5.6" 392 393 skip_final_snapshot = false 394 final_snapshot_identifier = "foobarbaz-test-terraform-final-snapshot-1" 395 }`, acctest.RandInt()) 396 } 397 398 var testAccNoSnapshotInstanceConfig = ` 399 provider "aws" { 400 region = "us-east-1" 401 } 402 resource "aws_db_instance" "no_snapshot" { 403 identifier = "foobarbaz-test-terraform-snapshot-2" 404 405 allocated_storage = 5 406 engine = "mysql" 407 engine_version = "5.6.21" 408 instance_class = "db.t1.micro" 409 name = "baz" 410 password = "barbarbarbar" 411 username = "foo" 412 security_group_names = ["default"] 413 backup_retention_period = 1 414 415 parameter_group_name = "default.mysql5.6" 416 417 skip_final_snapshot = true 418 final_snapshot_identifier = "foobarbaz-test-terraform-final-snapshot-2" 419 } 420 `