Deploy Your First Infrastructure on Scaleway using Terraform (Step by Step)

Terraform - Overview

HashiCorp Terraform is an open-source software tool to deploy IaaC: Infrastructure as Code. It means that you can automate infrastructure resources such as Network, Instances, Bare Metal servers and more. It allows you to use declarative configuration files to manage the full lifecycle — create new resources, manage existing ones, and delete those no longer needed. The configuration language used by Terraform is called Hashicorp Configuration Language (HCL).

During this tutorial you will learn how to:

Requirements

Installing Terraform

The first step is to install Terraform on a server or on your computer to deploy and manage your resources. Terraform is installed on a user environment (which can either be your local computer or a remote server used to manage your infrastructures) to push configuration files on your cloud environment. We suggest to add your configuration files in a versionning system, like GitHub or Bitbucket to manage the versioning of your configurations.

Installation on MacOS

Terraform can be easily installed on computers running MacOS X using the Homebrew packet manager. Run the following command in a terminal window to install the application:

$ brew install terraform

Installation on Windows

The installation of Terraform on Windows can be done in a single command-line using the Chocolatey packet manager. Run the following command in a terminal window to install Terraform on computers running Microsoft Windows:

$ choco install terraform

Installation on Linux

The installation of Terraform on Linux can be done in a few simple steps:

  • Go to the Terraform download page
  • Select the appropriate package for your operating system and architecture and download it.
  • Move the Terraform binary file to a directory included in your PATH variable.

1 . Start by creating the ~/bin directoy, which will be added automatically to your PATH on Ubuntu Linux:

$ mkdir ~/bin

2 . Download the latest release of the application and unzip it:

$ wget https://releases.hashicorp.com/terraform/0.12.24/terraform_0.12.24_linux_amd64.zip && unzip https://releases.hashicorp.com/terraform/0.12.24/terraform_0.12.24_linux_amd64.zip

3 . The archive contains a single binary file called terraform, move it to the previously created ~/bin directory:

$ mv terraform ~/bin

4 . Test the installation by running the terraform version command:

$ terraform version
# Terraform v0.12.24

Connect Terraform to Scaleway cloud by Creating API Key

Terraform uses API Key to authenticate. API Key are unique identifiers associated with your Scaleway account and consist of an Access Key and a Secret Key. The Secret key is required to authenticate against our API and will only be displayed when you create the keys. Consider the Access Key as a login, and the Secret Key as a password.

Each Scaleway Project can have several API Key. For security reasons, it is recommended to generate API Key on an application basis. This allows you to revoke any of them individually and at any moment, in case of leaked information.

1 . Log into your Scaleway Console.

2 . Your Default Project dashboard displays once logged in. Click on the Selected Project dropdown menu if you wish to change Projects:

3 . Click on the Credentials tab.

4 . Scroll down to the API Key section.

Note: If you are using Scaleway Developer Tools you will need to retrieve the project ID, which can be found in the Project Credentials page.

Click on Generate new API Key and a pop-up appears giving you the option of adding the API Key purpose (for internal organization). Click on Generate API Key to proceed.

The Access and Secret Key will show on your screen. Take a note of the Secret Key as it will not be recoverable.

Click OK to conclude.

Creating a first instance using Terraform

To create a first instance using Terraform, a declarative configuration file is required. This file contains all information of machine characteristics required to deploy. It has to be written in the Hashicorp Configuration Language (HCL). The deployment of Scaleway Elements resources is done using the Scaleway Provider for Terraform. For more information about HCL, refer to the official documentation.

1 . Organize your project. Start by creating a project folder (for example scaleway-terraform) and enter the newly created directory:

$ mkdir scaleway-terraform && cd scaleway-terraform

2 . Create a new text file called scaleway.tf in your favourite text editor, for example nano:

$ nano scaleway.tf 

3 . Add the following content to it to deploy a General Purpose GP1-M instance running the Ubuntu Focal Fossa (20.04 LTS) base image in the fr-par-1 zone:

provider "scaleway" {
  access_key      = "<SCALEWAY-ACCESS-KEY>"
  secret_key      = "<SCALEWAY-SECRET-KEY>"
  organization_id = "<SCALEWAY-ORGANIZATION-ID>"
  zone            = "fr-par-1"
  region          = "fr-par"
}

