Automating VMWare NFS Datastore Creation using the NetApp Powershell Toolkit

20151023 powershell datastores

Let’s say the Widgets team asks you, the storage administrator for a new datastore to be added in VMWare…

What information do you need to collect about the nature of the datastore?

  • Do you want that on SAS or SATA (maybe these VMs run everything they need in RAM, and rely little on disk, but need a lot of it)?
  • In which datacenter will this datastore reside?
  • What’s the purpose of this datastore, ie, how can it be differentiated from the others, and therefore named?
  • Which environment is it for? Production, Test, Dev, DR, a specific team?

Great, now that we have the facts, what are the steps for delivering the new datastore?

  1. Log into the right NetApp controller for the job, with access to the right storage
  2. Create a volume in the appropriate aggregate
  3. Perform all your favorite volume tweaks (storage efficiency settings, permission styles, volume autogrow, snapshot autodelete, etc)
  4. Create an NFS Export of that volume
  5. Permission your NFS export to allow RW and root to each individual ESX server
  6. Go to your vSphere server, then find the appropriate datacenter
  7. Configure, individually, each host in the datacenter to mount the newly exported NFS datastore and give it a name in VMWare

These are the high-level steps but if you have a pile of ESX hosts that need permissioning and mounting (you can’t mount once from one host and re-scan — it has to be done on each host individually), this can become pretty tedious. One datastore can take 5-10 minutes to fully provision.

So, 5-10 minutes is admittedly not a lot of time to be doing real work, but that’s a lot of time spent pointing and clicking. Furthermore, you can only improve your pointing and clicking so much, before carpal tunnel sets in or you can no longer find efficiency improvements.

So, when your DevOps team comes to you one day and says, I want every environment to have it’s own app and server-type specific datastore, you do some math (hmm, 15 new datastores you say?), and rather than jump out a window, you spend 4 days cranking out a monster Powershell script like the one I’m sharing with you today.

I’m sharing this script in the hopes that someone else finds it and finds it useful, and sees the wonderful things the NetApp Powershell Toolkit is capable of. A little about my environment, and therefore the inner workings of this script:

  • All that Q&A up front you conducted, to understand the nature of the datastores you’re building? This script prompts you for all that up-front.
  • This script pieces together all the bits of information it’s collected from you to spit out volumes and datastores with consistent, predictable, descriptive names. Check out the script’s guts and you’ll see what I’m doing, but for example:
    •  VOLUME: NFS_VMWare_LAB_OPS_SRV_W2
    • NFS EXPORT: /vol/NFS_VMWare_LAB_OPS_SRV_W2
    • DATASTORE: NFS_SATA_US_ATL_LAB_OPS_SRV
  • This script is targeting DataONTAP 7-Mode; it can likely be easily modified to work on Clustered DataONTAP by replacing the ‘Na’ with ‘Nc’ for each Netapp command.
  • This script has logic for determining which SAN controller to target, based on the physical datacenter you type (in the example I’ve used Portland and Atlanta), as well as the disk type you select (SAS vs SATA), in the event that one controller owns the aggregate of a given disk type. Use this logic or don’t, but I’m very proud of it.
    • The script assumes you have 2 physical datacenters, each with an HA pair of NetApp controllers and their own “datacenter” inside VMWare under a global vCenter server.

#Powershell script for creating NFS datastores on NetApp storage
#and permissioning them to multiple ESX hosts, then mounting datastores
#to each host.
#Assumes that VMWare and NetApp Powershell Toolkits are installed already. 

#Written by Matthew Fugel 2015 https://matthewfugel.wordpress.com

param(
[Parameter(
Mandatory=$true, HelpMessage=”Datacenter name – either Atlanta or Portland”)]
$dataCenter,
[Parameter(
Mandatory=$true, HelpMessage = “type of backing disk – either SATA or SAS”)]
$SANDiskType,
[Parameter(
Mandatory=$true, HelpMessage = “Purpose or Function – GRC_APP, GRC_SVC, GRC_SQL, OPS_SRV, BUS_SRV, BUS_SRV” )]
$dataStorePurpose,
[Parameter(
Mandatory=$true, HelpMessage = “Environment Abbreviation – PRD, UAT, L2S, DRE, LAB, INF, COR”)]
$environmentAbbrev,
[Parameter(
Mandatory=$true, HelpMessage = “Desired volume size – 100m, 200g, 1t”)]
$volumeSize
)

#
#Other Variables – Initialize sane defaults here
$domain= $env:USERDNSDOMAIN
$username =$env:USERDOMAIN + “\” + $env:username
$vCenterServer=”vcenter01.$domain”
$vmwareCreds= get-credential -UserName $username -Message “User account for VMWare”
$volTypePrefix=”NFS” #prefix for volume type (CIFS, NFS, L[un])
$volPresentOn=”VMWare” #server on which volume is present
$volPurpose = $dataStorePurpose #description of volume purpose

#Environment-Specific Variables
if ($datacenter -eq “Atlanta”)
{
$filer = “Prod-SAN-002”
#Iscsi initiator
$iscsi_wwpn=”Production_ESX_Cluster”
$nfsHost=”$filer.$domain”
$volGeoCountry=”US”
$volGeoSite=”ATL”
$volSANsuffix=”S2″
$volName = $volTypePrefix, $volPresentOn, $environmentAbbrev, $volPurpose, $volSANsuffix -join “_”
$ESXhosts = (‘prd1-esx’,’prd2-esx’,’prd3-esx’)

}

