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:
- Post launch, stop your EC2 instance, detach the default EBS volume, attach your desired volume, and restart the instance.
- Store your needed data on a secondary EBS volume. Then as part of your Cloud Init startup, attach that volume to your EC2 instance.
- Adjust instance size outside of CloudFormation.