Use the Conformity Knowledge Base AI to help improve your Cloud Posture

RDS Encryption Enabled

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: High (act today)
Rule ID: RDS-004

Ensure that your Amazon RDS database instances are encrypted to fulfill compliance requirements for data-at-rest encryption. The data encryption and decryption process is handled transparently and does not require any additional action from you or your application.

This rule can help you with the following compliance standards:

  • PCI
  • HIPAA
  • GDPR
  • APRA
  • MAS
  • NIST4

For further details on compliance standards supported by Conformity, see here.

This rule can help you work with the AWS Well-Architected Framework.

This rule resolution is part of the Conformity Security & Compliance tool for AWS.

Security

When dealing with production databases that hold sensitive and critical data, it is highly recommended to implement encryption in order to protect your data from unauthorized access. With Amazon RDS encryption enabled, the data stored on the instance underlying storage, the automated backups, Read Replicas, and snapshots, become all encrypted. The RDS encryption keys implement AES-256 algorithm and are entirely managed and protected by the AWS key management infrastructure through Amazon Key Management Service (KMS).


Audit

To determine if your Amazon RDS database instances are encrypted at rest, perform the following operations:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon RDS console at https://console.aws.amazon.com/rds/.

03 In the navigation panel, under Amazon RDS, choose Databases.

04 Click on the name (link) of the Amazon RDS database instance that you want to examine. To identify RDS database instances, check the database role available in the Role column (i.e. Instance).

05 Select the Configuration tab and check the Encryption attribute value. If the Encryption value is set to Not enabled, the encryption of data at rest is not enabled for the selected Amazon RDS database instance.

06 Repeat steps no. 4 and 5 for each Amazon RDS database instance available within the current AWS region.

07 Change the AWS cloud region from the navigation bar and repeat the Audit process for other regions.

Using AWS CLI

01 Run describe-db-instances command (OSX/Linux/UNIX) with custom query filters to list the names of the Amazon RDS database instances provisioned in the selected AWS region:

aws rds describe-db-instances
  --region us-east-1
  --output table
  --query 'DBInstances[*].DBInstanceIdentifier'

02 The command output should return a table with the requested database instance names:

--------------------------------
|     DescribeDBInstances      |
+------------------------------+
|  cc-project5-mysql-database  |
|  cc-prod-postgres-database   |
+------------------------------+

03 Run describe-db-instances command (OSX/Linux/UNIX) using the name of the Amazon RDS database instance that you want to examine as the identifier parameter and custom query filters to determine if the selected database instance is encrypted at rest:

aws rds describe-db-instances
  --region us-east-1
  --db-instance-identifier cc-project5-mysql-database
  --query 'DBInstances[*].StorageEncrypted'

04 The command output should return the encryption status (true for enabled, false for disabled):

[
    false
]

If the describe-db-instances command output returns false, as shown in the output example above, the encryption of data at rest is not enabled for the selected Amazon RDS database instance.

05 Repeat steps no. 3 and 4 for each Amazon RDS database instance available in the selected AWS region.

06 Change the AWS cloud region by updating the --region command parameter value and repeat the Audit process for other regions.

Remediation / Resolution

