Présentation du kit Cloud Foundation

1. Présentation de CFT 101

ea557448aaa1fffc.png

Dernière mise à jour:03/03/2020

Qu'est-ce que le kit Cloud Foundation ?

En bref, le kit Cloud Foundation fournit des modèles recommandés pour vous aider à vous lancer rapidement sur Google Cloud Platform. Dans ce tutoriel, vous allez apprendre à contribuer au kit Cloud Foundation.

Prérequis

  • Un compte GitHub
  • Docker installé sur votre ordinateur ( installation Mac, installation Windows)
  • Éditeur de code pour modifier le code (exemple: Visual Studio Code)
  • Connaissances de base sur Git et GitHub
  • Connaissance pratique de Terraform et de l'Infrastructure as Code
  • Autorisation permettant d'accorder le rôle de créateur de projet à un compte de service

Objectifs de l'atelier

Dans cet atelier de programmation, vous allez apprendre à contribuer au kit Cloud Foundation.

Vous découvrirez comment :

  • Configurer un environnement de développement pour contribuer au kit Cloud Foundation
  • Ajouter une fonctionnalité à un module du kit Cloud Foundation
  • Ajouter des tests pour la fonctionnalité ajoutée
  • Exécuter des tests d'intégration dans le kit Cloud Foundation
  • Exécuter des tests lint
  • Valider le code sur GitHub et envoyer une demande d'extraction (PR)

Pour exécuter toutes les étapes ci-dessus, vous allez ajouter une nouvelle fonctionnalité au module CFT de Google Cloud Storage. Vous allez ajouter une étiquette appelée "silly_label", qui sera automatiquement ajoutée à tous les buckets créés via le module CFT de GCS. Vous pourrez également écrire des tests pour valider votre fonctionnalité et garantir son intégration de bout en bout.

2. Configurer un environnement de développement

Si vous le souhaitez, vous pouvez utiliser Cloud Shell à des fins de développement. Si vous ne souhaitez pas utiliser Cloud Shell pour contribuer au kit Cloud Foundation, vous pouvez configurer votre environnement de développement sur votre machine.

Configurer Git

GitHub est basé sur un système de contrôle des versions (VCS) Open Source appelé Git. Git est responsable de toutes les opérations liées à GitHub qui se produisent localement sur votre machine ou dans Cloud Shell.

  1. Lorsque vous utilisez Cloud Shell, vous n'avez pas besoin d'installer git, car il est préinstallé.
$ git --version
# This will display the git version on the Cloud Shell.

Si vous configurez votre environnement de développement sur votre ordinateur, vous devez installer Git.

Définir votre nom d'utilisateur et votre adresse e-mail dans Git

Git utilise un nom d'utilisateur pour associer les commits à une identité. Le nom d'utilisateur Git est différent de votre nom d'utilisateur GitHub.

Vous pouvez modifier le nom associé à vos commits Git à l'aide de la commande git config. La modification du nom associé à vos commits Git à l'aide de git config n'affectera que les futurs commits et ne modifiera pas le nom utilisé pour les commits antérieurs.

Vous avez correctement configuré Git, et vous devriez pouvoir dupliquer, créer et cloner des branches. Nous utiliserons beaucoup Git dans cet atelier de programmation.

3. Dépôt GCS de Fork CFT

Dupliquer un dépôt Cloud Foundation

Vous avez configuré Git sur votre ordinateur local ou dans Cloud Shell à l'étape précédente. Vous devez maintenant dupliquer le dépôt CFT de Google Cloud Storage pour commencer à contribuer.

Une copie est une copie d'un dépôt. La duplication d'un dépôt vous permet de tester librement les modifications sans affecter le projet d'origine.

Le plus souvent, les fourchettes sont utilisées pour proposer des modifications au projet de quelqu'un d'autre ou pour utiliser le projet de quelqu'un d'autre comme point de départ de votre propre idée.

Par exemple, vous pouvez utiliser les duplications pour proposer des modifications liées à la correction d'un bug. Pour corriger un bug, vous pouvez:

  • Dupliquez le dépôt.
  • Résolvez le problème.
  • Envoyez une demande d'extraction au propriétaire du projet.

Étapes pour dupliquer un dépôt CFT:

  1. Ouvrez votre navigateur Web et accédez au dépôt terraform-google-modules/terraform-google-cloud-storage. Nous utiliserons ce dépôt tout au long de l'atelier de programmation.
  2. En haut à droite de la page, cliquez sur Fork (Dupliquer).

e3894c6de6a732b4.png

  1. Vous serez invité à indiquer l'emplacement souhaité de la duplication. Sélectionnez votre profil, et le dépôt sera dupliqué.

