Pour les besoins des cours que je donne Ă  l’UniversitĂ© de Lille, j’ai eu besoin de configurer des bases de donnĂ©es PostgreSQL et un serveur Vault sur Clever Cloud (l’installation et la configuration d’un Vault sur Clever Cloud feront l’objet d’un article consacrĂ©).

Étant aussi un grand utilisateur de Terraform (qui l’eut crĂ» ?), j’en ai profitĂ© pour automatiser tout ça avec mon outil prĂ©fĂ©rĂ©.

Cet article dĂ©crit comment utiliser le provider Terraform de Clever Cloud pour instancier une base de donnĂ©es et rĂ©cupĂ©rer ses accĂšs. La premiĂšre Ă©tape consistera Ă  configurer un backend pour y stocker le fichier d’Ă©tat de Terraform (state), la seconde Ă©tape consistera Ă  crĂ©er la base de donnĂ©es en elle-mĂȘme.

Pour pouvoir reproduire le contenu de cet article, vous aurez besoin d’un compte sur Clever Cloud, ainsi que des CLI Clever Cloud et Terraform (ou OpenTofu) installĂ©s sur votre machine.

Le code de cet article est aussi disponible sur GitHub : https://github.com/juwit/terraform-clevercloud-playground.

Cet article a été écrit avec des commandes Terraform, mais fonctionne également avec les commandes OpenTofu équivalentes.

CrĂ©ation d’un bucket avec Terraform

La crĂ©ation d’un bucket se fait en 2 Ă©tapes, la crĂ©ation de l’add-on Cellar, puis la crĂ©ation du bucket en lui-mĂȘme.

Nous écrivons alors un premier root-module Terraform, qui contiendra le code correspondant à la création de notre bucket.

Configurer le provider Clever Cloud

La configuration du provider de Clever Cloud est décrite dans la documentation de son provider Terraform sur registry.terraform.io.

Un premier fichier versions.tf permet de dĂ©clarer l’utilisation du provider Clever Cloud :

terraform {
  required_providers {
    clevercloud = {
      source = "CleverCloud/clevercloud"
      version = "0.5.1"
    }
  }
}

Un fichier provider.tf permet ensuite de dĂ©clarer l’instanciation du provider :

provider "clevercloud" {
  # Configuration options
}

PlutĂŽt que d’utiliser des paramĂštres en dur, je dĂ©clare les diffĂ©rents paramĂštres requis par le provider avec des variables d’environnement.

export CC_ORGANISATION=orga_6cd71100-5957-4a42-90b8-74cbbdef19a7
export CC_OAUTH_TOKEN=7abcc4ad51024d788a033066e6ae2bd5
export CC_OAUTH_SECRET=54707b61e5ff44a08137f64fa2bbf4ce

La commande clever login permet de récupérer les valeurs des variables CC_OAUTH_TOKEN et CC_OAUTH_SECRET :

Clever Login

La valeur de la variable CC_ORGANISATION se récupÚre directement dans la console de Clever Cloud.

L’exĂ©cution de terrafrom init permet ensuite d’installer le provider localement :

$ terraform init

Initializing the backend...
Initializing provider plugins...
- Finding clevercloud/clevercloud versions matching "0.5.1"...
- Installing clevercloud/clevercloud v0.5.1...
- Installed clevercloud/clevercloud v0.5.1 (self-signed, key ID DFAF28F92CC465CC)
Partner and community providers are signed by their developers.

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.

CrĂ©ation de l’add-on et du bucket.

Le provider Clever Cloud propose 2 ressources nous permettant de crĂ©er un add-on Cellar et un bucket, ce dernier devant rĂ©fĂ©rencer l’add-on dans lequel il sera crĂ©Ă© :

resource "clevercloud_cellar" "this" {
  # le nom que l'on souhaite donner Ă  notre addon
  name = "tfstate"
}

resource "clevercloud_cellar_bucket" "backend_bucket" {
  cellar_id = clevercloud_cellar.this.id
  # le nom que l'on souhaite donner Ă  notre bucket
  id        = "tfstate-bucket"
}

