Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Performance Insights configuration for aws_db_instance #6453

Merged
merged 1 commit into from
May 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions aws/resource_aws_db_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,25 @@ func resourceAwsDbInstance() *schema.Resource {
Optional: true,
},

"performance_insights_enabled": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This attribute (along with the other performance_insights_* attributes) are not currently handled during the RestoreDBInstanceFromDBSnapshot creation flow so attempting to creating a configuration with PI enabled and snapshot_identifier will require two applies of the configuration to converge.

While RestoreDBInstanceFromDBSnapshot does not directly support setting EnablePerformanceInsights, PerformanceInsightsKmsKeyId, and PerformanceInsightsRetentionPeriod, we have a framework in place to handle this situation by calling ModifyDBInstance immediately after restore, e.g.

// Provided as an example of this logic so similar logic can be added near it
		if attr, ok := d.GetOk("backup_window"); ok {
			modifyDbInstanceInput.PreferredBackupWindow = aws.String(attr.(string))
			requiresModifyDbInstance = true
		}

This should have an acceptance test added to ensure its functionality and prevent regressions, e.g. something similar to:

func TestAccAWSDBInstance_SnapshotIdentifier_PerformanceInsightsEnabled(t *testing.T) {
	var dbInstance, sourceDbInstance rds.DBInstance
	var dbSnapshot rds.DBSnapshot

	rName := acctest.RandomWithPrefix("tf-acc-test")
	kmsKeyResourceName := "aws_kms_key.test"
	sourceDbResourceName := "aws_db_instance.source"
	snapshotResourceName := "aws_db_snapshot.test"
	resourceName := "aws_db_instance.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSDBInstanceConfig_SnapshotIdentifier_PerformanceInsightsEnabled(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBInstanceExists(sourceDbResourceName, &sourceDbInstance),
					testAccCheckDbSnapshotExists(snapshotResourceName, &dbSnapshot),
					testAccCheckAWSDBInstanceExists(resourceName, &dbInstance),
					resource.TestCheckResourceAttr(resourceName, "performance_insights_enabled", "true"),
					resource.TestCheckResourceAttrPair(resourceName, "performance_insights_kms_key_id", kmsKeyResourceName, "arn"),
					resource.TestCheckResourceAttr(resourceName, "performance_insights_retention_period", "7"),
				),
			},
		},
	})
}

func testAccAWSDBInstanceConfig_SnapshotIdentifier_PerformanceInsightsEnabled(rName string) string {
	return fmt.Sprintf(`
resource "aws_kms_key" "test" {
  description = "Terraform acc test"
  policy      = <<POLICY
{
  "Version": "2012-10-17",
  "Id": "kms-tf-1",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "kms:*",
      "Resource": "*"
    }
  ]
}
POLICY
}

resource "aws_db_instance" "source" {
  allocated_storage   = 5
  engine              = "mysql"
  engine_version      = "5.6.41"
  identifier          = "%s-source"
  instance_class      = "db.m3.medium"
  password            = "avoid-plaintext-passwords"
  username            = "tfacctest"
  skip_final_snapshot = true
}

resource "aws_db_snapshot" "test" {
  db_instance_identifier = "${aws_db_instance.source.id}"
  db_snapshot_identifier = %q
}

resource "aws_db_instance" "test" {
  identifier                            = %q
  instance_class                        = "${aws_db_instance.source.instance_class}"
  performance_insights_enabled          = true
  performance_insights_kms_key_id       = "${aws_kms_key.test.arn}"
  performance_insights_retention_period = 7
  snapshot_identifier                   = "${aws_db_snapshot.test.id}"
  skip_final_snapshot                   = true
}
`, rName, rName, rName)
}

Type: schema.TypeBool,
Optional: true,
Default: false,
},

"performance_insights_kms_key_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validateArn,
},

"performance_insights_retention_period": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},

"tags": tagsSchema(),
},
}
Expand Down Expand Up @@ -573,6 +592,18 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
requiresModifyDbInstance = true
}