To enable data-at-rest encryption for your existing Amazon RDS database instances you must re-create (back up and restore) your instances with the encryption flag enabled, by performing the following operations:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
	"AWSTemplateFormatVersion": "2010-09-09",
	"Description": "Enable Encryption at Rest",
	"Parameters": {
		"DBInstanceName": {
			"Default": "mysql-database-instance",
			"Description": "RDS database instance name",
			"Type": "String",
			"MinLength": "1",
			"MaxLength": "63",
			"AllowedPattern": "^[0-9a-zA-Z-/]*$",
			"ConstraintDescription": "Must begin with a letter and must not end with a hyphen or contain two consecutive hyphens."
		},
		"DBInstanceClass": {
				"Default": "db.t2.small",
				"Description": "DB instance class/type",
				"Type": "String",
				"ConstraintDescription": "Must provide a valid DB instance type."
		},
		"DBAllocatedStorage": {
			"Default": "20",
			"Description": "The size of the database (GiB)",
			"Type": "Number",
			"MinValue": "20",
			"MaxValue": "65536",
			"ConstraintDescription": "Must be between 20 and 65536 GiB."
		},
		"DBName": {
			"Default": "mysqldb",
			"Description": "Database name",
			"Type": "String",
			"MinLength": "1",
			"MaxLength": "64",
			"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
			"ConstraintDescription": "Must begin with a letter and contain only alphanumeric characters."
		},
		"DBUsername": {
			"Description": "Master username for database access",
			"Type": "String",
			"MinLength": "1",
			"MaxLength": "16",
			"AllowedPattern": "[a-zA-Z][a-zA-Z0-9]*",
			"ConstraintDescription": "Must begin with a letter and contain only alphanumeric characters."
		},
		"DBPassword": {
			"NoEcho": "true",
			"Description": "Password for database access",
			"Type": "String",
			"MinLength": "8",
			"MaxLength": "41",
			"AllowedPattern": "[a-zA-Z0-9]*",
			"ConstraintDescription": "Must contain only alphanumeric characters."
		}
	},
	"Resources": {
		"RDSInstance": {
			"Type": "AWS::RDS::DBInstance",
			"Properties": {
				"DBInstanceIdentifier": {
					"Ref": "DBInstanceName"
				},
				"DBName": {
					"Ref": "DBName"
				},
				"MasterUsername": {
					"Ref": "DBUsername"
				},
				"MasterUserPassword": {
					"Ref": "DBPassword"
				},
				"DBInstanceClass": {
					"Ref": "DBInstanceClass"
				},
				"AllocatedStorage": {
					"Ref": "DBAllocatedStorage"
				},
				"Engine": "MySQL",
				"EngineVersion": "5.7.36",
				"StorageEncrypted": true
			}
		}
	}
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
	Description: Enable Encryption at Rest
	Parameters:
		DBInstanceName:
		Default: mysql-database-instance
		Description: RDS database instance name
		Type: String
		MinLength: '1'
		MaxLength: '63'
		AllowedPattern: ^[0-9a-zA-Z-/]*$
		ConstraintDescription: Must begin with a letter and must not end with a hyphen
			or contain two consecutive hyphens.
		DBInstanceClass:
		Default: db.t2.small
		Description: DB instance class/type
		Type: String
		ConstraintDescription: Must provide a valid DB instance type.
		DBAllocatedStorage:
		Default: '20'
		Description: The size of the database (GiB)
		Type: Number
		MinValue: '20'
		MaxValue: '65536'
		ConstraintDescription: Must be between 20 and 65536 GiB.
		DBName:
		Default: mysqldb
		Description: Database name
		Type: String
		MinLength: '1'
		MaxLength: '64'
		AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
		ConstraintDescription: Must begin with a letter and contain only alphanumeric
			characters.
		DBUsername:
		Description: Master username for database access
		Type: String
		MinLength: '1'
		MaxLength: '16'
		AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*'
		ConstraintDescription: Must begin with a letter and contain only alphanumeric
			characters.
		DBPassword:
		NoEcho: 'true'
		Description: Password for database access
		Type: String
		MinLength: '8'
		MaxLength: '41'
		AllowedPattern: '[a-zA-Z0-9]*'
		ConstraintDescription: Must contain only alphanumeric characters.
	Resources:
		RDSInstance:
		Type: AWS::RDS::DBInstance
		Properties:
			DBInstanceIdentifier: !Ref 'DBInstanceName'
			DBName: !Ref 'DBName'
			MasterUsername: !Ref 'DBUsername'
			MasterUserPassword: !Ref 'DBPassword'
			DBInstanceClass: !Ref 'DBInstanceClass'
			AllocatedStorage: !Ref 'DBAllocatedStorage'
			Engine: MySQL
			EngineVersion: 5.7.36
			StorageEncrypted: true

Using Terraform

01 Terraform configuration file (.tf):

terraform {
	required_providers {
		aws = {
			source  = "hashicorp/aws"
			version = "~> 3.27"
		}
	}

	required_version = ">= 0.14.9"
}

provider "aws" {
	profile = "default"
	region  = "us-east-1"
}

resource "aws_db_instance" "rds-database-instance" {
	allocated_storage         = 20
	engine                    = "mysql"
	engine_version            = "5.7"
	instance_class            = "db.t2.small"
	name                      = "mysqldb"
	username                  = "ccmysqluser01"
	password                  = "ccmysqluserpwd"
	parameter_group_name      = "default.mysql5.7"
	final_snapshot_identifier = "rds-database-instance-snapshot"

	# Enable Encryption at Rest
	storage_encrypted = true


	apply_immediately = true
}

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon RDS console at https://console.aws.amazon.com/rds/.

03 In the navigation panel, under Amazon RDS, choose Databases.

04 Select the Amazon RDS database instance that you want to encrypt, choose Actions, and select Take snapshot.

