Aller au contenu principal

Comment nous avons importé les ressource Terraform

danger

Ces étapes ont été réalisées une fois pour toutes lors de l'initialisation du code Terraform du projet. Elles ont été documentées ici seulement pour garder mémoire du processus et pour aider à débugger plus tard si nécessaire.

Tenter de reproduire ces étapes sur les states déjà initialisés pourraient avoir des effets inattendus et provoquer des problèmes graves.

Pré-requis

1. Scalingo

Correspondances entre Ressources Terraform et routes d'API

Resource TerraformRoute(s) d'API *Identifiant unique pour l'import
scalingo_app/v1/appsapp_id
scalingo_container_type/v1/apps/[:app]/containersapp_id:container_name
scalingo_autoscaler/v1/apps/[:app]/autoscalersapp_name:autoscaler_id
scalingo_addon/v1/apps/[:app]/addonsapp_id:addon_id
scalingo_scm_repo_link/v1/apps/[:app]/scm_repo_linkapp_id
scalingo_domain/v1/apps/[:app]/domainsapp_id:domain_id
scalingo_collaborator/v1/apps/[:app]/collaboratorsapp_id:email
scalingo_log_drain/v1/apps/[:app]/log_drainsapp_id#drain_url
scalingo_notification_platformTODO: à compléter quand on les importera
scalingo_notifierTODO: à compléter quand on les importera
scalingo_alertTODO: à compléter quand on les importera

* toujours préfixée(s) par https://$SCALINGO_API_URL sauf mention contraire

Initialiser les variables d'environnements

Obtenir un Token d'API Scalingo

Si vous n'avez pas encore créé un token d'API Scalingo vous pouvez le faire ici sur la page dédiée du dashboard. Les tokens que vous créez avec votre compte individuel n'ont évidemment accès qu'aux applications pour lesquelles des droits vous ont déjà été accordés. Pour jouer avec un token qui ait accès à toutes les applications Scalingo du compte "1j1s", il vous faut demander ce token "maître" à vos collègues qui l'ont déjà.

export SCALINGO_API_TOKEN="<Mettre votre clé d'API Scalingo ici>"
export SCALINGO_REGION=osc-fr1
export SCALINGO_API_URL="api.$SCALINGO_REGION.scalingo.com"

# Obtenir un token valable 1h,
# Lorsque celui sera expiré, il suffit de réexécuter cette commande seulement
export SCALINGO_BEARER=`curl -s \
-H "Accept: application/json" \
-u ":$SCALINGO_API_TOKEN" \
-X POST https://auth.scalingo.com/v1/tokens/exchange \
| jq -r '.token'`

Lister les applications qui vous sont accessibles

Normalement cette liste devrait être identique à ce que vous voyez depuis le dashboard.

curl -s -H "Accept: application/json" -H "Authorization: Bearer $SCALINGO_BEARER" \
https://$SCALINGO_API_URL/v1/apps \
| jq '.apps[].name'

Choisir l'application qu'on veut importer

Pour éviter de répéter le nom de l'application dans les prochaines commandes, vous pouvez le stocker dans une variable d'env :

export SCALINGO_APP_NAME="<nom de l'application>"

Une fois le nom de l'application configurée, il faut récupérer son ID avec la commande suivante :

export SCALINGO_APP_ID=`curl -s -H "Accept: application/json" -H "Authorization: Bearer ${SCALINGO_BEARER}" \
https://${SCALINGO_API_URL}/v1/apps/${SCALINGO_APP_NAME} \
| jq -r '.app.id' || echo 'error getting app id'`

Module Terraform

export TF_MODULE=front_app

Importer l'application

terraform import module.$TF_MODULE.scalingo_app.app $SCALINGO_APP_ID

Types de conteneurs

Récupèrons d'abord la liste des types de conteneurs qui sont présents sur notre application.

curl -s -H "Accept: application/json" -H "Authorization: Bearer $SCALINGO_BEARER" \
https://$SCALINGO_API_URL/v1/apps/$SCALINGO_APP_NAME/containers \
| jq '.containers[].name'

En général il y a au moins le process web, alors on peut d'abord importer celui-ci, puis importer les autres sur le même modèle.

terraform import "module.$TF_MODULE.scalingo_container_type.containers[\"web\"]" ${SCALINGO_APP_ID}:web

S'il y a d'autres types de conteneurs, voici la commande :

terraform import "module.$TF_MODULE.scalingo_container_type.containers[\"<container_name>\"]" ${SCALINGO_APP_ID}:<container_name>

Autoscalers

curl -s -H "Accept: application/json" -H "Authorization: Bearer $SCALINGO_BEARER" \
https://$SCALINGO_API_URL/v1/apps/$SCALINGO_APP_NAME/autoscalers \
| jq '.autoscalers[] | .container_type + " => " + .id'
terraform import "module.$TF_MODULE.scalingo_autoscaler.autoscalers[\"web\"]" ${SCALINGO_APP_ID}:<autoscalerId>

