Skip to content

Terraform Plugin User Guide

Introduction

whitesky.cloud BV consists of several locations where you can deploy your infrastructure. We have multiple ways of deploying said infrastructure: The portal, CLI, API and terraform. This article describes how you can use Terraform in combination with the whitesky.cloud BV's terraform provider to elevate the management of your infrastructure. Deploying new infrastructure and scaling them when needed has never been easier.

With our terraform provider you can create, update and destroy your cloud resources (Cloudspaces, Virtual Machine, Port forwards, etc.) It allows you to manage different locations from the same terraform file. If you have no experience with Terraform, we will guide you through your first steps as well. Let's get started with the prerequisites.

Prerequisites

  • User account
  • At least one location
  • JWT Token

To access a valid JWT token:

  1. Go to whitesky.cloud BV portal.
  2. Click APIs in the navigation drawer on the left side of the page.
  3. Click Copy JWT to copy the JWT token. You can also click on the downward-facing arrow icon to display the JWT token.

Access to a location: Ensure that your IAM user is added to the locations where you are going to deploy your infrastructure. Request your whitesky.cloud BV admin to provide you with the needed access.

Step 1 - Install Terraform

You are required to have Terraform version 0.12.4 or higher. Check the Terraform official documentation to learn more about how you can install Terraform on your machine. Additionally, you can Download the appropriate Terraform package for your system. Plus, you can check some previous versions if needed.

Note: Terraform version used in this tutorial: 0.14.7, OVC provider version: ~>2.0.0. Please make sure that you always use compatible Terraform and location provider binaries in order to manage locations using your Terraform file.

To install Terraform version 0.14.7:


  1. Execute the following command.
    curl -O https://releases.hashicorp.com/terraform/0.14.7/terraform_0.14.7_linux_amd64.zip
    
  2. Extract the .zip file in /usr/bin/ directory using the following command.
    sudo unzip terraform_0.14.7_linux_amd64.zip -d /usr/bin/
    


  1. Download the windows Terraform binary version from the list of Terraform releases.
  2. Extract Terraform to a directory
  3. Add the directory to the PATH.

Verify installation by executing terraform. You should see the Terraform help page appear in your terminal. Also, you can check the installed version by executing terraform -version.

Step 2 - Install location Terraform provider

Terraform uses provider plugins to interact with specific cloud infrastructures.

The Terraform provider is a binary used as a plugin for Terraform. You can find the whitesky.cloud BV's Terraform provider in the Downloads section.

After extracting the .zip file, move the provider binary to the following directory.

~/.terraform.d/plugins/registry.terraform.io/portal-whitesky-cloud/portal-whitesky-cloud/2.0.3/linux_amd64/terraform-provider-portal-whitesky-cloud_v2.0.3
Terraform expects the following format for third-party plugins: [host.domain]/portal-whitesky-cloud/portal-whitesky-cloud/[version]/[arch]

Note: The given plugin path is for Terraform versions 0.13 and higher. Different Terraform versions may require a different path than the one given above.

Step 3 - Terraform configuration

Configuration files

Now that Terraform and the necessary provider are ready to be used, we can create a directory for our terraform configuration using the following command.

mkdir ~/terraform_config

Note: Each configuration directory can contain only a single set of configuration files.

Make sure no irrelevant files with extension .tf are present in the directory, since Terraform will consume all .tf files.

In detail, you can learn about Terraform configuration files and Terraform configuration language in Terraform official docs.

In this tutorial we use three types of configuration files:

  1. terraform.tfvars - contains the settings we want to use.
  2. variables.tf - contains the definition of the variables and their defaults.
  3. main.tf - contains the configuration of the infrastructure we want to set up and consists of blocks of different types. In this tutorial we use the following constructs:

    • provider block describes provider configurations, resource types, their arguments and attributes. Each configuration should contain a provider block.
    • resource block describes a resource of a given type. By adding/changing/deleting this block we can create/update/destroy the resource it is pointing at.
    • data block describes a data resource. These types of blocks are used to export information of one or several existing resources to the local Terraform module where it can be used in other blocks.

Terraform commands

Initialize a working directory

This is the first step after creating a new Terraform configuration.

terraform init

Verify provider

