Question: How can I map drive letters to Amazon EBS volumes in Windows using CloudFormation?

I want to map drive letters to Amazon Elastic Block Store (Amazon EBS) volumes in Windows using AWS CloudFormation.

Short descriptionYou can use a custom script that runs during boot to map drive letters to Amazon EBS volumes in Windows with CloudFormation.Resolution1.    Launch a Windows instance using the Amazon Machine Image (AMI) for Windows Server 2016 Base or later.2.    (Optional) Create a D drive manually, and then put a data file in the D drive. For more information, see Make an Amazon EBS volume available for use on Windows.3.    Use the ShutDown with the Sysprep option to create an AMI from your instance. For more information, see Configure a Windows instance using EC2Launch.4.    Create a CloudFormation stack based on the following template.Permission is hereby granted, free of charge, to any person obtaining a copy of thissoftware and associated documentation files (the "Software"), to deal in the Softwarewithout restriction, including without limitation the rights to use, copy, modify,merge, publish, distribute, sublicense, and/or sell copies of the Software, and topermit persons to whom the Software is furnished to do so.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR APARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHTHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTIONOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THESOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.{  "AWSTemplateFormatVersion": "2010-09-09",  "Description": "AWS CloudFormation template AV Group, Launch Config for EC2",  "Resources": {    "DBServer": {      "Type": "AWS::EC2::Instance",      "Metadata" : {        "AWS::CloudFormation::Init" : {          "config" : {          "files" : {            "c:\\cfn\\cfn-hup.conf" : {            "content" : { "Fn::Join" : ["", [              "[main]\n",              "stack=", { "Ref" : "AWS::StackId" }, "\n",              "region=", { "Ref" : "AWS::Region" }, "\n"              ]]}            },            "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf" : {            "content": { "Fn::Join" : ["", [              "[cfn-auto-reloader-hook]\n",              "triggers=post.update\n",              "path=Resources.DBServer.Metadata.AWS::CloudFormation::Init\n",              "action=cfn-init.exe -v -s ", { "Ref" : "AWS::StackId" },                " -r DBServer",                " --region ", { "Ref" : "AWS::Region" }, "\n"            ]]}            },            "c:\\cfn\\hooks.d\\drives.diskpart.txt" : {              "content": { "Fn::Join" : ["", [                "select disk 2\n",                "attributes disk clear readonly\n",                "clean\n",                "online disk\n",                "convert gpt\n",                "create partition primary\n",                "format quick fs=ntfs label=","\"","ORATEMP","\"","\n",                "assign letter=X\n",                "select disk 3\n",                "attributes disk clear readonly\n",                "clean\n",                "online disk\n",                "convert gpt\n",                "create partition primary\n",                "format quick fs=ntfs label=","\"","ORADATA","\"","\n",                "assign letter=S\n",                "select disk 1\n",                "online disk\n"              ]]}},              "c:\\cfn\\hooks.d\\renamedrives.ps1" : {                "content": { "Fn::Join" : ["", [                  "diskpart /s c:\\cfn\\hooks.d\\drives.diskpart.txt\n"              ]]}}          },          "commands" : {            "1-rename-drives" : {              "command" : "powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -File c:\\cfn\\hooks.d\\renamedrives.ps1",              "waitAfterCompletion" : "0"            },            "2-signal-success" : {              "command" : { "Fn::Join" : [ "", [                "cfn-signal.exe -e %ERRORLEVEL% \"",                { "Fn::Base64" : { "Ref" : "WindowsServerWaitHandle" }},                "\""]]              }            }          },          "services" : {            "windows" : {            "cfn-hup" : {              "enabled" : "true",              "ensureRunning" : "true",              "files" : ["c:\\cfn\\cfn-hup.conf", "c:\\cfn\\hooks.d\\cfn-auto-reloader.conf"]            }            }          }          }        }      },      "Properties": {        "ImageId": "ami-01xxxxxxxxxx",        "InstanceType": "m4.xlarge",        "KeyName": "xxxxxxxx",        "BlockDeviceMappings": [          {"DeviceName": "xvdg","Ebs":{"VolumeSize":"20"}},          {"DeviceName": "xvdm","Ebs":{"VolumeSize":"20"}}        ],        "Tags": [ {          "Key": "Name",          "Value": {"Fn::Join": ["-", ["DB",{"Ref": "AWS::StackName"}]]}        }],        "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [          "<powershell>\n",          "cfn-init.exe -v -s ", { "Ref" : "AWS::StackId" },          " -r DBServer",          " --region ", { "Ref" : "AWS::Region" }, "\n",          "</powershell>"        ]]}}      }    },    "WindowsServerWaitHandle" : {      "Type" : "AWS::CloudFormation::WaitConditionHandle"    },    "WindowsServerWaitCondition" : {      "Type" : "AWS::CloudFormation::WaitCondition",      "DependsOn" : "DBServer",      "Properties" : {        "Handle" : {"Ref" : "WindowsServerWaitHandle"},        "Timeout" : "1800"      }    }  }}Note: The preceding template includes a script that creates Disk 2 with drive letter X and Disk 3 with drive letter S.The following script is part of the template shown in step 4 and is called out here for emphasis. The script configures the volume with the master boot record (MBR) partition structure, formats the volume as an NTFS volume, and then assigns a drive letter."select disk 2\n","attributes disk clear readonly\n","clean\n","online disk\n","convert gpt\n","create partition primary\n","format quick fs=ntfs label=","\"","ORATEMP","\"","\n","assign letter=X\n","select disk 3\n","attributes disk clear readonly\n","clean\n","online disk\n","convert gpt\n","create partition primary\n","format quick fs=ntfs label=","\"","ORADATA","\"","\n","assign letter=S\n","select disk 1\n","online disk\n"5.    Move the script to the files section of AWS::CloudFormation::Init, and then run the script using the command section.Note: Disk0 is always the root volume.Tip: Windows Explorer displays the drive sequence alphabetically. To find the disk number assigned to the disk letter from your CloudFormation template, run the diskmgmt command in the Disk Management utility.6.    Deploy your instance, and then connect to your instance using the Remote Desktop Protocol (RDP).For this example, your instance now has four drives. Your D drive has the data file that you saved in step 1.Drive D          =====> Drive with the data fileDrive S          =====> This is the Disk 3 Drive X          =====> This is the Disk 2