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