resource "scaleway_instance_ip" "public_ip" {}

resource "scaleway_instance_volume" "data" {
  size_in_gb = 550
  type = "l_ssd"
}

resource "scaleway_instance_server" "my-ubuntu-instance" {
  type  = "GP1-M"
  image = "ubuntu-focal"

  tags = [ "FocalFossa", "MyUbuntuInstance" ]

  ip_id = scaleway_instance_ip.public_ip.id

  additional_volume_ids = [ scaleway_instance_volume.data.id ]

}

Edit the parameters for access_key, secret_key and organization_id, save the file and exit the text editor.

4 . Run terraform init to load the newly created configuration file into Terraform:

$ terraform init

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "scaleway" (terraform-providers/scaleway) 1.15.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.scaleway: version = "~> 1.15"

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.

5 . Plan the execution of the tasks to be done by terraform using the command terraform 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.


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

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:

  # scaleway_instance_ip.public_ip will be created
  + resource "scaleway_instance_ip" "public_ip" {
      + address         = (known after apply)
      + id              = (known after apply)
      + organization_id = (known after apply)
      + reverse         = (known after apply)
      + zone            = (known after apply)
    }

  # scaleway_instance_server.my-ubuntu-instance will be created
  + resource "scaleway_instance_server" "my-ubuntu-instance" {
      + additional_volume_ids            = (known after apply)
      + boot_type                        = (known after apply)
      + disable_dynamic_ip               = false
      + disable_public_ip                = false
      + enable_dynamic_ip                = false
      + enable_ipv6                      = false
      + id                               = (known after apply)
      + image                            = "ubuntu-focal"
      + ip_id                            = (known after apply)
      + ipv6_address                     = (known after apply)
      + ipv6_gateway                     = (known after apply)
      + ipv6_prefix_length               = (known after apply)
      + name                             = (known after apply)
      + organization_id                  = (known after apply)
      + placement_group_policy_respected = (known after apply)
      + private_ip                       = (known after apply)
      + public_ip                        = (known after apply)
      + security_group_id                = (known after apply)
      + state                            = "started"
      + tags                             = [
          + "FocalFossa",
          + "MyUbuntuInstance",
        ]
      + type                             = "GP1-M"
      + zone                             = (known after apply)

      + root_volume {
          + delete_on_termination = (known after apply)
          + size_in_gb            = (known after apply)
          + volume_id             = (known after apply)
        }
    }

  # scaleway_instance_volume.data will be created
  + resource "scaleway_instance_volume" "data" {
      + id              = (known after apply)
      + name            = (known after apply)
      + organization_id = (known after apply)
      + server_id       = (known after apply)
      + size_in_gb      = 550
      + type            = "l_ssd"
      + zone            = (known after apply)
    }

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

6 . If the output obtained is the same as the one above, it is now time to apply the new configuration and to create the instance using Terraform by runnning terraform apply. Confirm the execution of the plan by typing yes when prompted:

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:

  # scaleway_instance_ip.public_ip will be created
  + resource "scaleway_instance_ip" "public_ip" {
      + address         = (known after apply)
      + id              = (known after apply)
      + organization_id = (known after apply)
      + reverse         = (known after apply)
      + zone            = (known after apply)
    }

  # scaleway_instance_server.my-ubuntu-instance will be created
  + resource "scaleway_instance_server" "my-ubuntu-instance" {
      + additional_volume_ids            = (known after apply)
      + boot_type                        = (known after apply)
      + disable_dynamic_ip               = false
      + disable_public_ip                = false
      + enable_dynamic_ip                = false
      + enable_ipv6                      = false
      + id                               = (known after apply)
      + image                            = "ubuntu-focal"
      + ip_id                            = (known after apply)
      + ipv6_address                     = (known after apply)
      + ipv6_gateway                     = (known after apply)
      + ipv6_prefix_length               = (known after apply)
      + name                             = (known after apply)
      + organization_id                  = (known after apply)
      + placement_group_policy_respected = (known after apply)
      + private_ip                       = (known after apply)
      + public_ip                        = (known after apply)
      + security_group_id                = (known after apply)
      + state                            = "started"
      + tags                             = [
          + "FocalFossa",
          + "MyUbuntuInstance",
        ]
      + type                             = "GP1-M"
      + zone                             = (known after apply)

      + root_volume {
          + delete_on_termination = (known after apply)
          + size_in_gb            = (known after apply)
          + volume_id             = (known after apply)
        }
    }

  # scaleway_instance_volume.data will be created
  + resource "scaleway_instance_volume" "data" {
      + id              = (known after apply)
      + name            = (known after apply)
      + organization_id = (known after apply)
      + server_id       = (known after apply)
      + size_in_gb      = 600
      + type            = "l_ssd"
      + zone            = (known after apply)
    }