In the previous step the portal-whitesky-cloud binary has been manually installed by moving it to the Terraform plugins folder.
In order for Terraform to actually recognize the plugin, a provider block needs to be specified. This can be done by entering the following in the main.tf file in the working directory.

terraform {
  required_providers {
    portal-whitesky-cloud = {
      source  = "portal-whitesky-cloud/portal-whitesky-cloud"
      version = "2.0.3"
    }
  }
  required_version = ">= 0.14"
}

Initialize the working directory again and Terraform should initalize the provider plugins.

terraform init

You can now also verify provider installation, Terraform should list installed provider plugins:

cd ~/terraform_config
$ terraform providers
.
└── provider[registry.terraform.io/portal-whitesky-cloud/portal-whitesky-cloud] 2.0.3

Verify configuration

Configuration can be validated by Terraform within the configuration directory.

terraform validate

Plan execution

Generate and show the execution plan.

terraform plan

Apply changes

Build or change infrastructure.

terraform apply

List states

Terraform is stateful, by default state of each resource is stored locally in the configuration directory in file terraform.tfstate. To list all the resources Terraform keeps track of, execute.

terraform state list

Environmental variables

Terraform makes use of a number of environmental variables to customize some aspects of Terraform behavior and to set input variables. For example, if a variable name is expected to be a part of the configuration, but is not defined in configuration files Terraform will try to fetch the value from the environmental variable TF_VAR_name.

Location configuration

Authentication

To configure your credentials with a location provider, set JWT as an environmental variable

export TF_VAR_client_jwt=""

Timeouts

By default, timeouts are set to 120 seconds. You can change the timeout by setting the environment variable

export TF_VAR_client_api_timeout=120s

You can also set the timeouts inside your Terraform configuration:

resource "example" "my_cluster" {
  # ...

  timeouts {
    create = "60m"
  }
}

Managing resources

portal-whitesky-cloud_machine

Provides a portal-whitesky-cloud machine which allows machines to be created, updated and deleted.

Example Usage

resource "portal-whitesky-cloud_machine" "machine" {
  customer_id   = "${var.customer_id}"
  cloudspace_id = "${var.cloudspace_id}"
  name          = "MyMachine"
  description   = "Machine Provisioned With Terraform"
  disk_size     = 10
  vcpus         = 1
  memory        = 1
  image_id      = 5
}

Argument Reference

The following arguments are supported:

Argument Description
customer_id (Required) Customer ID
cloudspace_id (Required) The cloudspace ID of the cloudspace where the machine needs to be created.
name (Required) Name of the machine.
description (Required) Description of the machine.
disk_size (Required) Size of the boot disk in gigabytes.
vCPUs (Required) Number of CPUs to assign to the machine.
memory (Required) Amount of memory to assign to the machine in MiB.
image_id (Optional) The image ID of the image to use for this instance.
cdrom_id (Optional) The CDROM ID of the image to use for this instance.
os_type (Optional) CD-ROM Image OS type. Available values: Linux, Windows, Unix, BSD, Darwin, Other.
private_ip (Optional) Private IP of the machine (should be inside the cloudspace network).
iops (Optional) IOPS limiting of the boot disk.
data_disks[] List of extra disk sizes in gigabytes.
external_networks[] List of extra external networks. External network ID should be used.
disk_id (Optional) Start the machine from this disk ID image.
act_as_default_gateway (Optional, default to false) Set to true if this machine should act as a default gateway of its cloudspace. Note that only one machine in the cloudspace can act as a gateway, if more than a single machine have this flag, each machine will set the default gateway to its IP address, which will lead to unexpected behavior. To reset the default gateway to the virtual gateway IP address, set the flag to false.

In order to set the default gateway to a different machine on the cloudspace:

  • set flag to false on the machine_1 - current gateway
  • set flag true on the machine_2 that will take over
  • add dependency to the resource of the machine 2: depends: [portal-whitesky-cloud_machine.machine_1] - this is necessary to sort actions to first reset gateway to default, and then to set a new machine to the gateway role.

portal-whitesky-cloud_port_forwarding

Creates a cloudspace port forward for a specific machine.

Example Usage

