In this tutorial, we will use AWS Auto-scaling as an example of how to grant permission to the Auto-scaling Service to read remote/local kms keys and also be able to grant permission to instances created by it’s launch templates/configuration.
Create a grant with CLI
Grant from remote account that has a multi-region shared kms key to another account on same region:
Ps: This can also be used for same account, just use asg_role_account_id
with the same account.
aws kms create-grant \\
--region us-west-2 \\
--key-id arn:aws:kms:us-west-2:<kms_key_account_id>:key/mrk-xxxxxx \\
--grantee-principal arn:aws:iam::<asg_role_account_id>:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling \\
--operations "Encrypt" "Decrypt" "ReEncryptFrom" "ReEncryptTo" "GenerateDataKey" "GenerateDataKeyWithoutPlaintext" "DescribeKey" "CreateGrant" \\
--profile aws-config-profile
Create a grant with Terraform:
If you need to grant this using Terraform for your existing process, here is the part of the code that you need to implement. (This recipe is incomplete. It is intended just to show the aws_kms_grant
usage)
locals {
account_id = data.aws_caller_identity.current.account_id
create_authorizations = true
create_external_auth = false
keys_authorize = ["ebs"]
keys_region1 = {
"backup" = { region = "us-west-2" }
"s3" = { region = "us-west-2" }
"cw_logs" = { region = "us-west-2" }
"cloudtrail" = { region = "us-west-2" }
"ebs" = { region = "us-west-2" }
}
resource "aws_kms_grant" "this" {
for_each = { for k, v in local.keys_region1 : k => v if contains(local.keys_authorize, k) }
name = each.value.name
key_id = "<kms-key-id>"
grantee_principal = "arn:aws:iam::${local.account_id}:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"
operations = ["Encrypt", "Decrypt", "ReEncryptFrom", "ReEncryptTo", "GenerateDataKey", "GenerateDataKeyWithoutPlaintext", "DescribeKey", "CreateGrant"] # Put your requirements in here
dynamic "constraints" {
for_each = length(lookup(each.value, "constraints", {})) == 0 ? [] : [each.value.constraints]
content {
encryption_context_equals = try(constraints.value.encryption_context_equals, null)
encryption_context_subset = try(constraints.value.encryption_context_subset, null)
}
}
retiring_principal = null # implement this as needed
grant_creation_tokens = null # implement this as needed
retire_on_delete = true # implement this as needed
}
Listing grants
aws kms list-grants \\
--key-id arn:aws:kms:us-west-2:<kms_key_account_id>:key/mrk-xxxxxx \\
--region us-west-2 \\
--grantee-principal arn:aws:iam::<asg_role_account_id>:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling \\
--profile aws-config-profile
Revoking a grant
Example of revoking a given grant after getting grant-id with the list-grants command:
aws kms revoke-grant \\
--key-id arn:aws:kms:us-west-2:<kms_key_account_id>:key/mrk-xxxxxx \\
--grant-id ea24d88d6dd6f1962191fabedb01cd64bce1f72ef7e9c9f84acb7ad4582280f4
If you need, you can also:
Describe a KMS key
$ aws kms describe-key --key-id arn:aws:kms:us-west-2:<kms_key_account_id>:key/mrk-xxxxxx
{
"KeyMetadata": {
"Origin": "AWS_KMS",
"KeyId": "mrk-xxxxxx",
"Description": "",
"KeyManager": "CUSTOMER",
"MultiRegion": false,
"Enabled": false,
"KeyState": "Disabled",
"KeyUsage": "ENCRYPT_DECRYPT",
"CreationDate": 1502911447.321,
"Arn": "arn:aws:kms:us-west-2:<kms_key_account_id>:key/mrk-xxxxxx",
"AWSAccountId": "<kms_key_account_id>"
"KeySpec": "SYMMETRIC_DEFAULT",
"CustomerMasterKeySpec": "SYMMETRIC_DEFAULT",
"EncryptionAlgorithms": [
"SYMMETRIC_DEFAULT"
]
}
}
Disable a KMS Key
aws kms disable-key --key-id arn:aws:kms:us-west-2:<kms_key_account_id>:key/mrk-xxxxxx
Enable a KMS Key
aws kms enable-key --key-id arn:aws:kms:us-west-2:<kms_key_account_id>:key/mrk-xxxxxx