L’exĂ©cution terraform plan permet de vĂ©rifier la bonne configuration du code :

$ terraform plan

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:

  # clevercloud_cellar.this will be created
  + resource "clevercloud_cellar" "this" {
      + host       = (known after apply)
      + id         = (known after apply)
      + key_id     = (known after apply)
      + key_secret = (sensitive value)
      + name       = "tfstate"
      + region     = "par"
    }

  # clevercloud_cellar_bucket.backend_bucket will be created
  + resource "clevercloud_cellar_bucket" "backend_bucket" {
      + cellar_id = (known after apply)
      + id        = "tfstate-bucket"
    }

Plan: 2 to add, 0 to change, 0 to destroy.

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you
run "terraform apply" now.

La crĂ©ation de l’add-on se fait ensuite avec la commande terraform apply :

$ terraform apply
clevercloud_cellar.this: Creating...
clevercloud_cellar.this: Creation complete after 2s [id=cellar_07eb54fc-34a9-4ed9-b802-b9c587741659]
clevercloud_cellar_bucket.backend_bucket: Creating...
clevercloud_cellar_bucket.backend_bucket: Creation complete after 0s [id=tfstate-bucket]

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

Une fois cette commande exĂ©cutĂ©e, l’add-on et le bucket apparaissent dans la console :

img.png

RĂ©cupĂ©ration des informations d’accĂšs au bucket

Les informations d’accĂšs au bucket sont affichĂ©es dans la console Clever Cloud, mais il est aussi possible de les extraire de nos ressources Terraform avec des outputs.

Le fichier outputs.tf permet d’exposer ces valeurs :

output "cellar_keys" {
  sensitive = true
  value = {
    host       = clevercloud_cellar.this.host
    key_id     = clevercloud_cellar.this.key_id
    key_secret = clevercloud_cellar.this.key_secret
  }
}

Les valeurs des attributs de la ressource clevercloud_cellar sont sensitive, l’output les utilisant doit donc ĂȘtre aussi marquĂ©e sensitive.

La commande terraform refresh permet ensuite de recalculer les outputs, puis terraform output cellar_keys permet de les récupérer :

$ terraform output

cellar_keys = <sensitive>

$ terraform output cellar_keys

{
  "host" = "cellar-c2.services.clever-cloud.com"
  "key_id" = "c62c0e82ed7542ec962657e4fd76cb4e"
  "key_secret" = "6c47d99041aa43e29d05dbdce20d3f34"
}

Ces informations nous permettront de configurer le backend pour notre second root-module.

CrĂ©ation d’une base de donnĂ©es PostgreSQL

Dans un nouveau root-module, nous crĂ©ons comme prĂ©cĂ©demment un fichier provider.tf et versions.tf pour dĂ©clarer l’utilisation du provider Clever Cloud.

Configuration du backend

Les buckets Clever Cloud peuvent ĂȘtre utilisĂ©s comme backend pour le state Terraform.

Il faut alors utiliser le backend s3 et adapter un peu sa configuration, dans un fichier backend.tf :

terraform {
  backend "s3" {
    bucket = "tfstate-bucket"
    key    = "terraform.tfstate"

    region = "eu-west-1"

    endpoints = {
      s3 = "https://cellar-c2.services.clever-cloud.com"
    }

    # désactivation des contrÎles liées à S3/AWS
    skip_credentials_validation = true
    skip_requesting_account_id  = true
    skip_s3_checksum            = true
  }
}

Les clĂ©s d’accĂšs sont rĂ©cupĂ©rĂ©es de l’Ă©tape prĂ©cĂ©dente, et exportĂ©es en variable d’environnement :

export AWS_ACCESS_KEY_ID=c62c0e82ed7542ec962657e4fd76cb4e
export AWS_SECRET_ACCESS_KEY=6c47d99041aa43e29d05dbdce20d3f34

La commande terraform init permet ensuite de configurer le provider Clever Cloud, ainsi que le backend s3 pointant vers notre bucket :

