Infrastructure as code easy with Terraform and scaleway

Oct 16, 2023 min read

Terraform, what is it?

Let’s put the context back: It’s a tool that allows creating objects in the cloud. Basically, we describe in files the instances, security groups, load-balancers, networks and everything that makes an IS.

Terraform reads files in which objects are described and creates them in the cloud system by connecting to the APIs of this same cloud. (I’m broadening the notion of cloud to any system allowing infrastructure management, like vmware, openstack or even kubernetes)

Terraform being a multicloud tool, in the following examples, we will use the SCALEWAY cloud, which I’m particularly fond of, both for its price and for the good ideas and dynamism of the teams.

1. Creating scaleway connection credentials

First create an account for free on https://console.scaleway.com/register and enter your banking details (and yes, it’s going to cost money if you follow this tutorial, but it’s for a good cause, but rest assured, we’ll start with an instance at 0.006€ per hour, which should be a few cents)

Then, you need to create an API token to be authorized to send requests to the cloud platform securely.

For scaleway, everything is explained here (English): How to generate an API token

But well otherwise, in summary, you click on “credentials” in the menu at the top right of the scaleway console:

Then, you click on the green “generate new token” button:

Give a name to your token:

Note the information well (the secret will only display once!)

There you go, the token is created.

DON’T SHARE IT! This gives direct access to your wallet and anyone could use it. (Don’t dream, the one I’m giving you is already deleted).

Keep in mind that objects you create with this are paid. In the case of scaleway, it doesn’t cost very much, but the bill can go up very fast at amazon, for example.

2. Creating terraform files

First, install the terraform client as indicated here: https://learn.hashicorp.com/terraform/getting-started/install.html

For practical questions, you can also clone right now this repo in which you’ll find all the code that follows:

_`git clone https://github.com/jeremiegoldberg/terraform_howto.git`_

We create the “provider.tf” file in our project. (File breakdown is not mandatory, but we do it for better readability), the provider being the link between your cloud and your code.

we enter the information retrieved previously:

`provider "scaleway" {`  
 `access_key      = "SCW4WVSRBY9TBRBWKHSR"`  
 `organization_id = "<my organization_ID>"`  
 `secret_key      = "f4609fc2-7964-47a4-835e-8ea9a44c6b30"`  
 `region          = "fr-par"`  
 `zone            = "fr-par-1"`  
`}`

We create the instance.tf file in which we’re going to put all information relative to our first server instance.

In this file, we start by creating a public ip address:

resource "scaleway\_instance\_ip" "public\_ip" {}

Then, the security group, which manages the server firewall we’re going to create:

resource "scaleway\_instance\_security\_group" "my\_security\_group" {  
 external\_rules = true  
 name = "netasgard\_VPC"  
}  
resource "scaleway\_instance\_security\_group\_rules" "security-rule" {  
security\_group\_id = "${scaleway\_instance\_security\_group.netasgard\_private.id}"  
  
inbound\_rule {  
action = "accept"  
 port   = "22"  
  }  inbound\_rule {  
action = "accept"  
 port   = "80"  
  }  inbound\_rule {  
action = "accept"  
 port   = "443"  
}  inbound\_rule {  
     action = "drop"  
  }  
}

We search for the latest docker x86_64 image:

data "scaleway\_image" "docker" {  
architecture = "x86\_64"  
name = "Docker"  
}

The following code allows creating an instance, a DEV1-S with the docker image retrieved just before:

resource "scaleway\_instance\_server" "instance" {  
  name  = "monserveur"  
  type  = "DEV1-S"  
  image = "${data.scaleway\_image.docker.id}"  
  tags = \[ "tag1", "tag2" \]  
  ip\_id = scaleway\_instance\_ip.public\_ip.id  
  security\_group\_id = "${scaleway\_instance\_security\_group.my\_security\_group.id}  
connection {  
    type     = "ssh"  
    user     = "root"  
    host     = "${scaleway\_instance\_ip.public\_ip.address}"  
  }  
  provisioner "file" {  
    source      = "files/docker-compose.yml"  
    destination = "/root/docker-compose.yml"  
  }  
  provisioner "remote-exec" {  
    inline = \[  
      "docker-compose up -d"  
    \]  
  }  
}

Note that I’ve added a small additional part in the code above. We’re going to start our instance and automatically deploy wordpress and mysql on it.

Because why not.

I declare an ssh connection with the user and remote ip which is our public ip (declared first in this tutorial)

  connection {  
    type     = "ssh"  
    user     = "root"  
    host     = "${scaleway\_instance\_ip.public\_ip.address}"  
  }

I copy via scp the docker-compose.yml file on the server in /root/

  provisioner "file" {  
    source      = "files/docker-compose.yml"  
    destination = "/root/docker-compose.yml"  
  } 

I execute docker-compose to start applications on the machine

  provisioner "remote-exec" {  
    inline = \[  
      "docker-compose up -d"  
    \]  
  }

Last thing, at the end of files, these last lines so that the script gives us our wordpress url:

output "lien\_de\_wordpress" {  
value = \["http://${scaleway\_instance\_ip.public\_ip.address}"\]  
}

/!\ Don’t forget to push your public ssh keys to scaleway (at the same place as credential creation), otherwise machine creation will fail. And even if we remove the 3 last code pieces above, you won’t be able to connect to the machine, ssh connection by password being abandoned at scaleway.

3. Code execution

Well, let’s start the magic part.

Let’s initialize the terraform repository:

_terraform init_

Which gives the following output:

There you go, Terraform is ready! We’re going to be able to launch hostilities and create our server with the command

terraform apply

Terraform details all objects that will be created before launching execution.

The prompt waits for a “yes” from you to continue:

Here we go for creating our instance!

And when everything went well, you get:

Follow the link and you’ll end up on a brand new wordpress:

To destroy everything that was created via terraform, it’s simple:

terraform destroy

And there you go, it no longer costs you anything.

In conclusion

In a few files, we’ve installed a wordpress CMS with its database. We’ve deployed this on an instance at 2.99€ per month on a cloud compatible with terraform.

With the same ease, we could have used ansible or other configuration manager on the newly created instance. We could have also deployed numerous instances in parallel to this one, with various applications, thanks to docker-compose.

Possibilities are infinite. This is only a very simple example of what we can do. The goal of this post is to prove that doing infrastructure as code is neither expensive, nor complicated. It’s above all a question of will.

To go deeper, if you want to understand the advantages and dangers of the cloud, I refer you to my post on the subject

-|