Cloner votre copie localement

La copie que vous avez créée est une copie du dépôt du module GCS. Vous allez maintenant cloner ce dépôt dans votre environnement local pour ajouter votre nouvelle fonctionnalité.

Étapes pour cloner votre copie:

  1. Ouvrez votre navigateur Web et accédez à votre copie sur terraform-google-modules/terraform-google-cloud-storage.
  2. En haut à droite, vous trouverez l'option "Cloner ou télécharger" cliquez dessus.

3bfa87b9f7f01f61.png

  1. Après avoir cliqué sur le bouton "Cloner ou télécharger" bouton, cliquez sur le « Bloc-notes » pour copier l'URL de la duplication. Vous utiliserez cette URL pour cloner la copie dans votre environnement local.

dbf3682d004e0ee0.png

  1. Accédez à un terminal de votre VSCode ou de votre machine, puis clonez la duplication.
$ git clone <url>
# This command will clone your fork locally.
# Paste the copied URL from the previous step.
  1. Maintenant que vous avez cloné votre duplication localement, vous devez accéder à votre dépôt, créer une nouvelle branche et modifier le code de la branche temporaire.

Par convention, vous pouvez nommer votre branche comme suit:

  • Pour les demandes de fonctionnalités: feature/feature-name
  • Pour les mises à jour internes, internal/change-name
  • Pour les corrections de bugs: bugfix/issue-name

Comme vous ajoutez une nouvelle fonctionnalité, vous pouvez appeler votre branche temporaire feature/silly_label

$ cd terraform-google-cloud-storage
# This command takes you into the cloned directory on your local machine.

$ git branch
# This command tells your current branch
# When you run this for the first time after you have cloned, your 
# output should say "master", that is your fork.

$ git checkout -b feature/silly_label
# This command creates a new branch on your fork and switches your 
# branch to the newly created branch.

$ git branch
# This command will confirm your current branch to be "feature/silly_label"

Vous êtes maintenant prêt à commencer à travailler sur le kit Cloud Foundation.

4. Créer un environnement de test

Le processus de développement standard du kit Cloud Foundation repose sur l'utilisation d'un projet de test isolé à des fins de test. Cette étape vous aide à créer le projet de test (basé sur une configuration standard) via un compte de service.

0. Installer Docker Engine

Si vous utilisez votre ordinateur à des fins de développement, vous devez installer Docker Engine.

1. Installer le SDK Google Cloud

Vous n'avez pas besoin d'installer le SDK Google Cloud si vous utilisez GCP Cloud Shell.

Accédez au SDK Google Cloud, puis téléchargez le programme d'installation interactif pour votre plate-forme.

2. Définir la configuration

Pour créer un environnement de test, vous avez besoin d'une organisation Google Cloud, d'un dossier de test et d'un compte de facturation. Ces valeurs doivent être définies via des variables d'environnement:

export TF_VAR_org_id="your_org_id"
export TF_VAR_folder_id="your_folder_id"
export TF_VAR_billing_account="your_billing_account_id"

3 Configurer votre compte de service

Avant de créer un environnement de test, vous devez télécharger une clé de compte de service dans votre environnement de test. Ce compte de service doit disposer des rôles Créateur de projet, Utilisateur de compte de facturation et Lecteur d'organisation. Cette procédure vous permet de créer un compte de service, mais vous pouvez également réutiliser un compte existant.

3.1 Créer ou sélectionner un projet GCP source

Avant de créer votre compte de service, vous devez sélectionner un projet dans lequel l'héberger. Vous pouvez également créer un projet.

gcloud config set core/project YOUR_PROJECT_ID

3.2 Activer les API Google Cloud

Activez les API Google Cloud suivantes sur votre projet source:

gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable iam.googleapis.com
gcloud services enable cloudbilling.googleapis.com

3.3 Créer un compte de service

Créez un compte de service pour gérer l'environnement de test:

# Creating a service account for CFT.
gcloud iam service-accounts create cft-onboarding \
  --description="CFT Onboarding Terraform Service Account" \
  --display-name="CFT Onboarding"

# Assign SERVICE_ACCOUNT environment variable for later steps
export SERVICE_ACCOUNT=cft-onboarding@$(gcloud config get-value core/project).iam.gserviceaccount.com

Vérifiez que votre compte de service a bien été créé:

gcloud iam service-accounts list --filter="EMAIL=${SERVICE_ACCOUNT}"

3.4 Attribuer les rôles Créateur de projet, Utilisateur de compte de facturation et Lecteur d'organisation au compte de service:

