github.com/nathanielks/terraform@v0.6.1-0.20170509030759-13e1a62319dc/builtin/providers/aws/resource_aws_rds_cluster_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"regexp"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/hashicorp/terraform/helper/acctest"
    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 TestAccAWSRDSCluster_basic(t *testing.T) {
    20  	var v rds.DBCluster
    21  
    22  	resource.Test(t, resource.TestCase{
    23  		PreCheck:     func() { testAccPreCheck(t) },
    24  		Providers:    testAccProviders,
    25  		CheckDestroy: testAccCheckAWSClusterDestroy,
    26  		Steps: []resource.TestStep{
    27  			{
    28  				Config: testAccAWSClusterConfig(acctest.RandInt()),
    29  				Check: resource.ComposeTestCheckFunc(
    30  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
    31  					resource.TestCheckResourceAttr(
    32  						"aws_rds_cluster.default", "storage_encrypted", "false"),
    33  					resource.TestCheckResourceAttr(
    34  						"aws_rds_cluster.default", "db_cluster_parameter_group_name", "default.aurora5.6"),
    35  					resource.TestCheckResourceAttrSet(
    36  						"aws_rds_cluster.default", "reader_endpoint"),
    37  				),
    38  			},
    39  		},
    40  	})
    41  }
    42  
    43  func TestAccAWSRDSCluster_namePrefix(t *testing.T) {
    44  	var v rds.DBCluster
    45  
    46  	resource.Test(t, resource.TestCase{
    47  		PreCheck:     func() { testAccPreCheck(t) },
    48  		Providers:    testAccProviders,
    49  		CheckDestroy: testAccCheckAWSClusterDestroy,
    50  		Steps: []resource.TestStep{
    51  			{
    52  				Config: testAccAWSClusterConfig_namePrefix(acctest.RandInt()),
    53  				Check: resource.ComposeTestCheckFunc(
    54  					testAccCheckAWSClusterExists("aws_rds_cluster.test", &v),
    55  					resource.TestMatchResourceAttr(
    56  						"aws_rds_cluster.test", "cluster_identifier", regexp.MustCompile("^tf-test-")),
    57  				),
    58  			},
    59  		},
    60  	})
    61  }
    62  
    63  func TestAccAWSRDSCluster_generatedName(t *testing.T) {
    64  	var v rds.DBCluster
    65  
    66  	resource.Test(t, resource.TestCase{
    67  		PreCheck:     func() { testAccPreCheck(t) },
    68  		Providers:    testAccProviders,
    69  		CheckDestroy: testAccCheckAWSClusterDestroy,
    70  		Steps: []resource.TestStep{
    71  			{
    72  				Config: testAccAWSClusterConfig_generatedName(acctest.RandInt()),
    73  				Check: resource.ComposeTestCheckFunc(
    74  					testAccCheckAWSClusterExists("aws_rds_cluster.test", &v),
    75  					resource.TestMatchResourceAttr(
    76  						"aws_rds_cluster.test", "cluster_identifier", regexp.MustCompile("^tf-")),
    77  				),
    78  			},
    79  		},
    80  	})
    81  }
    82  
    83  func TestAccAWSRDSCluster_takeFinalSnapshot(t *testing.T) {
    84  	var v rds.DBCluster
    85  	rInt := acctest.RandInt()
    86  
    87  	resource.Test(t, resource.TestCase{
    88  		PreCheck:     func() { testAccPreCheck(t) },
    89  		Providers:    testAccProviders,
    90  		CheckDestroy: testAccCheckAWSClusterSnapshot(rInt),
    91  		Steps: []resource.TestStep{
    92  			{
    93  				Config: testAccAWSClusterConfigWithFinalSnapshot(rInt),
    94  				Check: resource.ComposeTestCheckFunc(
    95  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
    96  				),
    97  			},
    98  		},
    99  	})
   100  }
   101  
   102  /// This is a regression test to make sure that we always cover the scenario as hightlighted in
   103  /// https://github.com/hashicorp/terraform/issues/11568
   104  func TestAccAWSRDSCluster_missingUserNameCausesError(t *testing.T) {
   105  	resource.Test(t, resource.TestCase{
   106  		PreCheck:     func() { testAccPreCheck(t) },
   107  		Providers:    testAccProviders,
   108  		CheckDestroy: testAccCheckAWSClusterDestroy,
   109  		Steps: []resource.TestStep{
   110  			{
   111  				Config:      testAccAWSClusterConfigWithoutUserNameAndPassword(acctest.RandInt()),
   112  				ExpectError: regexp.MustCompile(`required field is not set`),
   113  			},
   114  		},
   115  	})
   116  }
   117  
   118  func TestAccAWSRDSCluster_updateTags(t *testing.T) {
   119  	var v rds.DBCluster
   120  	ri := acctest.RandInt()
   121  
   122  	resource.Test(t, resource.TestCase{
   123  		PreCheck:     func() { testAccPreCheck(t) },
   124  		Providers:    testAccProviders,
   125  		CheckDestroy: testAccCheckAWSClusterDestroy,
   126  		Steps: []resource.TestStep{
   127  			{
   128  				Config: testAccAWSClusterConfig(ri),
   129  				Check: resource.ComposeTestCheckFunc(
   130  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   131  					resource.TestCheckResourceAttr(
   132  						"aws_rds_cluster.default", "tags.%", "1"),
   133  				),
   134  			},
   135  			{
   136  				Config: testAccAWSClusterConfigUpdatedTags(ri),
   137  				Check: resource.ComposeTestCheckFunc(
   138  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   139  					resource.TestCheckResourceAttr(
   140  						"aws_rds_cluster.default", "tags.%", "2"),
   141  				),
   142  			},
   143  		},
   144  	})
   145  }
   146  
   147  func TestAccAWSRDSCluster_kmsKey(t *testing.T) {
   148  	var v rds.DBCluster
   149  	keyRegex := regexp.MustCompile("^arn:aws:kms:")
   150  
   151  	resource.Test(t, resource.TestCase{
   152  		PreCheck:     func() { testAccPreCheck(t) },
   153  		Providers:    testAccProviders,
   154  		CheckDestroy: testAccCheckAWSClusterDestroy,
   155  		Steps: []resource.TestStep{
   156  			{
   157  				Config: testAccAWSClusterConfig_kmsKey(acctest.RandInt()),
   158  				Check: resource.ComposeTestCheckFunc(
   159  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   160  					resource.TestMatchResourceAttr(
   161  						"aws_rds_cluster.default", "kms_key_id", keyRegex),
   162  				),
   163  			},
   164  		},
   165  	})
   166  }
   167  
   168  func TestAccAWSRDSCluster_encrypted(t *testing.T) {
   169  	var v rds.DBCluster
   170  
   171  	resource.Test(t, resource.TestCase{
   172  		PreCheck:     func() { testAccPreCheck(t) },
   173  		Providers:    testAccProviders,
   174  		CheckDestroy: testAccCheckAWSClusterDestroy,
   175  		Steps: []resource.TestStep{
   176  			{
   177  				Config: testAccAWSClusterConfig_encrypted(acctest.RandInt()),
   178  				Check: resource.ComposeTestCheckFunc(
   179  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   180  					resource.TestCheckResourceAttr(
   181  						"aws_rds_cluster.default", "storage_encrypted", "true"),
   182  					resource.TestCheckResourceAttr(
   183  						"aws_rds_cluster.default", "db_cluster_parameter_group_name", "default.aurora5.6"),
   184  				),
   185  			},
   186  		},
   187  	})
   188  }
   189  
   190  func TestAccAWSRDSCluster_backupsUpdate(t *testing.T) {
   191  	var v rds.DBCluster
   192  
   193  	ri := acctest.RandInt()
   194  	resource.Test(t, resource.TestCase{
   195  		PreCheck:     func() { testAccPreCheck(t) },
   196  		Providers:    testAccProviders,
   197  		CheckDestroy: testAccCheckAWSClusterDestroy,
   198  		Steps: []resource.TestStep{
   199  			{
   200  				Config: testAccAWSClusterConfig_backups(ri),
   201  				Check: resource.ComposeTestCheckFunc(
   202  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   203  					resource.TestCheckResourceAttr(
   204  						"aws_rds_cluster.default", "preferred_backup_window", "07:00-09:00"),
   205  					resource.TestCheckResourceAttr(
   206  						"aws_rds_cluster.default", "backup_retention_period", "5"),
   207  					resource.TestCheckResourceAttr(
   208  						"aws_rds_cluster.default", "preferred_maintenance_window", "tue:04:00-tue:04:30"),
   209  				),
   210  			},
   211  
   212  			resource.TestStep{
   213  				Config: testAccAWSClusterConfig_backupsUpdate(ri),
   214  				Check: resource.ComposeTestCheckFunc(
   215  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   216  					resource.TestCheckResourceAttr(
   217  						"aws_rds_cluster.default", "preferred_backup_window", "03:00-09:00"),
   218  					resource.TestCheckResourceAttr(
   219  						"aws_rds_cluster.default", "backup_retention_period", "10"),
   220  					resource.TestCheckResourceAttr(
   221  						"aws_rds_cluster.default", "preferred_maintenance_window", "wed:01:00-wed:01:30"),
   222  				),
   223  			},
   224  		},
   225  	})
   226  }
   227  
   228  func TestAccAWSRDSCluster_iamAuth(t *testing.T) {
   229  	var v rds.DBCluster
   230  
   231  	resource.Test(t, resource.TestCase{
   232  		PreCheck:     func() { testAccPreCheck(t) },
   233  		Providers:    testAccProviders,
   234  		CheckDestroy: testAccCheckAWSClusterDestroy,
   235  		Steps: []resource.TestStep{
   236  			{
   237  				Config: testAccAWSClusterConfig_iamAuth(acctest.RandInt()),
   238  				Check: resource.ComposeTestCheckFunc(
   239  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   240  					resource.TestCheckResourceAttr(
   241  						"aws_rds_cluster.default", "iam_database_authentication_enabled", "true"),
   242  				),
   243  			},
   244  		},
   245  	})
   246  }
   247  
   248  func testAccCheckAWSClusterDestroy(s *terraform.State) error {
   249  	for _, rs := range s.RootModule().Resources {
   250  		if rs.Type != "aws_rds_cluster" {
   251  			continue
   252  		}
   253  
   254  		// Try to find the Group
   255  		conn := testAccProvider.Meta().(*AWSClient).rdsconn
   256  		var err error
   257  		resp, err := conn.DescribeDBClusters(
   258  			&rds.DescribeDBClustersInput{
   259  				DBClusterIdentifier: aws.String(rs.Primary.ID),
   260  			})
   261  
   262  		if err == nil {
   263  			if len(resp.DBClusters) != 0 &&
   264  				*resp.DBClusters[0].DBClusterIdentifier == rs.Primary.ID {
   265  				return fmt.Errorf("DB Cluster %s still exists", rs.Primary.ID)
   266  			}
   267  		}
   268  
   269  		// Return nil if the cluster is already destroyed
   270  		if awsErr, ok := err.(awserr.Error); ok {
   271  			if awsErr.Code() == "DBClusterNotFoundFault" {
   272  				return nil
   273  			}
   274  		}
   275  
   276  		return err
   277  	}
   278  
   279  	return nil
   280  }
   281  
   282  func testAccCheckAWSClusterSnapshot(rInt int) resource.TestCheckFunc {
   283  	return func(s *terraform.State) error {
   284  		for _, rs := range s.RootModule().Resources {
   285  			if rs.Type != "aws_rds_cluster" {
   286  				continue
   287  			}
   288  
   289  			// Try and delete the snapshot before we check for the cluster not found
   290  			snapshot_identifier := fmt.Sprintf("tf-acctest-rdscluster-snapshot-%d", rInt)
   291  
   292  			awsClient := testAccProvider.Meta().(*AWSClient)
   293  			conn := awsClient.rdsconn
   294  
   295  			arn, arnErr := buildRDSClusterARN(snapshot_identifier, awsClient.partition, awsClient.accountid, awsClient.region)
   296  			tagsARN := strings.Replace(arn, ":cluster:", ":snapshot:", 1)
   297  			if arnErr != nil {
   298  				return fmt.Errorf("Error building ARN for tags check with ARN (%s): %s", tagsARN, arnErr)
   299  			}
   300  
   301  			log.Printf("[INFO] Deleting the Snapshot %s", snapshot_identifier)
   302  			_, snapDeleteErr := conn.DeleteDBClusterSnapshot(
   303  				&rds.DeleteDBClusterSnapshotInput{
   304  					DBClusterSnapshotIdentifier: aws.String(snapshot_identifier),
   305  				})
   306  			if snapDeleteErr != nil {
   307  				return snapDeleteErr
   308  			}
   309  
   310  			// Try to find the Group
   311  			var err error
   312  			resp, err := conn.DescribeDBClusters(
   313  				&rds.DescribeDBClustersInput{
   314  					DBClusterIdentifier: aws.String(rs.Primary.ID),
   315  				})
   316  
   317  			if err == nil {
   318  				if len(resp.DBClusters) != 0 &&
   319  					*resp.DBClusters[0].DBClusterIdentifier == rs.Primary.ID {
   320  					return fmt.Errorf("DB Cluster %s still exists", rs.Primary.ID)
   321  				}
   322  			}
   323  
   324  			// Return nil if the cluster is already destroyed
   325  			if awsErr, ok := err.(awserr.Error); ok {
   326  				if awsErr.Code() == "DBClusterNotFoundFault" {
   327  					return nil
   328  				}
   329  			}
   330  
   331  			return err
   332  		}
   333  
   334  		return nil
   335  	}
   336  }
   337  
   338  func testAccCheckAWSClusterExists(n string, v *rds.DBCluster) resource.TestCheckFunc {
   339  	return func(s *terraform.State) error {
   340  		rs, ok := s.RootModule().Resources[n]
   341  		if !ok {
   342  			return fmt.Errorf("Not found: %s", n)
   343  		}
   344  
   345  		if rs.Primary.ID == "" {
   346  			return fmt.Errorf("No DB Instance ID is set")
   347  		}
   348  
   349  		conn := testAccProvider.Meta().(*AWSClient).rdsconn
   350  		resp, err := conn.DescribeDBClusters(&rds.DescribeDBClustersInput{
   351  			DBClusterIdentifier: aws.String(rs.Primary.ID),
   352  		})
   353  
   354  		if err != nil {
   355  			return err
   356  		}
   357  
   358  		for _, c := range resp.DBClusters {
   359  			if *c.DBClusterIdentifier == rs.Primary.ID {
   360  				*v = *c
   361  				return nil
   362  			}
   363  		}
   364  
   365  		return fmt.Errorf("DB Cluster (%s) not found", rs.Primary.ID)
   366  	}
   367  }
   368  
   369  func testAccAWSClusterConfig(n int) string {
   370  	return fmt.Sprintf(`
   371  resource "aws_rds_cluster" "default" {
   372    cluster_identifier = "tf-aurora-cluster-%d"
   373    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   374    database_name = "mydb"
   375    master_username = "foo"
   376    master_password = "mustbeeightcharaters"
   377    db_cluster_parameter_group_name = "default.aurora5.6"
   378    skip_final_snapshot = true
   379    tags {
   380      Environment = "production"
   381    }
   382  }`, n)
   383  }
   384  
   385  func testAccAWSClusterConfig_namePrefix(n int) string {
   386  	return fmt.Sprintf(`
   387  resource "aws_rds_cluster" "test" {
   388    cluster_identifier_prefix = "tf-test-"
   389    master_username = "root"
   390    master_password = "password"
   391    db_subnet_group_name = "${aws_db_subnet_group.test.name}"
   392    skip_final_snapshot = true
   393  }
   394  
   395  resource "aws_vpc" "test" {
   396    cidr_block = "10.0.0.0/16"
   397  }
   398  
   399  resource "aws_subnet" "a" {
   400    vpc_id = "${aws_vpc.test.id}"
   401    cidr_block = "10.0.0.0/24"
   402    availability_zone = "us-west-2a"
   403  }
   404  
   405  resource "aws_subnet" "b" {
   406    vpc_id = "${aws_vpc.test.id}"
   407    cidr_block = "10.0.1.0/24"
   408    availability_zone = "us-west-2b"
   409  }
   410  
   411  resource "aws_db_subnet_group" "test" {
   412    name = "tf-test-%d"
   413    subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"]
   414  }
   415  `, n)
   416  }
   417  
   418  func testAccAWSClusterConfig_generatedName(n int) string {
   419  	return fmt.Sprintf(`
   420  resource "aws_rds_cluster" "test" {
   421    master_username = "root"
   422    master_password = "password"
   423    db_subnet_group_name = "${aws_db_subnet_group.test.name}"
   424    skip_final_snapshot = true
   425  }
   426  
   427  resource "aws_vpc" "test" {
   428    cidr_block = "10.0.0.0/16"
   429  }
   430  
   431  resource "aws_subnet" "a" {
   432    vpc_id = "${aws_vpc.test.id}"
   433    cidr_block = "10.0.0.0/24"
   434    availability_zone = "us-west-2a"
   435  }
   436  
   437  resource "aws_subnet" "b" {
   438    vpc_id = "${aws_vpc.test.id}"
   439    cidr_block = "10.0.1.0/24"
   440    availability_zone = "us-west-2b"
   441  }
   442  
   443  resource "aws_db_subnet_group" "test" {
   444    name = "tf-test-%d"
   445    subnet_ids = ["${aws_subnet.a.id}", "${aws_subnet.b.id}"]
   446  }
   447  `, n)
   448  }
   449  
   450  func testAccAWSClusterConfigWithFinalSnapshot(n int) string {
   451  	return fmt.Sprintf(`
   452  resource "aws_rds_cluster" "default" {
   453    cluster_identifier = "tf-aurora-cluster-%d"
   454    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   455    database_name = "mydb"
   456    master_username = "foo"
   457    master_password = "mustbeeightcharaters"
   458    db_cluster_parameter_group_name = "default.aurora5.6"
   459    final_snapshot_identifier = "tf-acctest-rdscluster-snapshot-%d"
   460    tags {
   461      Environment = "production"
   462    }
   463  }`, n, n)
   464  }
   465  
   466  func testAccAWSClusterConfigWithoutUserNameAndPassword(n int) string {
   467  	return fmt.Sprintf(`
   468  resource "aws_rds_cluster" "default" {
   469    cluster_identifier = "tf-aurora-cluster-%d"
   470    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   471    database_name = "mydb"
   472    skip_final_snapshot = true
   473  }`, n)
   474  }
   475  
   476  func testAccAWSClusterConfigUpdatedTags(n int) string {
   477  	return fmt.Sprintf(`
   478  resource "aws_rds_cluster" "default" {
   479    cluster_identifier = "tf-aurora-cluster-%d"
   480    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   481    database_name = "mydb"
   482    master_username = "foo"
   483    master_password = "mustbeeightcharaters"
   484    db_cluster_parameter_group_name = "default.aurora5.6"
   485    skip_final_snapshot = true
   486    tags {
   487      Environment = "production"
   488      AnotherTag = "test"
   489    }
   490  }`, n)
   491  }
   492  
   493  func testAccAWSClusterConfig_kmsKey(n int) string {
   494  	return fmt.Sprintf(`
   495  
   496   resource "aws_kms_key" "foo" {
   497       description = "Terraform acc test %d"
   498       policy = <<POLICY
   499   {
   500     "Version": "2012-10-17",
   501     "Id": "kms-tf-1",
   502     "Statement": [
   503       {
   504         "Sid": "Enable IAM User Permissions",
   505         "Effect": "Allow",
   506         "Principal": {
   507           "AWS": "*"
   508         },
   509         "Action": "kms:*",
   510         "Resource": "*"
   511       }
   512     ]
   513   }
   514   POLICY
   515   }
   516  
   517   resource "aws_rds_cluster" "default" {
   518     cluster_identifier = "tf-aurora-cluster-%d"
   519     availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   520     database_name = "mydb"
   521     master_username = "foo"
   522     master_password = "mustbeeightcharaters"
   523     db_cluster_parameter_group_name = "default.aurora5.6"
   524     storage_encrypted = true
   525     kms_key_id = "${aws_kms_key.foo.arn}"
   526     skip_final_snapshot = true
   527   }`, n, n)
   528  }
   529  
   530  func testAccAWSClusterConfig_encrypted(n int) string {
   531  	return fmt.Sprintf(`
   532  resource "aws_rds_cluster" "default" {
   533    cluster_identifier = "tf-aurora-cluster-%d"
   534    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   535    database_name = "mydb"
   536    master_username = "foo"
   537    master_password = "mustbeeightcharaters"
   538    storage_encrypted = true
   539    skip_final_snapshot = true
   540  }`, n)
   541  }
   542  
   543  func testAccAWSClusterConfig_backups(n int) string {
   544  	return fmt.Sprintf(`
   545  resource "aws_rds_cluster" "default" {
   546    cluster_identifier = "tf-aurora-cluster-%d"
   547    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   548    database_name = "mydb"
   549    master_username = "foo"
   550    master_password = "mustbeeightcharaters"
   551    backup_retention_period = 5
   552    preferred_backup_window = "07:00-09:00"
   553    preferred_maintenance_window = "tue:04:00-tue:04:30"
   554    skip_final_snapshot = true
   555  }`, n)
   556  }
   557  
   558  func testAccAWSClusterConfig_backupsUpdate(n int) string {
   559  	return fmt.Sprintf(`
   560  resource "aws_rds_cluster" "default" {
   561    cluster_identifier = "tf-aurora-cluster-%d"
   562    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   563    database_name = "mydb"
   564    master_username = "foo"
   565    master_password = "mustbeeightcharaters"
   566    backup_retention_period = 10
   567    preferred_backup_window = "03:00-09:00"
   568    preferred_maintenance_window = "wed:01:00-wed:01:30"
   569    apply_immediately = true
   570    skip_final_snapshot = true
   571  }`, n)
   572  }
   573  
   574  func testAccAWSClusterConfig_iamAuth(n int) string {
   575  	return fmt.Sprintf(`
   576  resource "aws_rds_cluster" "default" {
   577    cluster_identifier = "tf-aurora-cluster-%d"
   578    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   579    database_name = "mydb"
   580    master_username = "foo"
   581    master_password = "mustbeeightcharaters"
   582    iam_database_authentication_enabled = true
   583    skip_final_snapshot = true
   584  }`, n)
   585  }