elseif ($datacenter -eq “Atlanta” -and $SANDiskType -eq “SATA”)
{
$filer = “Prod-SAN-001”
#Iscsi initiator
$iscsi_wwpn=”Production_ESX_Cluster”
$nfsHost=”$filer.$domain”
$volGeoCountry=”US”
$volGeoSite=”ATL”
$volSANsuffix=”S1″
$volName = $volTypePrefix, $volPresentOn, $environmentAbbrev, $volPurpose, $volSANsuffix -join “_”
$ESXhosts = (‘prd1-esx’,’prd2-esx’,’prd3-esx’)
}

elseif ($datacenter -eq “Portland” -and $SANDiskType -eq “SATA”)
{
$filer = “Corp-SAN-002”
#iscsi initiator
$iscsi_wwpn=”corp-esx”
$nfsHost=”$filer.$domain”
$volGeoCountry=”US”
$volGeoSite=”POR”
$volSANsuffix=”S2″
$volName = $volTypePrefix, $volPresentOn, $environmentAbbrev, $volPurpose, $volSANsuffix -join “_”
$ESXhosts = (‘cor1-esx’,’cor2-esx’,’cor3-esx’)

}
elseif ($datacenter -eq “Portland” -and $SANDiskType -eq “SAS”)
{
$filer = “Corp-SAN-001”
#iscsi initiator
$iscsi_wwpn=”corp-esx”
$nfsHost=”$filer.$domain”
$volGeoCountry=”US”
$volGeoSite=”POR”
$volSANsuffix=”S1″
$volName = $volTypePrefix, $volPresentOn, $environmentAbbrev, $volPurpose, $volSANsuffix -join “_”
$ESXhosts = (‘cor1-esx’,’cor2-esx’,’cor3-esx’)

}
$NFSName = ($volTypePrefix, $SANDiskType, $volGeoCountry, $volGeoSite, $environmentAbbrev, $datastorePurpose -join “_”)
#$NFSPath= “/vol/$($NFSname)”
$NFSPath = “/vol/$($volName)”
$NFSActualPath=”/vol/” + $volName

set-executionpolicy unrestricted
Import-Module DataONTAP
Add-PSSnapin VMware.VimAutomation.Core

#User needs to be added to Filer’s “API” group
write-host “”
Write-Host NETAPP – Connecting to Filer: $filer
connect-nacontroller $filer

if ($sandiskType -eq “SATA”)
{
$aggr= (get-NAdisk | where-object {($_.EffectiveDiskType -like “*SATA*”) -and $_.Aggregate} | Select Aggregate,Node | Get-Unique).Aggregate
}
elseif ($sandiskType -eq “SAS”)
{
$aggr= (get-NAdisk | where-object {($_.EffectiveDiskType -like “*SAS*”) -and $_.Aggregate} | Select Aggregate,Node | Get-Unique).Aggregate
}

write-host “”
write-host “”
Write-Host New volume: Destination aggregate will be $aggr
write-host “”
Write-Host New volume: Name will be $volName
write-host “”
write-host New volume: Size will be $volumeSize

New-NaVol -Name $volName -Aggregate $aggr -Size $volumeSize -SpaceReserve none | Out-Null
write-host VOLUME CREATED, THIN PROVISIONED
write-host “”

write-host Applying volume configuration tweaks
write-host “”

Set-NaVolAutosize -Name $volName -EnableGrow | Out-Null
write-host VOLUME AUTO-GROW ENABLED

Set-NaSnapshotAutodelete $volName state on | Out-Null
write-host SNAPSHOT AUTO-DELETE ENABLED

Set-NaVolOption $volName fractional_reserve 0 | Out-Null
Set-NaVolOption $volName nosnap on | Out-Null
write-host FRACTIONAL RESERVE DISABLED, SNAPSHOTS DISABLED

Get-NaVol $volName | Enable-NaSis | Start-NaSis | Out-Null
write-host STORAGE EFFICIENCY – DEDUPLICATION ENABLED

Set-NaVolOption $volname no_atime_update -Value on | Out-Null
write-host DISABLE ACCESS TIME UPDATES

#Show me the final volume
Get-NaVol -Name $volName

#NEXT STEP — CREATE NFS EXPORTS
write-host “”
write-host Creating NFS shares at $NFSPath

add-NaNfsExport -Path $NFSPath -Persistent -ReadWrite $ESXhosts -Root $ESXhosts -NoSuid | Out-Null

#show me the final NFS share
write-host “”
write-host NFS SHARE CREATED AND PERMISSIONED:
Get-NaNfsExport -Pathname $NFSPath | select * -ExpandProperty securityrules | select Pathname,ReadWrite, Root

#NEXT STEP — ATTACH IN VMWARE
write-host “”
write-host Connecting to VMWare…
Add-PSSnapin VMware.VimAutomation.Core
Connect-VIServer -Server $vCenterServer -Credential $vmwareCreds -WarningAction SilentlyContinue
Write-Host Connected to vCenter

$hosts = get-vmhost -location “$($datacenter)*”
foreach ($vmhost in $hosts){
New-Datastore -VMHost $vmhost.Name -Name $NFSname -Path $NFSPath -Nfs -nfshost $nfsHost | Out-Null
Write-Host NFS path mounted to $vmhost
}

write-host New datastore mounted in VMWare:
Get-Datastore -Name $nfsname | Format-list -Property Server,Location

Disconnect-VIServer -WarningAction SilentlyContinue
write-host disconnected from VMWare – all done.

Remove-PSSnapin vmware.vimautomation.core
Remove-Module DataOnTAP

Advertisements

What would you like to say?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s