There are many reasons why you would add a virtual network interface card (VNIC) to a Windows Server instance in Oracle Cloud Infrastructure Compute. This set of instructions allows the full automation in Oracle Cloud to create a Windows Server instance with multiple VNICs that reside in multiple subnets. We cover the current manual steps to create a second VNIC, then take you through the automation pieces necessary to create an instance with a second VNIC. The automation uses a combination of Terraform and PowerShell to create and configure the Windows Server instance.
There are a few items that we don’t discuss in this post. We’re not covering the building of the VCN, subnets, or other infrastructure components. Also, we don’t discuss how to set up your Terraform or other languages or coding scenarios that you can use to create a second VNIC in a Windows server.
The Manual Process
The process outlined in the documentation describes the manual process where once you have the instance up and running you use the console to create the VNIC. Use the following core instructions:
- Create the Windows Server instance.
- Add a secondary VNIC.
- Download PowerShell script from the Oracle Cloud documentation.
- Get the Oracle Cloud IDs (OCIDs) of the VNIC from the Console or the Oracle Cloud Metadata service.
- Execute the PowerShell script as the administrator. This interactive script requires the OCID of the new VNIC.
But we’re not here to discuss the manual process. Let’s get to the more interesting perspective of automating the entire process.
Automated Process
As most administrators will tell you, automation is the key to making life easier, allowing administrators to tackle the larger issues that bring more value to the business. You need Terraform components to execute the additional VNIC and PowerShell scripts in the user data and on the host itself. The automated process starts with loading the heavy-lifting PowerShell script into an Object Storage bucket and creating a preauthorized resource (PAR). That process is not covered in this description. Next, create the terraform. Then modify the user data script that’s executed when the instance is created.
Load the new second VNIC PowerShell script into an object store and create a PAR link to the script. You can use the Oracle Cloud command line interface or the Console instructions. The PowerShell script that activates the new VNIC gathers the necessary metadata from the Oracle Cloud Metadata service.
$vnicOcid = $vnic .vnicId
$allVnicsMetadata = ( $wc .downloadString( $metadataServiceVnicsUrl ) | ConvertFrom -Json -ErrorAction Stop);
if (! $vnicOcid )
{
if ( $allVnicsMetadata .Length -le 1)
{
Write-Error "Couldn't find any secondary VNICs attached to this instance."
Exit 1
}
}
$secondaryVnicMetadata = ( $allVnicsMetadata | Where-Object {$_.vnicId -eq $vnicOcid });
if (! $secondaryVnicMetadata )
{
Write-Error "Couldn't find a VNIC attached to this instance with the specified OCID."
Exit 1
}
if( @( $secondaryVnicAdapter ).Count -ne 1)
{
$secondaryVnicAdapter = (Get -NetAdapter -ErrorAction Stop | Where-Object {$_.Vlanid -eq $secondaryVnicMetadata .vlanTag -and $_.InterfaceDescription -like "Microsoft Network Adapter Multiplexor Driver #*" })
}
if (! $secondaryVnicAdapter )
{
Write-Error "Couldn't find a Network Interface for the specified VNIC."
Exit 1
}
$mac = Get -NetAdapter -Name $secondaryVnicAdapter .Name | select -expand MacAddress
{
Set -NetAdapter -Name $secondaryVnicAdapter .Name -MacAddress $secondaryVnicMetadata .macAddr.Replace( ":" , "-" )
}
$secondaryVnicAdapterIPConfig = (Get -NetIPAddress -InterfaceAlias $secondaryVnicAdapter .InterfaceAlias -AddressFamily IPv4 -ErrorAction SilentlyContinue);
if ( $secondaryVnicAdapterIPConfig )
{
Remove -NetIPAddress -InterfaceAlias $secondaryVnicAdapter .InterfaceAlias -AddressFamily IPv4 -Confirm true
}
New -NetIPAddress -InterfaceAlias $secondaryVnicAdapter .InterfaceAlias -AddressFamily IPv4 -IPAddress $secondaryVnicMetadata .privateIp -PrefixLength $subnetPrefix -ErrorAction Stop
Set -DnsClientServerAddress -InterfaceAlias $secondaryVnicAdapter .InterfaceAlias -ServerAddresses $dnsIPAddress -ErrorAction Stop
$secondaryVnicAdapterDefaultRoute = (Get -NetRoute -InterfaceAlias $secondaryVnicAdapter .InterfaceAlias -DestinationPrefix 0.0.0.0/0 -ErrorAction SilentlyContinue);
if ( $secondaryVnicAdapterDefaultRoute )
{
Remove -NetRoute -InterfaceAlias $secondaryVnicAdapter .InterfaceAlias -DestinationPrefix 0.0.0.0/0 -ErrorAction Stop -Confirm true
}
New -NetRoute -InterfaceAlias $secondaryVnicAdapter .InterfaceAlias -DestinationPrefix 0.0.0.0/0 -NextHop $secondaryVnicMetadata .virtualRouterIp -ErrorAction Stop | Out-Null
Unregister -ScheduledJob -Name Addvnic
Stop-Transcript
|
Adjust the transform for creating the host with another resource to attach the VNIC. Ensure that you have the subnet ID for the second subnet.
resource "oci_core_vnic_attachment" "Bastionvnic2" {
#Required
create_vnic_details {
#Required
#Optional
assign_public_ip = "false"
nsg_ids = []
}
}
|
The following code block is the full resource block for creating the Windows instance, including the user_data and the oci_core_vnic_attachment sections.
resource "oci_core_instance" "Bastion" {
metadata = {
user_data = base64encode(file( "/Users/mymac/Scripts/Powershell/bastionvnic.ps1" ))
}
source_details {
source_type = "image"
}
lifecycle {
ignore_changes = [
source_details[ 0 ].source_id,
]
}
}
resource "oci_core_vnic_attachment" "Bastionvnic2" {
#Required
create_vnic_details {
#Required
#Optional
assign_public_ip = "false"
nsg_ids = []
}
}
|
The script for the user data needs two additions: the user data Terraform call and the Powershell script for user data. You can also add other configurations necessary in this script.
The user data Terraform call retrieves the script from the local machine.
metadata = {
user_data = base64encode(file( "/Users/mymac/Scripts/Powershell/bastionvnic.ps1" ))
}
|
The PowerShell script for user data uses the PAR as the location for the heavy-lifting script that will be ran via a job on the next reboot. I used Invoke-WebRequest to get the file out of object storage and into the newly created Windows Server. The process has a five-minute wait to ensure that all the Oracle Cloud-Init processes finish before rebooting the Windows Server.
mkdir c:\OCIdata;
Invoke -Webrequest -uri $Addvnic -OutFile C:\OCIdata\vnicadd.ps1;
$trigger = New -JobTrigger -AtStartup -RandomDelay 00:00:45;
Register -ScheduledJob -Trigger $trigger -FilePath C:\OCIdata\vnicadd.ps1 -Name Addvnic;
Get -ScheduledJobOption -Name Addvnic | Set -ScheduledJobOption -RunElevated ;
start-sleep -s 300;
Stop-Transcript ;
Restart -Computer -ComputerName "localhost" -Force ;
|
Conclusion
You can automate your creation of a secondary VNIC on your Oracle Cloud Windows Server with a little Terraform and some PowerShell. For more resources on adding secondary VNICs and Terraform, check out the Oracle Cloud documentation and the following helpful links:
John Parker
Cloud Solution Architect
I am currently a Cloud Solutions Architect in the Oracle Cloud Infrastructure Compute team.