Plan: 3 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

scaleway_instance_volume.data: Creating...
scaleway_instance_ip.public_ip: Creating...
scaleway_instance_volume.data: Creation complete after 1s [id=fr-par-1/062d9304-1412-466f-95b9-1c0b8286d3ce]
scaleway_instance_ip.public_ip: Creation complete after 1s [id=fr-par-1/ac25fc43-610a-4993-b3ff-dfcb916925f4]
scaleway_instance_server.my-ubuntu-instance: Creating...
scaleway_instance_server.my-ubuntu-instance: Still creating... [10s elapsed]
scaleway_instance_server.my-ubuntu-instance: Still creating... [20s elapsed]
scaleway_instance_server.my-ubuntu-instance: Still creating... [30s elapsed]
scaleway_instance_server.my-ubuntu-instance: Still creating... [40s elapsed]
scaleway_instance_server.my-ubuntu-instance: Creation complete after 47s [id=fr-par-1/80ed6409-2d5b-4bed-90e8-6bdcf7d3ea34]

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

7 . Go to the Instances section in your Scaleway Console. You can see that the instance has been created:

Modifying an instance using Terraform

Now, as a first instance is up and running, we are going to modify it by restricting the access to it using Security Groups. We are going to DROP all traffic to the instance by default, only traffic to ports 80 (HTTP), 443 (HTTPS) and 22 (SSH) will be allowed. To do so, we have to add some more lines to our existing configuration file scaleway.tf.

Important: All changes made to the local configuration file are not effective in production before the new configuration is applied using the terraform apply command.

1 . Open the configuration file scaleway.tf in a text editor and edit it as follows:

provider "scaleway" {
  access_key      = "<SCALEWAY-ACCESS-KEY>"
  secret_key      = "<SCALEWAY-SECRET-KEY>"
  organization_id = "<SCALEWAY-ORGANIZATION-ID>"
  zone            = "fr-par-1"
  region          = "fr-par"
}

resource "scaleway_instance_ip" "public_ip" {}

resource "scaleway_instance_volume" "data" {
  size_in_gb = 550
  type = "l_ssd"
}

resource "scaleway_instance_security_group" "my-security-group" {
  inbound_default_policy  = "drop"
  outbound_default_policy = "accept"

  inbound_rule {
    action = "accept"
    port   = "22"
  }

  inbound_rule {
    action = "accept"
    port   = "80"
  }

  inbound_rule {
    action = "accept"
    port   = "443"
  }
}

resource "scaleway_instance_server" "my-ubuntu-instance" {
  type  = "GP1-M"
  image = "ubuntu-focal"

  tags = [ "FocalFossa", "MyUbuntuInstance" ]

  ip_id = scaleway_instance_ip.public_ip.id

  additional_volume_ids = [ scaleway_instance_volume.data.id ]
  security_group_id = scaleway_instance_security_group.my-security-group.id

}

Save the file and exit the text editor.

2 . Run terraform apply again to see how Terraform applies the new configuration to the existing instance:

$ terraform apply
scaleway_instance_volume.data: Refreshing state... [id=fr-par-1/37a68207-3eb7-4eb2-b39a-750bc26d412f]
scaleway_instance_ip.public_ip: Refreshing state... [id=fr-par-1/ac25fc43-610a-4993-b3ff-dfcb916925f4]
scaleway_instance_server.my-ubuntu-instance: Refreshing state... [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d]

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