05 On the Take DB snapshot setup page, enter a name for the instance snapshot in the Snapshot name box, and choose Take snapshot (the backup process may take a few minutes and depends on your RDS instance storage size).

06 Select the newly created database instance snapshot, choose Actions, and select Copy snapshot to create a new copy of the selected snapshot.

07 On the Copy snapshot setup page, perform the following actions:

  1. From the Destination Region dropdown list, select the region where you want to save the copy of the selected snapshot.
  2. In the New DB Snapshot Identifier box, type a unique name for the new database snapshot.
  3. (Optional) From Target Option Group (Optional) dropdown list, select an option group to associate with your target database snapshot.
  4. (Optional) Select the Copy Tags checkbox if you want your new database snapshot to have the same tags as the source snapshot.
  5. In the Encryption section, select the Enable Encryption checkbox to turn on encryption at rest for the new Amazon RDS database snapshot. Select (default) aws/rds from the Master key dropdown list to use the AWS-managed master key (a predefined key that protects your data when no other key is created for this purpose) or choose Enter a key ARN and provide the Amazon Resource Name (ARN) of your customer-managed Customer Master Key (CMK) in the ARN configuration box.
  6. Choose Copy snapshot to confirm the action. The process will take a couple of minutes to complete. Once created, you should see the encrypted Amazon RDS database snapshot (copy) in the Manual snapshots list.

08 Select the new snapshot copy (encrypted), choose Actions, and select Restore snapshot to restore the encrypted snapshot to a new Amazon RDS database instance.

09 On the Restore snapshot setup page, enter a unique name for your new, encrypted database instance in the DB instance identifier box. If required, configure the instance network and connectivity, instance type/class, storage and availability settings. Choose Restore DB instance to create your new Amazon RDS database instance.

10 As soon as your new database instance is ready (i.e. instance status becomes Available), you can update your database application configuration to refer to the endpoint of the new (encrypted) database instance.

11 (Optional) You can now delete the source (unencrypted) database instance to stop incurring charges for the RDS resource. To remove the source instance from your AWS cloud account, perform the following actions:

  1. Select the unencrypted database instance that you want to delete, choose Actions, and select Delete.
  2. In the Delete <instance-name> instance? confirmation box, select Create final snapshot?, type delete me into the required field, then choose Delete to confirm your action.

12 Repeat steps no. 4 – 11 for each unencrypted Amazon RDS database instance available within the current AWS region.

13 Change the AWS cloud region from the navigation bar and repeat the Remediation process for other regions.

Using AWS CLI

01 Run create-db-snapshot command (OSX/Linux/UNIX) to create a new snapshot for the Amazon RDS database instance that you want to encrypt:

aws rds create-db-snapshot
  --region us-east-1
  --db-snapshot-identifier cc-project5-mysql-database-snapshot
  --db-instance-identifier cc-project5-mysql-database

02 The command output should return the metadata of the new database instance snapshot:

{
	"DBSnapshot": {
		"Engine": "mysql",
		"Status": "creating",
		"AvailabilityZone": "us-east-1a",
		"ProcessorFeatures": [],
		"DBSnapshotArn": "arn:aws:rds:us-east-1:123456789012:snapshot:cc-project5-mysql-database-snapshot",
		"PercentProgress": 0,
		"MasterUsername": "ccadmin",
		"Encrypted": false,
		"LicenseModel": "general-public-license",
		"StorageType": "gp2",
		"VpcId": "vpc-abcdabcd",
		"DBSnapshotIdentifier": "cc-project5-mysql-database-snapshot",
		"InstanceCreateTime": "2021-05-19T07:25:18.958Z",
		"OptionGroupName": "default:mysql-5-6",
		"AllocatedStorage": 20,
		"EngineVersion": "5.6.40",
		"SnapshotType": "manual",
		"DbiResourceId": "db-ABCDABCDABCDABCDABCD",
		"IAMDatabaseAuthenticationEnabled": false,
		"Port": 3306,
		"DBInstanceIdentifier": "cc-project5-mysql-database"
	}
}

03 Run copy-db-snapshot command (OSX/Linux/UNIX) using the name of the unencrypted Amazon RDS database snapshot as the identifier parameter, to copy the selected snapshot and encrypt its data using the default master key (i.e. AWS-managed key). Replace <aws-region> and <aws-account-id> with your own AWS cloud environment details:

