Managing Oracle Cloud Infrastructure iSCSI Block Volume attachments with Terraform. Part 2: Windows Instances

Stephen Cross
Oracle Developers
Published in
4 min readJan 20, 2019

My initial post on Managing Oracle Cloud Infrastructure iSCSI Block Volume attachments with Terraform only covered the steps for Oracle Linux instances. In this article we’ll look at how the same approach can be used for attaching iSCSI block volumes to Windows instances.

Enable remote-exec provisioning with WinRM

First we need to enable the instance for remote provisioning on creation. The Oracle Cloud Infrastructure Windows images are enabled for cloudbase-init and WinRM (see Oracle-Provided Images), but before being able to use the Terraform remote-exec provisioner with WinRM there are some network and instance configuration pre-requisites that must be satisfied.

Enable ingress WinRM traffic

Configure your subnet security rules to allow ingress WinRM traffic to port 5986. For example the following rule can be added to the oci_core_security_list for the subnet the instance will be created in.

  # allow inbound winrm traffic
ingress_security_rules {
protocol = "6"
source = "0.0.0.0/0"
stateless = false
tcp_options {
"min" = 5986
"max" = 5986
}
}

Enable a remote access Administrator account

We need to enable a suitable remote management account. You should follow your own company security guidelines and policies for creation and management remote access accounts.

The default opc administrator account created for the Oracle provided Windows Server images is created with the password expiry enabled, which requires the user to change the account password on first login, this blocks any remote execution until the password has been manually changed. To enable remote access using the opc account during provisioning we need to disable the password expiry in the cloudbase-init startup script.

#ps1_sysnative
cmd /C 'wmic UserAccount where Name="opc" set PasswordExpires=False'

For details on how to including cloud init scripts in the instance configuration see Automating Instance Initialization with Terraform on Oracle Cloud Infrastructure: Part 2

Terraform remote-exec provisioner WinRM connection settings

Configure the resources connection block for the remote-exec provisioner with the following settings

  connection {
type = "winrm"
insecure = true
https = true
port = 5986
host = "${oci_core_instance.instance1.public_ip}"
user = "${data.oci_core_instance_credentials.instance1.username}"
password = "${data.oci_core_instance_credentials.instance1.password}"
}

As we are using the opc account we can get the initial password from the oci_core_instance_credentials data source.

data "oci_core_instance_credentials" "instance1" {
instance_id = "${oci_core_instance.instance1.id}"
}

iSCSI Block Volume attachment

As I covered in Managing Oracle Cloud Infrastructure iSCSI Block Volume attachments with Terraform, the process of attaching a block volume to an instance involves multiple steps to attach the block volume resource, connect the iSCSI device in the OS, and finally mount the volume.

The Oracle Cloud Infrastructure console provides the details of the required iSCSI PowerShell commands that need to be executed after attaching a volume in the Block Volume details page.

Oracle Cloud Infrastructure Block Volume iSCSI Commands and Information

The first two commands only need to be execute once to enable the iSCSI service, these can be added to the Instances cloudbase-init script to initialize on startup.

#ps1_sysnative
Set-Service -Name msiscsi -StartupType Automatic
Start-Service msiscsi

The device specific commands are included in a remote-exec provisioner for the oci_core_volume_attachment resource so they only run on attachment, after the instance has launched. To cleanly disconnect when detaching the block volume we also include a destroy time provisioner. The iSCSI commands differ for Windows Server 2008 and Windows Server 2012/2016

Windows Server 2012/2016

  # register and connect the iSCSI block volume
provisioner "remote-exec" {
inline = [
" Powershell New-IscsiTargetPortal –TargetPortalAddress ${self.ipv4}",
" Powershell Connect-IscsiTarget -NodeAddress ${self.iqn} -TargetPortalAddress ${self.ipv4} -IsPersistent $True",
]
}
# disconnect and unregister on destroy
provisioner "remote-exec" {
when = "destroy"
on_failure = "continue"
inline = [
" Powershell Disconnect-IscsiTarget -NodeAddress ${self.iqn} -Confirm:$false",
" Powershell Remove-IscsiTargetPortal -TargetPortalAddress ${self.ipv4} -Confirm:$false",
]
}

Note: the proceeding spaces before the Powershell command seem arbitrary but actually make a difference. I don’t know why, but it works :-)

Windows Server 2008

On Windows 2008 we need to use the iscsicli.exe command instead

  # register and connect the iSCSI block volume
provisioner "remote-exec" {
inline = [
"iscsicli.exe QAddTargetPortal ${self.ipv4}",
"iscsicli.exe QLoginTarget ${self.iqn}",
"iscsicli.exe PersistentLoginTarget ${self.iqn} * ${self.ipv4} ${self.port} * * * * * * * * * * * * * *"
]
}
# unregister on destroy
provisioner "remote-exec" {
when = "destroy"
on_failure = "continue"
inline = [
"iscsicli.exe RemovePersistentTarget Root\iScsiPrt\0000_0 ${self.iqn} * ${self.ipv4} ${self.port}"
"iscsicli.exe RemoveTarget ${self.iqn}",
"iscsicli.exe RemoveTargetPortal ${self.ipv4} ${self.port}",
]
}

Mounting the block volumes

In my original article on block volume attachment I covered how the deterministically mount the volumes using the unique iSCSI device ids to ensure each mount is consistently allocated the same mount point/drive. To be honest my Powershell skills are minimal at best, and I just I don’t know how to do that with Windows, so this section is primarily left as an exercise for the reader.

instead of providing bad advise its better to provide no advise at all.

However, for a very basic use case, if you just need to initialize and format a single new attached volume you can use the following Powershell commands. Do not add these commands to the oci_core_volume_attachment resource provisioner without some additional scripting to prevent destroying data on an already initialized volume.

Initialize-Disk -Number 1
New-Partition -DiskNumber 1 -UseMaximumSize -AssignDriveLetter
Powershell Format-Volume -DriveLetter D -Confirm:$false"

The final config

Here is there complete example to launch a Windows Server 2016 Standard Edition instance with an attached iSCSI Block Volume

Related Articles

--

--