if attr, ok := d.GetOk("performance_insights_enabled"); ok {
opts.EnablePerformanceInsights = aws.Bool(attr.(bool))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should have an acceptance test added to ensure its functionality and prevent regressions, e.g. something similar to:

func TestAccAWSDBInstance_ReplicateSourceDb_PerformanceInsightsEnabled(t *testing.T) {
	var dbInstance, sourceDbInstance rds.DBInstance

	rName := acctest.RandomWithPrefix("tf-acc-test")
	kmsKeyResourceName := "aws_kms_key.test"
	sourceResourceName := "aws_db_instance.source"
	resourceName := "aws_db_instance.test"

	resource.ParallelTest(t, resource.TestCase{
		PreCheck:     func() { testAccPreCheck(t) },
		Providers:    testAccProviders,
		CheckDestroy: testAccCheckAWSDBInstanceDestroy,
		Steps: []resource.TestStep{
			{
				Config: testAccAWSDBInstanceConfig_ReplicateSourceDb_PerformanceInsightsEnabled(rName),
				Check: resource.ComposeTestCheckFunc(
					testAccCheckAWSDBInstanceExists(sourceResourceName, &sourceDbInstance),
					testAccCheckAWSDBInstanceExists(resourceName, &dbInstance),
					testAccCheckAWSDBInstanceReplicaAttributes(&sourceDbInstance, &dbInstance),
					resource.TestCheckResourceAttr(resourceName, "performance_insights_enabled", "true"),
					resource.TestCheckResourceAttrPair(resourceName, "performance_insights_kms_key_id", kmsKeyResourceName, "arn"),
					resource.TestCheckResourceAttr(resourceName, "performance_insights_retention_period", "7"),
				),
			},
		},
	})
}

func testAccAWSDBInstanceConfig_ReplicateSourceDb_PerformanceInsightsEnabled(rName string) string {
	return fmt.Sprintf(`
resource "aws_kms_key" "test" {
  description = "Terraform acc test"
  policy      = <<POLICY
{
  "Version": "2012-10-17",
  "Id": "kms-tf-1",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "kms:*",
      "Resource": "*"
    }
  ]
}
POLICY
}

resource "aws_db_instance" "source" {
  allocated_storage       = 5
  backup_retention_period = 1
  engine                  = "mysql"
  engine_version          = "5.6.41"
  identifier              = "%s-source"
  instance_class          = "db.m3.medium"
  password                = "avoid-plaintext-passwords"
  username                = "tfacctest"
  skip_final_snapshot     = true
}

resource "aws_db_instance" "test" {
  identifier                            = %q
  instance_class                        = "${aws_db_instance.source.instance_class}"
  performance_insights_enabled          = true
  performance_insights_kms_key_id       = "${aws_kms_key.test.arn}"
  performance_insights_retention_period = 7
  replicate_source_db                   = "${aws_db_instance.source.id}"
  skip_final_snapshot                   = true
}
`, rName, rName)
}

}

if attr, ok := d.GetOk("performance_insights_kms_key_id"); ok {
opts.PerformanceInsightsKMSKeyId = aws.String(attr.(string))
}

if attr, ok := d.GetOk("performance_insights_retention_period"); ok {
opts.PerformanceInsightsRetentionPeriod = aws.Int64(int64(attr.(int)))
}

log.Printf("[DEBUG] DB Instance Replica create configuration: %#v", opts)
_, err := conn.CreateDBInstanceReadReplica(&opts)
if err != nil {
Expand Down Expand Up @@ -701,6 +732,18 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
opts.EnableIAMDatabaseAuthentication = aws.Bool(attr.(bool))
}

if attr, ok := d.GetOk("performance_insights_enabled"); ok {
opts.EnablePerformanceInsights = aws.Bool(attr.(bool))
}

if attr, ok := d.GetOk("performance_insights_kms_key_id"); ok {
opts.PerformanceInsightsKMSKeyId = aws.String(attr.(string))
}