aws rds copy-db-snapshot
  --region us-east-1
  --source-db-snapshot-identifier cc-project5-mysql-database-snapshot
  --target-db-snapshot-identifier cc-encrypted-project5-mysql-database-snapshot
  --kms-key-id arn:aws:kms:<aws-region>: <aws-account-id>:alias/aws/rds

04 The command output should return the metadata of the new Amazon RDS database snapshot:

{
	"DBSnapshot": {
		"MasterUsername": "ccadmin",
		"LicenseModel": "general-public-license",
		"InstanceCreateTime": "2021-05-18T15:31:20.677Z",
		"Engine": "mysql",
		"VpcId": "vpc-abcdabcd",
		"SourceRegion": "us-east-1",
		"AllocatedStorage": 20,
		"Status": "creating",
		"PercentProgress": 0,
		"SourceDBSnapshotIdentifier": "arn:aws:rds:us-east-1:123456789012:snapshot:cc-project5-mysql-database-snapshot",
		"DBSnapshotIdentifier": "cc-encrypted-project5-mysql-database-snapshot",
		"DBSnapshotArn": "arn:aws:rds:us-east-1:123456789012:snapshot:cc-encrypted-project5-mysql-database-snapshot",
		"EngineVersion": "8.0.20",
		"ProcessorFeatures": [],
		"OptionGroupName": "default:mysql-8-0",
		"AvailabilityZone": "us-east-1a",
		"StorageType": "gp2",
		"Encrypted": true,
		"IAMDatabaseAuthenticationEnabled": false,
		"KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/abcdabcd-1234-abcd-1234-abcd1234abcd",
		"DbiResourceId": "db-ABCDABCDABCDABCDABCD",
		"SnapshotType": "manual",
		"Port": 3306,
		"DBInstanceIdentifier": "cc-project5-mysql-database"
	}
}

05 Run restore-db-instance-from-db-snapshot command (OSX/Linux/UNIX) to restore the encrypted snapshot created at the previous step to a new Amazon RDS database instance:

aws rds restore-db-instance-from-db-snapshot
  --region us-east-1
  --db-instance-identifier cc-encrypted-project5-mysql-database
  --db-snapshot-identifier cc-encrypted-project5-mysql-database-snapshot

06 The command output should return the configuration metadata for the new, encrypted database instance:

{
	"DBInstance": {
		"PubliclyAccessible": true,
		"MasterUsername": "ccadmin",
		"MonitoringInterval": 0,
		"LicenseModel": "general-public-license",
		"VpcSecurityGroups": [
			{
				"Status": "active",
				"VpcSecurityGroupId": "sg-0abcd1234abcd1234"
			}
		],
		"InstanceCreateTime": "2021-05-12T08:00:00.677Z",
		"CopyTagsToSnapshot": true,
		"OptionGroupMemberships": [
			{
				"Status": "in-sync",
				"OptionGroupName": "default:mysql-5-7"
			}
		],
		"Engine": "mysql",
		"MultiAZ": false,
		"DBSecurityGroups": [],
		"DBParameterGroups": [
			{
				"DBParameterGroupName": "default.mysql5.7",
				"ParameterApplyStatus": "in-sync"
			}
		],
		"PerformanceInsightsEnabled": true,
		"AutoMinorVersionUpgrade": true,
		"PreferredBackupWindow": "06:02-06:32",
		"DBSubnetGroup": {
			"Subnets": [
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-abcd1234",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1d"
					}
				},
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-1234abcd",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1e"
					}
				},
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-abcdabcd",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1b"
					}
				},
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-12341234",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1a"
					}
				},
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-abcd1234",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1f"
					}
				},
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-1234abcd",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1c"
					}
				}
			],
			"DBSubnetGroupName": "default-vpc-abcdabcd",
			"VpcId": "vpc-abcdabcd",
			"DBSubnetGroupDescription": "Created from the AWS Management Console",
			"SubnetGroupStatus": "Complete"
		},
		"ReadReplicaDBInstanceIdentifiers": [],
		"AllocatedStorage": 20,
		"DBInstanceArn": "arn:aws:rds:us-east-1:123456789012:db:cc-project5-mysql-database",
		"BackupRetentionPeriod": 0,
		"PreferredMaintenanceWindow": "thu:03:27-thu:03:57",
		"Endpoint": {
			"HostedZoneId": "ABCDABCDABCD",
			"Port": 3306,
			"Address": "cc-project5-mysql-database.abcdabcdabcd.us-east-1.rds.amazonaws.com"
		},
		"DBInstanceStatus": "available",
		"IAMDatabaseAuthenticationEnabled": true,
		"EngineVersion": "5.7.30",
		"DeletionProtection": true,
		"AvailabilityZone": "us-east-1a",
		"DomainMemberships": [],
		"StorageType": "gp2",
		"DbiResourceId": "db-ABCDABCDABCDABCDABCDABCDAB",
		"CACertificateIdentifier": "rds-ca-2019",
		"StorageEncrypted": true,
		"AssociatedRoles": [],
		"DBInstanceClass": "db.t3.medium",
		"DbInstancePort": 0,
		"DBInstanceIdentifier": "cc-project5-mysql-database"
	}
}

