Terraform using Nutanix Provider and V3 APIs

Below is an example of creating a basic VM (CentOS) on a Nutanix cluster using Terraform

Points to note:

  • Cluster is already UP and running AHV
  • CentOS image is already present – uploading using the Image Service
  • We will be creating the VM on Prism and not connecting to Prism Central – but the same can be used on Prism Central as well

We will be using the below document from Hashicorp for the Nutanix provider details

https://www.terraform.io/docs/providers/nutanix/index.html

Also, the Nutanix API’s are here

http://developer.nutanix.com/reference/prism_central/v3/#vms

The tf file is below

provider "nutanix" {
  username = "PE_Username_Here"
  password = "PE_Password"
  endpoint = "PE_IP_Address_Here"
  insecure = true
  port     = 9440
}
data "nutanix_image" "centos" {
    image_id = "2b4b5942-2c0e-45eb-b17e-a10b8479c824"
}
resource "nutanix_virtual_machine" "ayan-test" {
 name = "ayan-test"
 description = "ayan terra"
 num_vcpus_per_socket = 2
 num_sockets          = 1
 memory_size_mib      = 4096
}

So what this is doing is authenticating to PE, using the CentOS image on the cluster to create a VM (ayan-test) with description as “ayan terra” with the VM configuration next.

Note this VM does not have a NIC card – but this can be added, plus any additional configuration that is needed

Let’s initialize and run Terraform

$terraform init

Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "nutanix" (1.0.0)...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.nutanix: version = "~> 1.0"

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

So plugin is up to date. Let’s run Plan

$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.nutanix_image.centos: Refreshing state...

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + nutanix_virtual_machine.ayan-test
      id:                                                 <computed>
      api_version:                                        <computed>
      availability_zone_reference.%:                      <computed>
      boot_device_disk_address.%:                         <computed>
      boot_device_mac_address:                            <computed>
      boot_device_order_list.#:                           <computed>
      categories.%:                                       <computed>
      cluster_name:                                       <computed>
      cluster_reference.%:                                <computed>
      description:                                        "ayan terra"
      enable_script_exec:                                 <computed>
      gpu_list.#:                                         <computed>
      guest_customization_cloud_init_custom_key_values.%: <computed>
      guest_customization_cloud_init_meta_data:           <computed>
      guest_customization_cloud_init_user_data:           <computed>
      guest_customization_is_overridable:                 <computed>
      guest_customization_sysprep.%:                      <computed>
      guest_customization_sysprep_custom_key_values.%:    <computed>
      guest_os_id:                                        <computed>
      hardware_clock_timezone:                            <computed>
      host_reference.%:                                   <computed>
      hypervisor_type:                                    <computed>
      memory_size_mib:                                    "4096"
      metadata.%:                                         <computed>
      name:                                               "ayan-test"
      nic_list.#:                                         "1"
      nic_list.0.floating_ip:                             <computed>
      nic_list.0.ip_endpoint_list.#:                      "1"
      nic_list.0.ip_endpoint_list.0.ip:                   "IP_for_VM"
      nic_list.0.ip_endpoint_list.0.type:                 "ASSIGNED"
      nic_list.0.mac_address:                             <computed>
      nic_list.0.model:                                   <computed>
      nic_list.0.network_function_chain_reference.%:      <computed>
      nic_list.0.network_function_nic_type:               <computed>
      nic_list.0.nic_type:                                <computed>
      nic_list.0.subnet_reference.%:                      "2"
      nic_list.0.subnet_reference.kind:                   "subnet"
      nic_list.0.subnet_reference.uuid:                   "aee9fd0b-41e1-4be2-9d9e-a501b37e2fad"
      nic_list.0.subnet_reference_name:                   <computed>
      nic_list.0.uuid:                                    <computed>
      num_sockets:                                        "1"
      num_vcpus_per_socket:                               "2"
      num_vnuma_nodes:                                    <computed>
      nutanix_guest_tools.%:                              <computed>
      owner_reference.%:                                  <computed>
      parent_reference.%:                                 <computed>
      power_state:                                        <computed>
      power_state_mechanism:                              <computed>
      project_reference.%:                                <computed>
      should_fail_on_script_failure:                      <computed>
      state:                                              <computed>
      vga_console_enabled:                                <computed>


Plan: 1 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

The (+) shows you the configuration that will be added and the (-) shows you the configuration that will be removed. Let’s now apply the same