Terraform will perform the following actions:

  # scaleway_instance_security_group.my-security-group will be created
  + resource "scaleway_instance_security_group" "my-security-group" {
      + external_rules          = false
      + id                      = (known after apply)
      + inbound_default_policy  = "drop"
      + name                    = (known after apply)
      + organization_id         = (known after apply)
      + outbound_default_policy = "accept"
      + zone                    = (known after apply)

      + inbound_rule {
          + action   = "accept"
          + port     = 22
          + protocol = "TCP"
        }
      + inbound_rule {
          + action   = "accept"
          + port     = 80
          + protocol = "TCP"
        }
      + inbound_rule {
          + action   = "accept"
          + port     = 443
          + protocol = "TCP"
        }
    }

  # scaleway_instance_server.my-ubuntu-instance will be updated in-place
  ~ resource "scaleway_instance_server" "my-ubuntu-instance" {
        additional_volume_ids = [
            "fr-par-1/37a68207-3eb7-4eb2-b39a-750bc26d412f",
        ]
        boot_type             = "local"
        disable_dynamic_ip    = false
        disable_public_ip     = false
        enable_dynamic_ip     = false
        enable_ipv6           = false
        id                    = "fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d"
        image                 = "ubuntu-focal"
        ip_id                 = "fr-par-1/ac25fc43-610a-4993-b3ff-dfcb916925f4"
        ipv6_prefix_length    = 0
        name                  = "tf-srv-heuristic-rubin"
        private_ip            = "10.12.170.1"
        public_ip             = "212.47.245.174"
      ~ security_group_id     = "fr-par-1/9881050d-c994-4613-86b9-7dcc5de4e74a" -> (known after apply)
        state                 = "started"
        tags                  = [
            "FocalFossa",
            "MyUbuntuInstance",
        ]
        type                  = "GP1-M"
        zone                  = "fr-par-1"

        root_volume {
            delete_on_termination = true
            size_in_gb            = 50
            volume_id             = "fr-par-1/1f2a8bec-816e-4407-9e9f-40f3fcb133c0"
        }
    }

Plan: 1 to add, 1 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

scaleway_instance_security_group.my-security-group: Creating...
scaleway_instance_security_group.my-security-group: Creation complete after 4s [id=fr-par-1/88de0af5-1b7a-4270-9add-f6d51689e832]
scaleway_instance_server.my-ubuntu-instance: Modifying... [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d]
scaleway_instance_server.my-ubuntu-instance: Modifications complete after 2s [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d]

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

3 . Terraform has created the security group and modified the configuration of the existing instance by adding it to the newly created group. You can see the group from the Scaleway console and check the rules that have been created:

Adding Resources to an Infrastructure

Terraform allows also to add resources to infrastructures and is capable of managing both, Virtual Instances and Bare Metal Servers. Let us add a Bare Metal Server to our Terraform project using the Bare Metal module of the Scaleway provider.

1 . Open the file scaleway.tf in a text editor and modify it as follows:

provider "scaleway" {
  access_key      = "<SCALEWAY-ACCESS-KEY>"
  secret_key      = "<SCALEWAY-SECRET-KEY>"
  organization_id = "<SCALEWAY-ORGANIZATION-ID>"
  zone            = "fr-par-1"
  region          = "fr-par"
}

resource "scaleway_instance_ip" "public_ip" {}

resource "scaleway_instance_volume" "data" {
  size_in_gb = 550
  type = "l_ssd"
}

resource "scaleway_instance_security_group" "my-security-group" {
  inbound_default_policy  = "drop"
  outbound_default_policy = "accept"

  inbound_rule {
    action = "accept"
    port   = "22"
  }

  inbound_rule {
    action = "accept"
    port   = "80"
  }

  inbound_rule {
    action = "accept"
    port   = "443"
  }
}

resource "scaleway_instance_server" "my-ubuntu-instance" {
  type  = "GP1-M"
  image = "ubuntu-focal"

  tags = [ "FocalFossa", "MyUbuntuInstance" ]

  ip_id = scaleway_instance_ip.public_ip.id

  additional_volume_ids = [ scaleway_instance_volume.data.id ]
  security_group_id = scaleway_instance_security_group.my-security-group.id

}

data "scaleway_account_ssh_key" "main" {
  ssh_key_id  = "254a5c59-89bf-4e47-a5d1-48d8a31e8c5d"
}