07 As soon as your new database instance is ready, you can update your database application configuration to refer to the endpoint of the new (encrypted) database instance.

08 (Optional) You can choose to delete the source (unencrypted) database instance. Run delete-db-instance command (OSX/Linux/UNIX) using the name of the unencrypted database instance as the identifier parameter, to remove specified RDS instance from your AWS cloud account:

aws rds delete-db-instance
  --region us-east-1
  --db-instance-identifier cc-project5-mysql-database
  --final-db-snapshot-identifier cc-project5-mysql-database-final-snapshot

09 The command output should return the delete-db-instance command request metadata:

{
	"DBInstance": {
		"PubliclyAccessible": true,
		"MasterUsername": "ccadmin",
		"MonitoringInterval": 0,
		"LicenseModel": "general-public-license",
		"VpcSecurityGroups": [
			{
				"Status": "active",
				"VpcSecurityGroupId": "sg-0abcd1234abcd1234"
			}
		],
		"InstanceCreateTime": "2021-05-12T08:00:00.677Z",
		"CopyTagsToSnapshot": true,
		"OptionGroupMemberships": [
			{
				"Status": "in-sync",
				"OptionGroupName": "default:mysql-5-7"
			}
		],
		"Engine": "mysql",
		"MultiAZ": false,
		"DBSecurityGroups": [],
		"DBParameterGroups": [
			{
				"DBParameterGroupName": "default.mysql5.7",
				"ParameterApplyStatus": "in-sync"
			}
		],
		"PerformanceInsightsEnabled": true,
		"AutoMinorVersionUpgrade": true,
		"PreferredBackupWindow": "06:02-06:32",
		"DBSubnetGroup": {
			"Subnets": [
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-abcd1234",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1d"
					}
				},
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-1234abcd",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1e"
					}
				},
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-abcdabcd",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1b"
					}
				},
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-12341234",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1a"
					}
				},
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-abcd1234",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1f"
					}
				},
				{
					"SubnetStatus": "Active",
					"SubnetIdentifier": "subnet-1234abcd",
					"SubnetOutpost": {},
					"SubnetAvailabilityZone": {
						"Name": "us-east-1c"
					}
				}
			],
			"DBSubnetGroupName": "default-vpc-abcdabcd",
			"VpcId": "vpc-abcdabcd",
			"DBSubnetGroupDescription": "Created from the AWS Management Console",
			"SubnetGroupStatus": "Complete"
		},
		"ReadReplicaDBInstanceIdentifiers": [],
		"AllocatedStorage": 20,
		"DBInstanceArn": "arn:aws:rds:us-east-1:123456789012:db:cc-project5-mysql-database",
		"BackupRetentionPeriod": 0,
		"PreferredMaintenanceWindow": "thu:03:27-thu:03:57",
		"Endpoint": {
			"HostedZoneId": "ABCDABCDABCD",
			"Port": 3306,
			"Address": "cc-project5-mysql-database.abcdabcdabcd.us-east-1.rds.amazonaws.com"
		},
		"DBInstanceStatus": "available",
		"IAMDatabaseAuthenticationEnabled": true,
		"EngineVersion": "5.7.30",
		"DeletionProtection": false,
		"AvailabilityZone": "us-east-1a",
		"DomainMemberships": [],
		"StorageType": "gp2",
		"DbiResourceId": "db-ABCDABCDABCDABCDABCDABCDAB",
		"CACertificateIdentifier": "rds-ca-2019",
		"StorageEncrypted": false,
		"AssociatedRoles": [],
		"DBInstanceClass": "db.t3.medium",
		"DbInstancePort": 0,
		"DBInstanceIdentifier": "cc-project5-mysql-database"
	}
}

10 Repeat steps no. 1 – 9 for each unencrypted Amazon RDS database instance available in the selected AWS region.

11 Change the AWS cloud region by updating the --region command parameter value and repeat the Remediation process for other regions.

References

Publication date May 1, 2016