07.06.2023

How to automate server deployment via Terraform?

Terraform

Terraform provider Serverspace allows you to manage cloud resources using the Infrastructure as Code approach. Management is done using special configuration files in which you describe the desired state of your infrastructure.

Installing Terraform

First, let’s install Terraform in your operating system. We recommend using the Terraform developer's manual.

Provider Configuration

    1. Create an API key for the project that will work with Terraform.
    2. Create and navigate to the directory which will be used to work with Terraform Provider.
    3. Create and open the provider.tf configuration file.
    4. Insert the provider information in the file, where is your API key, and save the changes:
    5. terraform {
      required_providers {
      serverspace = {
      source = "itglobalcom/serverspace"
      version = "0.2.2"
      }
      }
      }

      variable "s2_token" {
      type = string
      default = ""
      }

      provider "serverspace" {
      key = var.s2_token
      }

    6. Open a command prompt and navigate to the directory where you created the file. Perform an initialization to verify that it is correct:
      terraform init

      You will see the following message if initialization is successful:

      Initializing the backend...
      Initializing provider plugins...
      - Finding itglobalcom/serverspace versions matching "0.2.0"...
      - Installing itglobalcom/serverspace v0.2.0...
      - Installed itglobalcom/serverspace v0.2.0 (self-signed, key ID 062XXXXXXXXXXXX)

      Partner and community providers are signed by their developers.
      If you'd like to know more about provider signing, you can read about it here: https://www.terraform.io/docs/cli/plugins/signing.html

      Terraform has created a lock file .terraform.lock.hcl to record the provider selections it made above. Include this file in your version control repository so that Terraform can guarantee to make the same selections by default when you run "terraform init" in the future.

      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.

Your Infrastructure Description

With Serverspace Terraform Provider, you can create infrastructure with various configurations. You can find detailed documentation in the Terraform Registry.

Let's take a look at the example of creating a simple infrastructure with two servers connected via isolated network:

