Я пытаюсь использовать группы Auto Scaling в AWS для создания и управления экземплярами, созданными из AMI с зашифрованными моментальными снимками, которые были зашифрованы CMK, принадлежащим другой учетной записи AWS.
Я продолжаю получать сообщение об ошибке «Client.InternalError: Ошибка клиента при запуске». В соответствии со сценарием 2 в https://docs.aws.amazon.com/autoscaling/ec2/userguide/ts-as-instancelaunchfailure.html#ts-as-instancelaunchfailure-12 мне нужно создать грант для CMK с ролью, связанной со службой группы Auto Scaling, в качестве получателя гранта.
Я попытался следовать рекомендациям в документации AWS и в https://forums.aws.amazon.com/thread.jspa?threadID=277523 для настройки гранта.
Однако я продолжаю получать AccessDeniedException, говорящий о том, что мой пользователь не авторизован для выполнения kms:CreateGrant на CMK.
Я чувствую, что полностью следовал инструкциям, но это не работает. Я надеюсь, что кто-то может дать некоторое представление.
Я общался с сотрудником AWS, который столкнулся с той же проблемой, пока не перечитал сообщение на форуме. Ключевой строкой в случае 2, шаг 4, является «Условие kms:GrantIsForAWSResource не включено, чтобы позволить пользователю или роли IAM в учетной записи 111122223333 создать грант на следующем шаге».
Другими словами, вам необходимо удалить это условие из политики ключей по умолчанию для CMK, управляемого клиентом.
Инструкции могли бы сделать это требование гораздо более явным, но технически оно существует и решает проблему.
Обновлено: чтобы уточнить, я собираюсь включить JSON по умолчанию и измененный ниже.
Ниже приведена политика ключей по умолчанию, как показано в https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default.
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-2",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::111122223333:root"},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {"AWS": [
"arn:aws:iam::111122223333:user/KMSAdminUser",
"arn:aws:iam::111122223333:role/KMSAdminRole"
]},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {"AWS": [
"arn:aws:iam::111122223333:user/KMSUser",
"arn:aws:iam::111122223333:role/KMSRole",
"arn:aws:iam::444455556666:root"
]},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {"AWS": [
"arn:aws:iam::111122223333:user/KMSUser",
"arn:aws:iam::111122223333:role/KMSRole",
"arn:aws:iam::444455556666:root"
]},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*",
"Condition": {"Bool": {"kms:GrantIsForAWSResource": "true"}}
}
]
}
Ключевым моментом является удаление условия для «kms:GrantIsForAWSResource», как показано ниже.
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-2",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::111122223333:root"},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {"AWS": [
"arn:aws:iam::111122223333:user/KMSAdminUser",
"arn:aws:iam::111122223333:role/KMSAdminRole"
]},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {"AWS": [
"arn:aws:iam::111122223333:user/KMSUser",
"arn:aws:iam::111122223333:role/KMSRole",
"arn:aws:iam::444455556666:root"
]},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {"AWS": [
"arn:aws:iam::111122223333:user/KMSUser",
"arn:aws:iam::111122223333:role/KMSRole",
"arn:aws:iam::444455556666:root"
]},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*"
}
]
}
Прочитав вашу полезную информацию, я смог решить эту проблему, поэтому решил опубликовать свои выводы и для других.
Вот что я сделал, чтобы позволить пользовательскому ключу KMS (CMK) из учетной записи «dev» получить доступ и использовать «SharedAccountId».
Для этого примера предположим, что учетная запись «dev» находится в us-west-2, а «SharedAccount» — в us-east-1.
Cloudformation для создания ключа:
ПРИМЕЧАНИЕ. Запустите этот стек cloudformation в учетной записи «Dev», которая в этом примере находится в us-west-2.
{
"Description": "Creates a KMS key used to encrypt snapshots and allows sharing with another account.",
"Outputs": {
"AMIKeyIdOutput": {
"Description": "The KMS Key id used to encrypted snapshots.",
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}-kmskeyid"
}
},
"Value": {
"Ref": "AMIKmsKey"
}
},
"AMIKmsAliasOutput": {
"Description": "The KMS key alias used to encrypted snapshots.",
"Export": {
"Name": {
"Fn::Sub": "${AWS::StackName}-kmsalias"
}
},
"Value": {
"Ref": "AMIKmsAlias"
}
}
},
"Parameters": {
"SharedAccountId": {
"AllowedPattern": "^(?!\\s*$).+",
"ConstraintDescription": "You must supply a account id you want to share with.",
"Description": "The account id you want to share this key with.",
"Type": "String"
}
},
"Resources": {
"AMIKmsAlias": {
"Properties": {
"AliasName": {
"Fn::Sub": "alias/amiencryptionkey"
},
"TargetKeyId": {
"Ref": "AMIKmsKey"
}
},
"Type": "AWS::KMS::Alias"
},
"AMIKmsKey": {
"Properties": {
"Description": "AMI encryption key.",
"EnableKeyRotation": "true",
"Enabled": "true",
"KeyPolicy": {
"Statement": [
{
"Action": [
"kms:*"
],
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Sub": "arn:aws:iam::${AWS::AccountId}:root"
}
},
"Resource": [
"*"
],
"Sid": "Allow access for Key Administrators"
},
{
"Action": [
"kms:Decrypt",
"kms:Encrypt",
"kms:DescribeKey",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Effect": "Allow",
"Principal": {
"AWS": [
{
"Fn::Join": [
"",
[
"arn:aws:iam::",
{"Ref":"SharedAccountId"},
":root"
]
]
},
{
"Fn::Join": [
"",
[
"arn:aws:iam::",
{"Ref":"SharedAccountId"},
":role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"
]
]
},
{
"Fn::Sub": "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"
}
]
},
"Resource": [
"*"
],
"Sid": "Allow use of the key"
},
{
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Effect": "Allow",
"Principal": {
"AWS": [
{
"Fn::Sub": "arn:aws:iam::${AWS::AccountId}:root"
},
{
"Fn::Join": [
":",
[
"arn:aws:iam:",
{"Ref":"SharedAccountId"},
"root"
]
]
},
{
"Fn::Join": [
"",
[
"arn:aws:iam::",
{"Ref":"SharedAccountId"},
":role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"
]
]
},
{
"Fn::Sub": "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"
}
]
},
"Resource": [
"*"
],
"Sid": "Allow attachment of persistent resources."
}
],
"Version": "2012-10-17"
}
},
"Type": "AWS::KMS::Key"
}
}
}
Также важно отметить, что некоторые принципы не нужны, но их должно хватить для начала. После настройки ключа kms в соответствии с приведенной выше логикой вам необходимо выполнить следующую команду cli:
ПРИМЕЧАНИЕ. В этом примере
* SharedAccountId в us-east-1
* Ключ KMS находится в учетной записи «Dev», которая находится в us-west-2.
aws kms create-grant \
--region us-east-1 \
--profile SharedAccountProfile \
--key-id arn:aws:kms:us-west-2:<DevAccountId>:key/<KMS_KEY_ID From above CF template> \
--grantee-principal arn:aws:iam::<SharedAccountId>:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling \
--operations "Encrypt" "Decrypt" "ReEncryptFrom" "ReEncryptTo" "GenerateDataKey" "GenerateDataKeyWithoutPlaintext" "DescribeKey" "CreateGrant"
Это должно сработать. Теперь вы можете обмениваться зашифрованными образами AMI между учетными записями и разрешать группам автомасштабирования запускать экземпляры с ними.
Спасибо, что поделились тем, что вы здесь сделали! Я также собираюсь отредактировать свой ответ, чтобы он был более явным.