Terraform is a popular tool from HashiCorp that’s widely used by data center admins for managing and provisioning infrastructure as code. In this blog, let’s look at how to use Terraform and NetApp Service Level Manager (NSLM) for provisioning a LUN in ONTAP.
Before we start, this blog assumes a couple of things:
- You have (some) experience with Terraform, the different provisioners and providers that come out of the box, its configuration files, tfstate files, etc.
- You are comfortable with the Go language and its code organization.
- You have basic idea of NSLM.
Getting Started
First, we must decide on the parameters we would take from admin for creating a LUN. Here is the input:
host
: This is the hostname where NSLM is deployeduser_name
: Username to be used to login to NSLMpassword
: Password to login to NSLMsvm
: The Storage Virtual Machine on which we got to create the LUNstorage_service_level_name
: This is the SSL name to be used while deciding where to create the LUN for the given application’s QoS needs.lun_name
: Name of the LUNlun_size
: Size of LUN to be created
Next, we need to define a resource schema under the project root as provider.go
:
package main import ( "github.com/hashicorp/terraform/helper/schema" ) func Provider() *schema.Provider { return &schema.Provider{ ResourcesMap: map[string]*schema.Resource{ "netapp_lun" : resourceNetappLun(), }, } }
The resource name is “netapp_lun
” here and any Terraform script which wants to import this resource would do it like as shown below in main.tf
file under project root:
resource "netapp_lun" "my-lun" { host = "https://<>:<>" user_name = <> password = <> svm = "vs1" storage_service_level_name = "Value" lun_name = "rak_lun_terraform4" lun_size = 20971520 }
Once we have this in place, we need to declare the CRUD handlers as part of resourceNetappLun()
under “resource_netapp_lun.go
” file under project root (which gets invoked when the script runs).
func resourceNetappLun() *schema.Resource { return &schema.Resource{ Create: lunCreate, Read: lunRead, Update: lunUpdate, Delete: lunDelete, }, } }
Using Terraform to Provision Storage
Once we declare the CRUD handlers, we then need to define these handlers. For this example, let’s take a look at the implementation of Create operation (i.e: lunCreate()
).
The basic flow is:
- Fetch the SVM key using SVM name.
finalUrl = nslmUrl+"/api/1.0/slo/storage-vms?name="+svmName req, err := http.NewRequest("GET", finalUrl, nil)
- Fetch the SSL key for the given value.
// get the SSL identifier from NSLM sslUrl = nslmUrl + "/api/1.0/slo/storage-service-levels?name=" + sslName req, err = http.NewRequest("GET", sslUrl, nil)
- Formulate a JSON body that consists of SVM key, SSL key, LUN name and LUN size.
postObject := new(LunCreateBody) postObject.SslKey = sslKey postObject.SvmKey = svmKey postObject.LunName = lunName postObject.Size = lunSize b, err := json.Marshal(postObject)
- Invoke a POST method with the JSON body as text.
lunPostUrl = nslmUrl + "/api/1.0/slo/luns" req, err = http.NewRequest("POST", lunPostUrl, in)
Once we have the required code in place, build the GO code.
Run the terraform commands
Here is a small demo which captures the state of the controller before and after running the Terraform script.
To summarize, what we have demonstrated here is a new Netapp provider resource for LUN creation in Terraform that uses NSLM to provision storage from ONTAP. We can extend the same to have resources for file shares and other storage attributes which NSLM supports today. Watch out for a blog series in the future for more on Terraform + NSLM use cases to see a complete end-to-end application deployment stack!
If you have questions please use the comments below or reach out using our Slack channels!