Skip to content

RestoreDbInstanceFromDbSnapshot fails when SCP policy for encryption exists #2678

Closed
@shawon-crosen

Description

Acknowledgements

Describe the bug

When restoring a database from a snapshot using RestoreDBInstanceFromDBSnapshot it does not encrypt the new database with the KMS key used on the database being restored from.

Expected Behavior

I would expect the new database to either use the existing KMS key for the snapshot being restored to encrypt the database, or have an option to set a KMS key for encryption for the new database.

I believe this would probably need to just use the existing key as the snapshot must be decrypted with it first.

Current Behavior

Our AWS organization has a service control policy that requires storage encryption for a database being created or restored:

{
"Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "rds:CreateDBInstance",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "rds:StorageEncrypted": "false"
        }
      }
    },
    {
      "Effect": "Deny",
      "Action": "rds:RestoreDBInstanceFromDBSnapshot",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "rds:StorageEncrypted": "false"
        }
      }
    }
  ]
}

The RestoreDbInstanceFromDbSnapshot function is failing this policy check as it seems to be trying to restore the database snapshot to a new database that is not encrypted. There is no option to specify a KMS key in the RestoreDBInstanceFromDBSnapshotInput struct.

There is also no option to specify a snapshot identifier in the CreateDBInstanceInput struct for the CreateDBInstance function, or I would have just used that.

Reproduction Steps

This is our function that is calling the client func:

func CloneDbInstance(client *rds.Client, identifier string, snapshot string, options map[string]interface{}) (*string, error) {
	data, err := client.RestoreDBInstanceFromDBSnapshot(
		context.TODO(),
		&rds.RestoreDBInstanceFromDBSnapshotInput{
			AllocatedStorage:     aws.Int32(options["allocatedStorage"].(int32)),
			DBInstanceIdentifier: aws.String(identifier),
			DBParameterGroupName: aws.String(options["parameterGroup"].(string)),
			DBSnapshotIdentifier: aws.String(snapshot),
			DBSubnetGroupName:    aws.String(options["subnet"].(string)),
			DeletionProtection:   aws.Bool(false),
			StorageType:          aws.String(options["storageType"].(string)),
			VpcSecurityGroupIds:  options["vpcIds"].([]string),
		},
	)

	if err != nil {
		return nil, err
	}

	return data.DBInstance.DBInstanceStatus, nil
}

Possible Solution

I suggest that the function just uses the existing KMS key that must be used to decrypt the snapshot to encrypt the new database being created. This also makes sense because if you have a database that is already encrypted, you would want your new database restored from a snapshot to also be encrypted with the same key.

Additional Information/Context

This is primarily an issue due to an SCP on our organization denying creation of rds instances that are not encrypted.

AWS Go SDK V2 Module Versions Used

github.com/aws/aws-sdk-go-v2/service/rds v1.79.6

Compiler and Version used

go version go1.22.4 darwin/amd64

Operating System and version

macOS Sonoma 14.5

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Labels

bugThis issue is a bug.service-apiThis issue is due to a problem in a service API, not the SDK implementation.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions