Create new EC2 instance with existing EBS volume as root device using CloudFormation

I'm trying to mount an existing volume to a new EC2 Windows instance using CloudFormation. This seems like something that should be possible.

Big Picture

I have a vendor provided AMI which installs some preconfigured software. We want to create a single instance, and we'll change the EC2 instance size occasionally for performance testing. We don't want to lose the data on the single EBS disk that we'll create from the AMI.

Since we're using CloudFormation, if we simply change the AWS::EC2::Instance.InstanceType property and upload the modified stack CloudFormation will a new instance and volume from the AMI. That's not helpful as we'll lose the data we'd have uploaded from the existing disk.

Volumes Method

I tried this script first.

WindowsVolume:
  Type: AWS::EC2::Volume
  Properties:
    AutoEnableIO: true
    AvailabilityZone: "ap-southeast-2b"
    Encrypted: true
    Size: 30
    SnapshotId: snap-0008f111111111
    Tags:
      - Key: Name
        Value:
          Ref: AWS::StackName
    VolumeType: gp2

EC2Instance:
  Type: AWS::EC2::Instance
  InstanceType: t2.micro
  ImageId: ami-663bdc04 # Windows Server stock image
  KeyName: removed
  IamInstanceProfile: removed
  InstanceInitiatedShutdownBehavior: stop
  SecurityGroupIds:
    Fn::Split: [",", "Fn::ImportValue": StackName-ServerSecurityGroup]
  SubnetId:
    !ImportValue StackName-Subnet1
  Volumes:
    - Device: "/dev/sda1"
      VolumeId:
        Ref: WindowsVolume

I got the error message

Invalid value '/dev/sda1' for unixDevice. Attachment point /dev/sda1 is already in use

BlockDeviceMappings Method

Next I tried using BlockDeviceMappings

BlockDeviceMappings:
  - DeviceName: "/dev/sda1"
    Ebs:
      Ref: WindowsVolume

The error message this time was

Value of property Ebs must be an object

VolumeAttachment Method

I've also tried using a VolumeAttachment instead of the Volumes property or a BlockDeviceMapping.

VolAttach:
  Type: AWS::EC2::VolumeAttachment
  Properties:
    Device: "/dev/sda1"
    InstanceId: !Ref EC2Instance
    VolumeId: !Ref WindowsVolume

This gave me the same message as above

Invalid value '/dev/sda1' for unixDevice. Attachment point /dev/sda1 is already in use

Key Question

Has anyone successfully mounted an existing root volume, or a snapshot, to a new EC2 instance? If it's possible what's the proper method?

Alternate Approaches

Happy to hear alternate approaches. For example options I've considered are:

  • Creating the VPC and related resources using CloudFormation, then create the instance manually using the console.
  • Creating the VPC, related resources, and EC2 instance using CloudFormation. From that point stop using CloudFormation and simply use the web console to change instance size.

It is not possible to mount an existing EBS volume when launching an EC2 instance.

When an EC2 instance is launched, the EBS volumes will always be created fresh from the AMI's associated EBS snapshots.

There are some workarounds:

  1. Post launch, stop your EC2 instance, detach the default EBS volume, attach your desired volume, and restart the instance.
  2. Store your needed data on a secondary EBS volume. Then as part of your Cloud Init startup, attach that volume to your EC2 instance.
  3. Adjust instance size outside of CloudFormation.