Bra*_*rad 5 windows amazon-ec2 drive-letter chef-infra terraform
我正在使用 terraform 和 Chef 创建多个 aws ebs 卷并将它们附加到 EC2 实例。
问题是我希望能够为每个 ebs 卷指定一个特定的 Windows 驱动器号。问题是当 EC2 实例被实例化时,窗口只给它顺序驱动器号(D、E、F 等)
某些驱动器的大小相同,因此我不一定会根据驱动器大小进行重命名。有谁知道用 terraform 或厨师来做到这一点的方法。我的 google foo 没有找到任何东西。
当然,这必须为其他人提出吗?
我确实看到了使用 EC2Config Windows GUI 来设置它们的参考,但重点是自动化该过程,因为最终我希望 Chef 安装 SQL 服务器,并且某些数据预计会出现在某些驱动器号上。
这似乎有效 - 尽管我确实想知道是否有更简单的方法。
function Convert-SCSITargetIdToDeviceName
{
param([int]$SCSITargetId)
If ($SCSITargetId -eq 0) {
return "/dev/sda1"
}
$deviceName = "xvd"
If ($SCSITargetId -gt 25) {
$deviceName += [char](0x60 + [int]($SCSITargetId / 26))
}
$deviceName += [char](0x61 + $SCSITargetId % 26)
return $deviceName
}
Get-WmiObject -Class Win32_DiskDrive | ForEach-Object {
$DiskDrive = $_
$Volumes = Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='$($DiskDrive.DeviceID)'} WHERE AssocClass=Win32_DiskDriveToDiskPartition" | ForEach-Object {
$DiskPartition = $_
Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='$($DiskPartition.DeviceID)'} WHERE AssocClass=Win32_LogicalDiskToPartition"
}
If ($DiskDrive.PNPDeviceID -like "*PROD_PVDISK*") {
$BlockDeviceName = Convert-SCSITargetIdToDeviceName($DiskDrive.SCSITargetId)
If ($BlockDeviceName -eq "xvdf") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="D:"; Label="SQL Data"} };
If ($BlockDeviceName -eq "xvdg") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="L:"; Label="SQL Logs"} };
If ($BlockDeviceName -eq "xvdh") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="R:"; Label="Report Data"} };
If ($BlockDeviceName -eq "xvdi") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="T:"; Label="Temp DB"} };
If ($BlockDeviceName -eq "xvdj") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="M:"; Label="MSDTC"} };
If ($BlockDeviceName -eq "xvdk") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="B:"; Label="Backups"} };
} ElseIf ($DiskDrive.PNPDeviceID -like "*PROD_AMAZON_EC2_NVME*") {
$BlockDeviceName = Get-EC2InstanceMetadata "meta-data/block-device-mapping/ephemeral$($DiskDrive.SCSIPort - 2)"
If ($BlockDeviceName -eq "xvdf") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="D:"; Label="SQL Data"} };
If ($BlockDeviceName -eq "xvdg") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="L:"; Label="SQL Logs"} };
If ($BlockDeviceName -eq "xvdh") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="R:"; Label="Report Data"} };
If ($BlockDeviceName -eq "xvdi") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="T:"; Label="Temp DB"} };
If ($BlockDeviceName -eq "xvdj") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="M:"; Label="MSDTC"} };
If ($BlockDeviceName -eq "xvdk") { $drive = gwmi win32_volume -Filter "DriveLetter = '$($Volumes.DeviceID)'"; Set-WmiInstance -input $drive -Arguments @{DriveLetter="B:"; Label="Backups"} };
} Else {
write-host "Couldn't find disks";
}
}
Run Code Online (Sandbox Code Playgroud)
如果您考虑此链接中的表格: https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-volumes.html
您可以看到在 EBS 上,第一行是:
Bus Number 0, Target ID 0, LUN 0 /dev/sda1
Bus Number 0, Target ID 1, LUN 0 xvdb
Run Code Online (Sandbox Code Playgroud)
EC2 始终将磁盘 0 (/dev/sda1) 设置为 C:
所以您知道,当您运行“New-Partition -DiskNumber 1 -UseMaximumSize -IsActive -AssignDriveLetter”时,您将获得 D: 。
因此,如果您在 Builders 中使用以下卷通过 Packer 预置 AMI 映像(本示例中只有两个卷,但您可以执行任意多个卷):
"launch_block_device_mappings": [{
"device_name": "/dev/sda1",
"volume_size": 30,
"volume_type": "gp2",
"delete_on_termination": true
},
{
"device_name": "xvdb",
"volume_size": 30,
"volume_type": "gp2",
"delete_on_termination": true
}]
Run Code Online (Sandbox Code Playgroud)
..您可以计划,知道 xvd[ b ] 实际上是要映射的内容后面的两个字母。
然后使用 Terraform 启动此多卷 AMI 的 EC2 实例,并将其放在 aws_instance 资源的 user_data 部分中:
user_data = <<EOF
<powershell>
Initialize-Disk -Number 1 -PartitionStyle "MBR"
New-Partition -DiskNumber 1 -UseMaximumSize -IsActive -AssignDriveLetter
Format-Volume -DriveLetter d -Confirm:$FALSE
Set-Partition -DriveLetter D -NewDriveLetter S
</powershell>
EOF
Run Code Online (Sandbox Code Playgroud)
这些Set-Partition -DriveLetter D -NewDriveLetter S行用于将已知的顺序驱动器重命名为您习惯的任何字母。就我而言,他们想要 D: 作为 S: - 只需重复此行即可将 E: 重命名为 X: 或您需要的任何内容。
希望这可以帮助。
更新: 还有另一种方法(Server 2016 up),当我发现 Sysprep 会破坏所有被烘焙到 AMI 映像中的映射时,我发现了这种方法。
您必须在 C:\ProgramData\Amazon\EC2-Windows\Launch\Config 中提供 DriveLetterMappingConfig.json 文件才能进行映射。文件的格式为:
{
"driveLetterMapping": [
{
"volumeName": "sample volume",
"driveLetter": "H"
}
]
}
Run Code Online (Sandbox Code Playgroud)
...只是,默认情况下,我的驱动器没有卷名称;他们是空白的。回到 1980 年的旧“LABEL”命令。将 D: 驱动器标记为volume2。所以该文件看起来像:
{
"driveLetterMapping": [
{
"volumeName": "volume2",
"driveLetter": "S"
}
]
}
Run Code Online (Sandbox Code Playgroud)
运行 C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeDisks.ps1 测试此工作正常(D: 变为 S:)
因此,现在,回到 Packer,我还需要在 C:\ProgramData\Amazon\EC2-Windows\Launch\Config 中使用此 DriveLetterMappingConfig.json 文件配置映像,以确保我在 AMI 的 S: 上执行的所有驱动器工作都正常返回实例上的 S:。(我将该文件与我们要安装在盒子上的所有其他垃圾一起放入 S3 存储桶中。)
我将磁盘内容放入 .ps1 并从配置程序中调用它:
{“类型”:“powershell”,“脚本”:“./setup_two_drive_names_c_and_s.ps1”
},
其中上面的 .ps1 是:
# Do volume config of the two drives
write-host "Setting up drives..."
Initialize-Disk -Number 1 -PartitionStyle "MBR"
New-Partition -DiskNumber 1 -UseMaximumSize -IsActive -AssignDriveLetter
Format-Volume -DriveLetter d -Confirm:$FALSE
label c: "volume1"
label d: "volume2"
Set-Partition -DriveLetter D -NewDriveLetter S
# Now insert DriveLetterMappingConfig.json file into C:\ProgramData\Amazon\EC2-Windows\Launch\Config to ensure instance starts with correct drive mappings
Write-Host "S3 Download: DriveLetterMappingConfig.json"
Read-S3Object -BucketName ********* -Key DriveLetterMappingConfig.json -File 'c:\temp\DriveLetterMappingConfig.json'
Write-Host "Copying DriveLetterMappingConfig.json to C:\ProgramData\Amazon\EC2-Windows\Launch\Config..."
Copy-Item "c:\temp\DriveLetterMappingConfig.json" -Destination "C:\ProgramData\Amazon\EC2-Windows\Launch\Config\DriveLetterMappingConfig.json" -Force
Write-Host "Set Initialze Disks to run on every boot..."
C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeDisks.ps1 -Schedule
Run Code Online (Sandbox Code Playgroud)
是的,没有理由给c贴上标签:但我很高兴......
最后一行带有“-Schedule”参数意味着每次启动时都会发生这种情况。