resource "portal-whitesky-cloud_port_forwarding" "machine_pfwd0" {
  vm_id         = "${var.var_id}"
  cloudspace_id = "${var.cloudspace_id}"
  customer_id   = "${var.customer_id}"
  protocol      = "${var.protocol}"
  local_port    = "${var.local_port}"
  public_port   = "${var.public_port}"
}

Argument Reference

The following arguments are supported:

Argument Description
vm_id (Required) VM ID.
cloudspace_id (Required) The cloudspace ID of the cloudspace where the port forward needs to be created.
customer_id (Required) Customer ID.
protocol (Required) Protocol for port forwarding. Available values: UDP, TCP.
local_port (Required) local port of the machine where to forward to.
public_port (Required) public port which should be forwarded.
nested_cs_id (Optional) Nested Cloudspace ID.

portal-whitesky-cloud_disk

Creates extra disks used by portal-whitesky-cloud machines

Example Usage

resource "portal-whitesky-cloud_machine" "machine" {
  customer_id   = "${var.customer_id}"
  cloudspace_id = "${var.cloudspace_id}"
  name          = "MyMachine"
  description   = "Machine Provisioned With Terraform"
  disk_size     = 10
  vcpus         = 1
  memory        = 1
  image_id      = 5
}

resource "portal-whitesky-cloud_disk" "disk1" {
  customer_id = "${var.customer_id}"
  vm_id       = "${ portal-whitesky-cloud_machine.machine.id }"
  location    = "${var.location}"
  disk_name   = "terraform_disk"
  description = "Disk created by terraform"
  size        = 10
  type        = "DATA"
  iops        = 1000
}

resource "portal-whitesky-cloud_disk" "disk2" {
  customer_id = "${var.customer_id}"
  vm_id       = "${ portal-whitesky-cloud_machine.machine.id }"
  location    = "${var.location}"
  disk_name   = "terraform_disk"
  description = "Disk created by terraform"
  size        = 15
  type        = "DATA"
  iops        = 1500
  depends_on  = ["portal-whitesky-cloud_disk.disk1"]
}

For creating several disks add resource construct for each disk separately, add dependency between disks to create them sequentially.

Terraform allows creating multiple objects with attribute count, but in this case it is not allowed, since portal-whitesky-cloud supports only adding one disk to a VM at a time.

Argument Reference

The following arguments are supported:

Argument Description
customer_id (Required) Customer ID.
vm_id (Required) VM ID of the machine where the disk should be attached.
location (Required) Location.
disk_name (Required) Disk name of the disk.
description (Required) Disk description.
size (Required) Size in gigabytes of the disk.
type (Required) Type of disk, following options are supported: BOOT, DATA.
iops (Optional) Maximum IOPS disk can perform, defaults to 2000.

portal-whitesky-cloud_cloudspace

Creates cloudpsaces

Example Usage

resource "portal-whitesky-cloud_cloudspace" "cloudspace" {
  customer_id         = "${var.customer_id}"
  location            = "${var.location}"
  name                = "cloudspace"
  private_network     = "192.168.100.0/24"
  external_network_id = 1
  private             = false
  resource_limits     = {
     memory_quota           = 3.0
     vdisk_space_quota      = 12
     public_ip_quota        = 3
     vcpu_quota             = 4
     external_network_quota = 4
   }
}

Argument Reference

Argument Description
customer_id (Required) Customer ID where the cloudspace will belong to.
location (Required) Location.
name (Required) Name of space to create.
private_network (Optional) private network CIDR eg. 192.168.103.0/24.
resource_limits (Optional) specify resource limits block.
memory_quota (Optional) max size of memory in GB.
vdisk_space_quota (Optional) max size of aggregated vdisks in GB.
vcpu_quota (Optional) max number of CPU cores.
public_ip_quota (Optional) max number of assigned public IPs.
external_network_quota (Optional) max number of external networks.
private (Required) Firewall should be private (true or false).
external_network_id (Optional, Conflicts with parent_cloudspace_id) External network ID to use.
parent_cloudspace_id (Optional, Conflicts with external_network_id) Parent cloudspace ID to use.
custom_fw_cdrom_id (Optional) Custom firewall CDROM ID to use.
custom_fw_image_id (Optional) Custom firewall image ID to use.
custom_fw_disk_size (Optional) Custom firewall disk size.
custom_fw_memory (Optional) Custom firewall memory size.
custom_fw_vcpus (Optional) Custom firewall number of CPU.
custom_fw_type (Optional) Custom firewall type. Available type: [Linux, Windows, Unix, BSD, Darwin, Other].

