COMMENT GÉRER LE MULTI-COMPTES AVEC TERRAFORM ?

Terraform est un très bon outil qui permet rapidement de mettre en place un environnement sur Amazon Web Services, AWS, (ou autre fournisseur infonuagique). Cependant quand il s’agit de créer plusieurs environnements avec les mêmes fichiers de configuration, cela peut être chronophage et source d’erreurs. Cet article détaille comment rendre possible cette opération.

Terraform est un outil permettant de créer, de modifier et de versionner une infrastructure de manière sûre et efficace. Terraform peut gérer des fournisseurs de services existants et populaires ainsi que des solutions internes personnalisées.

 

Les fichiers de configuration décrivent à Terraform les composants nécessaires pour exécuter une seule application ou l’ensemble de votre centre de données. Terraform génère un plan d’exécution décrivant ce qu’il fera pour atteindre l’état souhaité, puis l’exécute pour construire l’infrastructure décrite. À mesure que la configuration change, Terraform est en mesure de déterminer ce qui a changé et de créer des plans d’exécution incrémentiels qui peuvent être appliqués.

 

Traduit du site Internet Terraform de HarshiCorp

Les Terraform Workspaces offrent la possibilité de déployer plusieurs ressources depuis un seul (ou ensemble) de fichier(s).

 

Chaque Workspace est un environnement, dans notre cas : DEV (Développement), QA (Quality Insurrance ou Assurance Qualité) et PROD (Production). Chaque Workspace partagera un seul bucket S3 pour tous les états, ou state, Terraform.

 

Par Benoit Vernochet, expert infonuagique chez LINKBYNET

Prérequis

 

  • Un Landing zone avec un compte principal, ou master account, et des sous comptes, ou sub account, par exemple :
    • DEV
    • QA
    • PROD
  • Les droits d’assumer des rôles depuis le master account
  • Terraform

Préparation sur AWS

 

Sur les sous-comptes

 

Dans chacun des sous-comptes il faudra créer un rôle que l’utilisateur du master account (créé plus tard) pourra assumer.

 

Exemple sur le compte de DEV :

 

  • Créer un IAM rôle nommé : « AssumeRoleTerraformDev »
  • Associer une policy, ou stratégie, au rôle : dans mon cas je vais autoriser le rôle à tout faire donc, je vais lui affecter la policy « AdministratorAccess »
  • Dans « Trust Relationships », il faut ajouter le numéro de compte du master account donc cliquer sur « edit trust relationship » et utiliser cette policy en remplaçant par votre numéro de compte :

 

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::ID_ACCOUNT_MASTER_ACCOUNT:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

 

Voilà à quoi devrait ressembler votre rôle :

Sur le compte master 

 

  • Créer le bucket S3 pour les Workspaces dans le master account (ce nom doit être unique à vous).

Ici : terraform-state

 

  • Créer une IAM policy « AssumeRoleTerraformAdmin » qui permettra d’assumer le rôle précédemment créé dans les sous-comptes :

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "123",
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::ID_ACCOUNT_DEV:role/AssumeRoleTerraformDev",
                "arn:aws:iam:: ID_ACCOUNT_QA:role/AssumeRoleTerraformQA",
                "arn:aws:iam:: ID_ACCOUNT_PROD:role/AssumeRoleTerraformProd"
            ]
        }
    ]
}

 

  • Créer une IAM policy « S3AssumeRoleTerraformAdmin » qui permettra à Terraform de poser les fichiers Terraform state dans le bucket S3 :

 

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:ListAllMyBuckets",
                "s3:ListBucket",
                "s3:HeadBucket"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::terraform-state/*"
        }
    ]
}

 

  • Créer un utilisateur nominatif qui assumera les rôles des sous-comptes. Ici bvernochet.
  • Affecter les deux IAM policies précédemment créées à l’utilisateur. (Dans le cas d’un groupe d’administrateur, il est possible de créer un groupe IAM, d’affecter les IAM policies à ce groupe et d’ajouter les adminitrateurs au groupe)
  • Pour cet utilisateur, créer une « Access Key ID » avec sa « Secret Key »

Préparation sur le poste de travail

 

Sur le poste de travail il faut éditer le fichier :

 

~ .aws/credentials

 

Avec les informations suivantes :

 

[client]
aws_access_key_id = VOTRE_ACCESS_KEY_ID
aws_secret_access_key = VOTRE_SECRET_KEY
region = ca-central-1
output = json

 

Maintenant vous êtes prêt à créer les Workspaces pour les différents environnements, placez-vous dans votre répertoire Terraform.

 

terraform workspace new dev
terraform workspace new qa
terraform workspace new prod

 

Sélectionnez un Workspace :

 

Terraform workspace select dev

 

Vous pouvez présentement travailler sur votre environnement de DEV sans impacter la QA ni la PROD.

Exemple d’utilisation

 

Nous allons créer une instance dans chacun des environnements avec un nom d’instance dépendant de l’environnement. Par exemple :

 

  • qa-appli
  • dev-appli
  • prod-appli

 

En utilisant la variable ${terraform.workspace}, je peux nommer mes instances comme voulu

 

Main.tf :

 

provider "aws" {
  profile = var.profile
  region  = var.region
  assume_role { role_arn = var.workspace_iam_roles[terraform.workspace] }
}
### The S3 bucket to save and share the tfstate
terraform {
  backend "s3" {
    bucket  = "terraform-state"
    key     = "terraform.tfstate"
    region  = "ca-central-1"
    profile = "client"
    # No credentials explicitly set here because they come from your .aws/credentials file
    #assume_role_policy = "arn:aws:iam::ID_ACCOUNT_MASTER_ACCOUNT:role/AssumeRoleTerraformDev"
  }
}
resource "aws_instance" " ${terraform.workspace}-appli" {
  ami           = "${data.aws_ami.ubuntu.id}"
  instance_type = "t2.micro"
  tags = {
    Name = "${terraform.workspace}-appli"
  }
}

 

Lors de la première utilisation, il faudra initialiser le fichier Terraform :

 

terraform init

 

Controller que tout fonctionne correctement :

 

terraform plan

 

Appliquer les changements et créer l’instance en DEV :

 

terraform apply

 

Une fois l’instance dev-appli créée en DEV, vous pouvez la créer en QA :

 

terraform workspace select qa
terraform init
terraform plan
terraform apply

 

L’instance qa-appli est maintenant créée sur l’environnement de QA. Vous pouvez donc faire la même chose pour la PROD.

 

Il est aussi possible de mettre des variables dépendantes de l’environnement dans un fichier variables.tf

 

Exemple :

 

variable "inst-var" {
  default = {
    dev  = "var1"
    qa   = "var2"
    prod = "var3"
  }
}

 

Cette variable est alors utilisable dans les fichiers Terraform :

 

Name = var.inst-var[terraform.workspace]

Conclusion

 

Même si les bouts de code ne sont pas tous complet, cette démonstration vous permettra d’avoir une idée générale pour utiliser le même fichier de configuration Terraform pour tous vos environnements.

 

Grâce à l’utilisation de Terraform Workspaces sur AWS, nous avons été capables de déployer avec un seul fichier de configuration des ressources sur plusieurs comptes.

 

Ce cas est un exemple concret que nous avons réalisé pour un client, nous pouvons donc vous accompagnez si vous avez des problématiques similaires.

Vous souhaitez en découvrir davantage ou nous poser vos questions, n’hésitez pas à nous contacter :

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.