resource "scaleway_baremetal_server" "base" {

  zone        = "fr-par-2"
  offer       = "GP-BM1-M"
  os          = "d17d6872-0412-45d9-a198-af82c34d3c5c"
  ssh_key_ids = [data.scaleway_account_ssh_key.main.ssh_key_id]
}

Apply the new configuration using terraform apply. Terraform will add a Bare Metal Server to the existing infrastructure

  # scaleway_baremetal_server.base will be created
  + resource "scaleway_baremetal_server" "base" {
      + domain          = (known after apply)
      + id              = (known after apply)
      + ips             = (known after apply)
      + name            = (known after apply)
      + offer           = "GP-BM1-M"
      + offer_id        = (known after apply)
      + organization_id = (known after apply)
      + os              = "d17d6872-0412-45d9-a198-af82c34d3c5c"
      + os_id           = (known after apply)
      + ssh_key_ids     = [
          + "6c72f8e9-be39-4295-afb1-ce934c88a1de",
        ]
      + zone            = "fr-par-2"
    }

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

scaleway_baremetal_server.base: Creating...
scaleway_baremetal_server.base: Still creating... [10s elapsed]
scaleway_baremetal_server.base: Still creating... [20s elapsed]
scaleway_baremetal_server.base: Still creating... [30s elapsed]
scaleway_baremetal_server.base: Still creating... [40s elapsed]
scaleway_baremetal_server.base: Still creating... [50s elapsed]
scaleway_baremetal_server.base: Still creating... [1m0s elapsed]
scaleway_baremetal_server.base: Still creating... [1m10s elapsed]
scaleway_baremetal_server.base: Still creating... [1m20s elapsed]
scaleway_baremetal_server.base: Still creating... [1m30s elapsed]
[...]
scaleway_baremetal_server.base: Creation complete after 12m42s [id=fr-par-2/f761ff74-de50-44c3-afab-3c1ef00b16b7]

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

Note: The creation of a Bare Metal server may take up to several minutes.

Storing the Terraform state in the Cloud

Optionally, you can use the S3 Backend to store your Terraform state in a Scaleway Object Storage. Configure your backend as follows:

terraform {
  backend "s3" {
    bucket                      = "terraform_state"
    key                         = "my_state.tfstate"
    region                      = "fr-par"
    endpoint                    = "https://s3.fr-par.scw.cloud"
    access_key                  = "my-access-key"
    secret_key                  = "my-secret-key"
    skip_credentials_validation = true
    skip_region_validation      = true
  }
}

Deleting Infrastructures using Terraform

Now you have deployed a Terraform infrastructure, modified its settings and added additional resources. In case you want to destroy the infrastructure, you can clean up everything using the terraform destroy command.

1 . Run terraform destroy in your terminal. The infrastructure created previously will be destroyed:

