github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/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_takeFinalSnapshot(t *testing.T) {
    44  	var v rds.DBCluster
    45  	rInt := acctest.RandInt()
    46  
    47  	resource.Test(t, resource.TestCase{
    48  		PreCheck:     func() { testAccPreCheck(t) },
    49  		Providers:    testAccProviders,
    50  		CheckDestroy: testAccCheckAWSClusterSnapshot(rInt),
    51  		Steps: []resource.TestStep{
    52  			{
    53  				Config: testAccAWSClusterConfigWithFinalSnapshot(rInt),
    54  				Check: resource.ComposeTestCheckFunc(
    55  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
    56  				),
    57  			},
    58  		},
    59  	})
    60  }
    61  
    62  /// This is a regression test to make sure that we always cover the scenario as hightlighted in
    63  /// https://github.com/hashicorp/terraform/issues/11568
    64  func TestAccAWSRDSCluster_missingUserNameCausesError(t *testing.T) {
    65  	resource.Test(t, resource.TestCase{
    66  		PreCheck:     func() { testAccPreCheck(t) },
    67  		Providers:    testAccProviders,
    68  		CheckDestroy: testAccCheckAWSClusterDestroy,
    69  		Steps: []resource.TestStep{
    70  			{
    71  				Config:      testAccAWSClusterConfigWithoutUserNameAndPassword(acctest.RandInt()),
    72  				ExpectError: regexp.MustCompile(`required field is not set`),
    73  			},
    74  		},
    75  	})
    76  }
    77  
    78  func TestAccAWSRDSCluster_updateTags(t *testing.T) {
    79  	var v rds.DBCluster
    80  	ri := acctest.RandInt()
    81  
    82  	resource.Test(t, resource.TestCase{
    83  		PreCheck:     func() { testAccPreCheck(t) },
    84  		Providers:    testAccProviders,
    85  		CheckDestroy: testAccCheckAWSClusterDestroy,
    86  		Steps: []resource.TestStep{
    87  			{
    88  				Config: testAccAWSClusterConfig(ri),
    89  				Check: resource.ComposeTestCheckFunc(
    90  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
    91  					resource.TestCheckResourceAttr(
    92  						"aws_rds_cluster.default", "tags.%", "1"),
    93  				),
    94  			},
    95  			{
    96  				Config: testAccAWSClusterConfigUpdatedTags(ri),
    97  				Check: resource.ComposeTestCheckFunc(
    98  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
    99  					resource.TestCheckResourceAttr(
   100  						"aws_rds_cluster.default", "tags.%", "2"),
   101  				),
   102  			},
   103  		},
   104  	})
   105  }
   106  
   107  func TestAccAWSRDSCluster_kmsKey(t *testing.T) {
   108  	var v rds.DBCluster
   109  	keyRegex := regexp.MustCompile("^arn:aws:kms:")
   110  
   111  	resource.Test(t, resource.TestCase{
   112  		PreCheck:     func() { testAccPreCheck(t) },
   113  		Providers:    testAccProviders,
   114  		CheckDestroy: testAccCheckAWSClusterDestroy,
   115  		Steps: []resource.TestStep{
   116  			{
   117  				Config: testAccAWSClusterConfig_kmsKey(acctest.RandInt()),
   118  				Check: resource.ComposeTestCheckFunc(
   119  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   120  					resource.TestMatchResourceAttr(
   121  						"aws_rds_cluster.default", "kms_key_id", keyRegex),
   122  				),
   123  			},
   124  		},
   125  	})
   126  }
   127  
   128  func TestAccAWSRDSCluster_encrypted(t *testing.T) {
   129  	var v rds.DBCluster
   130  
   131  	resource.Test(t, resource.TestCase{
   132  		PreCheck:     func() { testAccPreCheck(t) },
   133  		Providers:    testAccProviders,
   134  		CheckDestroy: testAccCheckAWSClusterDestroy,
   135  		Steps: []resource.TestStep{
   136  			{
   137  				Config: testAccAWSClusterConfig_encrypted(acctest.RandInt()),
   138  				Check: resource.ComposeTestCheckFunc(
   139  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   140  					resource.TestCheckResourceAttr(
   141  						"aws_rds_cluster.default", "storage_encrypted", "true"),
   142  					resource.TestCheckResourceAttr(
   143  						"aws_rds_cluster.default", "db_cluster_parameter_group_name", "default.aurora5.6"),
   144  				),
   145  			},
   146  		},
   147  	})
   148  }
   149  
   150  func TestAccAWSRDSCluster_backupsUpdate(t *testing.T) {
   151  	var v rds.DBCluster
   152  
   153  	ri := acctest.RandInt()
   154  	resource.Test(t, resource.TestCase{
   155  		PreCheck:     func() { testAccPreCheck(t) },
   156  		Providers:    testAccProviders,
   157  		CheckDestroy: testAccCheckAWSClusterDestroy,
   158  		Steps: []resource.TestStep{
   159  			{
   160  				Config: testAccAWSClusterConfig_backups(ri),
   161  				Check: resource.ComposeTestCheckFunc(
   162  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   163  					resource.TestCheckResourceAttr(
   164  						"aws_rds_cluster.default", "preferred_backup_window", "07:00-09:00"),
   165  					resource.TestCheckResourceAttr(
   166  						"aws_rds_cluster.default", "backup_retention_period", "5"),
   167  					resource.TestCheckResourceAttr(
   168  						"aws_rds_cluster.default", "preferred_maintenance_window", "tue:04:00-tue:04:30"),
   169  				),
   170  			},
   171  
   172  			resource.TestStep{
   173  				Config: testAccAWSClusterConfig_backupsUpdate(ri),
   174  				Check: resource.ComposeTestCheckFunc(
   175  					testAccCheckAWSClusterExists("aws_rds_cluster.default", &v),
   176  					resource.TestCheckResourceAttr(
   177  						"aws_rds_cluster.default", "preferred_backup_window", "03:00-09:00"),
   178  					resource.TestCheckResourceAttr(
   179  						"aws_rds_cluster.default", "backup_retention_period", "10"),
   180  					resource.TestCheckResourceAttr(
   181  						"aws_rds_cluster.default", "preferred_maintenance_window", "wed:01:00-wed:01:30"),
   182  				),
   183  			},
   184  		},
   185  	})
   186  }
   187  
   188  func testAccCheckAWSClusterDestroy(s *terraform.State) error {
   189  	for _, rs := range s.RootModule().Resources {
   190  		if rs.Type != "aws_rds_cluster" {
   191  			continue
   192  		}
   193  
   194  		// Try to find the Group
   195  		conn := testAccProvider.Meta().(*AWSClient).rdsconn
   196  		var err error
   197  		resp, err := conn.DescribeDBClusters(
   198  			&rds.DescribeDBClustersInput{
   199  				DBClusterIdentifier: aws.String(rs.Primary.ID),
   200  			})
   201  
   202  		if err == nil {
   203  			if len(resp.DBClusters) != 0 &&
   204  				*resp.DBClusters[0].DBClusterIdentifier == rs.Primary.ID {
   205  				return fmt.Errorf("DB Cluster %s still exists", rs.Primary.ID)
   206  			}
   207  		}
   208  
   209  		// Return nil if the cluster is already destroyed
   210  		if awsErr, ok := err.(awserr.Error); ok {
   211  			if awsErr.Code() == "DBClusterNotFoundFault" {
   212  				return nil
   213  			}
   214  		}
   215  
   216  		return err
   217  	}
   218  
   219  	return nil
   220  }
   221  
   222  func testAccCheckAWSClusterSnapshot(rInt int) resource.TestCheckFunc {
   223  	return func(s *terraform.State) error {
   224  		for _, rs := range s.RootModule().Resources {
   225  			if rs.Type != "aws_rds_cluster" {
   226  				continue
   227  			}
   228  
   229  			// Try and delete the snapshot before we check for the cluster not found
   230  			snapshot_identifier := fmt.Sprintf("foobarbaz-test-terraform-final-snapshot-%d", rInt)
   231  
   232  			awsClient := testAccProvider.Meta().(*AWSClient)
   233  			conn := awsClient.rdsconn
   234  
   235  			arn, arnErr := buildRDSClusterARN(snapshot_identifier, awsClient.partition, awsClient.accountid, awsClient.region)
   236  			tagsARN := strings.Replace(arn, ":cluster:", ":snapshot:", 1)
   237  			if arnErr != nil {
   238  				return fmt.Errorf("Error building ARN for tags check with ARN (%s): %s", tagsARN, arnErr)
   239  			}
   240  
   241  			log.Printf("[INFO] Deleting the Snapshot %s", snapshot_identifier)
   242  			_, snapDeleteErr := conn.DeleteDBClusterSnapshot(
   243  				&rds.DeleteDBClusterSnapshotInput{
   244  					DBClusterSnapshotIdentifier: aws.String(snapshot_identifier),
   245  				})
   246  			if snapDeleteErr != nil {
   247  				return snapDeleteErr
   248  			}
   249  
   250  			// Try to find the Group
   251  			var err error
   252  			resp, err := conn.DescribeDBClusters(
   253  				&rds.DescribeDBClustersInput{
   254  					DBClusterIdentifier: aws.String(rs.Primary.ID),
   255  				})
   256  
   257  			if err == nil {
   258  				if len(resp.DBClusters) != 0 &&
   259  					*resp.DBClusters[0].DBClusterIdentifier == rs.Primary.ID {
   260  					return fmt.Errorf("DB Cluster %s still exists", rs.Primary.ID)
   261  				}
   262  			}
   263  
   264  			// Return nil if the cluster is already destroyed
   265  			if awsErr, ok := err.(awserr.Error); ok {
   266  				if awsErr.Code() == "DBClusterNotFoundFault" {
   267  					return nil
   268  				}
   269  			}
   270  
   271  			return err
   272  		}
   273  
   274  		return nil
   275  	}
   276  }
   277  
   278  func testAccCheckAWSClusterExists(n string, v *rds.DBCluster) 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  		resp, err := conn.DescribeDBClusters(&rds.DescribeDBClustersInput{
   291  			DBClusterIdentifier: aws.String(rs.Primary.ID),
   292  		})
   293  
   294  		if err != nil {
   295  			return err
   296  		}
   297  
   298  		for _, c := range resp.DBClusters {
   299  			if *c.DBClusterIdentifier == rs.Primary.ID {
   300  				*v = *c
   301  				return nil
   302  			}
   303  		}
   304  
   305  		return fmt.Errorf("DB Cluster (%s) not found", rs.Primary.ID)
   306  	}
   307  }
   308  
   309  func testAccAWSClusterConfig(n int) string {
   310  	return fmt.Sprintf(`
   311  resource "aws_rds_cluster" "default" {
   312    cluster_identifier = "tf-aurora-cluster-%d"
   313    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   314    database_name = "mydb"
   315    master_username = "foo"
   316    master_password = "mustbeeightcharaters"
   317    db_cluster_parameter_group_name = "default.aurora5.6"
   318    skip_final_snapshot = true
   319    tags {
   320      Environment = "production"
   321    }
   322  }`, n)
   323  }
   324  
   325  func testAccAWSClusterConfigWithFinalSnapshot(n int) string {
   326  	return fmt.Sprintf(`
   327  resource "aws_rds_cluster" "default" {
   328    cluster_identifier = "tf-aurora-cluster-%d"
   329    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   330    database_name = "mydb"
   331    master_username = "foo"
   332    master_password = "mustbeeightcharaters"
   333    db_cluster_parameter_group_name = "default.aurora5.6"
   334    skip_final_snapshot = true
   335    final_snapshot_identifier = "tf-acctest-rdscluster-snapshot-%d"
   336    tags {
   337      Environment = "production"
   338    }
   339  }`, n, n)
   340  }
   341  
   342  func testAccAWSClusterConfigWithoutUserNameAndPassword(n int) string {
   343  	return fmt.Sprintf(`
   344  resource "aws_rds_cluster" "default" {
   345    cluster_identifier = "tf-aurora-cluster-%d"
   346    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   347    database_name = "mydb"
   348    skip_final_snapshot = true
   349  }`, n)
   350  }
   351  
   352  func testAccAWSClusterConfigUpdatedTags(n int) string {
   353  	return fmt.Sprintf(`
   354  resource "aws_rds_cluster" "default" {
   355    cluster_identifier = "tf-aurora-cluster-%d"
   356    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   357    database_name = "mydb"
   358    master_username = "foo"
   359    master_password = "mustbeeightcharaters"
   360    db_cluster_parameter_group_name = "default.aurora5.6"
   361    skip_final_snapshot = true
   362    tags {
   363      Environment = "production"
   364      AnotherTag = "test"
   365    }
   366  }`, n)
   367  }
   368  
   369  func testAccAWSClusterConfig_kmsKey(n int) string {
   370  	return fmt.Sprintf(`
   371  
   372   resource "aws_kms_key" "foo" {
   373       description = "Terraform acc test %d"
   374       policy = <<POLICY
   375   {
   376     "Version": "2012-10-17",
   377     "Id": "kms-tf-1",
   378     "Statement": [
   379       {
   380         "Sid": "Enable IAM User Permissions",
   381         "Effect": "Allow",
   382         "Principal": {
   383           "AWS": "*"
   384         },
   385         "Action": "kms:*",
   386         "Resource": "*"
   387       }
   388     ]
   389   }
   390   POLICY
   391   }
   392  
   393   resource "aws_rds_cluster" "default" {
   394     cluster_identifier = "tf-aurora-cluster-%d"
   395     availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   396     database_name = "mydb"
   397     master_username = "foo"
   398     master_password = "mustbeeightcharaters"
   399     db_cluster_parameter_group_name = "default.aurora5.6"
   400     storage_encrypted = true
   401     kms_key_id = "${aws_kms_key.foo.arn}"
   402     skip_final_snapshot = true
   403   }`, n, n)
   404  }
   405  
   406  func testAccAWSClusterConfig_encrypted(n int) string {
   407  	return fmt.Sprintf(`
   408  resource "aws_rds_cluster" "default" {
   409    cluster_identifier = "tf-aurora-cluster-%d"
   410    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   411    database_name = "mydb"
   412    master_username = "foo"
   413    master_password = "mustbeeightcharaters"
   414    storage_encrypted = true
   415    skip_final_snapshot = true
   416  }`, n)
   417  }
   418  
   419  func testAccAWSClusterConfig_backups(n int) string {
   420  	return fmt.Sprintf(`
   421  resource "aws_rds_cluster" "default" {
   422    cluster_identifier = "tf-aurora-cluster-%d"
   423    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   424    database_name = "mydb"
   425    master_username = "foo"
   426    master_password = "mustbeeightcharaters"
   427    backup_retention_period = 5
   428    preferred_backup_window = "07:00-09:00"
   429    preferred_maintenance_window = "tue:04:00-tue:04:30"
   430    skip_final_snapshot = true
   431  }`, n)
   432  }
   433  
   434  func testAccAWSClusterConfig_backupsUpdate(n int) string {
   435  	return fmt.Sprintf(`
   436  resource "aws_rds_cluster" "default" {
   437    cluster_identifier = "tf-aurora-cluster-%d"
   438    availability_zones = ["us-west-2a","us-west-2b","us-west-2c"]
   439    database_name = "mydb"
   440    master_username = "foo"
   441    master_password = "mustbeeightcharaters"
   442    backup_retention_period = 10
   443    preferred_backup_window = "03:00-09:00"
   444    preferred_maintenance_window = "wed:01:00-wed:01:30"
   445    apply_immediately = true
   446    skip_final_snapshot = true
   447  }`, n)
   448  }