Ok, I think I figured this out.
It is a two-step process with some prep up front. My ultimate goal is to be able to provision LUNs using a third-party tool to be used as quick, temporary lab environments. Here are the steps I went through.
Prep work
1. Create a separate SVM with vsadmin enabled. I don't want my script hitting anything but this SVM and I don't want it having system-wide admin privileges.
2. The hosts on the other end will have static WWPNs so I created the igroups ahead of time in the new SVM.
3. Assign the appropriate aggregates to the SVM using vserver modify command:
# vserver modify -vserver <svm_name> -aggr-list <comma-delimited aggregate list>
Script - Logged in as vsadmin
1. Create the volume. Note that if you don't use the -policy option, it will not create the mount point which is the only difference from a SAN volume.
# vol create -volume <volume_name> -aggregate <aggregate_name> -size <GB,TB> -state online -type RW
2. Create the LUN.
# lun create -path </vol/volume_name/lun_name> -size <GB,TB> -ostype <os_name> -space-reserve <enabled,disabled> -space-allocation <enabled,disabled>
3. Map the LUN.
# lun map-path </vol/volume_name/lun_name> -igroup <igroup_name> -lun-id <#>