portal-whitesky-cloud_connected_cloudspaces

Adds a remote connection to cloudspace

Example Usage

resource "portal-whitesky-cloud_connected_cloudspaces" "tunnel" {
  customer_id             = "${var.customer_id}"
  cloudspace_id           = "${var.cloudspace0.id}"
  connected_cloudspace_id = "${var.cloudspace1.id}"
}

Argument Reference

Argument Description
customer_id (Required) Customer ID where the cloudspace will belong to.
cloudspace_id (Required) ID of the cloudspace.
connected_cloudspace_id (Required) ID of the cloudspace to connect to.

portal-whitesky-cloud_antiaffinity

Adds Anti-Affinity Group

Example Usage

resource "portal-whitesky-cloud_antiaffinity" "af" {
  customer_id   = "${var.customer_id}"
  cloudspace_id = "${var.cloudspace0.id}"
  group_id      = "${var.group_id}"
  spread        = "${var.spread}"
}

Argument Reference

Argument Description
customer_id (Required) Customer ID where the cloudspace will belong to.
cloudspace_id (Required) ID of the cloudspace.
group_id (Required) Name of the group.
spread (Required) Amount of physical nodes to spread VMs over. Set to -1 for infinite spread.

portal-whitesky-cloud_machine_antiaffinity

Adds virtual machine anti-affinity group

Example Usage

resource "portal-whitesky-cloud_machine_antiaffinity" "machine_af" {
  customer_id   = "${var.customer_id}"
  cloudspace_id = "${var.cloudspace0.id}"
  group_id      = "${var.group_id}"
  vm_id         = "${var.vm_id}"
}

Argument Reference

Argument Description
customer_id (Required) Customer ID where the cloudspace will belong to.
cloudspace_id (Required) ID of the cloudspace.
group_id (Required) Name of the group.
vm_id (Required) VM ID.

Retrieving data sources

portal-whitesky-cloud_machine

Use this data source to retrieve information about a machine in a cloudspace either by name or VMID

Example Usage

data "portal-whitesky-cloud_machine" "machine" {
   cloudspace_id = "${var.cloudspace_id}"
   customer_id   = "${var.customer_id}"
   vm_id         = "${var.vm_id}"
}

Argument Reference

Argument Description
cloudspace_id (Required) ID of the cloudspace where the machine is located.
customer_id (Required) ID of the customer.
vm_id (Optional, Conflicts with name) ID of the machine to look up.
name (Optional, Conflicts with vm_id) Name of the machine to look up.

portal-whitesky-cloud_machines

Use this data source to retrieve information about all machines in a given cloudspace

Example Usage

data "portal-whitesky-cloud_machines" "machines" {
   cloudspace_id = "${var.cloudspace_id}"
   customer_id   = "${customer_id}"
}

Argument Reference

Argument Description
cloudspace_id (Required) ID of the cloudspace where the machines are located.
customer_id (Required) ID of the customer.

portal-whitesky-cloud_cloudspace

Use this data source to get information like quota for a cloudspace

Example Usage

data "portal-whitesky-cloud_cloudspace" "cloudspace" {
   cloudspace_id = "${var.cloudspace_id}"
   customer_id   = "${var.customer_id}"
}

Argument Reference

Argument Description
customer_id (Required) ID of the customer.
cloudspace_id (Optional, Conflicts with name) ID of the cloudspace.
name (Optional, Conflicts with cloudspace_id) Name of the cloudspace.

portal-whitesky-cloud_cloudspaces

Use this data source to retrieve information about all cloudspaces for a given customer

Example Usage

data "portal-whitesky-cloud_cloudspaces" "cloudspaces" {
   customer_id = "${customer_id}"
}

Argument Reference

Argument Description
customer_id (Required) ID of the customer.

portal-whitesky-cloud_location

Use this data source to get location information by name

Example Usage

data "portal-whitesky-cloud_location" "location" {
   customer_id = "${var.customer_id}"
   name_regex  = "${var.name_regex}"
}