gcloud resource-manager folders add-iam-policy-binding ${TF_VAR_folder_id} \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/resourcemanager.projectCreator"
gcloud organizations add-iam-policy-binding ${TF_VAR_org_id} \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/billing.user"
gcloud organizations add-iam-policy-binding ${TF_VAR_org_id} \
  --member="serviceAccount:${SERVICE_ACCOUNT}" \
  --role="roles/resourcemanager.organizationViewer"

Vous disposez maintenant d'un compte de service pour gérer l'environnement de test.

4. Attribuer le rôle d'utilisateur de compte de facturation sur la ressource de compte de facturation

4.1 Récupérer la stratégie IAM du compte de facturation

Télécharger les liaisons de stratégie IAM existantes sur le compte de facturation

gcloud beta billing accounts get-iam-policy ${TF_VAR_billing_account} | tee policy.yml

4.2 Mettre à jour la règle pour inclure le compte de service

Mettez à jour le fichier policy.yml afin d'ajouter une liaison pour le compte de service doté du rôle roles/billing.user.

bindings:
- members:
  - serviceAccount:cft-onboarding@<YOUR_PROJECT_ID>.iam.gserviceaccount.com
  role: roles/billing.user

4.3 Mettre à jour la règle concernant les comptes de facturation

Appliquer les modifications au compte de facturation

gcloud beta billing accounts set-iam-policy ${TF_VAR_billing_account} policy.yml

5. Préparer les identifiants Terraform

Pour créer l'environnement de test, vous devez télécharger la clé du compte de service dans votre interface système.

5.1 Clé de compte de service

Créer et télécharger une clé de compte de service pour Terraform

gcloud iam service-accounts keys create cft.json --iam-account=${SERVICE_ACCOUNT}

5.2 Configurer les identifiants Terraform

Fournissez la clé à Terraform à l'aide de la variable d'environnement SERVICE_ACCOUNT_JSON, en définissant la valeur sur le contenu de votre clé de compte de service.

export SERVICE_ACCOUNT_JSON=$(< cft.json)

6. Créer un projet de test pour les déploiements Terraform

Maintenant que tout est prêt, vous pouvez créer le projet de test à l'aide d'une seule commande. Exécutez cette commande à partir de la racine du répertoire "terraform-google-cloud-storage" :

make docker_test_prepare

Le résultat ci-dessous s'affiche lorsque vous exécutez make docker_test_prepare. À la fin, vous recevez l'ID de projet de test qui a été créé, dans lequel vous allez déployer et tester votre module Cloud Storage avec votre nouvelle fonctionnalité.

macbookpro3:terraform-google-cloud-storage user$ make docker_test_prepare
docker run --rm -it \
                -e SERVICE_ACCOUNT_JSON \
                -e TF_VAR_org_id \
                -e TF_VAR_folder_id \
                -e TF_VAR_billing_account \
                -v /Users/cft/terraform-google-cloud-storage:/workspace \
                gcr.io/cloud-foundation-cicd/cft/developer-tools:0.8.0 \
                /usr/local/bin/execute_with_credentials.sh prepare_environment
Activated service account credentials for: [cft-onboarding@<project_id>.iam.gserviceaccount.com]
Activated service account credentials for: [cft-onboarding@<project_id>.iam.gserviceaccount.com]
Initializing modules...

Initializing the backend...

Initializing provider plugins...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.google-beta: version = "~> 3.9"
* provider.null: version = "~> 2.1"
* provider.random: version = "~> 2.2"

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.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
module.project.module.project-factory.null_resource.preconditions: Refreshing state... [id=8723188031607443970]
module.project.module.project-factory.null_resource.shared_vpc_subnet_invalid_name[0]: Refreshing state... [id=5109975723938185892]
module.project.module.gsuite_group.data.google_organization.org[0]: Refreshing state...
module.project.module.project-factory.random_id.random_project_id_suffix: Refreshing state... [id=rnk]
module.project.module.project-factory.google_project.main: Refreshing state... [id=<project-id>]
module.project.module.project-factory.google_project_service.project_services[0]: Refreshing state... [id=<project-id>/storage-api.googleapis.com]
module.project.module.project-factory.google_project_service.project_services[1]: Refreshing state... [id=<project-id>/cloudresourcemanager.googleapis.com]
module.project.module.project-factory.google_project_service.project_services[2]: Refreshing state... [id=<project-id>/compute.googleapis.com]
module.project.module.project-factory.data.null_data_source.default_service_account: Refreshing state...
module.project.module.project-factory.google_service_account.default_service_account: Refreshing state... [id=projects/ci-cloud-storage-ae79/serviceAccounts/project-service-account@<project-id>.iam.gserv
iceaccount.com]
module.project.module.project-factory.google_project_service.project_services[3]: Refreshing state... [id=<project-id>/serviceusage.googleapis.com]
module.project.module.project-factory.null_resource.delete_default_compute_service_account[0]: Refreshing state... [id=3576396874950891283]
google_service_account.int_test: Refreshing state... [id=projects/<project-id>/serviceAccounts/cft-onboarding@<project-id>.iam.gserviceaccount.com]
google_service_account_key.int_test: Refreshing state... [id=projects/<project-id>/serviceAccounts/cft-onboarding@<project-id>.iam.gserviceaccount.com/keys/351009a1e011e88049ab2097994d1c627a61
6961]
google_project_iam_member.int_test[1]: Refreshing state... [id=<project-id>/roles/iam.serviceAccountUser/serviceaccount:cft-onboarding@<project-id>.iam.gserviceaccount.com]
google_project_iam_member.int_test[0]: Refreshing state... [id=<project-id>/roles/storage.admin/serviceaccount:cft-onboarding@<project-id>.iam.gserviceaccount.com]

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

