github.com/sathiyas/terraform@v0.6.9-0.20151210233947-3330da00b997/builtin/providers/aws/resource_aws_db_instance_test.go (about)

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