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  `