Reputation: 18482
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
Upvotes: 42
Views: 30292
Reputation: 75
this is the policy you have to use for your kms key of the source vault.
{
"Version": "2012-10-17",
"Id": "cab-kms-key",
"Statement": [{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::SourceAccountID:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::SourceAccountID:root",
"arn:aws:iam::DestinationAccountID:root"
]
},
"Action": [
"kms:DescribeKey",
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::SourceAccountID:root",
"arn:aws:iam::DestinationAccountID:root"
]
},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
]
}
worked well in my case. I found it here: https://repost.aws/knowledge-center/backup-cross-account-copy-error
Upvotes: 0
Reputation: 445
I was trying to copy db cluster snapshot (mostly Aurora clusters would use that) from one region to another using boto3 and I went through all the answers but I was simply getting the same error as mentioned in the question. We cannot specify destination region of snapshot in parameter of copy_db_cluster_snapshot API in boto3.
So I am writing this so that whoever faces issue with copy_db_cluster_snapshot method to copy it to another region can follow this guide.
I had a Lambda function and the code would look like below:
Destination region of snapshot = us-west-2
Source region of snapshot = us-east-1
Below points are important:
def copy_to_other_region_lambda_handler(event, context):
client = boto3.client('rds','us-west-2')
response = client.copy_db_cluster_snapshot(
SourceDBClusterSnapshotIdentifier='arn:aws:rds:us-east-1:account-id:cluster-snapshot:source',
TargetDBClusterSnapshotIdentifier='target-snapshot',
CopyTags=True,
SourceRegion='us-east-1',
KmsKeyId='arn:aws:kms:us-west-2:account-id:key/key-id'
)
Upvotes: 0
Reputation: 22392
If this is a one time event (possibly copying/cloning a RDS from another account) and you are willing to use AWS console here are the steps:
Full credit to AWS documentation https://aws.amazon.com/premiumsupport/knowledge-center/share-encrypted-rds-snapshot-kms-key/
Upvotes: 1
Reputation: 4216
Aside from the permissions from the other answers, make sure to use a symmetric encryption key. AWS errors are not clear on what they mean and that very same error message is used when you are trying to do something with an asymmetric key that should be done with a symmetric one.
Upvotes: 3
Reputation: 101
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!
Upvotes: 10
Reputation: 1616
I'm also doing a copy of an RDS database snapshot, but using Powershell and my database is MS SQL. I'm getting the same error:
The target snapshot KMS key [<kms-arn>] does not exist,
is not enabled or you do not have permissions to access it.
I ended up here with my searches, checking my profile, credentials, roles, etc... but all seems good.
My mistake was not specifying the region in the Copy-RDSDBSnapshot
(in Powershell; equivalent to copy-db-snapshot
in CLI). Since I'm copying across regions for a Disaster Recovery scenario, I must specify the KmsKeyId of the target Region (as it will defer from the source Region). The source region us-east-1 is my default region, so executing this didn't work, it failed with the error above, since i'm not specify anything, it runs in my default region us-east-1 and therefore it can't find the us-west-2 key, just as the error say, it "does not exist" in that region, it's nothing to do with permissions:
Copy-RDSDBSnapshot -SourceDBSnapshotIdentifier $dBSnapshotArn `
-SourceRegion 'us-east-1' `
-TargetDBSnapshotIdentifier $targetSnapshotName `
-KmsKeyId 'arn:aws:kms:us-west-2:xxxxx:key/xxxxx' `
-CopyTag $true -OptionGroupName 'myOptionGroup'
Adding the so called "Common Parameter" Region
did the trick:
Copy-RDSDBSnapshot -SourceDBSnapshotIdentifier $dBSnapshotArn `
-SourceRegion 'us-east-1' `
-TargetDBSnapshotIdentifier $targetSnapshotName `
-KmsKeyId 'arn:aws:kms:us-west-2:xxxxx:key/xxxxx' `
-CopyTag $true -OptionGroupName 'myOptionGroup' `
-Region 'us-west-2' # <-- new line
Upvotes: 2
Reputation: 18482
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(" ")'
Upvotes: 77