$ terraform destroy
scaleway_instance_volume.data: Refreshing state... [id=fr-par-1/37a68207-3eb7-4eb2-b39a-750bc26d412f]
data.scaleway_account_ssh_key.main: Refreshing state...
scaleway_instance_ip.public_ip: Refreshing state... [id=fr-par-1/ac25fc43-610a-4993-b3ff-dfcb916925f4]
scaleway_instance_security_group.my-security-group: Refreshing state... [id=fr-par-1/88de0af5-1b7a-4270-9add-f6d51689e832]
scaleway_baremetal_server.base: Refreshing state... [id=fr-par-2/f761ff74-de50-44c3-afab-3c1ef00b16b7]
scaleway_instance_server.my-ubuntu-instance: Refreshing state... [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d]

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:

  # scaleway_baremetal_server.base will be destroyed
  - resource "scaleway_baremetal_server" "base" {
      - domain          = "f761ff74-de50-44c3-afab-3c1ef00b16b7.fr-par-2.baremetal.scw.cloud" -> null
      - id              = "fr-par-2/f761ff74-de50-44c3-afab-3c1ef00b16b7" -> null
      - ips             = [
          - {
              - address = "2001:bc8:1200:1:dac4:97ff:fe5b:7551"
              - id      = "3cc6979a-3776-42dd-8fdd-9ed552ed57e1"
              - reverse = "f761ff74-de50-44c3-afab-3c1ef00b16b7.fr-par-2.baremetal.scw.cloud"
              - version = "IPv6"
            },
          - {
              - address = "51.159.57.46"
              - id      = "cc18b9aa-b748-4185-af46-c4bec865c75b"
              - reverse = "f761ff74-de50-44c3-afab-3c1ef00b16b7.fr-par-2.baremetal.scw.cloud"
              - version = "IPv4"
            },
        ] -> null
      - name            = "tf-bm-cranky-kowalevski" -> null
      - offer           = "GP-BM1-M" -> null
      - offer_id        = "fr-par-2/964f9b38-577e-470f-a220-7d762f9e8672" -> null
      - organization_id = "<ORGANIZATION-ID>" -> null
      - os              = "d17d6872-0412-45d9-a198-af82c34d3c5c" -> null
      - os_id           = "fr-par-2/d17d6872-0412-45d9-a198-af82c34d3c5c" -> null
      - ssh_key_ids     = [
          - "254a5c59-89bf-4e47-a5d1-48d8a31e8c5d",
        ] -> null
      - tags            = [] -> null
      - zone            = "fr-par-2" -> null
    }

  # scaleway_instance_ip.public_ip will be destroyed
  - resource "scaleway_instance_ip" "public_ip" {
      - address         = "212.47.245.174" -> null
      - id              = "fr-par-1/ac25fc43-610a-4993-b3ff-dfcb916925f4" -> null
      - organization_id = "<ORGANIZATION-ID>" -> null
      - zone            = "fr-par-1" -> null
    }

  # scaleway_instance_security_group.my-security-group will be destroyed
  - resource "scaleway_instance_security_group" "my-security-group" {
      - external_rules          = false -> null
      - id                      = "fr-par-1/88de0af5-1b7a-4270-9add-f6d51689e832" -> null
      - inbound_default_policy  = "drop" -> null
      - name                    = "tf-sg-magical-jones" -> null
      - organization_id         = "a6a05c73-fa53-46a4-9ea1-e53b4f625527" -> null
      - outbound_default_policy = "accept" -> null
      - zone                    = "fr-par-1" -> null

      - inbound_rule {
          - action   = "accept" -> null
          - port     = 22 -> null
          - protocol = "TCP" -> null
        }
      - inbound_rule {
          - action   = "accept" -> null
          - port     = 80 -> null
          - protocol = "TCP" -> null
        }
      - inbound_rule {
          - action   = "accept" -> null
          - port     = 443 -> null
          - protocol = "TCP" -> null
        }
    }

  # scaleway_instance_server.my-ubuntu-instance will be destroyed
  - resource "scaleway_instance_server" "my-ubuntu-instance" {
      - additional_volume_ids = [
          - "fr-par-1/37a68207-3eb7-4eb2-b39a-750bc26d412f",
        ] -> null
      - boot_type             = "local" -> null
      - disable_dynamic_ip    = false -> null
      - disable_public_ip     = false -> null
      - enable_dynamic_ip     = false -> null
      - enable_ipv6           = false -> null
      - id                    = "fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d" -> null
      - image                 = "ubuntu-focal" -> null
      - ip_id                 = "fr-par-1/ac25fc43-610a-4993-b3ff-dfcb916925f4" -> null
      - ipv6_prefix_length    = 0 -> null
      - name                  = "tf-srv-heuristic-rubin" -> null
      - private_ip            = "10.12.170.1" -> null
      - public_ip             = "212.47.245.174" -> null
      - security_group_id     = "fr-par-1/88de0af5-1b7a-4270-9add-f6d51689e832" -> null
      - state                 = "started" -> null
      - tags                  = [
          - "FocalFossa",
          - "MyUbuntuInstance",
        ] -> null
      - type                  = "GP1-M" -> null
      - zone                  = "fr-par-1" -> null

      - root_volume {
          - delete_on_termination = true -> null
          - size_in_gb            = 50 -> null
          - volume_id             = "fr-par-1/1f2a8bec-816e-4407-9e9f-40f3fcb133c0" -> null
        }
    }

  # scaleway_instance_volume.data will be destroyed
  - resource "scaleway_instance_volume" "data" {
      - id              = "fr-par-1/37a68207-3eb7-4eb2-b39a-750bc26d412f" -> null
      - name            = "tf-vol-condescending-shirley" -> null
      - organization_id = "<ORGANIZATION-ID>" -> null
      - server_id       = "df778c76-36dc-43eb-b028-f000d131a75d" -> null
      - size_in_gb      = 550 -> null
      - type            = "l_ssd" -> null
      - zone            = "fr-par-1" -> null
    }