Argument Reference

Argument Description
customer_id (Required) ID of the customer.
name_regex (Required) full name or name pattern for regex search.

portal-whitesky-cloud_locations

Use this data source to retrieve information for all customer locations

Example Usage

data "portal-whitesky-cloud_locations" "locations" {
   customer_id = "${customer_id}"
}

Argument Reference

Argument Description
customer_id (Required) ID of the customer.

portal-whitesky-cloud_disk

Use this data source to get the information of a disk in a location by disk ID

Example Usage

data "portal-whitesky-cloud_disk" "disk" {
   customer_id = "${var.customer_id}"
   location    = "${var.location}"
   disk_id     = "${var.disk_id}"
}

Argument Reference

Argument Description
customer_id (Required) ID of the customer.
disk_id (Required) ID of the disk.
location (Required) location of the disk.

portal-whitesky-cloud_port_forwarding

Use this data source to get information about a port forward of a specific machine and a local port

Example Usage

data "portal-whitesky-cloud_port_forwarding" "pfwd" {
   cloudspace_id = "${var.cloudspace_id}"
   customer_id   = "${var.customer_id}"
   local_port    = "${var.local_port}"
   vm_id         = "${var.vm_id}"
}

Argument Reference

Argument Description
vm_id (Required) VM ID.
cloudspace_id (Required) Cloudspace ID.
customer_id (Required) ID of the customer.
local_port (Required) local port.

portal-whitesky-cloud_image

Use this data source to retrieve image by name. If more than a single image matches the query, Terraform will fail. To return the list of images use the data source portal-whitesky-cloud_images.

Example Usage

data "portal-whitesky-cloud_image" "im"{
   customer_id = "${var.customer_id}"
   location    = "${var.location}"
   name_regex  = "${var.name_regex}"
   most_recent = true
}

Argument Reference

Argument Description
customer_id (Required) ID of the customer.
location (Required) Location.
name_regex (Optional) full name or name pattern for regex search. If set to "" all available images will be looked up.
most_recent (Optional) If set to true, it will search for the latest created image within the scope (image with the largest ID).

portal-whitesky-cloud_images

Use this data source to retrieve a list of images by name

Example Usage

data "portal-whitesky-cloud_image" "im"{
   customer_id = "${var.customer_id}"
   location    = "${var.location}"
   name_regex  = "${var.name_regex}"
}

Argument Reference

Argument Description
customer_id (Required) ID of the customer.
location (Required) Location.
name_regex (Optional) full name or name pattern for regex search. If set to "" all available images will be looked up.

portal-whitesky-cloud_external_network

Use this data source to retrieve external network information either by name or ID. To return the list of external networks use the data source portal-whitesky-cloud_external_networks.

Example Usage

data "portal-whitesky-cloud_external_network" "en"{
   customer_id = "${var.customer_id}"
   location    = "${var.location}"
   name        = "${var.name}"
}

Argument Reference

Argument Description
customer_id (Required) ID of the customer.
location (Required) Location.
name (Optional - Conflicts with external_network_id) full name.
external_network_id (Conflicts with name) external network ID.

portal-whitesky-cloud_external_networks

Use this data source to retrieve a list of external networks

Example Usage

data "portal-whitesky-cloud_external_networks" "ens"{
   customer_id = "${var.customer_id}"
   location    = "${var.location}"
}

Argument Reference

Argument Description
customer_id (Required) ID of the customer.
location (Required) Location.

Examples

This section contains a few Terraform examples. Each example requires several settings to make it work. Below are the settings that are required in each example:

  • client_jwt - The portal-whitesky-cloud JWT.
  • cs_name - The name of the cloudspace.

Apart from these settings, each example can have its own specific settings.

Client-JWT

This example uses a JWT from portal-whitesky-cloud for authentication and uses the ovc_image data source to fetch the latest ubuntu 16 image ID from OVC using regex.

There is also a port forward defined for the machine, forwarding port 2222 on the public IP of the cloudspace to 22 on the VM.

In terraform.tfvars , the userdata is given where a user Carmichael is defined to be created with a public key to be added to Carmichael's authorized_keys file.

