github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/resource_aws_rds_cluster.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 "log" 6 "regexp" 7 "strings" 8 "time" 9 10 "github.com/aws/aws-sdk-go/aws" 11 "github.com/aws/aws-sdk-go/aws/awserr" 12 "github.com/aws/aws-sdk-go/service/rds" 13 "github.com/hashicorp/terraform/helper/resource" 14 "github.com/hashicorp/terraform/helper/schema" 15 ) 16 17 func resourceAwsRDSCluster() *schema.Resource { 18 return &schema.Resource{ 19 Create: resourceAwsRDSClusterCreate, 20 Read: resourceAwsRDSClusterRead, 21 Update: resourceAwsRDSClusterUpdate, 22 Delete: resourceAwsRDSClusterDelete, 23 Importer: &schema.ResourceImporter{ 24 State: resourceAwsRdsClusterImport, 25 }, 26 27 Schema: map[string]*schema.Schema{ 28 29 "availability_zones": { 30 Type: schema.TypeSet, 31 Elem: &schema.Schema{Type: schema.TypeString}, 32 Optional: true, 33 ForceNew: true, 34 Computed: true, 35 Set: schema.HashString, 36 }, 37 38 "cluster_identifier": { 39 Type: schema.TypeString, 40 Required: true, 41 ForceNew: true, 42 ValidateFunc: validateRdsId, 43 }, 44 45 "cluster_members": { 46 Type: schema.TypeSet, 47 Elem: &schema.Schema{Type: schema.TypeString}, 48 Optional: true, 49 Computed: true, 50 Set: schema.HashString, 51 }, 52 53 "database_name": { 54 Type: schema.TypeString, 55 Optional: true, 56 Computed: true, 57 ForceNew: true, 58 }, 59 60 "db_subnet_group_name": { 61 Type: schema.TypeString, 62 Optional: true, 63 ForceNew: true, 64 Computed: true, 65 }, 66 67 "db_cluster_parameter_group_name": { 68 Type: schema.TypeString, 69 Optional: true, 70 Computed: true, 71 }, 72 73 "endpoint": { 74 Type: schema.TypeString, 75 Computed: true, 76 }, 77 78 "reader_endpoint": { 79 Type: schema.TypeString, 80 Computed: true, 81 }, 82 83 "engine": { 84 Type: schema.TypeString, 85 Computed: true, 86 }, 87 88 "storage_encrypted": { 89 Type: schema.TypeBool, 90 Optional: true, 91 Default: false, 92 ForceNew: true, 93 }, 94 95 "final_snapshot_identifier": { 96 Type: schema.TypeString, 97 Optional: true, 98 ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { 99 value := v.(string) 100 if !regexp.MustCompile(`^[0-9A-Za-z-]+$`).MatchString(value) { 101 es = append(es, fmt.Errorf( 102 "only alphanumeric characters and hyphens allowed in %q", k)) 103 } 104 if regexp.MustCompile(`--`).MatchString(value) { 105 es = append(es, fmt.Errorf("%q cannot contain two consecutive hyphens", k)) 106 } 107 if regexp.MustCompile(`-$`).MatchString(value) { 108 es = append(es, fmt.Errorf("%q cannot end in a hyphen", k)) 109 } 110 return 111 }, 112 }, 113 114 "skip_final_snapshot": { 115 Type: schema.TypeBool, 116 Optional: true, 117 Default: false, 118 }, 119 120 "master_username": { 121 Type: schema.TypeString, 122 Computed: true, 123 Optional: true, 124 ForceNew: true, 125 }, 126 127 "master_password": { 128 Type: schema.TypeString, 129 Optional: true, 130 Sensitive: true, 131 }, 132 133 "snapshot_identifier": { 134 Type: schema.TypeString, 135 Computed: false, 136 Optional: true, 137 Elem: &schema.Schema{Type: schema.TypeString}, 138 }, 139 140 "port": { 141 Type: schema.TypeInt, 142 Optional: true, 143 Computed: true, 144 }, 145 146 // apply_immediately is used to determine when the update modifications 147 // take place. 148 // See http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.DBInstance.Modifying.html 149 "apply_immediately": { 150 Type: schema.TypeBool, 151 Optional: true, 152 Computed: true, 153 }, 154 155 "vpc_security_group_ids": { 156 Type: schema.TypeSet, 157 Optional: true, 158 Computed: true, 159 Elem: &schema.Schema{Type: schema.TypeString}, 160 Set: schema.HashString, 161 }, 162 163 "preferred_backup_window": { 164 Type: schema.TypeString, 165 Optional: true, 166 Computed: true, 167 ValidateFunc: validateOnceADayWindowFormat, 168 }, 169 170 "preferred_maintenance_window": { 171 Type: schema.TypeString, 172 Optional: true, 173 Computed: true, 174 StateFunc: func(val interface{}) string { 175 if val == nil { 176 return "" 177 } 178 return strings.ToLower(val.(string)) 179 }, 180 ValidateFunc: validateOnceAWeekWindowFormat, 181 }, 182 183 "backup_retention_period": { 184 Type: schema.TypeInt, 185 Optional: true, 186 Default: 1, 187 ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { 188 value := v.(int) 189 if value > 35 { 190 es = append(es, fmt.Errorf( 191 "backup retention period cannot be more than 35 days")) 192 } 193 return 194 }, 195 }, 196 197 "kms_key_id": { 198 Type: schema.TypeString, 199 Optional: true, 200 Computed: true, 201 ForceNew: true, 202 ValidateFunc: validateArn, 203 }, 204 205 "replication_source_identifier": { 206 Type: schema.TypeString, 207 Optional: true, 208 }, 209 210 "tags": tagsSchema(), 211 }, 212 } 213 } 214 215 func resourceAwsRdsClusterImport( 216 d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { 217 // Neither skip_final_snapshot nor final_snapshot_identifier can be fetched 218 // from any API call, so we need to default skip_final_snapshot to true so 219 // that final_snapshot_identifier is not required 220 d.Set("skip_final_snapshot", true) 221 return []*schema.ResourceData{d}, nil 222 } 223 224 func resourceAwsRDSClusterCreate(d *schema.ResourceData, meta interface{}) error { 225 conn := meta.(*AWSClient).rdsconn 226 tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{})) 227 228 if _, ok := d.GetOk("snapshot_identifier"); ok { 229 opts := rds.RestoreDBClusterFromSnapshotInput{ 230 DBClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)), 231 SnapshotIdentifier: aws.String(d.Get("snapshot_identifier").(string)), 232 Engine: aws.String("aurora"), 233 Tags: tags, 234 } 235 236 if attr := d.Get("availability_zones").(*schema.Set); attr.Len() > 0 { 237 opts.AvailabilityZones = expandStringList(attr.List()) 238 } 239 240 if attr, ok := d.GetOk("db_subnet_group_name"); ok { 241 opts.DBSubnetGroupName = aws.String(attr.(string)) 242 } 243 244 if attr, ok := d.GetOk("database_name"); ok { 245 opts.DatabaseName = aws.String(attr.(string)) 246 } 247 248 if attr, ok := d.GetOk("option_group_name"); ok { 249 opts.OptionGroupName = aws.String(attr.(string)) 250 } 251 252 if attr, ok := d.GetOk("port"); ok { 253 opts.Port = aws.Int64(int64(attr.(int))) 254 } 255 256 var sgUpdate bool 257 if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 { 258 sgUpdate = true 259 opts.VpcSecurityGroupIds = expandStringList(attr.List()) 260 } 261 262 log.Printf("[DEBUG] RDS Cluster restore from snapshot configuration: %s", opts) 263 _, err := conn.RestoreDBClusterFromSnapshot(&opts) 264 if err != nil { 265 return fmt.Errorf("Error creating RDS Cluster: %s", err) 266 } 267 268 if sgUpdate { 269 log.Printf("[INFO] RDS Cluster is restoring from snapshot with default security, but custom security should be set, will now update after snapshot is restored!") 270 271 d.SetId(d.Get("cluster_identifier").(string)) 272 273 log.Printf("[INFO] RDS Cluster Instance ID: %s", d.Id()) 274 275 log.Println("[INFO] Waiting for RDS Cluster to be available") 276 277 stateConf := &resource.StateChangeConf{ 278 Pending: []string{"creating", "backing-up", "modifying"}, 279 Target: []string{"available"}, 280 Refresh: resourceAwsRDSClusterStateRefreshFunc(d, meta), 281 Timeout: 120 * time.Minute, 282 MinTimeout: 3 * time.Second, 283 Delay: 30 * time.Second, // Wait 30 secs before starting 284 } 285 286 // Wait, catching any errors 287 _, err := stateConf.WaitForState() 288 if err != nil { 289 return err 290 } 291 292 err = resourceAwsRDSClusterInstanceUpdate(d, meta) 293 if err != nil { 294 return err 295 } 296 } 297 } else if _, ok := d.GetOk("replication_source_identifier"); ok { 298 createOpts := &rds.CreateDBClusterInput{ 299 DBClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)), 300 Engine: aws.String("aurora"), 301 StorageEncrypted: aws.Bool(d.Get("storage_encrypted").(bool)), 302 ReplicationSourceIdentifier: aws.String(d.Get("replication_source_identifier").(string)), 303 Tags: tags, 304 } 305 306 if attr, ok := d.GetOk("port"); ok { 307 createOpts.Port = aws.Int64(int64(attr.(int))) 308 } 309 310 if attr, ok := d.GetOk("db_subnet_group_name"); ok { 311 createOpts.DBSubnetGroupName = aws.String(attr.(string)) 312 } 313 314 if attr, ok := d.GetOk("db_cluster_parameter_group_name"); ok { 315 createOpts.DBClusterParameterGroupName = aws.String(attr.(string)) 316 } 317 318 if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 { 319 createOpts.VpcSecurityGroupIds = expandStringList(attr.List()) 320 } 321 322 if attr := d.Get("availability_zones").(*schema.Set); attr.Len() > 0 { 323 createOpts.AvailabilityZones = expandStringList(attr.List()) 324 } 325 326 if v, ok := d.GetOk("backup_retention_period"); ok { 327 createOpts.BackupRetentionPeriod = aws.Int64(int64(v.(int))) 328 } 329 330 if v, ok := d.GetOk("preferred_backup_window"); ok { 331 createOpts.PreferredBackupWindow = aws.String(v.(string)) 332 } 333 334 if v, ok := d.GetOk("preferred_maintenance_window"); ok { 335 createOpts.PreferredMaintenanceWindow = aws.String(v.(string)) 336 } 337 338 if attr, ok := d.GetOk("kms_key_id"); ok { 339 createOpts.KmsKeyId = aws.String(attr.(string)) 340 } 341 342 log.Printf("[DEBUG] Create RDS Cluster as read replica: %s", createOpts) 343 resp, err := conn.CreateDBCluster(createOpts) 344 if err != nil { 345 log.Printf("[ERROR] Error creating RDS Cluster: %s", err) 346 return err 347 } 348 349 log.Printf("[DEBUG]: RDS Cluster create response: %s", resp) 350 351 } else { 352 if _, ok := d.GetOk("master_password"); !ok { 353 return fmt.Errorf(`provider.aws: aws_rds_cluster: %s: "master_password": required field is not set`, d.Get("database_name").(string)) 354 } 355 356 if _, ok := d.GetOk("master_username"); !ok { 357 return fmt.Errorf(`provider.aws: aws_rds_cluster: %s: "master_username": required field is not set`, d.Get("database_name").(string)) 358 } 359 360 createOpts := &rds.CreateDBClusterInput{ 361 DBClusterIdentifier: aws.String(d.Get("cluster_identifier").(string)), 362 Engine: aws.String("aurora"), 363 MasterUserPassword: aws.String(d.Get("master_password").(string)), 364 MasterUsername: aws.String(d.Get("master_username").(string)), 365 StorageEncrypted: aws.Bool(d.Get("storage_encrypted").(bool)), 366 Tags: tags, 367 } 368 369 if v := d.Get("database_name"); v.(string) != "" { 370 createOpts.DatabaseName = aws.String(v.(string)) 371 } 372 373 if attr, ok := d.GetOk("port"); ok { 374 createOpts.Port = aws.Int64(int64(attr.(int))) 375 } 376 377 if attr, ok := d.GetOk("db_subnet_group_name"); ok { 378 createOpts.DBSubnetGroupName = aws.String(attr.(string)) 379 } 380 381 if attr, ok := d.GetOk("db_cluster_parameter_group_name"); ok { 382 createOpts.DBClusterParameterGroupName = aws.String(attr.(string)) 383 } 384 385 if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 { 386 createOpts.VpcSecurityGroupIds = expandStringList(attr.List()) 387 } 388 389 if attr := d.Get("availability_zones").(*schema.Set); attr.Len() > 0 { 390 createOpts.AvailabilityZones = expandStringList(attr.List()) 391 } 392 393 if v, ok := d.GetOk("backup_retention_period"); ok { 394 createOpts.BackupRetentionPeriod = aws.Int64(int64(v.(int))) 395 } 396 397 if v, ok := d.GetOk("preferred_backup_window"); ok { 398 createOpts.PreferredBackupWindow = aws.String(v.(string)) 399 } 400 401 if v, ok := d.GetOk("preferred_maintenance_window"); ok { 402 createOpts.PreferredMaintenanceWindow = aws.String(v.(string)) 403 } 404 405 if attr, ok := d.GetOk("kms_key_id"); ok { 406 createOpts.KmsKeyId = aws.String(attr.(string)) 407 } 408 409 log.Printf("[DEBUG] RDS Cluster create options: %s", createOpts) 410 resp, err := conn.CreateDBCluster(createOpts) 411 if err != nil { 412 log.Printf("[ERROR] Error creating RDS Cluster: %s", err) 413 return err 414 } 415 416 log.Printf("[DEBUG]: RDS Cluster create response: %s", resp) 417 } 418 419 d.SetId(d.Get("cluster_identifier").(string)) 420 421 log.Printf("[INFO] RDS Cluster ID: %s", d.Id()) 422 423 log.Println( 424 "[INFO] Waiting for RDS Cluster to be available") 425 426 stateConf := &resource.StateChangeConf{ 427 Pending: []string{"creating", "backing-up", "modifying"}, 428 Target: []string{"available"}, 429 Refresh: resourceAwsRDSClusterStateRefreshFunc(d, meta), 430 Timeout: 120 * time.Minute, 431 MinTimeout: 3 * time.Second, 432 } 433 434 // Wait, catching any errors 435 _, err := stateConf.WaitForState() 436 if err != nil { 437 return fmt.Errorf("[WARN] Error waiting for RDS Cluster state to be \"available\": %s", err) 438 } 439 440 return resourceAwsRDSClusterRead(d, meta) 441 } 442 443 func resourceAwsRDSClusterRead(d *schema.ResourceData, meta interface{}) error { 444 conn := meta.(*AWSClient).rdsconn 445 446 resp, err := conn.DescribeDBClusters(&rds.DescribeDBClustersInput{ 447 DBClusterIdentifier: aws.String(d.Id()), 448 }) 449 450 if err != nil { 451 if awsErr, ok := err.(awserr.Error); ok { 452 if "DBClusterNotFoundFault" == awsErr.Code() { 453 d.SetId("") 454 log.Printf("[DEBUG] RDS Cluster (%s) not found", d.Id()) 455 return nil 456 } 457 } 458 log.Printf("[DEBUG] Error describing RDS Cluster (%s)", d.Id()) 459 return err 460 } 461 462 var dbc *rds.DBCluster 463 for _, c := range resp.DBClusters { 464 if *c.DBClusterIdentifier == d.Id() { 465 dbc = c 466 } 467 } 468 469 if dbc == nil { 470 log.Printf("[WARN] RDS Cluster (%s) not found", d.Id()) 471 d.SetId("") 472 return nil 473 } 474 475 if err := d.Set("availability_zones", aws.StringValueSlice(dbc.AvailabilityZones)); err != nil { 476 return fmt.Errorf("[DEBUG] Error saving AvailabilityZones to state for RDS Cluster (%s): %s", d.Id(), err) 477 } 478 479 // Only set the DatabaseName if it is not nil. There is a known API bug where 480 // RDS accepts a DatabaseName but does not return it, causing a perpetual 481 // diff. 482 // See https://github.com/hashicorp/terraform/issues/4671 for backstory 483 if dbc.DatabaseName != nil { 484 d.Set("database_name", dbc.DatabaseName) 485 } 486 487 d.Set("cluster_identifier", dbc.DBClusterIdentifier) 488 d.Set("db_subnet_group_name", dbc.DBSubnetGroup) 489 d.Set("db_cluster_parameter_group_name", dbc.DBClusterParameterGroup) 490 d.Set("endpoint", dbc.Endpoint) 491 d.Set("engine", dbc.Engine) 492 d.Set("master_username", dbc.MasterUsername) 493 d.Set("port", dbc.Port) 494 d.Set("storage_encrypted", dbc.StorageEncrypted) 495 d.Set("backup_retention_period", dbc.BackupRetentionPeriod) 496 d.Set("preferred_backup_window", dbc.PreferredBackupWindow) 497 d.Set("preferred_maintenance_window", dbc.PreferredMaintenanceWindow) 498 d.Set("kms_key_id", dbc.KmsKeyId) 499 d.Set("reader_endpoint", dbc.ReaderEndpoint) 500 d.Set("replication_source_identifier", dbc.ReplicationSourceIdentifier) 501 502 var vpcg []string 503 for _, g := range dbc.VpcSecurityGroups { 504 vpcg = append(vpcg, *g.VpcSecurityGroupId) 505 } 506 if err := d.Set("vpc_security_group_ids", vpcg); err != nil { 507 return fmt.Errorf("[DEBUG] Error saving VPC Security Group IDs to state for RDS Cluster (%s): %s", d.Id(), err) 508 } 509 510 var cm []string 511 for _, m := range dbc.DBClusterMembers { 512 cm = append(cm, *m.DBInstanceIdentifier) 513 } 514 if err := d.Set("cluster_members", cm); err != nil { 515 return fmt.Errorf("[DEBUG] Error saving RDS Cluster Members to state for RDS Cluster (%s): %s", d.Id(), err) 516 } 517 518 // Fetch and save tags 519 arn, err := buildRDSClusterARN(d.Id(), meta.(*AWSClient).partition, meta.(*AWSClient).accountid, meta.(*AWSClient).region) 520 if err != nil { 521 log.Printf("[DEBUG] Error building ARN for RDS Cluster (%s), not setting Tags", *dbc.DBClusterIdentifier) 522 } else { 523 if err := saveTagsRDS(conn, d, arn); err != nil { 524 log.Printf("[WARN] Failed to save tags for RDS Cluster (%s): %s", *dbc.DBClusterIdentifier, err) 525 } 526 } 527 528 return nil 529 } 530 531 func resourceAwsRDSClusterUpdate(d *schema.ResourceData, meta interface{}) error { 532 conn := meta.(*AWSClient).rdsconn 533 requestUpdate := false 534 535 req := &rds.ModifyDBClusterInput{ 536 ApplyImmediately: aws.Bool(d.Get("apply_immediately").(bool)), 537 DBClusterIdentifier: aws.String(d.Id()), 538 } 539 540 if d.HasChange("master_password") { 541 req.MasterUserPassword = aws.String(d.Get("master_password").(string)) 542 requestUpdate = true 543 } 544 545 if d.HasChange("vpc_security_group_ids") { 546 if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 { 547 req.VpcSecurityGroupIds = expandStringList(attr.List()) 548 } else { 549 req.VpcSecurityGroupIds = []*string{} 550 } 551 requestUpdate = true 552 } 553 554 if d.HasChange("preferred_backup_window") { 555 req.PreferredBackupWindow = aws.String(d.Get("preferred_backup_window").(string)) 556 requestUpdate = true 557 } 558 559 if d.HasChange("preferred_maintenance_window") { 560 req.PreferredMaintenanceWindow = aws.String(d.Get("preferred_maintenance_window").(string)) 561 requestUpdate = true 562 } 563 564 if d.HasChange("backup_retention_period") { 565 req.BackupRetentionPeriod = aws.Int64(int64(d.Get("backup_retention_period").(int))) 566 requestUpdate = true 567 } 568 569 if d.HasChange("db_cluster_parameter_group_name") { 570 d.SetPartial("db_cluster_parameter_group_name") 571 req.DBClusterParameterGroupName = aws.String(d.Get("db_cluster_parameter_group_name").(string)) 572 requestUpdate = true 573 } 574 575 if requestUpdate { 576 _, err := conn.ModifyDBCluster(req) 577 if err != nil { 578 return fmt.Errorf("[WARN] Error modifying RDS Cluster (%s): %s", d.Id(), err) 579 } 580 } 581 582 if arn, err := buildRDSClusterARN(d.Id(), meta.(*AWSClient).partition, meta.(*AWSClient).accountid, meta.(*AWSClient).region); err == nil { 583 if err := setTagsRDS(conn, d, arn); err != nil { 584 return err 585 } else { 586 d.SetPartial("tags") 587 } 588 } 589 590 return resourceAwsRDSClusterRead(d, meta) 591 } 592 593 func resourceAwsRDSClusterDelete(d *schema.ResourceData, meta interface{}) error { 594 conn := meta.(*AWSClient).rdsconn 595 log.Printf("[DEBUG] Destroying RDS Cluster (%s)", d.Id()) 596 597 deleteOpts := rds.DeleteDBClusterInput{ 598 DBClusterIdentifier: aws.String(d.Id()), 599 } 600 601 skipFinalSnapshot := d.Get("skip_final_snapshot").(bool) 602 deleteOpts.SkipFinalSnapshot = aws.Bool(skipFinalSnapshot) 603 604 if skipFinalSnapshot == false { 605 if name, present := d.GetOk("final_snapshot_identifier"); present { 606 deleteOpts.FinalDBSnapshotIdentifier = aws.String(name.(string)) 607 } else { 608 return fmt.Errorf("RDS Cluster FinalSnapshotIdentifier is required when a final snapshot is required") 609 } 610 } 611 612 log.Printf("[DEBUG] RDS Cluster delete options: %s", deleteOpts) 613 _, err := conn.DeleteDBCluster(&deleteOpts) 614 if err != nil { 615 if awsErr, ok := err.(awserr.Error); ok { 616 if "InvalidDBClusterStateFault" == awsErr.Code() { 617 return fmt.Errorf("RDS Cluster cannot be deleted: %s", awsErr.Message()) 618 } 619 } 620 } 621 622 stateConf := &resource.StateChangeConf{ 623 Pending: []string{"available", "deleting", "backing-up", "modifying"}, 624 Target: []string{"destroyed"}, 625 Refresh: resourceAwsRDSClusterStateRefreshFunc(d, meta), 626 Timeout: 15 * time.Minute, 627 MinTimeout: 3 * time.Second, 628 } 629 630 // Wait, catching any errors 631 _, err = stateConf.WaitForState() 632 if err != nil { 633 return fmt.Errorf("[WARN] Error deleting RDS Cluster (%s): %s", d.Id(), err) 634 } 635 636 return nil 637 } 638 639 func resourceAwsRDSClusterStateRefreshFunc( 640 d *schema.ResourceData, meta interface{}) resource.StateRefreshFunc { 641 return func() (interface{}, string, error) { 642 conn := meta.(*AWSClient).rdsconn 643 644 resp, err := conn.DescribeDBClusters(&rds.DescribeDBClustersInput{ 645 DBClusterIdentifier: aws.String(d.Id()), 646 }) 647 648 if err != nil { 649 if awsErr, ok := err.(awserr.Error); ok { 650 if "DBClusterNotFoundFault" == awsErr.Code() { 651 return 42, "destroyed", nil 652 } 653 } 654 log.Printf("[WARN] Error on retrieving DB Cluster (%s) when waiting: %s", d.Id(), err) 655 return nil, "", err 656 } 657 658 var dbc *rds.DBCluster 659 660 for _, c := range resp.DBClusters { 661 if *c.DBClusterIdentifier == d.Id() { 662 dbc = c 663 } 664 } 665 666 if dbc == nil { 667 return 42, "destroyed", nil 668 } 669 670 if dbc.Status != nil { 671 log.Printf("[DEBUG] DB Cluster status (%s): %s", d.Id(), *dbc.Status) 672 } 673 674 return dbc, *dbc.Status, nil 675 } 676 } 677 678 func buildRDSClusterARN(identifier, partition, accountid, region string) (string, error) { 679 if partition == "" { 680 return "", fmt.Errorf("Unable to construct RDS Cluster ARN because of missing AWS partition") 681 } 682 if accountid == "" { 683 return "", fmt.Errorf("Unable to construct RDS Cluster ARN because of missing AWS Account ID") 684 } 685 686 arn := fmt.Sprintf("arn:%s:rds:%s:%s:cluster:%s", partition, region, accountid, identifier) 687 return arn, nil 688 689 }