Plan: 0 to add, 0 to change, 5 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

scaleway_instance_server.my-ubuntu-instance: Destroying... [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d]
scaleway_baremetal_server.base: Destroying... [id=fr-par-2/f761ff74-de50-44c3-afab-3c1ef00b16b7]
scaleway_baremetal_server.base: Still destroying... [id=fr-par-2/f761ff74-de50-44c3-afab-3c1ef00b16b7, 10s elapsed]
scaleway_instance_server.my-ubuntu-instance: Still destroying... [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d, 10s elapsed]
scaleway_baremetal_server.base: Still destroying... [id=fr-par-2/f761ff74-de50-44c3-afab-3c1ef00b16b7, 20s elapsed]
scaleway_instance_server.my-ubuntu-instance: Still destroying... [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d, 20s elapsed]
scaleway_baremetal_server.base: Still destroying... [id=fr-par-2/f761ff74-de50-44c3-afab-3c1ef00b16b7, 30s elapsed]
scaleway_instance_server.my-ubuntu-instance: Still destroying... [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d, 30s elapsed]
scaleway_baremetal_server.base: Destruction complete after 31s
scaleway_instance_server.my-ubuntu-instance: Still destroying... [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d, 40s elapsed]
scaleway_instance_server.my-ubuntu-instance: Still destroying... [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d, 50s elapsed]
scaleway_instance_server.my-ubuntu-instance: Still destroying... [id=fr-par-1/df778c76-36dc-43eb-b028-f000d131a75d, 1m0s elapsed]
scaleway_instance_server.my-ubuntu-instance: Destruction complete after 1m6s
scaleway_instance_ip.public_ip: Destroying... [id=fr-par-1/ac25fc43-610a-4993-b3ff-dfcb916925f4]
scaleway_instance_volume.data: Destroying... [id=fr-par-1/37a68207-3eb7-4eb2-b39a-750bc26d412f]
scaleway_instance_security_group.my-security-group: Destroying... [id=fr-par-1/88de0af5-1b7a-4270-9add-f6d51689e832]
scaleway_instance_ip.public_ip: Destruction complete after 0s
scaleway_instance_security_group.my-security-group: Destruction complete after 0s
scaleway_instance_volume.data: Destruction complete after 1s

Destroy complete! Resources: 5 destroyed.

You know have managed a complete lifecycle of an infrastructure using Terraform. To discover more Terraform commands, use the terraform -h command. Common Terraform commands include for example:

  • apply: Builds or changes infrastructure
  • console: Interactive console for Terraform interpolations
  • destroy: Destroy Terraform-managed infrastructure env Workspace management
  • fmt: Rewrites config files to canonical format
  • get: Download and install modules for the configuration
  • graph: Create a visual graph of Terraform resources
  • import: Import existing infrastructure into Terraform
  • init: Initialize a Terraform working directory
  • output: Read an output from a state file
  • plan: Generate and show an execution plan
  • providers: Prints a tree of the providers used in the configuration
  • refresh: Update local state file against real resources
  • show: Inspect Terraform state or plan
  • taint: Manually mark a resource for recreation
  • untaint: Manually unmark a resource as tainted
  • validate Validates the Terraform files
  • version: Prints the Terraform version
  • workspace: Workspace management

To create configurations that are truely shareable and version controlled, it is recommended to organize your code with modules. Modules are used to encapsulate logic and design a layer of abstraction for Terraform code.

Most modules manage a few closely related resources from a single provider and allow to parameterize the configurations. You can define variables to simplify the management of your infrastructures and to duplicate it in no time.

For example, create a configuration file variables.tf in your Terraform Project directory and edit it as follows:

variable "zone" { 
  default = "fr-par-1" 
  } 

You have 3 options to use these variables:

1 . As an environment variable: TF_VAR_zone=${var.zone} terraform apply

2 . As a command-line parameter variable: terraform apply -var zone=${var.zone}

3 . As a variables file: terraform apply -var-file=variables.tf

To learn more, discover how to deploy your cloud resources using Packer and Terraform.

Discover the Cloud That Makes Sense