github.com/bendemaree/terraform@v0.5.4-0.20150613200311-f50d97d6eee6/builtin/providers/aws/resource_aws_db_instance.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"strings"
     7  	"time"
     8  
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/awserr"
    11  	"github.com/aws/aws-sdk-go/service/iam"
    12  	"github.com/aws/aws-sdk-go/service/rds"
    13  
    14  	"github.com/hashicorp/terraform/helper/resource"
    15  	"github.com/hashicorp/terraform/helper/schema"
    16  )
    17  
    18  func resourceAwsDbInstance() *schema.Resource {
    19  	return &schema.Resource{
    20  		Create: resourceAwsDbInstanceCreate,
    21  		Read:   resourceAwsDbInstanceRead,
    22  		Update: resourceAwsDbInstanceUpdate,
    23  		Delete: resourceAwsDbInstanceDelete,
    24  
    25  		Schema: map[string]*schema.Schema{
    26  			"name": &schema.Schema{
    27  				Type:     schema.TypeString,
    28  				Optional: true,
    29  				Computed: true,
    30  				ForceNew: true,
    31  			},
    32  
    33  			"username": &schema.Schema{
    34  				Type:     schema.TypeString,
    35  				Required: true,
    36  				ForceNew: true,
    37  			},
    38  
    39  			"password": &schema.Schema{
    40  				Type:     schema.TypeString,
    41  				Required: true,
    42  			},
    43  
    44  			"engine": &schema.Schema{
    45  				Type:     schema.TypeString,
    46  				Required: true,
    47  				ForceNew: true,
    48  			},
    49  
    50  			"engine_version": &schema.Schema{
    51  				Type:     schema.TypeString,
    52  				Required: true,
    53  			},
    54  
    55  			"storage_encrypted": &schema.Schema{
    56  				Type:     schema.TypeBool,
    57  				Optional: true,
    58  				ForceNew: true,
    59  			},
    60  
    61  			"allocated_storage": &schema.Schema{
    62  				Type:     schema.TypeInt,
    63  				Required: true,
    64  			},
    65  
    66  			"storage_type": &schema.Schema{
    67  				Type:     schema.TypeString,
    68  				Optional: true,
    69  				Computed: true,
    70  			},
    71  
    72  			"identifier": &schema.Schema{
    73  				Type:     schema.TypeString,
    74  				Required: true,
    75  				ForceNew: true,
    76  			},
    77  
    78  			"instance_class": &schema.Schema{
    79  				Type:     schema.TypeString,
    80  				Required: true,
    81  			},
    82  
    83  			"availability_zone": &schema.Schema{
    84  				Type:     schema.TypeString,
    85  				Optional: true,
    86  				Computed: true,
    87  				ForceNew: true,
    88  			},
    89  
    90  			"backup_retention_period": &schema.Schema{
    91  				Type:     schema.TypeInt,
    92  				Optional: true,
    93  				Computed: true,
    94  			},
    95  
    96  			"backup_window": &schema.Schema{
    97  				Type:     schema.TypeString,
    98  				Optional: true,
    99  				Computed: true,
   100  			},
   101  
   102  			"iops": &schema.Schema{
   103  				Type:     schema.TypeInt,
   104  				Optional: true,
   105  			},
   106  
   107  			"license_model": &schema.Schema{
   108  				Type:     schema.TypeString,
   109  				Optional: true,
   110  				Computed: true,
   111  			},
   112  
   113  			"maintenance_window": &schema.Schema{
   114  				Type:     schema.TypeString,
   115  				Optional: true,
   116  				Computed: true,
   117  			},
   118  
   119  			"multi_az": &schema.Schema{
   120  				Type:     schema.TypeBool,
   121  				Optional: true,
   122  				Computed: true,
   123  			},
   124  
   125  			"port": &schema.Schema{
   126  				Type:     schema.TypeInt,
   127  				Optional: true,
   128  				Computed: true,
   129  				ForceNew: true,
   130  			},
   131  
   132  			"publicly_accessible": &schema.Schema{
   133  				Type:     schema.TypeBool,
   134  				Optional: true,
   135  				ForceNew: true,
   136  			},
   137  
   138  			"vpc_security_group_ids": &schema.Schema{
   139  				Type:     schema.TypeSet,
   140  				Optional: true,
   141  				Computed: true,
   142  				Elem:     &schema.Schema{Type: schema.TypeString},
   143  				Set:      schema.HashString,
   144  			},
   145  
   146  			"security_group_names": &schema.Schema{
   147  				Type:     schema.TypeSet,
   148  				Optional: true,
   149  				Elem:     &schema.Schema{Type: schema.TypeString},
   150  				Set:      schema.HashString,
   151  			},
   152  
   153  			"final_snapshot_identifier": &schema.Schema{
   154  				Type:     schema.TypeString,
   155  				Optional: true,
   156  			},
   157  
   158  			"db_subnet_group_name": &schema.Schema{
   159  				Type:     schema.TypeString,
   160  				Optional: true,
   161  				ForceNew: true,
   162  				Computed: true,
   163  			},
   164  
   165  			"parameter_group_name": &schema.Schema{
   166  				Type:     schema.TypeString,
   167  				Optional: true,
   168  				Computed: true,
   169  			},
   170  
   171  			"address": &schema.Schema{
   172  				Type:     schema.TypeString,
   173  				Computed: true,
   174  			},
   175  
   176  			"endpoint": &schema.Schema{
   177  				Type:     schema.TypeString,
   178  				Computed: true,
   179  			},
   180  
   181  			"status": &schema.Schema{
   182  				Type:     schema.TypeString,
   183  				Computed: true,
   184  			},
   185  
   186  			// apply_immediately is used to determine when the update modifications
   187  			// take place.
   188  			// See http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.DBInstance.Modifying.html
   189  			"apply_immediately": &schema.Schema{
   190  				Type:     schema.TypeBool,
   191  				Optional: true,
   192  				Computed: true,
   193  			},
   194  
   195  			"replicate_source_db": &schema.Schema{
   196  				Type:     schema.TypeString,
   197  				Optional: true,
   198  			},
   199  
   200  			"replicas": &schema.Schema{
   201  				Type:     schema.TypeList,
   202  				Computed: true,
   203  				Elem:     &schema.Schema{Type: schema.TypeString},
   204  			},
   205  
   206  			"tags": tagsSchema(),
   207  		},
   208  	}
   209  }
   210  
   211  func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error {
   212  	conn := meta.(*AWSClient).rdsconn
   213  	tags := tagsFromMapRDS(d.Get("tags").(map[string]interface{}))
   214  
   215  	if v, ok := d.GetOk("replicate_source_db"); ok {
   216  		opts := rds.CreateDBInstanceReadReplicaInput{
   217  			SourceDBInstanceIdentifier: aws.String(v.(string)),
   218  			DBInstanceClass:            aws.String(d.Get("instance_class").(string)),
   219  			DBInstanceIdentifier:       aws.String(d.Get("identifier").(string)),
   220  			Tags:                       tags,
   221  		}
   222  		if attr, ok := d.GetOk("iops"); ok {
   223  			opts.IOPS = aws.Long(int64(attr.(int)))
   224  		}
   225  
   226  		if attr, ok := d.GetOk("port"); ok {
   227  			opts.Port = aws.Long(int64(attr.(int)))
   228  		}
   229  
   230  		if attr, ok := d.GetOk("availability_zone"); ok {
   231  			opts.AvailabilityZone = aws.String(attr.(string))
   232  		}
   233  
   234  		if attr, ok := d.GetOk("publicly_accessible"); ok {
   235  			opts.PubliclyAccessible = aws.Boolean(attr.(bool))
   236  		}
   237  		_, err := conn.CreateDBInstanceReadReplica(&opts)
   238  		if err != nil {
   239  			return fmt.Errorf("Error creating DB Instance: %s", err)
   240  		}
   241  	} else {
   242  		opts := rds.CreateDBInstanceInput{
   243  			AllocatedStorage:     aws.Long(int64(d.Get("allocated_storage").(int))),
   244  			DBName:               aws.String(d.Get("name").(string)),
   245  			DBInstanceClass:      aws.String(d.Get("instance_class").(string)),
   246  			DBInstanceIdentifier: aws.String(d.Get("identifier").(string)),
   247  			MasterUsername:       aws.String(d.Get("username").(string)),
   248  			MasterUserPassword:   aws.String(d.Get("password").(string)),
   249  			Engine:               aws.String(d.Get("engine").(string)),
   250  			EngineVersion:        aws.String(d.Get("engine_version").(string)),
   251  			StorageEncrypted:     aws.Boolean(d.Get("storage_encrypted").(bool)),
   252  			Tags:                 tags,
   253  		}
   254  
   255  		attr := d.Get("backup_retention_period")
   256  		opts.BackupRetentionPeriod = aws.Long(int64(attr.(int)))
   257  		if attr, ok := d.GetOk("multi_az"); ok {
   258  			opts.MultiAZ = aws.Boolean(attr.(bool))
   259  		}
   260  
   261  		if attr, ok := d.GetOk("maintenance_window"); ok {
   262  			opts.PreferredMaintenanceWindow = aws.String(attr.(string))
   263  		}
   264  
   265  		if attr, ok := d.GetOk("backup_window"); ok {
   266  			opts.PreferredBackupWindow = aws.String(attr.(string))
   267  		}
   268  
   269  		if attr, ok := d.GetOk("license_model"); ok {
   270  			opts.LicenseModel = aws.String(attr.(string))
   271  		}
   272  		if attr, ok := d.GetOk("parameter_group_name"); ok {
   273  			opts.DBParameterGroupName = aws.String(attr.(string))
   274  		}
   275  
   276  		if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 {
   277  			var s []*string
   278  			for _, v := range attr.List() {
   279  				s = append(s, aws.String(v.(string)))
   280  			}
   281  			opts.VPCSecurityGroupIDs = s
   282  		}
   283  
   284  		if attr := d.Get("security_group_names").(*schema.Set); attr.Len() > 0 {
   285  			var s []*string
   286  			for _, v := range attr.List() {
   287  				s = append(s, aws.String(v.(string)))
   288  			}
   289  			opts.DBSecurityGroups = s
   290  		}
   291  		if attr, ok := d.GetOk("storage_type"); ok {
   292  			opts.StorageType = aws.String(attr.(string))
   293  		}
   294  
   295  		if attr, ok := d.GetOk("db_subnet_group_name"); ok {
   296  			opts.DBSubnetGroupName = aws.String(attr.(string))
   297  		}
   298  
   299  		if attr, ok := d.GetOk("iops"); ok {
   300  			opts.IOPS = aws.Long(int64(attr.(int)))
   301  		}
   302  
   303  		if attr, ok := d.GetOk("port"); ok {
   304  			opts.Port = aws.Long(int64(attr.(int)))
   305  		}
   306  
   307  		if attr, ok := d.GetOk("availability_zone"); ok {
   308  			opts.AvailabilityZone = aws.String(attr.(string))
   309  		}
   310  
   311  		if attr, ok := d.GetOk("publicly_accessible"); ok {
   312  			opts.PubliclyAccessible = aws.Boolean(attr.(bool))
   313  		}
   314  
   315  		log.Printf("[DEBUG] DB Instance create configuration: %#v", opts)
   316  		var err error
   317  		_, err = conn.CreateDBInstance(&opts)
   318  		if err != nil {
   319  			return fmt.Errorf("Error creating DB Instance: %s", err)
   320  		}
   321  	}
   322  
   323  	d.SetId(d.Get("identifier").(string))
   324  
   325  	log.Printf("[INFO] DB Instance ID: %s", d.Id())
   326  
   327  	log.Println(
   328  		"[INFO] Waiting for DB Instance to be available")
   329  
   330  	stateConf := &resource.StateChangeConf{
   331  		Pending:    []string{"creating", "backing-up", "modifying"},
   332  		Target:     "available",
   333  		Refresh:    resourceAwsDbInstanceStateRefreshFunc(d, meta),
   334  		Timeout:    40 * time.Minute,
   335  		MinTimeout: 10 * time.Second,
   336  		Delay:      30 * time.Second, // Wait 30 secs before starting
   337  	}
   338  
   339  	// Wait, catching any errors
   340  	_, err := stateConf.WaitForState()
   341  	if err != nil {
   342  		return err
   343  	}
   344  
   345  	return resourceAwsDbInstanceRead(d, meta)
   346  }
   347  
   348  func resourceAwsDbInstanceRead(d *schema.ResourceData, meta interface{}) error {
   349  	v, err := resourceAwsDbInstanceRetrieve(d, meta)
   350  
   351  	if err != nil {
   352  		return err
   353  	}
   354  	if v == nil {
   355  		d.SetId("")
   356  		return nil
   357  	}
   358  
   359  	d.Set("name", v.DBName)
   360  	d.Set("username", v.MasterUsername)
   361  	d.Set("engine", v.Engine)
   362  	d.Set("engine_version", v.EngineVersion)
   363  	d.Set("allocated_storage", v.AllocatedStorage)
   364  	d.Set("storage_type", v.StorageType)
   365  	d.Set("instance_class", v.DBInstanceClass)
   366  	d.Set("availability_zone", v.AvailabilityZone)
   367  	d.Set("backup_retention_period", v.BackupRetentionPeriod)
   368  	d.Set("backup_window", v.PreferredBackupWindow)
   369  	d.Set("license_model", v.LicenseModel)
   370  	d.Set("maintenance_window", v.PreferredMaintenanceWindow)
   371  	d.Set("multi_az", v.MultiAZ)
   372  	if v.DBSubnetGroup != nil {
   373  		d.Set("db_subnet_group_name", v.DBSubnetGroup.DBSubnetGroupName)
   374  	}
   375  
   376  	if len(v.DBParameterGroups) > 0 {
   377  		d.Set("parameter_group_name", v.DBParameterGroups[0].DBParameterGroupName)
   378  	}
   379  
   380  	if v.Endpoint != nil {
   381  		d.Set("port", v.Endpoint.Port)
   382  		d.Set("address", v.Endpoint.Address)
   383  
   384  		if v.Endpoint.Address != nil && v.Endpoint.Port != nil {
   385  			d.Set("endpoint",
   386  				fmt.Sprintf("%s:%d", *v.Endpoint.Address, *v.Endpoint.Port))
   387  		}
   388  	}
   389  
   390  	d.Set("status", v.DBInstanceStatus)
   391  	d.Set("storage_encrypted", v.StorageEncrypted)
   392  
   393  	// list tags for resource
   394  	// set tags
   395  	conn := meta.(*AWSClient).rdsconn
   396  	arn, err := buildRDSARN(d, meta)
   397  	if err != nil {
   398  		name := "<empty>"
   399  		if v.DBName != nil && *v.DBName != "" {
   400  			name = *v.DBName
   401  		}
   402  
   403  		log.Printf("[DEBUG] Error building ARN for DB Instance, not setting Tags for DB %s", name)
   404  	} else {
   405  		resp, err := conn.ListTagsForResource(&rds.ListTagsForResourceInput{
   406  			ResourceName: aws.String(arn),
   407  		})
   408  
   409  		if err != nil {
   410  			log.Printf("[DEBUG] Error retreiving tags for ARN: %s", arn)
   411  		}
   412  
   413  		var dt []*rds.Tag
   414  		if len(resp.TagList) > 0 {
   415  			dt = resp.TagList
   416  		}
   417  		d.Set("tags", tagsToMapRDS(dt))
   418  	}
   419  
   420  	// Create an empty schema.Set to hold all vpc security group ids
   421  	ids := &schema.Set{
   422  		F: schema.HashString,
   423  	}
   424  	for _, v := range v.VPCSecurityGroups {
   425  		ids.Add(*v.VPCSecurityGroupID)
   426  	}
   427  	d.Set("vpc_security_group_ids", ids)
   428  
   429  	// Create an empty schema.Set to hold all security group names
   430  	sgn := &schema.Set{
   431  		F: schema.HashString,
   432  	}
   433  	for _, v := range v.DBSecurityGroups {
   434  		sgn.Add(*v.DBSecurityGroupName)
   435  	}
   436  	d.Set("security_group_names", sgn)
   437  
   438  	// replica things
   439  
   440  	var replicas []string
   441  	for _, v := range v.ReadReplicaDBInstanceIdentifiers {
   442  		replicas = append(replicas, *v)
   443  	}
   444  	if err := d.Set("replicas", replicas); err != nil {
   445  		return fmt.Errorf("[DEBUG] Error setting replicas attribute: %#v, error: %#v", replicas, err)
   446  	}
   447  
   448  	d.Set("replicate_source_db", v.ReadReplicaSourceDBInstanceIdentifier)
   449  
   450  	return nil
   451  }
   452  
   453  func resourceAwsDbInstanceDelete(d *schema.ResourceData, meta interface{}) error {
   454  	conn := meta.(*AWSClient).rdsconn
   455  
   456  	log.Printf("[DEBUG] DB Instance destroy: %v", d.Id())
   457  
   458  	opts := rds.DeleteDBInstanceInput{DBInstanceIdentifier: aws.String(d.Id())}
   459  
   460  	finalSnapshot := d.Get("final_snapshot_identifier").(string)
   461  	if finalSnapshot == "" {
   462  		opts.SkipFinalSnapshot = aws.Boolean(true)
   463  	} else {
   464  		opts.FinalDBSnapshotIdentifier = aws.String(finalSnapshot)
   465  	}
   466  
   467  	log.Printf("[DEBUG] DB Instance destroy configuration: %v", opts)
   468  	if _, err := conn.DeleteDBInstance(&opts); err != nil {
   469  		return err
   470  	}
   471  
   472  	log.Println(
   473  		"[INFO] Waiting for DB Instance to be destroyed")
   474  	stateConf := &resource.StateChangeConf{
   475  		Pending: []string{"creating", "backing-up",
   476  			"modifying", "deleting", "available"},
   477  		Target:     "",
   478  		Refresh:    resourceAwsDbInstanceStateRefreshFunc(d, meta),
   479  		Timeout:    40 * time.Minute,
   480  		MinTimeout: 10 * time.Second,
   481  		Delay:      30 * time.Second, // Wait 30 secs before starting
   482  	}
   483  	if _, err := stateConf.WaitForState(); err != nil {
   484  		return err
   485  	}
   486  
   487  	return nil
   488  }
   489  
   490  func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error {
   491  	conn := meta.(*AWSClient).rdsconn
   492  
   493  	d.Partial(true)
   494  
   495  	req := &rds.ModifyDBInstanceInput{
   496  		ApplyImmediately:     aws.Boolean(d.Get("apply_immediately").(bool)),
   497  		DBInstanceIdentifier: aws.String(d.Id()),
   498  	}
   499  	d.SetPartial("apply_immediately")
   500  
   501  	requestUpdate := false
   502  	if d.HasChange("allocated_storage") {
   503  		d.SetPartial("allocated_storage")
   504  		req.AllocatedStorage = aws.Long(int64(d.Get("allocated_storage").(int)))
   505  		requestUpdate = true
   506  	}
   507  	if d.HasChange("backup_retention_period") {
   508  		d.SetPartial("backup_retention_period")
   509  		req.BackupRetentionPeriod = aws.Long(int64(d.Get("backup_retention_period").(int)))
   510  		requestUpdate = true
   511  	}
   512  	if d.HasChange("instance_class") {
   513  		d.SetPartial("instance_class")
   514  		req.DBInstanceClass = aws.String(d.Get("instance_class").(string))
   515  		requestUpdate = true
   516  	}
   517  	if d.HasChange("parameter_group_name") {
   518  		d.SetPartial("parameter_group_name")
   519  		req.DBParameterGroupName = aws.String(d.Get("parameter_group_name").(string))
   520  		requestUpdate = true
   521  	}
   522  	if d.HasChange("engine_version") {
   523  		d.SetPartial("engine_version")
   524  		req.EngineVersion = aws.String(d.Get("engine_version").(string))
   525  		requestUpdate = true
   526  	}
   527  	if d.HasChange("iops") {
   528  		d.SetPartial("iops")
   529  		req.IOPS = aws.Long(int64(d.Get("iops").(int)))
   530  		requestUpdate = true
   531  	}
   532  	if d.HasChange("backup_window") {
   533  		d.SetPartial("backup_window")
   534  		req.PreferredBackupWindow = aws.String(d.Get("backup_window").(string))
   535  		requestUpdate = true
   536  	}
   537  	if d.HasChange("maintenance_window") {
   538  		d.SetPartial("maintenance_window")
   539  		req.PreferredMaintenanceWindow = aws.String(d.Get("maintenance_window").(string))
   540  		requestUpdate = true
   541  	}
   542  	if d.HasChange("password") {
   543  		d.SetPartial("password")
   544  		req.MasterUserPassword = aws.String(d.Get("password").(string))
   545  		requestUpdate = true
   546  	}
   547  	if d.HasChange("multi_az") {
   548  		d.SetPartial("multi_az")
   549  		req.MultiAZ = aws.Boolean(d.Get("multi_az").(bool))
   550  		requestUpdate = true
   551  	}
   552  	if d.HasChange("storage_type") {
   553  		d.SetPartial("storage_type")
   554  		req.StorageType = aws.String(d.Get("storage_type").(string))
   555  		requestUpdate = true
   556  	}
   557  
   558  	if d.HasChange("vpc_security_group_ids") {
   559  		if attr := d.Get("vpc_security_group_ids").(*schema.Set); attr.Len() > 0 {
   560  			var s []*string
   561  			for _, v := range attr.List() {
   562  				s = append(s, aws.String(v.(string)))
   563  			}
   564  			req.VPCSecurityGroupIDs = s
   565  		}
   566  		requestUpdate = true
   567  	}
   568  
   569  	if d.HasChange("vpc_security_group_ids") {
   570  		if attr := d.Get("security_group_names").(*schema.Set); attr.Len() > 0 {
   571  			var s []*string
   572  			for _, v := range attr.List() {
   573  				s = append(s, aws.String(v.(string)))
   574  			}
   575  			req.DBSecurityGroups = s
   576  		}
   577  		requestUpdate = true
   578  	}
   579  
   580  	log.Printf("[DEBUG] Send DB Instance Modification request: %#v", requestUpdate)
   581  	if requestUpdate {
   582  		log.Printf("[DEBUG] DB Instance Modification request: %#v", req)
   583  		_, err := conn.ModifyDBInstance(req)
   584  		if err != nil {
   585  			return fmt.Errorf("Error modifying DB Instance %s: %s", d.Id(), err)
   586  		}
   587  	}
   588  
   589  	// seperate request to promote a database
   590  	if d.HasChange("replicate_source_db") {
   591  		if d.Get("replicate_source_db").(string) == "" {
   592  			// promote
   593  			opts := rds.PromoteReadReplicaInput{
   594  				DBInstanceIdentifier: aws.String(d.Id()),
   595  			}
   596  			attr := d.Get("backup_retention_period")
   597  			opts.BackupRetentionPeriod = aws.Long(int64(attr.(int)))
   598  			if attr, ok := d.GetOk("backup_window"); ok {
   599  				opts.PreferredBackupWindow = aws.String(attr.(string))
   600  			}
   601  			_, err := conn.PromoteReadReplica(&opts)
   602  			if err != nil {
   603  				return fmt.Errorf("Error promoting database: %#v", err)
   604  			}
   605  			d.Set("replicate_source_db", "")
   606  		} else {
   607  			return fmt.Errorf("cannot elect new source database for replication")
   608  		}
   609  	}
   610  
   611  	if arn, err := buildRDSARN(d, meta); err == nil {
   612  		if err := setTagsRDS(conn, d, arn); err != nil {
   613  			return err
   614  		} else {
   615  			d.SetPartial("tags")
   616  		}
   617  	}
   618  	d.Partial(false)
   619  	return resourceAwsDbInstanceRead(d, meta)
   620  }
   621  
   622  func resourceAwsDbInstanceRetrieve(
   623  	d *schema.ResourceData, meta interface{}) (*rds.DBInstance, error) {
   624  	conn := meta.(*AWSClient).rdsconn
   625  
   626  	opts := rds.DescribeDBInstancesInput{
   627  		DBInstanceIdentifier: aws.String(d.Id()),
   628  	}
   629  
   630  	log.Printf("[DEBUG] DB Instance describe configuration: %#v", opts)
   631  
   632  	resp, err := conn.DescribeDBInstances(&opts)
   633  
   634  	if err != nil {
   635  		dbinstanceerr, ok := err.(awserr.Error)
   636  		if ok && dbinstanceerr.Code() == "DBInstanceNotFound" {
   637  			return nil, nil
   638  		}
   639  		return nil, fmt.Errorf("Error retrieving DB Instances: %s", err)
   640  	}
   641  
   642  	if len(resp.DBInstances) != 1 ||
   643  		*resp.DBInstances[0].DBInstanceIdentifier != d.Id() {
   644  		if err != nil {
   645  			return nil, nil
   646  		}
   647  	}
   648  
   649  	return resp.DBInstances[0], nil
   650  }
   651  
   652  func resourceAwsDbInstanceStateRefreshFunc(
   653  	d *schema.ResourceData, meta interface{}) resource.StateRefreshFunc {
   654  	return func() (interface{}, string, error) {
   655  		v, err := resourceAwsDbInstanceRetrieve(d, meta)
   656  
   657  		if err != nil {
   658  			log.Printf("Error on retrieving DB Instance when waiting: %s", err)
   659  			return nil, "", err
   660  		}
   661  
   662  		if v == nil {
   663  			return nil, "", nil
   664  		}
   665  
   666  		if v.DBInstanceStatus != nil {
   667  			log.Printf("[DEBUG] DB Instance status for instance %s: %s", d.Id(), *v.DBInstanceStatus)
   668  		}
   669  
   670  		return v, *v.DBInstanceStatus, nil
   671  	}
   672  }
   673  
   674  func buildRDSARN(d *schema.ResourceData, meta interface{}) (string, error) {
   675  	iamconn := meta.(*AWSClient).iamconn
   676  	region := meta.(*AWSClient).region
   677  	// An zero value GetUserInput{} defers to the currently logged in user
   678  	resp, err := iamconn.GetUser(&iam.GetUserInput{})
   679  	if err != nil {
   680  		return "", err
   681  	}
   682  	userARN := *resp.User.ARN
   683  	accountID := strings.Split(userARN, ":")[4]
   684  	arn := fmt.Sprintf("arn:aws:rds:%s:%s:db:%s", region, accountID, d.Id())
   685  	return arn, nil
   686  }