$ terraform init

Initializing the backend...

Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Reusing previous version of clevercloud/clevercloud from the dependency lock file
- Using previously-installed clevercloud/clevercloud v0.5.1

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.

Initialisation de la base de donnée

La base de donnĂ©es peut ensuite ĂȘtre initialisĂ©e avec le code Terraform suivant :

resource "clevercloud_postgresql" "this" {
  name   = "tf_pg"
  plan   = "dev"
  region = "par"
}

L’exĂ©cution de terraform plan permet de vĂ©rifier que tout est correct :

$ terraform plan -out tfplan

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:

  # clevercloud_postgresql.this will be created
  + resource "clevercloud_postgresql" "this" {
      + creation_date = (known after apply)
      + database      = (known after apply)
      + host          = (known after apply)
      + id            = (known after apply)
      + name          = "tf_pg"
      + password      = (known after apply)
      + plan          = "dev"
      + port          = (known after apply)
      + region        = "par"
      + user          = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Saved the plan to: tfplan

To perform exactly these actions, run the following command to apply:
    terraform apply "tfplan"

Une fois les vĂ©rifications effectuĂ©es, la commande terraform apply permet d’exĂ©cuter la crĂ©ation de la base de donnĂ©es :

$ terraform apply tfplan
clevercloud_postgresql.this: Creating...
clevercloud_postgresql.this: Creation complete after 1s [id=addon_e4dd9dd4-bc97-4b5a-9a2e-11f6c80b083a]

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

La base de données apparaßt alors dans la console Clever Cloud :

img.png

La ressource clevercloud_postgresql permet également de récupérer les informations de connexion à la base de données.

Le fichier outputs.tf suivant permet de les exposer :

output "postgresql_credentials" {
  value = {
    host     = clevercloud_postgresql.this.host
    port     = clevercloud_postgresql.this.port
    database = clevercloud_postgresql.this.database
    user     = clevercloud_postgresql.this.user
    password = clevercloud_postgresql.this.password
  }
}

L’exĂ©cution de terraform refresh permet ensuite de les rĂ©cupĂ©rer dans la console :

$ terraform refresh
clevercloud_postgresql.this: Refreshing state... [id=addon_e4dd9dd4-bc97-4b5a-9a2e-11f6c80b083a]

Outputs:

postgresql_credentials = {
  "database" = "blbsoihwh9ustbil2knl"
  "host" = "blbsoihwh9ustbil2knl-postgresql.services.clever-cloud.com"
  "password" = "nGeASi8d9fjINdjpdax9aYzeP5TIpa"
  "port" = 50013
  "user" = "u2odugbazligrb9mmdzw"
}

En conclusion

Le provider Terraform Clever Cloud permet une utilisation basique des services et il est plutĂŽt simple Ă  utiliser. Il est maintenu Ă  jour par les Ă©quipes de Clever Cloud, ce qui est un bel effort de leur part, bravo Ă  eux !

Pendant l’Ă©criture de cet article, j’ai rencontrĂ© quelques points d’amĂ©lioration sur le provider, auxquels je vais probablement contribuer :

  • la documentation du provider Clever Cloud manque clairement d’exemples fonctionnels de code pour pouvoir dĂ©marrer rapidement
  • la documentation de Clever Cloud ne mentionne aucun cas d’usage de leur provider Terraform
  • l’utilisation de Cellar comme backend m’a nĂ©cessitĂ© plusieurs expĂ©rimentations avant de trouver le bon paramĂ©trage, cette utilisation mĂ©riterait une documentation en bon et dĂ»e forme
  • l’argument organisation du bloc provider est obligatoire, ce qui va Ă  l’encontre de son utilisation avec une variable d’environnement
  • les attributs de la ressource clevercloud_postgresql pourraient ĂȘtre marquĂ©s sensitive, en particulier le user et password

Le prochain article traitera de l’installation et de la configuration d’un serveur Vault sur Clever Cloud !

Liens et références