
In this lab, you will:
In the future, it will be more comfortable if you're able to use terraform from your PC and IDE.
To install terraform, refer to the respective documentation here:
Please ensure, that the terraform binary is in your path!
To check if terraform is installed and as accessible, open a shell and run: terraform version. This should return the version of Terraform. If not and you changed the PATH before, ensure that you restarted your terminal and the Terraform Binary is located in a directory which is accessible there.
Exoscale is a European Cloud Provider, which provides services as:
During this lab, we will deal with virtual instances and object storage. In the first step, we will provision a virtual machine there.
You can log in to the Exoscale Console here.
As a Cloud Engineer, your want to test a new tool. As you don't have the possibility to run a virtual machine on your machine, you decide to run the machine in the cloud. After the machine is provisioned, you are running the tool you wanted to test and destroy the Virtual Instance again.
We will deploy the Virtual Machine via the Exoscale UI. Therefore, open the Exoscale Console and Log In with your credentials.
You might want to be able to access your Virtual Machine after it is provisioned. Therefore, we need to precreate an SSH Key which can be used to access this machine.
This SSH Key has to be created on your machine. On Linux, Mac or WSL machines, this should work as follows:
ssh-keygen -t ed25519 -f exoscale (and remember where you ran this!) The public part of the SSH Keypair has to be stored in Exoscale to make it usable in Virtual Machines. Therefore, select "Compute" -> "SSH-Keys" -> "Add", assign a name you remember to the key and paste the public part.
With this, we should have everything we need to provision a virtual machine.

In our lab, we might want to try out a tool and therefore it is beneficial to have shell access. Now it's time to remember where you stored the private ssh key. When you found it, open up your shell and execute:
ssh -i {{path-to-your-private-key}} debian@{{ip-address-of-your-instance}} (you can find the ip address on the instance screen)You will find out that you are not able to connect to the machine. This is due to a missing security group.
To add the security group, select "Security Groups" in the "Compute" menu:
Public Access and "Create Group"There were many steps we had to take until we got our simple virtual machine working. The current setup is fairly enough to try out some new things, but in the real world you might want to do this in a more reproducible and scalable way.
This is where Infrastructure-as-Code comes into play. When you are provisioning 100s of instances, you might not want to click through the consoles for every one you are provisioning. Infrastructure-as-Code (IaC) gives you the possibility to configure your instances:
Let's take a closer look on all of this.
"Infrastructure-as-Code is an approach to infrastructure-automation based on practices from software development. It emphasizes consisten, repeatable routines for provisioning and changing systems and their configuration. You make changes to code, then use automation to tsest and apply those changes to your systems. (Kief Morris(2020), Infrastructure-as-Code, 2nd Edition)"
When we're talking about Infrastructure-as-Code, we are no more creating our Infrastructure via the UI (ClickOps). Instead, we are writing Code, mainly in a declarative way to describe the state, we want our Infrastructure to be in after it is applied.
Declarative configuration means that you express your intention (desired state), and a tool takes care of transitioning the managed objects to this state. Using imperative language, you would tell the tooling what it should do. You can distinguish between these two styles using the following statements:
Please note, that each declarative tool, will have some kind of imperative logic in it to transition to the state.
When we're provisioning Infrastructure-as-Code, we often have the possibility to modularize components, as well as having mechanisms in there, which help us creating multiple, similar objects. This are practices, we know from typical software development. As we are using practices from Software Development, we should also treat our Infrastructure as such. Therefore, the code should be versioned, there should be automatic tests in place and pull requests should be on the order of the day.
There are many tools out there for Infrastructure-as-Code like:
Which tool you use, often depends on your own preferences and your use-cases. In this lab, we will take a closer look on Terraform.
Further Information / Videos:
Before we will start with our first configuration, we will put some light on Terraform.
Terraform is an Infrastructure-as-Code tool developed by Hashicorp. It uses a declarative language to describe infrastructure. The language used is the "Hashicorp Configuration Language (HCL)". It is designed to work with many cloud providers. Nevertheless, it is not really cloud-agnostic as knowledge about the individual providers is needed when writing the code.
To start using Terraform, we should be familiar with the following terms:
For this lab, we will use a local state, Exoscale as provider and a Compute resource to create our Virtual Machine.
Your Boss heard about a new technique to provision virtual instances. He tells you that you should get familiar with this and provision the same virtual machine as before using Terraform
terraform.tf in your directoryterraform {
required_providers {
exoscale = {
source = "exoscale/exoscale"
version = "0.48.0"
}
}
}
provider "exoscale" {
key = "key"
secret = "secret"
}
terraform init
Initializing the backend...
Initializing provider plugins...
- Finding exoscale/exoscale versions matching "0.48.0"...
- Installing exoscale/exoscale v0.48.0...
- Installed exoscale/exoscale v0.48.0 (signed by a HashiCorp partner, key ID 81426F034A3D05F7)
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.
In the second step, we will try to create a virtual instance ...
To do so, we'll create a second file called main.tf. Furthermore, we copy the following configuration in this file. Replace the ssh_key with the name of the one you created before:
data "exoscale_compute_template" "my_template" {
zone = "at-vie-1"
name = "Linux Ubuntu 22.04 LTS 64-bit"
}
data "exoscale_security_group" "public" {
name = "<your-security-group-name>"
}
resource "exoscale_compute_instance" "my_instance" {
zone = "at-vie-1"
name = "my-instance"
template_id = data.exoscale_compute_template.my_template.id
type = "standard.medium"
disk_size = 10
ssh_key = "<your-ssh-key-name>"
security_group_ids = [ data.exoscale_security_group.public.id ]
}
Notable Things:
Data Sources are here to get configurations from your cloud provider, but will change nothing and are used for referencing in other objects
Resources are objects you are managing with terraform
terraform plan
terraform apply
❯ terraform apply
data.exoscale_security_group.public: Reading...
data.exoscale_compute_template.my_template: Reading...
data.exoscale_security_group.public: Read complete after 1s [id=8b225a34-9e8e-4583-a604-a64f61e9c4b9]
data.exoscale_compute_template.my_template: Read complete after 1s [id=5ef4024a-32bd-4ed4-8887-9bcb21290579]
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:
# exoscale_compute_instance.my_instance will be created
+ resource "exoscale_compute_instance" "my_instance" {
+ created_at = (known after apply)
+ disk_size = 10
+ id = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ name = "my-instance"
+ private = false
+ private_network_ids = (known after apply)
+ public_ip_address = (known after apply)
+ security_group_ids = [
+ "8b225a34-9e8e-4583-a604-a64f61e9c4b9",
]
+ ssh_key = "exoscale-thsc"
+ state = (known after apply)
+ template_id = "5ef4024a-32bd-4ed4-8887-9bcb21290579"
+ type = "standard.medium"
+ zone = "at-vie-1"
}
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
exoscale_compute_instance.my_instance: Creating...
exoscale_compute_instance.my_instance: Still creating... [10s elapsed]
exoscale_compute_instance.my_instance: Still creating... [20s elapsed]
exoscale_compute_instance.my_instance: Creation complete after 21s [id=f4ce2306-ff14-4e8d-8a8a-65e97b872931]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

ubuntu now.terraform destroy
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
exoscale_compute_instance.my_instance: Destroying... [id=f4ce2306-ff14-4e8d-8a8a-65e97b872931]
exoscale_compute_instance.my_instance: Still destroying... [id=f4ce2306-ff14-4e8d-8a8a-65e97b872931, 10s elapsed]
exoscale_compute_instance.my_instance: Destruction complete after 13s
Destroy complete! Resources: 1 destroyed.