Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AWS Java SDK:为EBS指定KMS密钥Id_Java_Amazon Web Services_Aws Sdk_Amazon Kms - Fatal编程技术网

AWS Java SDK:为EBS指定KMS密钥Id

AWS Java SDK:为EBS指定KMS密钥Id,java,amazon-web-services,aws-sdk,amazon-kms,Java,Amazon Web Services,Aws Sdk,Amazon Kms,在AWS Java SDK 1.10.69中,我可以启动一个实例并为该实例指定EBS卷映射: RunInstancesRequest runInstancesRequest = new RunInstancesRequest(); String userDataString = Base64.encodeBase64String(userData.toString().getBytes()); runInstancesRequest .with

在AWS Java SDK 1.10.69中,我可以启动一个实例并为该实例指定EBS卷映射:

    RunInstancesRequest runInstancesRequest = new RunInstancesRequest();

    String userDataString = Base64.encodeBase64String(userData.toString().getBytes());

    runInstancesRequest
            .withImageId(machineImageId)
            .withInstanceType(instanceType.toString())
            .withMinCount(minCount)
            .withMaxCount(maxCount)
            .withKeyName(sshKeyName)
            .withSecurityGroupIds(securityGroupIds)
            .withSubnetId(subnetId)
            .withUserData(userDataString)
            .setEbsOptimized(true);


    final EbsBlockDevice ebsBlockDevice = new EbsBlockDevice();
    ebsBlockDevice.setDeleteOnTermination(true);
    ebsBlockDevice.setVolumeType(VolumeType.Gp2);
    ebsBlockDevice.setVolumeSize(256);
    ebsBlockDevice.setEncrypted(true);

    final BlockDeviceMapping mapping = new BlockDeviceMapping();
    mapping.setDeviceName("/dev/sdb");
    mapping.setEbs(ebsBlockDevice);
似乎目前我只能在卷上启用/禁用加密,而不能指定要为卷使用的KMS客户主密钥


有办法解决这个问题吗?

编辑:请参阅下面我的另一个答案(),以获得更简单的解决方案

要为实例的EBS卷指定客户主密钥(CMK),必须将
RunInstanceRequest
CreateVolumeRequest
AttachVolumeRequest
组合起来。否则,如果您仅为
ebsblock设备
上的加密指定
true
,它将使用默认的CMK

首先创建实例,而不在
runInstanceRequest
的块设备映射中指定EBS卷,然后分别创建实例

CreateVolumeRequest
具有
和kmskeyid()
/
setKmsKeyId()
选项

例如,更新代码可能如下所示:

RunInstancesRequest runInstancesRequest = new RunInstancesRequest();

String userDataString = Base64.encodeBase64String(userData.toString().getBytes());

runInstancesRequest
        .withImageId(machineImageId)
        .withInstanceType(instanceType.toString())
        .withMinCount(minCount)
        .withMaxCount(maxCount)
        .withKeyName(sshKeyName)
        .withSecurityGroupIds(securityGroupIds)
        .withSubnetId(subnetId)
        .withUserData(userDataString)
        .setEbsOptimized(true);
RunInstancesResult runInstancesResult = ec2Client.runInstances(runInstancesRequest);

for (Instance instance : runInstancesResult.getReservation()) {
    CreateVolumeRequest volumeRequest = new CreateVolumeRequest()
            .withAvailabilityZone(instance.getPlacement().getAvailabilityZone())
            .withKmsKeyId(/* CMK id or alias/yourkeyaliashere */)
            .withEncrypted(true)
            .withSize(256)
            .withVolumeType(VolumeType.Gp2);
    CreateVolumeResult volumeResult = ec2Client.createVolume(volumeRequest);
    AttachVolumeRequest attachRequest = new AttachVolumeRequest()
            .withDevice("/dev/sdb")
            .withInstanceId(instance.getInstanceId())
            .withVolumeId(volumeResult.getVolume().getVolumeId());
    ec2Client.attachVolume(attachRequest);
}

注意:如果在实例元数据中使用块设备映射,则将卷附加到正在运行的实例时不会更新该映射。要使其更新,您可以停止/启动实例。

好消息!AWS刚刚添加了在启动实例时在块设备映射中指定CMK密钥ID的功能

这是在版本1.11.237中添加到AWS Java SDK的

因此,您现在只需在原始代码中添加

ebsBlockDevice.setKmsKeyId(keyId);
其中keyId可以是CMK别名(格式为
alias/
),keyId(看起来像
1234abcd-12ab-34cd-56ef-1234567890ab
)或完整的CMK ARN(
ARN:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab