I am trying to setup minimal permissions for doing aws rds copy-db-snapshot
with a KMS encryption key:
$ aws rds copy-db-snapshot --source-db-snapshot-identifier rds-backup-share- mysql --target-db-snapshot-identifier rds-backup-share-mysql-reencrypted --kms-key-id <kms-arn>
(Everything within <>
is stripped out by me and contains valid values.)
Unfortunately I get this error:
An error occurred (KMSKeyNotAccessibleFault) when calling the CopyDBSnapshot operation: The target snapshot KMS key [<kms-arn>] does not exist, is not enabled or you do not have permissions to access it.
Currently I allow these actions:
"Action": [ "kms:ReEncrypt*", "kms:ListKeys", "kms:ListAliases", "kms:GenerateDataKey*", "kms:Encrypt", "kms:DescribeKey", "kms:Decrypt" ],
It works if I replace it with kms:*{code}
, so it must be a permission issue.
I tried to figure out the correct permissions with CloudTrail, but it just contains the same unhelpful error message.
So my actual questions:
Edit: This is the is the bottom part of the log output with --debug
enabled:
2017-08-22 17:15:37,521 - MainThread - botocore.endpoint - DEBUG - Sending http request: <PreparedRequest [POST]> 2017-08-22 17:15:37,522 - MainThread - botocore.vendored.requests.packages.urllib3.connectionpool - INFO - Starting new HTTPS connection (1): rds.eu-west-1.amazonaws.com 2017-08-22 17:15:37,927 - MainThread - botocore.vendored.requests.packages.urllib3.connectionpool - DEBUG - "POST / HTTP/1.1" 400 437 2017-08-22 17:15:37,934 - MainThread - botocore.parsers - DEBUG - Response headers: {'x-amzn-requestid': 'c097fe4e-874c-11e7-a56a-9d1acedaf516', 'content-type': 'text/xml', 'content-length': '437', 'date': 'Tue, 22 Aug 2017 15:15:37 GMT', 'connection': 'close'} 2017-08-22 17:15:37,936 - MainThread - botocore.parsers - DEBUG - Response body: b'<ErrorResponse xmlns="http://rds.amazonaws.com/doc/2014-10-31/">\n <Error>\n <Type>Sender</Type>\n <Code>KMSKeyNotAccessibleFault</Code>\n <Message>The target snapshot KMS key [<kms-arn>] does not exist, is not enabled or you do not have permissions to access it. </Message>\n </Error>\n <RequestId>c097fe4e-874c-11e7-a56a-9d1acedaf516</RequestId>\n</ErrorResponse>\n' 2017-08-22 17:15:37,938 - MainThread - botocore.hooks - DEBUG - Event needs-retry.rds.CopyDBSnapshot: calling handler <botocore.retryhandler.RetryHandler object at 0x7f9c7ce84860> 2017-08-22 17:15:37,939 - MainThread - botocore.retryhandler - DEBUG - No retry needed. 2017-08-22 17:15:37,952 - MainThread - awscli.clidriver - DEBUG - Exception caught in main() Traceback (most recent call last): File "/usr/lib/python3.6/site-packages/awscli/clidriver.py", line 200, in main return command_table[parsed_args.command](remaining, parsed_args) File "/usr/lib/python3.6/site-packages/awscli/clidriver.py", line 338, in __call__ return command_table[parsed_args.operation](remaining, parsed_globals) File "/usr/lib/python3.6/site-packages/awscli/clidriver.py", line 508, in __call__ call_parameters, parsed_globals) File "/usr/lib/python3.6/site-packages/awscli/clidriver.py", line 627, in invoke client, operation_name, parameters, parsed_globals) File "/usr/lib/python3.6/site-packages/awscli/clidriver.py", line 639, in _make_client_call **parameters) File "/usr/lib/python3.6/site-packages/botocore/client.py", line 310, in _api_call return self._make_api_call(operation_name, kwargs) File "/usr/lib/python3.6/site-packages/botocore/client.py", line 599, in _make_api_call raise error_class(parsed_response, operation_name) botocore.errorfactory.KMSKeyNotAccessibleFault: An error occurred (KMSKeyNotAccessibleFault) when calling the CopyDBSnapshot operation: The target snapshot KMS key [<kms-arn>] does not exist, is not enabled or you do not have permissions to access it. 2017-08-22 17:15:37,955 - MainThread - awscli.clidriver - DEBUG - Exiting with rc 255 An error occurred (KMSKeyNotAccessibleFault) when calling the CopyDBSnapshot operation: The target snapshot KMS key [<kms-arn>] does not exist, is not enabled or you do not have permissions to access it.
FTR: I did a cross-post to the AWS forum: https://forums.aws.amazon.com/thread.jspa?messageID=801745
To create a DB snapshotSign in to the AWS Management Console and open the Amazon RDS console at https://console.aws.amazon.com/rds/ . In the navigation pane, choose Databases. In the list of DB instances, choose the DB instance for which you want to take a snapshot. For Actions, choose Take snapshot.
To copy your encrypted snapshot to a different AWS Region, simply select the destination region during the Copy Snapshot operation on the AWS Management Console or via the AWS Command Line Interface. You do not need to do anything differently to gain the benefits of incremental copies.
Restoring from the Snapshot takes 25 minutes! 25 minutes for the restore is too long considering users are forced to stay in read only mode for all this period and that our DB size is less than 10 mb at the moment. I am wondering if this restore time is the usual time for Amazon RDS or if we are doing something wrong.
Choose Snapshots from the navigation pane. From the Snapshots pane, choose the Shared with Me tab. Select the DB snapshot that was shared. Choose Actions, and then choose Copy Snapshot to copy the snapshot into the same AWS Region and with a KMS key from the target account.
Now, I figured it out by trial and error. Since I don't like to do the same task more than once, I automated it (see script below).
This are the required permissions for copying a RDS snapshot:
["kms:CreateGrant","kms:DescribeKey"]
This is the script I used. Maybe it is useful for other people which have a similar problem. It is hacked together, so don't expect it to work out of the box.
#!/bin/bash set -euo pipefail unknown=( kms:CancelKeyDeletion kms:CreateAlias kms:CreateAlias kms:CreateGrant kms:CreateKey kms:Decrypt kms:DeleteAlias kms:DeleteAlias kms:DescribeKey kms:DisableKey kms:DisableKeyRotation kms:EnableKey kms:EnableKeyRotation kms:Encrypt kms:GenerateRandom kms:GenerateDataKey kms:GenerateDataKeyWithoutPlaintext kms:GetKeyPolicy kms:GetKeyRotationStatus kms:ListAliases kms:ListGrants kms:ListKeyPolicies kms:ListKeys kms:ListRetirableGrants kms:PutKeyPolicy kms:ReEncryptFrom kms:ReEncryptTo kms:RetireGrant kms:RevokeGrant kms:ScheduleKeyDeletion kms:UpdateAlias kms:UpdateAlias kms:UpdateKeyDescription ) required=() KEY_ID=86a6300d-38f9-4892-b7a1-d8f821e8438c export AWS_DEFAULT_OUTPUT=json function check_copy { permissions=$( echo -n "${required[*]} ${unknown[*]}" | jq -R -s 'split(" ")' ) policy=$( aws kms \ get-key-policy \ --key-id ${KEY_ID} \ --policy-name default \ | jq ".Policy" -r \ | jq ".Statement[1].Action |= ${permissions}" ) aws kms \ put-key-policy \ --key-id ${KEY_ID} \ --policy-name default \ --policy "${policy}" aws rds \ delete-db-snapshot \ --db-snapshot-identifier rds-backup-share-mysql-reencrypted \ || true ( set -x AWS_ACCESS_KEY_ID=XXX \ AWS_SECRET_ACCESS_KEY=XXX \ aws rds \ copy-db-snapshot \ --source-db-snapshot-identifier rds-backup-share-mysql \ --target-db-snapshot-identifier rds-backup-share-mysql-reencrypted \ --kms-key-id alias/rds-snapshot-share \ || return 1 aws rds \ wait db-snapshot-completed \ --db-snapshot-identifier rds-backup-share-mysql-reencrypted ) || return 1 return 0 } check_copy while [ ${#unknown[@]} -gt 0 ] do removed=${unknown[0]} unknown=(${unknown[@]:1}) if ! check_copy then required+=($removed) fi echo "Required permissions so far: ${required[*]}" echo "Unknown permissions so far: ${unknown[*]}" done echo -n "Minimal permissions: " echo -n "${required[*]}" | jq -R -s -c 'split(" ")'
I found another root cause for this, and another solution:
Just create, then delete, a RDS in the target region!
AWS RDS simply refused to copy a snapshot, no matter what I did to key policies, UNTIL I created a small, automatic RDS. Now any key works "out-of-box", even new ones without any policy change!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With