$ terraform apply
data.nutanix_image.centos: Refreshing state...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + nutanix_virtual_machine.ayan-test
      id:                                                 <computed>
      api_version:                                        <computed>
      availability_zone_reference.%:                      <computed>
      boot_device_disk_address.%:                         <computed>
      boot_device_mac_address:                            <computed>
      boot_device_order_list.#:                           <computed>
      categories.%:                                       <computed>
      cluster_name:                                       <computed>
      cluster_reference.%:                                <computed>
      description:                                        "ayan terra"
      enable_script_exec:                                 <computed>
      gpu_list.#:                                         <computed>
      guest_customization_cloud_init_custom_key_values.%: <computed>
      guest_customization_cloud_init_meta_data:           <computed>
      guest_customization_cloud_init_user_data:           <computed>
      guest_customization_is_overridable:                 <computed>
      guest_customization_sysprep.%:                      <computed>
      guest_customization_sysprep_custom_key_values.%:    <computed>
      guest_os_id:                                        <computed>
      hardware_clock_timezone:                            <computed>
      host_reference.%:                                   <computed>
      hypervisor_type:                                    <computed>
      memory_size_mib:                                    "4096"
      metadata.%:                                         <computed>
      name:                                               "ayan-test"
      nic_list.#:                                         <computed>
      num_sockets:                                        "1"
      num_vcpus_per_socket:                               "2"
      num_vnuma_nodes:                                    <computed>
      nutanix_guest_tools.%:                              <computed>
      owner_reference.%:                                  <computed>
      parent_reference.%:                                 <computed>
      power_state:                                        <computed>
      power_state_mechanism:                              <computed>
      project_reference.%:                                <computed>
      should_fail_on_script_failure:                      <computed>
      state:                                              <computed>
      vga_console_enabled:                                <computed>


Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

nutanix_virtual_machine.ayan-test: Creating...
  api_version:                                        "" => "<computed>"
  availability_zone_reference.%:                      "" => "<computed>"
  boot_device_disk_address.%:                         "" => "<computed>"
  boot_device_mac_address:                            "" => "<computed>"
  boot_device_order_list.#:                           "" => "<computed>"
  categories.%:                                       "" => "<computed>"
  cluster_name:                                       "" => "<computed>"
  cluster_reference.%:                                "" => "<computed>"
  description:                                        "" => "ayan terra"
  enable_script_exec:                                 "" => "<computed>"
  gpu_list.#:                                         "" => "<computed>"
  guest_customization_cloud_init_custom_key_values.%: "" => "<computed>"
  guest_customization_cloud_init_meta_data:           "" => "<computed>"
  guest_customization_cloud_init_user_data:           "" => "<computed>"
  guest_customization_is_overridable:                 "" => "<computed>"
  guest_customization_sysprep.%:                      "" => "<computed>"
  guest_customization_sysprep_custom_key_values.%:    "" => "<computed>"
  guest_os_id:                                        "" => "<computed>"
  hardware_clock_timezone:                            "" => "<computed>"
  host_reference.%:                                   "" => "<computed>"
  hypervisor_type:                                    "" => "<computed>"
  memory_size_mib:                                    "" => "4096"
  metadata.%:                                         "" => "<computed>"
  name:                                               "" => "ayan-test"
  nic_list.#:                                         "" => "<computed>"
  num_sockets:                                        "" => "1"
  num_vcpus_per_socket:                               "" => "2"
  num_vnuma_nodes:                                    "" => "<computed>"
  nutanix_guest_tools.%:                              "" => "<computed>"
  owner_reference.%:                                  "" => "<computed>"
  parent_reference.%:                                 "" => "<computed>"
  power_state:                                        "" => "<computed>"
  power_state_mechanism:                              "" => "<computed>"
  project_reference.%:                                "" => "<computed>"
  should_fail_on_script_failure:                      "" => "<computed>"
  state:                                              "" => "<computed>"
  vga_console_enabled:                                "" => "<computed>"
nutanix_virtual_machine.ayan-test: Still creating... (10s elapsed)
nutanix_virtual_machine.ayan-test: Creation complete after 11s (ID: 6c5b058b-74ce-4d00-b626-d1947f340ae4)

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

If everything goes well, you will be able to see the VM on Prism

Terraform Nutanix Provider
Nutanix Terraform Provider

Destroying the VM is pretty simple – just run terraform destroy. The VM does not need to be powered off for the destroy operation to go through

$ terraform destroy
nutanix_virtual_machine.ayan-test: Refreshing state... (ID: 6c5b058b-74ce-4d00-b626-d1947f340ae4)
data.nutanix_image.centos: Refreshing state...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  - nutanix_virtual_machine.ayan-test


Plan: 0 to add, 0 to change, 1 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

nutanix_virtual_machine.ayan-test: Destroying... (ID: 6c5b058b-74ce-4d00-b626-d1947f340ae4)
nutanix_virtual_machine.ayan-test: Still destroying... (ID: 6c5b058b-74ce-4d00-b626-d1947f340ae4, 10s elapsed)
nutanix_virtual_machine.ayan-test: Destruction complete after 10s

Destroy complete! Resources: 1 destroyed.
Destroy

Now that we have the base construct for the VM on PE using Terraform, let’s get more creative on the next set of posts! Stay tuned!

1 Comment

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *