WritingScalewayScalewaypublished Mar 30, 2023seen 5d

Migrating an infrastructure using Terraform: Kanta's case

Open original ↗

Captured source

source ↗
published Mar 30, 2023seen 5dcaptured 3dhttp 200method plain

Migrating an infrastructure using Terraform: Kanta's case Deploy • Charles-Edouard Gagnaire • 30/03/23 • 9 min read

As a Professional Services Consultant at Scaleway, I help companies wishing to migrate to Scaleway, as part of the Scale Program launched earlier this year, in which my team plays a key role. We provide clients with ready-to-use infrastructure, and with the skills they need to make the change, to allow them to become autonomous later on.

Our first client was Kanta , a startup founded two years ago, which allows accountants to prevent money-laundering, and to automatize previously time-intensive tasks. Their technical team’s priority is to develop their application, not their infrastructure. This is why they asked the Scale Program to help them with their transfer.

The actions carried out during this mission are the result of work between several teams within Scaleway: the Solutions Architects, the Key Account Manager, as well as the Startup Program team, which supports startups.

In this article, I will share with you the Terraform templates that were developed to enable this migration, and the implementation, via Terraform, of the bastion, the database, the instances, the Object Storage bucket and the load balancer.

Preparing the migration: choosing the stack

To integrate a customer into the Scale program, we first had to define their needs, in order to understand how we can help them. Based on the target architecture recommended by the Solutions Architect, we defined the elements necessary for a Scaleway deployment.

When we work for a client, we focus on the tools we will use. The choice of infrastructure-as-code tools is central to our approach, because they guarantee the reproducibility of deployments, and simplify the creation of multiple identical environments.

Since the client was not yet familiar with Terraform, we decided together to start with a simple and well-documented code. Our service also includes skills transfer, so we made sure to focus on the Terraform aspect, to ensure that the client's teams can become autonomous afterwards.

Evaluating the architecture

The application that Kanta wished to migrate from OVH to Scaleway was a traditional application composed of:

A load balancer, open to the internet

A redundant application on two servers

A MySQL database

A Redis cache

Taking into account these needs, we proposed a simple architecture that meets these needs, while allowing an isolation of resources through the use of a Private Network. The customer will be able to access their machines thanks to an SSH bastion . In order to limit administrative tasks, we advised the customer to use a managed MySQL database and a managed Redis cluster.

Migrating the project

Here, the customer already has a Scaleway account that they use to do tests. We therefore decided to create a new project within this account. This allows us to segment resources and accesses, depending on the environment.

I started working on the Terraform files that allow me to deploy the development environment. To do this, I worked incrementally, starting from the lowest layers and adding elements as I go along.

Architecture

Provider

During our discussions with the client, we agreed on several things:

Firstly, the client wanted all of its data to be stored in the Paris region

Secondly, in order to perpetuate their Terraform status file, we decided to store it inside an Object Storage bucket

Finally, we decided to use the most recent version of Terraform, so we decided to add a strong constraint on the Terraform version.

When we take these different constraints into account, we end up with a providers.tf file, which looks like this:

terraform { required_providers { scaleway = { source = "scaleway/scaleway" } } // State storage backend "s3" { bucket = “bucket_name” // Path in the Object Storage bucket key = "dev/terraform.tfstate" // Region of the bucket region = "fr-par" // Change the endpoint if we change the region endpoint = "https://s3.fr-par.scw.cloud" // Needed for SCW skip_credentials_validation = true skip_region_validation = true } // Terraform version required_version = ">= 1.3" } CopyContentIcon Copy code This file allowed us to start deploying resources. As we saw earlier, the client is not familiar with Terraform and therefore wants to deploy the different environments themselves.

In order to make sure that everything works well, I still needed to deploy my resources as I work. So I used a test account with a temporary Object Storage bucket to validate my code.

Importantly, the bucket allowing us to store our Terraform states had to be created by hand in another project before we could make our first terraform run.

Creating the project

In the interests of simplicity, I decided to create a Terraform file for each type of resource, and so I ended up with a first project.tf file. This file is very short, it only contains the code for the creation of the new project:

resource "scaleway_account_project" "project" { provider = scaleway name = “Project - $ { var . env_name } " } CopyContentIcon Copy code In order to guarantee the reusability of the code, the project creation code requires a env_name variable, so I created a variables.tf file, in which I can put my first variable:

variable "env_name" { default = "dev" } CopyContentIcon Copy code This env_name variable is important, because we will use it in most resource names. This information may seem redundant, but with the use of multiple projects, it would be easy to make a mistake and find yourself in the wrong project without realizing it. Using the name of the environment in the name of the resources limits the risk of errors.

Attaching the SSH keys

Since we are creating a new project, we need to attach to it the public SSH keys that allow the client's teams to connect to their machine via the Public Gateway SSH bastion. So I created a new ssh_keys.tf file, where I can add the client's public SSH keys:

// Create Public SSH Keys and attach them to the Project resource "scaleway_iam_ssh_key" “ci - cd” { name = “ci - cd” public_key = “ssh - ed25519 xxxxxxxx” project_id = scaleway_account_project . project . id } resource "scaleway_iam_ssh_key" “user - admin” { name = “user - admin” public_key = “ssh - ed25519 xxxxxxxx” project_id = scaleway_account_project . project . id } CopyContentIcon Copy code It is quite possible to pass the public SSH keys as a variable in order to…

Excerpt shown — open the source for the full document.