if attr, ok := d.GetOk("performance_insights_retention_period"); ok {
opts.PerformanceInsightsRetentionPeriod = aws.Int64(int64(attr.(int)))
}

log.Printf("[DEBUG] DB Instance S3 Restore configuration: %#v", opts)
var err error
// Retry for IAM eventual consistency
Expand Down Expand Up @@ -897,6 +940,19 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
requiresModifyDbInstance = true
}

if attr, ok := d.GetOk("performance_insights_enabled"); ok {
modifyDbInstanceInput.EnablePerformanceInsights = aws.Bool(attr.(bool))
requiresModifyDbInstance = true

if attr, ok := d.GetOk("performance_insights_kms_key_id"); ok {
modifyDbInstanceInput.PerformanceInsightsKMSKeyId = aws.String(attr.(string))
}

if attr, ok := d.GetOk("performance_insights_retention_period"); ok {
modifyDbInstanceInput.PerformanceInsightsRetentionPeriod = aws.Int64(int64(attr.(int)))
}
}

log.Printf("[DEBUG] DB Instance restore from snapshot configuration: %s", opts)
_, err := conn.RestoreDBInstanceFromDBSnapshot(&opts)

Expand Down Expand Up @@ -1045,6 +1101,18 @@ func resourceAwsDbInstanceCreate(d *schema.ResourceData, meta interface{}) error
opts.DomainIAMRoleName = aws.String(attr.(string))
}

if attr, ok := d.GetOk("performance_insights_enabled"); ok {
opts.EnablePerformanceInsights = aws.Bool(attr.(bool))
}

if attr, ok := d.GetOk("performance_insights_kms_key_id"); ok {
opts.PerformanceInsightsKMSKeyId = aws.String(attr.(string))
}

if attr, ok := d.GetOk("performance_insights_retention_period"); ok {
opts.PerformanceInsightsRetentionPeriod = aws.Int64(int64(attr.(int)))
}

log.Printf("[DEBUG] DB Instance create configuration: %#v", opts)
var err error
err = resource.Retry(5*time.Minute, func() *resource.RetryError {
Expand Down Expand Up @@ -1154,6 +1222,9 @@ func resourceAwsDbInstanceRead(d *schema.ResourceData, meta interface{}) error {
d.Set("kms_key_id", v.KmsKeyId)
d.Set("port", v.DbInstancePort)
d.Set("iam_database_authentication_enabled", v.IAMDatabaseAuthenticationEnabled)
d.Set("performance_insights_enabled", v.PerformanceInsightsEnabled)
d.Set("performance_insights_kms_key_id", v.PerformanceInsightsKMSKeyId)
d.Set("performance_insights_retention_period", v.PerformanceInsightsRetentionPeriod)
if v.DBSubnetGroup != nil {
d.Set("db_subnet_group_name", v.DBSubnetGroup.DBSubnetGroupName)
}
Expand Down Expand Up @@ -1475,6 +1546,18 @@ func resourceAwsDbInstanceUpdate(d *schema.ResourceData, meta interface{}) error
requestUpdate = true
}

if d.HasChange("performance_insights_enabled") || d.HasChange("performance_insights_kms_key_id") || d.HasChange("performance_insights_retention_period") {
d.SetPartial("performance_insights_enabled")
req.EnablePerformanceInsights = aws.Bool(d.Get("performance_insights_enabled").(bool))

d.SetPartial("performance_insights_kms_key_id")
req.PerformanceInsightsKMSKeyId = aws.String(d.Get("performance_insights_kms_key_id").(string))

d.SetPartial("performance_insights_retention_period")
req.PerformanceInsightsRetentionPeriod = aws.Int64(int64(d.Get("performance_insights_retention_period").(int)))
requestUpdate = true
}

log.Printf("[DEBUG] Send DB Instance Modification request: %t", requestUpdate)
if requestUpdate {
log.Printf("[DEBUG] DB Instance Modification request: %s", req)
Expand Down
Loading