Outputs:

project_id = <test-project-id>
sa_key = <sensitive>
Found test/setup/make_source.sh. Using it for additional explicit environment configuration.

Vous venez de créer un projet de test référencé par project_id, comme vous pouvez le voir dans le résultat de la console. Votre environnement de développement et de test est configuré.

5. Ajouter une nouvelle fonctionnalité au module du kit Cloud Foundation

Maintenant que vos environnements de développement et de test sont configurés, ajoutez l'élément "silly_label" au module CFT google-cloud-storage.

Assurez-vous d'être dans terraform-google-cloud-storage et ouvrez le fichier main.tf comme indiqué ci-dessous dans la structure de dossiers.

17f2d3b9893be853.png

Depuis "silly_label" est un libellé, ajoutez l'élément géographique à la ligne 27 dans la variable "labels" dans main.tf, comme indiqué ci-dessous:

terraform-google-cloud-storage/main.tf

resource "google_storage_bucket" "buckets" {
 <...>
 storage_class = var.storage_class
 // CODELAB:Add silly label in labels variable
 labels        = merge(var.labels, { name = replace("${local.prefix}${lower(element(var.names, count.index))}", ".", "-") }, { "silly" = var.silly_label })
 force_destroy = lookup(
 <...>
}

Vous allez maintenant ajouter la variable "silly_label" au fichier variables.tf que vous voyez dans la structure de dossiers ci-dessus.

Copiez et collez le code ci-dessous et ajoutez-le à la ligne 29 dans variables.tf. Assurez-vous qu'il existe un nouveau caractère de ligne au-dessus et en dessous du bloc "variable" que vous ajoutez.

terraform-google-cloud-storage/variables.tf

variable "names" {
 description = "Bucket name suffixes."
 type        = list(string)
}

// CODELAB: Add "silly_label" variable to variables.tf between "names" and "location"
variable "silly_label" {
 description = "Sample label for bucket."
 type        = string
}

variable "location" {
 description = "Bucket location."
 default     = "EU"
}

6. Ajouter une fonctionnalité à un exemple de bucket de stockage

Vous avez ajouté votre fonctionnalité au fichier main.tf du module. Vous allez maintenant la tester à l'aide d'un exemple.

"silly_label" doit être ajouté au répertoire "examples/multiple-buckets/main.tf"

À l'étape suivante, cet exemple servira à effectuer des tests d'intégration par un équipement.

Copiez et collez la ligne "silly_label" ci-dessous à la ligne 27 du fichier main.tf sous terraform-google-cloud-storage/examples/multiple-buckets/, comme indiqué dans la structure de dossiers:

408cb1365b2a0793.png

terraform-google-cloud-storage/examples/multiple-buckets/main.tf

module "cloud_storage" {
 <...>
 // CODELAB: Add "silly_label" as an example to main.tf.
 silly_label        = "awesome"

 <..>
}

7. Écrire un test Inspec pour vérifier la fonctionnalité

Vous avez ajouté votre fonctionnalité au fichier main.tf du module, puis vous l'avez ajoutée à l'exemple "multiple_buckets" pour la tester via l'outil. Vous devez tester votre fonctionnalité via un test d'intégration InSpec écrit en Ruby.

Vous allez ajouter vos nouveaux tests dans le fichier gsutil.rb qui se trouve dans la structure de dossiers ci-dessous:

b2bfeb203477e0c8.png

Vous avez ajouté "silly_label" sur tous les buckets créés via le module multiple_buckets. Vous devez maintenant écrire des tests pour tester la nouvelle fonctionnalité.

Dans le code ci-dessous, vous obtenez l'étiquette de chaque bucket via la commande gsutil, puis vous vérifiez le résultat renvoyé par la commande.

terraform-google-cloud-storage/test/integration/multiple-buckets/controls/gsutil.rb

control "gsutil" do
 <..>

# CODELAB: Copy paste the below test in gsutil.rb to test silly_label feature.

# command to get the labels for bucket_1
describe command("gsutil label get gs://#{attribute("names_list")[0]}") do
   //check if the command gave a valid response
   its(:exit_status) { should eq 0 }
   its(:stderr) { should eq "" }

   //parse the command's output into JSON
   let!(:data) do
     if subject.exit_status == 0
         JSON.parse(subject.stdout)
     else
         {}
     end
   end

   # check if bucket_1 has the new "silly" label with the value "awesome"
   describe "bucket_1" do
   it "has label" do
       data.each do |bucket|
           expect(data["silly"]).to include("awesome")
       end
     end
   end
 end

8. Exécuter des tests d'intégration dans le kit Cloud Foundation

Tests d'intégration

Les tests d'intégration permettent de vérifier le comportement du module racine, des sous-modules et des exemples de modules. Les ajouts, modifications et corrections doivent être accompagnés de tests.

Les tests d'intégration sont exécutés à l'aide de Kitchen, Kitchen-Terraform et InSpec. Pour plus de commodité, ces outils sont empaquetés dans une image Docker.

La stratégie générale de ces tests consiste à vérifier le comportement des exemples de modules, afin de s'assurer que le module racine, les sous-modules et les exemples de modules fonctionnent tous correctement.

Lors d'une exécution interactive, vous exécutez chaque étape via plusieurs commandes.

  1. Exécutez make docker_run pour démarrer le conteneur Docker de test en mode interactif.

Make est un outil d'automatisation de compilation qui compile automatiquement des programmes et des bibliothèques exécutables à partir du code source en lisant des fichiers appelés Makefiles, qui spécifient comment extraire le programme cible. Lorsque vous modifiez un fichier, le conteneur Docker doit être mis à jour automatiquement.

Lorsque vous exécutez make docker_run, vous créez un espace de travail dans votre conteneur Docker et activez les identifiants de votre compte de service. L'espace de travail sera utilisé lors des prochaines étapes pour exécuter des tests.

Le résultat ci-dessous s'affiche dans votre terminal:

Activated service account credentials for: [cft@<PROJECT_ID>.iam.gserviceaccount.com]
  1. Exécutez kitchen_do list pour répertorier toutes les instances de votre espace de travail qui contiennent des tests d'intégration.
     You will see the below output in your terminal.
    
[root@<CONTAINER_ID> workspace]# kitchen_do list
Automatically setting inputs from outputs of test/setup
Found test/source.sh. Using it for additional explicit environment configuration.
Activated service account credentials for: [cft@<PROJECT_ID>.iam.gserviceaccount.com]
Instance                  Driver     Provisioner  Verifier   Transport  Last Action  Last Error
multiple-buckets-default  Terraform  Terraform    Terraform  Ssh        Verified     <None>
  1. Exécutez kitchen_do create <EXAMPLE_NAME> pour initialiser le répertoire de travail pour un exemple de module.

Cette étape initialise Kitchen et Terraform dans l'espace de travail.

Le résultat ci-dessous s'affiche dans votre terminal.

[root@<CONTAINER_ID> workspace]# kitchen_do create multiple-buckets-default
Automatically setting inputs from outputs of test/setup
Found test/source.sh. Using it for additional explicit environment configuration.
Activated service account credentials for: [cft@<PROJECT_ID>.iam.gserviceaccount.com]
-----> Starting Kitchen (v1.24.0)
-----> Creating <multiple-buckets-default>...
       Terraform v0.12.12
       + provider.google v3.10.0
       
       Your version of Terraform is out of date! The latest version
       is 0.12.21. You can update by downloading from www.terraform.io/downloads.html
$$$$$$ Running command `terraform init -input=false -lock=true -lock-timeout=0s  -upgrade -force-copy -backend=true  -get=true -get-plugins=true -verify-plugins=true` in directory /workspace/test/fi
xtures/multiple_buckets
       Upgrading modules...
       - example in ../../../examples/multiple_buckets
       - example.cloud_storage in ../../..
       
       Initializing the backend...
       
       Initializing provider plugins...
       - Checking for available provider plugins...
       - Downloading plugin for provider "google" (hashicorp/google) 2.18.1...
       - Downloading plugin for provider "random" (hashicorp/random) 2.2.1...
       
       Terraform has been successfully initialized!
$$$$$$ Running command `terraform workspace select kitchen-terraform-multiple-buckets-default` in directory /workspace/test/fixtures/multiple_buckets
       Finished creating <multiple-buckets-default> (0m11.01s).
-----> Kitchen is finished. (0m12.62s)
  1. Exécutez kitchen_do converge <EXAMPLE_NAME> pour appliquer l'exemple de module.

Cette étape applique l'espace de travail Terraform créé à l'étape précédente au projet GCP créé précédemment dans l'atelier de programmation.

Le résultat ci-dessous s'affiche dans votre terminal.

[root@<CONTAINER_ID> workspace]# kitchen_do converge multiple-buckets-default
Automatically setting inputs from outputs of test/setup
Found test/source.sh. Using it for additional explicit environment configuration.
Activated service account credentials for: [cft@<YOUR_PROJECT_ID>.iam.gserviceaccount.com]
-----> Starting Kitchen (v1.24.0)
-----> Converging <multiple-buckets-default>...
       Terraform v0.12.20
       + provider.google v3.9.0
       
       Your version of Terraform is out of date! The latest version
       is 0.12.21. You can update by downloading from https://www.terraform.io/downloads.html
$$$$$$ Running command `terraform workspace select kitchen-terraform-multiple-buckets-default` in directory /workspace/test/fixtures/multiple_buckets
$$$$$$ Running command `terraform get -update` in directory /workspace/test/fixtures/multiple_buckets
       - example in ../../../examples/multiple_buckets
       - example.cloud_storage in ../../..
$$$$$$ Running command `terraform validate   ` in directory /workspace/test/fixtures/multiple_buckets
       Success! The configuration is valid.
       
$$$$$$ Running command `terraform apply -lock=true -lock-timeout=0s -input=false -auto-approve=true  -parallelism=10 -refresh=true  ` in directory /workspace/test/fixtures/multiple_buckets
       random_pet.main: Creating...
       random_pet.main: Creation complete after 0s [id=<BUCKET-ID>]
       module.example.module.cloud_storage.google_storage_bucket.buckets[0]: Creating...
       module.example.module.cloud_storage.google_storage_bucket.buckets[1]: Creating...
       module.example.module.cloud_storage.google_storage_bucket.buckets[1]: Creation complete after 3s [id=<BUCKET-ID-01>]
       module.example.module.cloud_storage.google_storage_bucket.buckets[0]: Creation complete after 3s [id=<BUCKET-ID-02>]
       
       Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
       
       Outputs:
       
       names = {
         "one" = "<BUCKET-ID-01>"
         "two" = "<BUCKET-ID-02>"
       }
       names_list = [
         "<BUCKET-NAME-01>",
         "<BUCKET-NAME-02>",
       ]
       project_id = ci-cloud-storage-ae79
       Finished converging <multiple-buckets-default> (0m7.17s).
-----> Kitchen is finished. (0m8.77s)
  1. Exécutez kitchen_do verify <EXAMPLE_NAME> pour tester l'exemple de module.

Cette étape exécutera le fichier gsutils.rb qui contient des tests pour le module multiple_buckets. Chaque test comporte une commande gsutil qui sera exécutée sur le projet de test que vous avez créé précédemment à l'aide des identifiants du compte de service.

Si vous obtenez des erreurs, vous verrez ce qui était attendu et ce qui a été reçu par la commande pour le test.

Le résultat ci-dessous s'affiche dans votre terminal.

multiple_buckets local: Verifying

Profile: multiple_buckets
Version: (not specified)
Target:  local://

  ✔  gsutil: gsutil
     ✔  Command: `gsutil ls -p <PROJECT_ID>` exit_status should eq 0
     ✔  Command: `gsutil ls -p <PROJECT_ID>` stderr should eq ""
     ✔  Command: `gsutil ls -p <PROJECT_ID>` stdout should include "multiple-buckets-mzgy-eu-one"
     ✔  Command: `gsutil ls -p <PROJECT_ID>` stdout should include "<BUCKET-ID-01>"
     ✔  Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-01>` exit_status should eq 0
     ✔  Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-01>` stderr should eq ""
     ✔  Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-01>` stdout should include "Enabled: True"
     ✔  Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-02>` exit_status should eq 0
     ✔  Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-02>` stderr should eq ""
     ✔  Command: `gsutil bucketpolicyonly get gs://<BUCKET-ID-02>` stdout should include "Enabled: False"
     ✔  Command: `gsutil label get gs://<BUCKET-ID-01>` exit_status should eq 0
     ✔  Command: `gsutil label get gs://<BUCKET-ID-01>` stderr should eq ""
     ✔  Command: `gsutil label get gs://<BUCKET-ID-01>` bucket_1 has label
     ✔  Command: `gsutil label get gs://<BUCKET-ID-02>` exit_status should eq 0
     ✔  Command: `gsutil label get gs://<BUCKET-ID-02>` stderr should eq ""
     ✔  Command: `gsutil label get gs://<BUCKET-ID-02>` bucket_2 has label
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` should eq "NEARLINE"
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` should eq "SetStorageClass"
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` should eq 10
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` should eq false
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` should eq ["MULTI_REGIONAL", "STANDARD", "DURABLE_REDUCED_AVAILABILITY"]
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` exit_status should eq 0
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-01>` stderr should eq ""
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` should eq "NEARLINE"
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` should eq "SetStorageClass"
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` should eq 10
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` should eq false
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` should eq ["MULTI_REGIONAL", "STANDARD", "DURABLE_REDUCED_AVAILABILITY"]
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` exit_status should eq 0
     ✔  Command: `gsutil lifecycle get gs://<BUCKET-ID-02>` stderr should eq ""


Profile Summary: 1 successful control, 0 control failures, 0 controls skipped
Test Summary: 30 successful, 0 failures, 0 skipped
       Finished verifying <multiple-buckets-default> (0m8.83s).
-----> Kitchen is finished. (0m16.61s)
  1. Exécutez kitchen_do destroy <EXAMPLE_NAME> pour détruire l'exemple d'état du module.

Cette étape détruit l'espace de travail que vous avez créé précédemment. Cette étape détruira également les buckets GCS créés dans le projet, ainsi que l'étiquette que vous avez ajoutée au module GCS.

Vous pouvez afficher la sortie ci-dessous dans votre terminal.

[root@<CONTAINER_ID> workspace]# kitchen_do destroy multiple-buckets-default
Automatically setting inputs from outputs of test/setup
Found test/source.sh. Using it for additional explicit environment configuration.
Activated service account credentials for: [ci-cloud-storage@ci-cloud-storage-54ab.iam.gserviceaccount.com]
-----> Starting Kitchen (v1.24.0)
-----> Destroying <multiple-buckets-default>...
       Terraform v0.12.12
       + provider.google v3.10.0
       
       Your version of Terraform is out of date! The latest version
       is 0.12.21. You can update by downloading from www.terraform.io/downloads.html
$$$$$$ Running command `terraform init -input=false -lock=true -lock-timeout=0s  -force-copy -backend=true  -get=true -get-plugins=true -verify-plugins=true` in directory /workspace/test/fixtures/mu
ltiple_buckets
       Initializing modules...
       
       Initializing the backend...
       
       Initializing provider plugins...
       
       Terraform has been successfully initialized!
$$$$$$ Running command `terraform workspace select kitchen-terraform-multiple-buckets-default` in directory /workspace/test/fixtures/multiple_buckets
$$$$$$ Running command `terraform destroy -auto-approve -lock=true -lock-timeout=0s -input=false  -parallelism=10 -refresh=true  ` in directory /workspace/test/fixtures/multiple_buckets
       random_string.prefix: Refreshing state... [id=mzgy]
       module.example.module.cloud_storage.google_storage_bucket.buckets[0]: Refreshing state... [id=<BUCKET-ID-01>]
       module.example.module.cloud_storage.google_storage_bucket.buckets[1]: Refreshing state... [id=<BUCKET-ID-02>]
       module.example.module.cloud_storage.google_storage_bucket.buckets[0]: Destroying... [id=<BUCKET-ID-01>]
       module.example.module.cloud_storage.google_storage_bucket.buckets[1]: Destroying... [id=<BUCKET-ID-02>]
       module.example.module.cloud_storage.google_storage_bucket.buckets[0]: Destruction complete after 1s
       module.example.module.cloud_storage.google_storage_bucket.buckets[1]: Destruction complete after 2s
       random_string.prefix: Destroying... [id=mzgy]
       random_string.prefix: Destruction complete after 0s
       
       Destroy complete! Resources: 3 destroyed.
$$$$$$ Running command `terraform workspace select default` in directory /workspace/test/fixtures/multiple_buckets
       Switched to workspace "default".
$$$$$$ Running command `terraform workspace delete kitchen-terraform-multiple-buckets-default` in directory /workspace/test/fixtures/multiple_buckets
       Deleted workspace "kitchen-terraform-multiple-buckets-default"!
       Finished destroying <multiple-buckets-default> (0m6.49s).
-----> Kitchen is finished. (0m8.10s)

9. Générer de la documentation pour les entrées et les sorties

Les tables d'entrées et de sorties dans les fichiers README du module racine, des sous-modules et des exemples de modules sont automatiquement générées en fonction des variables et outputs des modules respectifs. Ces tables doivent être actualisées en cas de modification des interfaces des modules.

Exécutez la commande suivante :

make generate_docs
# This will generate new Inputs and Outputs tables

10. Exécuter des tests lint dans CFT

Un lint est un outil qui analyse le code source pour signaler les erreurs de programmation, les bugs, les erreurs de style et les constructions suspectes.

De nombreux fichiers du dépôt peuvent être soumis à des fonctions d'analyse lint ou formatés pour maintenir un niveau de qualité. Pour garantir la qualité du kit Cloud Foundation, vous allez utiliser un test lint.

Exécutez la commande suivante :

make docker_test_lint
# This will run all lint tests on your repo

11. Envoyer un PR sur GitHub

Maintenant que vous avez modifié votre code localement et que vous l'avez testé lors des tests d'intégration, vous pouvez le publier dans le dépôt maître.

Pour rendre votre code disponible dans le dépôt maître, vous devez valider les modifications de code dans votre branche et les transférer vers le dépôt maître. Pour que votre code soit ajouté au dépôt principal que vous avez dupliqué au début de l'atelier de programmation, vous devez envoyer une demande d'extraction (PR) dans le dépôt maître après avoir validé le code dans votre dépôt.

Lorsque vous envoyez une demande d'extraction, l'administrateur du dépôt est invité à examiner les modifications de code proposées. Vous pouvez également ajouter d'autres utilisateurs en tant qu'examinateurs pour obtenir des commentaires sur les modifications apportées à votre code. Le PR déclenchera une compilation Cloud Build qui exécutera des tests dans le dépôt.

En fonction des modifications que vous apportez au code, les examinateurs formuleront des commentaires sur votre code et demanderont des modifications si quelque chose doit être modifié sur la base des bonnes pratiques et de la documentation. L'administrateur examinera les modifications apportées à votre code, s'assurera que celui-ci est conforme au dépôt et pourra à nouveau vous demander d'apporter des modifications avant de fusionner votre code dans le dépôt maître.

Exécutez les étapes suivantes pour valider le code dans votre branche dupliquée et transférer le code vers votre branche dupliquée:

  1. La première étape consiste à ajouter les fichiers modifiés dans le dépôt local.
$ git add main.tf
$ git add README.md
$ git add variables.tf
$ git add examples/multiple-buckets/main.tf
$ git add test/integration/multiple-buckets/controls/gsutil.rb
# The ‘git add' command adds the file in the local repository and 
# stages the file for commit. To unstage a file, use git reset HEAD YOUR-FILE
  1. Vos fichiers sont à présent en préproduction. Vous allez maintenant valider les modifications.
$ git commit -m "First CFT commit"
# This will commit the staged changes and prepares them to be pushed 
# to a remote repository. To remove this commit and modify the file, 
# use 'git reset --soft HEAD~1' and commit and add the file again.
  1. Transférez les modifications validées dans votre dépôt local vers GitHub pour créer une demande d'extraction.
$ git push -u origin master
# Pushes the changes in your local repository up to the remote
# repository you specified as the origin

Vous pouvez maintenant envoyer vos modifications de code pour une demande d'extraction.

Procédez comme suit pour créer une demande d'extraction dans le dépôt terraform-google-modules/terraform-google-cloud-storage :

  1. Dans votre navigateur Web, accédez à la page principale du dépôt.
  2. Dans le menu "Branch" (Branche), choisissez la duplication contenant vos commits.
  3. À droite de "Branche" cliquez sur "Nouvelle demande d'extraction".

40087ce52ee5ed35.png

  1. Utiliser la "base" de base Menu déroulant pour sélectionner la branche dans laquelle vous souhaitez fusionner vos modifications. Il s'agit généralement de la branche "maître" car vous avez validé les modifications de code de votre duplication.
  2. Saisissez un titre et une description pour votre demande d'extraction afin de décrire les modifications apportées au code. Soyez aussi précis que possible tout en étant concis.
  3. Pour créer une demande d'extraction en vue de son examen, cliquez sur "Créer une demande d'extraction".

a9e70a2ec9653cd7.png

  1. Vous verrez que les déclencheurs Cloud Build sont en cours d'exécution et sont déclenchés en raison du PR.

Vous venez d'appliquer votre première modification de code à votre branche dupliqué et de générer votre premier PR CFT sur la branche principale.

12. Félicitations

Félicitations ! Vous venez d'ajouter une fonctionnalité à un module du kit Cloud Foundation et d'envoyer une demande d'approbation pour examen.

Vous avez ajouté une fonctionnalité à un module du kit Cloud Foundation, l'avez testée en local via un exemple et effectué des tests avant de valider votre code sur GitHub. Enfin, vous avez envoyé un PR pour examen et fusion finale dans le kit Cloud Foundation.

Vous connaissez maintenant les étapes importantes pour commencer à utiliser le kit Cloud Foundation.