The following parameters need to be configured in terraform.tfvars:

  • client_jwt
  • customer_id
  • cs_id
  • location
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
terraform {
  required_providers {
    portal-whitesky-cloud = {
      source  = "portal-whitesky-cloud/portal-whitesky-cloud"
      version = "~> 2.0"
    }
  }
}

provider "portal-whitesky-cloud" {
  client_jwt = var.client_jwt
}

# Data definition for every cloudspace
# To be able to get the ip address
data "portal-whitesky-cloud_cloudspace" "cs" {
  customer_id   = var.customer_id
  cloudspace_id = var.cs_id
}

# Data definition for image
data "portal-whitesky-cloud_image" "im"{
  most_recent = true
  name_regex  = "(?i).*\\.?ubuntu.*16*"
  customer_id = var.customer_id
  location    = var.location
}

# Definition of the VM to be created with the settings defined in terraform.tfvars
resource "portal-whitesky-cloud_machine" "mymachine" {
  customer_id   = var.customer_id
  cloudspace_id = data.portal-whitesky-cloud_cloudspace.cs.id
  image_id      = data.portal-whitesky-cloud_image.im.image_id
  disk_size     = var.disksize
  name          = "mymachine"
  description   = var.vm_description
  userdata      = var.userdata
  vcpus         = 1
  memory        = 1024
}