Addons (et notamment les bases de données)

Récupèrons d'abord la liste des addons qui sont présents sur notre application.

curl -s -H "Accept: application/json" -H "Authorization: Bearer $SCALINGO_BEARER" \
https://$SCALINGO_API_URL/v1/apps/$SCALINGO_APP_NAME/addons \
| jq '.addons[]|.addon_provider.id+" ("+.plan.name+") => "+.id'

# => "redis (redis-business-256) => ad-********-****-****-****-************"

Pour chaque ligne : le premier élément (ici "redis") est à mettre dans l'emplacement addonProvider, le dernier élement (qui ressemble à un uuid) est à mettre dans l'emplacement addonId. Le plan est donné à titre informatif mais n'est pas utilisé pour l'import.

terraform import "module.$TF_MODULE.scalingo_addon.addons[\"<addonProvider>\"]" ${SCALINGO_APP_ID}:<addonId>

Collaborateurs

info

Il a été décidé de ne pas gérer les collaborateurs avec Terraform pour l'instant. Ces commandes d'imports n'ont pas été utilisées.

curl -s -H "Accept: application/json" -H "Authorization: Bearer $SCALINGO_BEARER" \
https://$SCALINGO_API_URL/v1/apps/$SCALINGO_APP_NAME/collaborators \
| jq '.collaborators[].email'
curl -s -H "Accept: application/json" -H "Authorization: Bearer $SCALINGO_BEARER" \
https://$SCALINGO_API_URL/v1/apps/$SCALINGO_APP_NAME/collaborators \
| jq -r '.collaborators[].email' \
| while IFS= read -r email ; do \
terraform import "module.$TF_MODULE.scalingo_collaborator.collaborators[\"$email\"]" $SCALINGO_APP_ID:$email; \
done

Log drains

curl -s -H "Accept: application/json" -H "Authorization: Bearer $SCALINGO_BEARER" \
https://$SCALINGO_API_URL/v1/apps/$SCALINGO_APP_NAME/log_drains \
| jq '.drains[].url'
terraform import "module.$TF_MODULE.scalingo_log_drain.log_drain[\"elk\"]" ${SCALINGO_APP_ID}#<drain_url>

Ce n'est même pas la peine de les lister car il ne peut y en avoir qu'un seul par application, mais si vous souhaitez vérifier sa présence avant d'importer vous pouvez utiliser la commande suivante :

curl -s -H "Accept: application/json" -H "Authorization: Bearer $SCALINGO_BEARER" \
https://$SCALINGO_API_URL/v1/apps/$SCALINGO_APP_NAME/scm_repo_link \
| jq '"scm_type = " + .scm_repo_link.scm_type'
terraform import "module.$TF_MODULE.scalingo_scm_repo_link.scm_repo_link[\"github\"]" ${SCALINGO_APP_ID}

Noms de domaine

curl -s -H "Accept: application/json" -H "Authorization: Bearer $SCALINGO_BEARER" \
https://$SCALINGO_API_URL/v1/apps/$SCALINGO_APP_NAME/domains \
| jq '.domains[] | .name + " => " + .id + (if .canonical then " [!!CANONICAL!!]" else " [alias]" end)'

# Pour le domaine principal ('canonical')
terraform import "module.$TF_MODULE.scalingo_domain.canonical_domain[\"<domainName>\"]" ${SCALINGO_APP_ID}:<domainId>

# S'il y a d'autres domaine ('alias')
terraform import "module.$TF_MODULE.scalingo_domain.domain_aliases[\"<domainName>\"]" ${SCALINGO_APP_ID}:<domainId>

2. Cloudflare

Domaine du site

export CLOUDFLARE_API_TOKEN="<Mettre votre Token API Cloudflare ici>"
export CLOUDFLARE_ZONE_ID="<Mettre votre Zone ID ici>"

curl -s -H "Content-Type: application/json" \
-H "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records \
| jq '.result[] | "[" + .type +"] " + .name + " => " + .id'

terraform import "cloudflare_record.domaine[\"<domainName>\"]" $CLOUDFLARE_ZONE_ID/<recordId>

Domaine pour l'analytics

terraform import "cloudflare_record.domaine_analytics_eulerian[\"<domainName>\"]" $CLOUDFLARE_ZONE_ID/<recordId>

3. StatusCake

info

Les clés d'API StatusCake se génèrent facilement sur la page "My Account"

export STATUSCAKE_API_TOKEN="<Mettre votre clé d'API StatusCake ici>"

curl -s -H "Authorization: Bearer ${STATUSCAKE_API_TOKEN}" \
https://api.statuscake.com/v1/uptime \
| jq '.data[] | "[" + .test_type + "] " + .name + " => " + .id'

# => "[HTTP] 1j1s-******* => 12456789"
# "[HEAD] https://********.gouv.fr => 987654321"
terraform import statuscake_uptime_check.http_check "<uptime_check_id>"