Context:
I'm trying to programmatically encrypt existing unencrypted EBS volumes attached to EC2's in my AWS environment via python and Boto3.
My process is as follows (assuming AWS credentials are already setup on the machine from where my Python script is being run from):
- Create unencrypted snapshot(s) from the existing volume(s) attached to an EC2.
- Create encrypted volume(s) from the unencrypted snapshot(s) using an AWS KMS key.
- Stop the EC2 with the unencrypted volume(s) in question.
- Detach the existing unencrypted EBS volume(s) from the EC2 (done via
detach_volume()). - Attach the encrypted volume(s) we made in step 2 to the EC2.
- Start the EC2 again. Hopefully, the volumes attached to the EC2 work fine in terms of the file system and should now be encrypted.
Problem:
The issue is in step 4. According to the AWS Boto3 SDK Docs, when using the detach_volume() method of the EC2.Instance resource, one should make sure to "unmount any file systems on the device within your operating system before detaching the volume."
According to another AWS guide, this can be done via something like sudo umount -d <DEVICE_NAME> e.g. sudo umount -d /dev/sdh
However, the above is a Linux shell command, and not something that can be executed via boto3.
Question:
How can I programmatically run that Linux shell command to unmount the filesystem on each EC2 instance that my Python script targets so that I can stop the EC2 and safely detach the volumes attached to it?
Would I have to SSH into each instance via some Python SSH library (e.g. Paramiko) and run the command?
I think if you can in your code sleep for a minute or two till the instance become completely stopped, or query the instance state and only execute step 5 when state == 'stopped', that would do it. You have to unmount when you are detaching a volume on a running ec2, not a stopped one.