3

在 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 客户主密钥。

有没有解决的办法?

4

2 回答 2

2

编辑:请参阅下面我的其他答案(https://stackoverflow.com/a/47602790/7692970)以获得更简单的解决方案

要为实例的 EBS 卷指定客户主密钥 (CMK),您必须将RunInstancesRequest与 aCreateVolumeRequest和结合起来AttachVolumeRequest。否则,如果您只是指定true加密,EbsBlockDevice它将使用默认 CMK。

首先创建实例,而不在 的块储存设备映射中指定 EBS 卷RunInstancesRequest,然后单独创建卷,然后附加它们

CreateVolumeRequestwithKmsKeyId()/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);
}

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

于 2017-03-23T23:29:19.593 回答
0

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

https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/ec2/model/EbsBlockDevice.html#setKmsKeyId-java.lang.String-

这已添加到版本 1.11.237 中的 AWS Java 开发工具包中。

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

ebsBlockDevice.setKmsKeyId(keyId);

其中 keyId 可以是 CMK 别名(格式为alias/<alias name>)、密钥 ID(看起来像1234abcd-12ab-34cd-56ef-1234567890ab)或完整的 CMK ARN ( arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab)。

于 2017-12-01T23:12:35.573 回答