Follow the steps below to set up this infrastructure:

    1. Create and open the file ssh_key.tf, which will contain the public part of the ssh key to create the server.
    2. Insert the information about the public part of the ssh key into the file ssh_key.tf and save the changes, replacing the contents of the public_key variable with your value:
      resource "serverspace_ssh" "terraform" {
      name = "terraform-key"
      public_key = "ssh-rsa AAAAB3Nza...JUDjlM= root@CentOS.local"
      }

      variable "pvt_key" {
      type = string
      default = ""
      }

    3. Create and open the main.tf file that will contain the infrastructure description.
    4. Insert the description of your infrastructure into the file.
      resource "serverspace_server" "server1" {
      image = "Ubuntu-20.04-X64"
      name = "server-1"
      location = "am2"
      cpu = 2
      ram = 2048

      boot_volume_size = 40*1024

      volume {
      name = "bar"
      size = 20*1024
      }

      nic {
      network = ""
      network_type = "PublicShared"
      bandwidth = 50
      }
      nic {
      network = resource.serverspace_isolated_network.my_net.id
      network_type = "Isolated"
      bandwidth = 0
      }

      ssh_keys = [
      resource.serverspace_ssh.terraform.id,
      ]

      connection {
      host = self.public_ip_addresses[0]
      user = "root"
      type = "ssh"
      private_key = file(var.pvt_key)
      timeout = "2m"
      }

      provisioner "remote-exec" {
      inline = [
      "export PATH=$PATH:/usr/bin",
      "sudo apt-get update",
      "sudo apt-get install -y redis-server",
      "exit 0"
      ]
      }

      }

      resource "serverspace_server" "server2" {
      image = "Ubuntu-20.04-X64"
      name = "server-2"
      location = "am2"
      cpu = 4
      ram = 8192

      boot_volume_size = 40*1024

      nic {
      network = ""
      network_type = "PublicShared"
      bandwidth = 70
      }
      nic {
      network = resource.serverspace_isolated_network.my_net.id
      network_type = "Isolated"
      bandwidth = 0
      }
      }

      resource"serverspace_isolated_network" "my_net" {
      location = "am2"
      name = "my_net"
      description = "Example for Terraform"
      network_prefix = "192.168.0.0"
      mask = 24
      }

    5. To create the infrastructure described above, run the command:
      terraform apply

      A dialog window will appear:

      Terraform used the selected providers to generate the following execution plan.
      Resource actions are indicated with the following symbols:
      + create

      Terraform will perform the following actions:

      # serverspace_isolated_network.my_net will be created
      + resource "serverspace_isolated_network" "my_net" {
      + description = "Example for Terraform"
      + id = (known after apply)
      + location = "am2"
      + mask = 24
      + name = "my_net"
      + network_prefix = "192.168.0.0"
      }

      # serverspace_server.server1 will be created
      + resource "serverspace_server" "server1" {
      + boot_volume_id = (known after apply)
      + boot_volume_size = 40960
      + cpu = 2
      + id = (known after apply)
      + image = "Ubuntu-20.04-X64"
      + location = "am2"
      + name = "server-1"
      + public_ip_addresses = (known after apply)
      + ram = 2048
      + ssh_keys = (known after apply)

      + nic {
      + bandwidth = 0
      + id = (known after apply)
      + ip_address = (known after apply)
      + network = (known after apply)
      + network_type = "Isolated"
      }
      + nic {
      + bandwidth = 50
      + id = (known after apply)
      + ip_address = (known after apply)
      + network_type = "PublicShared"
      }

      + volume {
      + id = (known after apply)
      + name = "bar"
      + size = 20480
      }
      }

      # serverspace_server.server2 will be created
      + resource "serverspace_server" "server2" {
      + boot_volume_id = (known after apply)
      + boot_volume_size = 40960
      + cpu = 4
      + id = (known after apply)
      + image = "Ubuntu-20.04-X64"
      + location = "am2"
      + name = "server-2"
      + public_ip_addresses = (known after apply)
      + ram = 8192
      + ssh_keys = (known after apply)

      + nic {
      + bandwidth = 0
      + id = (known after apply)
      + ip_address = (known after apply)
      + network = (known after apply)
      + network_type = "Isolated"
      }
      + nic {
      + bandwidth = 70
      + id = (known after apply)
      + ip_address = (known after apply)
      + network_type = "PublicShared"
      }
      }

      # serverspace_ssh.terraform will be created
      + resource "serverspace_ssh" "terraform" {
      + id = (known after apply)
      + name = "terraform-key"
      + public_key = "ssh-rsa AAAAB3Nza...JUDjlM= root@CentOS.local"
      }

      Plan: 4 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.

    6. Enter yes to create the infrastructure.
      Enter a value: yesserverspace_ssh.terraform: Creating...
      serverspace_isolated_network.my_net: Creating...
      serverspace_ssh.terraform: Creation complete after 1s [id=3181]
      serverspace_isolated_network.my_net: Creation complete after 8s [id=l2n403]
      serverspace_server.server2: Creating...
      serverspace_server.server1: Creating...
      serverspace_server.server1: Still creating... [10s elapsed]
      serverspace_server.server2: Still creating... [10s elapsed]
      ...
      serverspace_server.server1 (remote-exec): (Reading database ...
      serverspace_server.server1 (remote-exec): (Reading database ... 5%
      serverspace_server.server1 (remote-exec): (Reading database ... 10%
      ...
      serverspace_server.server1: Creation complete after 1m3s [id=l2s190038]
      Apply complete! Resources: 4 added, 0 changed, 0 destroyed.
    7. To view the current infrastructure, run the command:
      terraform show

      This will display the current infrastructure configuration:

      # serverspace_isolated_network.my_net:
      resource "serverspace_isolated_network" "my_net" {
      description = "Example for Terraform"
      id = "l2n403"
      location = "am2"
      mask = 24
      name = "my_net"
      network_prefix = "192.168.0.0"
      }

      # serverspace_server.server1:
      resource "serverspace_server" "server1" {
      boot_volume_id = 58909
      boot_volume_size = 40960
      cpu = 2
      id = "l2s190038"
      image = "Ubuntu-20.04-X64"
      location = "am2"
      name = "server-1"
      public_ip_addresses = [
      "45.138.24.19",
      ]
      ram = 2048
      ssh_keys = [
      3181,
      ]

      nic {
      bandwidth = 0
      id = 59576
      ip_address = "192.168.0.1"
      network = "l2n403"
      network_type = "Isolated"
      }
      nic {
      bandwidth = 50
      id = 59575
      ip_address = "45.138.24.19"
      network_type = "PublicShared"
      }

      volume {
      id = 58910
      name = "bar"
      size = 20480
      }
      }

      # serverspace_server.server2:
      resource "serverspace_server" "server2" {
      boot_volume_id = 58911
      boot_volume_size = 40960
      cpu = 4
      id = "l2s190039"
      image = "Ubuntu-20.04-X64"
      location = "am2"
      name = "server-2"
      public_ip_addresses = [
      "31.44.3.68",
      ]
      ram = 8192
      ssh_keys = []

      nic {
      bandwidth = 0
      id = 59578
      ip_address = "192.168.0.2"
      network = "l2n403"
      network_type = "Isolated"
      }
      nic {
      bandwidth = 70
      id = 59577
      ip_address = "31.44.3.68"
      network_type = "PublicShared"
      }
      }

      # serverspace_ssh.terraform:
      resource "serverspace_ssh" "terraform" {
      id = "3181"
      name = "terraform-key"
      public_key = "ssh-rsa AAAAB3Nza...JUDjlM= root@CentOS.local"
      }

Congrats with your first infrastructure as a code implementation.