resource "portal-whitesky-cloud_port_forwarding" "ssh" {
  customer_id   = var.customer_id
  cloudspace_id = data.portal-whitesky-cloud_cloudspace.cs.id
  public_port   = 2222
  vm_id         = portal-whitesky-cloud_machine.mymachine.id
  local_port    = 22
  protocol      = "tcp"
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# portal-whitesky-cloud Customer ID
customer_id = "<Customer ID>"

# portal-whitesky-cloud client secret.
client_jwt = "<portal-whitesky-cloud JWT>"

# cloudspace ID
cs_id = "<CS ID>"

# location
location = "<Location>"

# disk size in GB you can get that from ovc first
disksize = 10

# The description of the VM
vm_description = "Terraform test VM"

# User data to be added to the VM
userdata = "users: [{name: Carmichael, shell: /bin/bash, ssh-authorized-keys: [<public key to be added to the VM's authorized_keys>]}]"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
variable "client_jwt" {
  description = "portal-whitesky-cloud JWT"
}
variable "customer_id" {
  description = "customer id"
}

variable "location" {
  description = "location"
}

variable "cs_id" {
  description = "cloudspace id"
}

variable "vm_description" {
  description = "Description of the VM"
}

variable "image_id" {
  description = "Image_id"
  default     = "1"
}

variable "disksize" {
  description = "disksize"
  default     = "20"
}

variable "userdata" {
  description = "user data"
  default = ""
}

Multiple disks

This is an example of how to set up a VM with a boot disk and 2 additional data disks attached to the VM.

The following parameters need to be configured:

  • client_jwt
  • customer_id
  • location
  • cs_name
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
terraform {
  required_providers {
    portal-whitesky-cloud = {
      source  = "portal-whitesky-cloud/portal-whitesky-cloud"
      version = "~> 2.0"
    }
  }
}

provider "portal-whitesky-cloud" {
  client_jwt = var.client_jwt
}

data "portal-whitesky-cloud_cloudspace" "cs" {
  customer_id   = var.customer_id
  cloudspace_id = var.cs_name
}

data "portal-whitesky-cloud_image" "ubuntu16"{
  most_recent = true
  name_regex  = "(?i).*\\.?ubuntu.*16*"
  customer_id = var.customer_id
  location    = var.location
}

# machine definition
resource "portal-whitesky-cloud_machine" "machine" {
  customer_id    = var.customer_id
  cloudspace_id  = data.portal-whitesky-cloud_cloudspace.cs.id
  image_id       = data.portal-whitesky-cloud_image.ubuntu16.image_id
  disk_size      = var.disksize
  name           = var.machine
  description    = var.vm_description
  vcpus          = 1
  memory         = 1024
}

# Definition of the disks
resource "portal-whitesky-cloud_disk" "disk1" {
  customer_id = var.customer_id
  vm_id       = portal-whitesky-cloud_machine.machine.id
  location    = var.location
  disk_name   = "terraform_disk_1"
  description = "Disk created by terraform"
  size        = 10
  type        = "DATA"
  iops        = 2000
}

resource "portal-whitesky-cloud_disk" "disk2" {
  customer_id = var.customer_id
  vm_id       = portal-whitesky-cloud_machine.machine.id
  location    = var.location
  disk_name   = "terraform_disk_2"
  description = "Disk created by terraform"
  size        = 20
  type        = "DATA"
  iops        = 3000
  depends_on  = ["portal-whitesky-cloud_disk.disk1"]
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# portal-whitesky-cloud Customer ID
customer_id = "<Customer ID>"

# portal-whitesky-cloud client secret.
client_jwt = "<portal-whitesky-cloud JWT>"

# Location
location = "<Location>"

# cloudspace name
cs_name = "<CS Name>"

# machine name
machine = "test_vm"

# boot disk size in GB of the machine
disksize = 10

# The description of the VM
vm_description = "Terraform multi disk example VM"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
variable "client_jwt" {
  description = "portal-whitesky-cloud jwt token"
}

variable "location" {
  description = "Location"
}

variable "customer_id" {
  description = "Customer ID"
}

variable "cs_name" {
  description = "cloudspace ID"
}

variable "machine" {
  description = "machine name"
}

variable "disksize" {
  description = "disksize"
  default     = "20"
}

variable "vm_description" {
  description = "Description of the VM"
}

External networks

This is an example of how to attach a VM to an external network or detach it from an external network.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
terraform {
  required_providers {
    portal-whitesky-cloud = {
      source  = "portal-whitesky-cloud/portal-whitesky-cloud"
      version = "~> 2.0"
    }
  }
}

provider "portal-whitesky-cloud" {
  client_jwt = var.client_jwt
}

// use this data source to get a list of all networks available for this account

data "portal-whitesky-cloud_external_networks" "nets"{
  customer_id = var.customer_id
  location    = var.location
}

// use this data source to get external network by name
data "portal-whitesky-cloud_external_network" "net"{
  customer_id = var.customer_id
  location    = var.location
  name        = var.external_network
}

data "portal-whitesky-cloud_cloudspace" "cs"{
  customer_id   = var.customer_id
  cloudspace_id = var.cs_name
}

# Data definition for image
data "portal-whitesky-cloud_image" "ubuntu16"{
  most_recent = true
  name_regex  = "(?i).*\\.?ubuntu.*16*"
  customer_id = var.customer_id
  location    = var.location
}

resource "portal-whitesky-cloud_machine" "machine" {
  customer_id    = var.customer_id
  cloudspace_id  = data.portal-whitesky-cloud_cloudspace.cs.id
  image_id       = data.portal-whitesky-cloud_image.ubuntu16.image_id
  disk_size      = var.disksize
  name           = var.machine
  description    = var.vm_description
  vcpus          = 1
  memory         = 1024
  external_networks     = [
    # if network ID is given, VM will be attached to this network
    data.portal-whitesky-cloud_external_network.net.id,
    # Several IP addresses from the same external network can be added, just add NICs for the same network ID
    data.portal-whitesky-cloud_external_network.net.id,
  ]
}
// print VM id
output "id"{
  value = portal-whitesky-cloud_machine.machine.id
}

// list external networks
output "nets"{
  value = data.portal-whitesky-cloud_external_networks.nets.entities
}

// list VM external nics
output "attached_external_networks"{
  value = portal-whitesky-cloud_machine.machine.interfaces
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# portal-whitesky-cloud Customer ID
customer_id = "<Customer ID>"

# portal-whitesky-cloud client secret.
client_jwt = "<portal-whitesky-cloud JWT>"

# Location
location = "<Location>"

# cloudspace name
cs_name = "<CS Name>"

# machine name
machine = "test_vm"

# boot disk size in GB of the machine
disksize = 10

# external network name
external_network = "<External Network Name>"

# external network ID
external_network_id = "<External Network ID>"

# The description of the VM
vm_description = "Managing external networks with Terraform"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
variable "customer_id" {
  description = "customer ID"
}

variable "location" {
  description = "location"
}

variable "cs_name" {
  description = "cloudspace name"
}

variable "external_network" {
  description = "external network name"
  default = ""
}

variable "external_network_id" {
  description = "external network ID"
}

variable "client_jwt" {
  description = "portal-whitesky-cloud jwt token"
}

variable "disksize" {
  description = "Disk Size"
}

variable "machine" {
  description = "VM Name"
}

variable "vm_description" {
  description = "VM Description"
}

Custom firewall

This is an example of how to deploy a cloudspace with a custom firewall.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
terraform {
  required_providers {
    portal-whitesky-cloud = {
      source  = "portal-whitesky-cloud/portal-whitesky-cloud"
      version = "~> 2.0"
    }
  }
}

provider "portal-whitesky-cloud" {
  client_jwt = var.client_jwt
}
# Resource definition for private cloudspace with no public interface
resource "portal-whitesky-cloud_cloudspace" "private" {
  customer_id         = var.customer_id
  location            = var.location
  name                = "PRIVATE-CS-TERRAFORM"
  private_network     = "192.168.103.0/24"
  private             = true
  external_network_id = var.external_network_id
}
# Resource definition for nested cloudspace
resource "portal-whitesky-cloud_cloudspace" "nested" {
  customer_id          = var.customer_id
  location             = var.location
  name                 = "NESTED-CS-TERRAFORM"
  private_network      = "192.168.104.0/24"
  private              = false
  parent_cloudspace_id = portal-whitesky-cloud_cloudspace.private.id # parent network ID
}
data "portal-whitesky-cloud_image" "im"{
  most_recent = true
  name_regex  = "(?i).*\\.?ubuntu.*16*"
  customer_id = var.customer_id
  location    = var.location
}
data "portal-whitesky-cloud_image" "checkpoint"{
  most_recent = true
  name_regex  = "Checkpoint" # set name of checkpoint image uploaded to portal-whitesky-cloud
  customer_id = var.customer_id
  location    = var.location
}
data "portal-whitesky-cloud_external_network" "net"{
  customer_id = var.customer_id
  location    = var.location
  name        = var.external_network
}
# this is customizable firewall
resource "portal-whitesky-cloud_machine" "checkpoint" {
  customer_id            = var.customer_id
  cloudspace_id          = portal-whitesky-cloud_cloudspace.private.id
  image_id               = data.portal-whitesky-cloud_image.checkpoint.image_id
  disk_size              = var.disksize
  name                   = "CHECKPOINT-VM"
  description            = var.vm_description
  userdata               = var.userdata
  act_as_default_gateway = true
  external_networks      = [data.portal-whitesky-cloud_external_network.net.id]
  vcpus                  = 1
  memory                 = 1024
}
# this machine will have access to the internet via the checkpoint
resource "portal-whitesky-cloud_machine" "server" {
  customer_id   = var.customer_id
  cloudspace_id = portal-whitesky-cloud_cloudspace.nested.id
  image_id      = data.portal-whitesky-cloud_image.im.image_id
  disk_size     = var.disksize
  name          = "SERVER-VM"
  description   = var.vm_description
  userdata      = var.userdata
  vcpus         = 1
  memory        = 1024
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# portal-whitesky-cloud Customer ID
customer_id = "<Customer ID>"

# portal-whitesky-cloud client secret.
client_jwt = "<portal-whitesky-cloud JWT>"

# Location
location = "<Location>"

disksize = "<Disk size required for checkpoint image>"
external_network = "<External Newtork Name>"
external_network_id = "<External Newtork ID>"

# User data to be added to the VM
userdata = "users: [{name: user, shell: /bin/bash, ssh-authorized-keys:[]},{name: root, shell: /bin/bash, ssh-authorized-keys: [<SSH KEYS to add on machine>]}]"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
variable "client_jwt" {
  description = "portal-whitesky-cloud jwt token"
}

variable "customer_id" {
  description = "customer ID"
}

variable "location" {
  description = "location"
}

variable "disksize" {
  description = "data disk size"
  default = 10
}

variable "external_network" {
  description = "external network name"
}
variable "vm_description" {
  description = "machine description"
  default = "machine deployed with Terraform"
}

variable "userdata" {
  description = "user info"
  default = "users: [{name: root, shell: /bin/bash, ssh-authorized-keys: []}]"
}