1. Introduzione al corso CFT 101
Ultimo aggiornamento: 2020-03-03
Cos'è Cloud Foundation Toolkit?
In sostanza, CFT fornisce modelli di best practice per iniziare rapidamente a utilizzare la piattaforma Google Cloud. In questo tutorial imparerai a contribuire al Cloud Foundation Toolkit.
Che cosa ti serve
- Un account GitHub.
- Docker installato sulla macchina ( installazione per Mac, installazione per Windows)
- Editor di codice per la modifica del codice (ad esempio: codice Visual Studio)
- Familiarità di base con Git e GitHub
- Una certa esperienza con Terraform e con Infrastructure as Code
- Autorizzazione per concedere il ruolo Autore progetto a un account di servizio
Cosa creerai
In questo codelab, imparerai come contribuire al Cloud Foundation Toolkit (CFT).
Imparerai a:
- Imposta un ambiente di sviluppo per contribuire a CFT
- Aggiungere una funzionalità a un modulo CFT
- Aggiungi test per la funzionalità aggiunta
- Esegui test di integrazione in CFT
- Esegui test lint
- Esegui il commit del codice su GitHub e invia una richiesta di pull (PR)
Eseguirai tutti i passaggi precedenti aggiungendo una nuova funzionalità al modulo CFT di Google Cloud Storage. Stai aggiungendo un'etichetta denominata "silly_label"
che viene aggiunta automaticamente a tutti i bucket creati tramite il modulo CFT di GCS. Inoltre, potrai scrivere test per convalidare la tua caratteristica e garantire l'integrazione end-to-end.
2. Configura l'ambiente di sviluppo
Se vuoi, puoi utilizzare Cloud Shell per i tuoi sviluppi. Se non vuoi utilizzare Cloud Shell per contribuire a CFT, puoi configurare il tuo ambiente di sviluppo sulla tua macchina.
Configura Git
GitHub si basa su un sistema di controllo della versione (VCS) open source chiamato Git. Git è responsabile di tutto ciò che riguarda GitHub che avviene localmente sulla tua macchina o su Cloud Shell.
- Quando utilizzi Cloud Shell, non è necessario installare Git perché è preinstallato.
$ git --version
# This will display the git version on the Cloud Shell.
Se stai configurando il tuo ambiente di sviluppo sulla tua macchina, devi installare Git.
Impostazione del nome utente e dell'email in Git
Git utilizza un nome utente per associare i commit a un'identità. Il nome utente Git non è uguale al nome utente GitHub.
Puoi modificare il nome associato ai tuoi commit Git utilizzando il comando git config. La modifica del nome associato ai commit Git utilizzando git config
influirà solo sui commit futuri e non cambierà il nome utilizzato per i commit precedenti.
Hai configurato Git correttamente e dovresti essere in grado di creare un fork, creare e clonare i rami. Useremo molto Git in questo codelab.
3. Repository GCS di Fork CFT
Crea un fork di un repository CFT
Hai configurato Git sulla tua macchina locale o su Cloud Shell nel passaggio precedente. Ora devi creare il fork del repository CFT di Google Cloud Storage per iniziare a contribuire.
Un fork è una copia di un repository. Il forking di un repository ti consente di sperimentare liberamente le modifiche senza influire sul progetto originale.
Di solito i fork sono usati per proporre modifiche al progetto di un'altra persona o per usare il progetto di un'altra persona come punto di partenza per la tua idea.
Ad esempio, puoi utilizzare i fork per proporre modifiche relative alla correzione di un bug. Per correggere un bug, puoi:
- Crea un fork del repository.
- Apporta la correzione.
- Invia una richiesta di pull al proprietario del progetto.
Procedura per il fork di un repository CFT:
- Apri il browser web e vai al repository terraform-google-modules/terraform-google-cloud-storage. Utilizzeremo questo repository per l'intero codelab.
- Nell'angolo in alto a destra della pagina, fai clic su Fork.
- Verrà visualizzata un'opzione per scegliere dove inserire il fork, scegliere il tuo profilo e verrà creato un fork del repository.
Clonare la fork in locale
Il fork che hai creato è una copia del repository del modulo GCS. Ora clonerai questo repository nel tuo ambiente locale per aggiungere la tua nuova caratteristica.
Procedura per clonare la forchetta:
- Apri il browser web e vai al tuo fork su terraform-google-modules/terraform-google-cloud-storage.
- Nell'angolo in alto a destra, troverai l'opzione "Clona o scarica" fai clic sul pulsante.
- Dopo aver fatto clic sul pulsante "Clona o scarica", fai clic su "Blocco note" per copiare l'URL della forchetta. Utilizzerai questo URL per clonare il tuo fork nel tuo ambiente locale.
- Vai a un terminale nel tuo VSCode o nella tua macchina e clona il fork.
$ git clone <url>
# This command will clone your fork locally.
# Paste the copied URL from the previous step.
- Ora che hai clonato il fork in locale, devi accedere al repository, creare un nuovo ramo dal fork e apportare modifiche al codice nel ramo temporaneo.
Per convenzione, puoi denominare il ramo come segue:
- Per le richieste di funzionalità:
feature/feature-name
- Per gli aggiornamenti interni,
internal/change-name
- Per correzioni di bug:
bugfix/issue-name
Poiché stai aggiungendo una nuova funzionalità, puoi chiamare la tua filiale temporanea 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"
Ora è tutto pronto per iniziare a lavorare sul Cloud Foundation Toolkit.
4. Crea un ambiente di test
Il processo di sviluppo standard di CFT si basa sull'utilizzo di un progetto di test isolato per i test. Questo passaggio ti guiderà nella creazione del progetto di test (basato su una configurazione standard) tramite un account di servizio.
0. Installa Docker Engine
Se utilizzi la macchina a scopo di sviluppo, devi installare Docker Engine.
1. Installa Google Cloud SDK
Non è necessario installare Google Cloud SDK se utilizzi Cloud Shell di Google Cloud.
Vai a Google Cloud SDK e scarica il programma di installazione interattivo per la tua piattaforma.
2. Imposta configurazione
Per creare un ambiente di test, devi avere un'organizzazione Google Cloud, una cartella di test e un account di fatturazione. Questi valori devono essere impostati tramite le variabili di ambiente:
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 Configurare l'account di servizio
Prima di creare un ambiente di test, devi scaricare una chiave dell'account di servizio nell'ambiente di test. Questo account di servizio avrà bisogno dei ruoli Autore progetto, Utente account di fatturazione e Visualizzatore organizzazione. Questi passaggi ti aiutano a creare un nuovo account di servizio, ma puoi anche riutilizzare un account esistente.
3.1 Creare o selezionare un progetto Google Cloud di origine
Prima di creare il tuo account di servizio, devi selezionare un progetto in cui ospitarlo. Puoi anche creare un nuovo progetto.
gcloud config set core/project YOUR_PROJECT_ID
3.2 Abilita le API Google Cloud
Abilita le seguenti API Google Cloud nel tuo progetto di origine:
gcloud services enable cloudresourcemanager.googleapis.com
gcloud services enable iam.googleapis.com
gcloud services enable cloudbilling.googleapis.com
3.3 Creare l'account di servizio
Crea un nuovo account di servizio per gestire l'ambiente di 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
Verifica che l'account di servizio sia stato creato:
gcloud iam service-accounts list --filter="EMAIL=${SERVICE_ACCOUNT}"
3.4 Concedi i ruoli Creatore progetto, Utente account di fatturazione e Visualizzatore organizzazione all'account di servizio:
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"
Ora hai un account di servizio che può essere utilizzato per gestire l'ambiente di test.
4. Assegna il ruolo Utente account di fatturazione per la risorsa dell'account di fatturazione
4.1 Recuperare il criterio IAM dell'account di fatturazione
Scarica le associazioni di criteri IAM esistenti nell'account di fatturazione
gcloud beta billing accounts get-iam-policy ${TF_VAR_billing_account} | tee policy.yml
4.2 Aggiornare le norme per includere l'account di servizio
Aggiorna il file policy.yml
per aggiungere una nuova associazione per l'account di servizio con il ruolo roles/billing.user
bindings:
- members:
- serviceAccount:cft-onboarding@<YOUR_PROJECT_ID>.iam.gserviceaccount.com
role: roles/billing.user
4.3 Aggiornare le norme dell'account di fatturazione
Applica le modifiche all'account di fatturazione
gcloud beta billing accounts set-iam-policy ${TF_VAR_billing_account} policy.yml
5. prepara la credenziale Terraform
Per creare l'ambiente di test, devi scaricare la chiave dell'account di servizio nella shell.
5.1 Chiave dell'account di servizio
Crea e scarica una chiave dell'account di servizio per Terraform
gcloud iam service-accounts keys create cft.json --iam-account=${SERVICE_ACCOUNT}
5.2 Configurare la credenziale Terraform
Fornisci la chiave a Terraform utilizzando la variabile di ambiente SERVICE_ACCOUNT_JSON
, impostando il valore su contents della chiave dell'account di servizio.
export SERVICE_ACCOUNT_JSON=$(< cft.json)
6. Crea un progetto di test per i deployment Terraform
Ora che è tutto pronto, puoi creare il progetto di test con un singolo comando. Esegui questo comando dalla directory radice di terraform-google-cloud-storage:
make docker_test_prepare
Quando esegui make docker_test_prepare
vedrai l'output riportato di seguito. Al termine, riceverai il project_id di test creato, dove eseguirai il deployment e testerai il modulo Cloud Storage con la nuova funzionalità.
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.
Hai creato un progetto di test a cui fa riferimento il parametro project_id, come puoi vedere nell'output della console. L'ambiente di sviluppo e test è configurato.
5. Aggiungi una nuova funzionalità al modulo CFT
Ora che l'ambiente di sviluppo e test è configurato, iniziamo ad aggiungere "silly_label" al modulo CFT di google-cloud-storage.
Assicurati di essere in terraform-google-cloud-storage e apri il file main.tf come mostrato di seguito nella struttura delle cartelle.
Da "silly_label" è un'etichetta, aggiungerai la caratteristica alla riga 27 nella variabile "labels" in main.tf, come mostrato sotto:
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(
<...>
}
Ora aggiungerai la variabile silly_label nel file variables.tf che vedi nella struttura di cartelle precedente.
Copia e incolla il codice riportato di seguito e aggiungilo alla riga 29 in variables.tf e assicurati di avere un nuovo carattere di riga sopra e sotto il blocco di variabili che aggiungi.
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. Aggiungi una nuova caratteristica a un esempio di bucket di archiviazione
Hai aggiunto la tua caratteristica al file main.tf del modulo e ora testerai la caratteristica aggiunta attraverso un esempio.
"silly_label" dovrà essere aggiunto al file example/multiple-buckets/main.tf
Questo esempio verrà utilizzato da un dispositivo nel passaggio successivo per eseguire i test di integrazione.
Copia e incolla la riga seguente della variabile silly_label nella riga 27 di main.tf su terraform-google-cloud-storage/examples/multiple-buckets/ come illustrato nella struttura delle cartelle:
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. Scrivi un test di ispezione per verificare la caratteristica
Hai aggiunto la tua caratteristica al file main.tf del modulo e quindi l'hai aggiunta all'esempio di multiple_buckets per poterla testare attraverso l'attrezzatura. Devi testare la tua caratteristica tramite un test di integrazione InSpec scritto in Ruby.
Aggiungerai i nuovi test nel file gsutil.rb che trovi nella seguente struttura di cartelle:
Hai aggiunto "silly_label" su tutti i bucket creati tramite il modulo multiple_buckets e ora dovrai scrivere dei test per testare la nuova funzionalità.
Nel codice riportato di seguito ottieni l'etichetta di ciascun bucket tramite il comando gsutil, quindi controlli l'output restituito dal comando.
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. Esegui test di integrazione in CFT
Test di integrazione
I test di integrazione vengono utilizzati per verificare il comportamento del modulo principale, dei sottomoduli e dei moduli di esempio. Aggiunte, modifiche e correzioni devono essere accompagnate da test.
I test di integrazione vengono eseguiti utilizzando Kitchen, Kitchen-Terraform e InSpec. Questi strumenti vengono pacchettizzati all'interno di un'immagine Docker per praticità.
La strategia generale per questi test consiste nel verificare il comportamento dei moduli di esempio, garantendo così che il modulo principale, i sottomoduli e i moduli di esempio siano tutti funzionalmente corretti.
Nell'esecuzione interattiva, ogni passaggio viene eseguito tramite più comandi.
- Esegui
make docker_run
per avviare il container Docker di test in modalità interattiva.
Make è uno strumento di automazione delle build che crea automaticamente librerie e programmi eseguibili dal codice sorgente leggendo file chiamati Makefiles che specificano come ricavare il programma di destinazione. Quando apporti modifiche al file, il contenitore Docker deve essere aggiornato automaticamente.
Quando esegui make docker_run
, crei un'area di lavoro nel container Docker e attivi le credenziali per il tuo account di servizio. L'area di lavoro verrà utilizzata nei passaggi successivi per eseguire i test.
Nel terminale verrà visualizzato l'output seguente:
Activated service account credentials for: [cft@<PROJECT_ID>.iam.gserviceaccount.com]
- Esegui
kitchen_do list
per elencare tutte le istanze nell'area di lavoro che contengono test di integrazione.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>
- Esegui
kitchen_do create <EXAMPLE_NAME>
per inizializzare la directory di lavoro per un modulo di esempio.
Questo passaggio inizializza la cucina e inizializza Terraform nell'area di lavoro.
Vedrai l'output seguente nel tuo terminale.
[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)
- Esegui
kitchen_do converge <EXAMPLE_NAME>
per applicare il modulo di esempio.
Questo passaggio applica l'area di lavoro Terraform creata nel passaggio precedente al progetto Google Cloud creato in precedenza nel codelab.
Vedrai l'output seguente nel tuo terminale.
[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)
- Esegui
kitchen_do verify <EXAMPLE_NAME>
per testare il modulo di esempio.
Questo passaggio illustra il file gsutils.rb, che contiene i test per il modulo multiple_buckets. Ogni test include un comando gsutil che verrà eseguito sul progetto di test che hai creato in precedenza utilizzando la configurazione delle credenziali dell'account di servizio.
Se ricevi degli errori, vedrai ciò che ci aspettavi e cosa è stato ricevuto dal comando per il test.
Vedrai l'output seguente nel tuo terminale.
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)
- Esegui
kitchen_do destroy <EXAMPLE_NAME>
per eliminare lo stato di esempio del modulo.
Questo passaggio elimina l'area di lavoro che hai creato nei passaggi precedenti. Questo passaggio distruggerà anche i bucket GCS creati nel progetto insieme all'etichetta che hai aggiunto al modulo GCS.
Puoi visualizzare l'output di seguito nel tuo terminale.
[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. Generazione della documentazione per gli input e gli output
Le tabelle di input e output nei README del modulo principale, dei sottomoduli e dei moduli di esempio vengono generate automaticamente in base ai valori variables
e outputs
dei rispettivi moduli. Queste tabelle devono essere aggiornate se le interfacce del modulo vengono modificate.
Esegui:
make generate_docs
# This will generate new Inputs and Outputs tables
10. Esegui test lint in CFT
Un linter è uno strumento che analizza il codice sorgente per segnalare errori di programmazione, bug, errori stilistici e costrutti sospetti.
Molti dei file nel repository possono essere sottoposti a lint o formattati per mantenere uno standard di qualità. Per garantire la qualità in CFT, utilizzerai un test lint.
Esegui:
make docker_test_lint
# This will run all lint tests on your repo
11. Invio di un PR su GitHub
Ora che hai modificato il codice localmente e testato tramite i test di integrazione, vuoi pubblicare il codice nel repository principale.
Per rendere disponibile il codice nel repository master, dovrai eseguire il commit delle modifiche al codice nel ramo ed eseguirne il push nel repository master. Per aggiungere il codice al repository principale che hai creato con fork all'inizio del codelab, devi inviare una richiesta di pull (PR) al repository master dopo aver eseguito il commit del codice nel repository.
Quando presenti un PR, l'amministratore del repository viene informato di esaminare le modifiche al codice proposte. Inoltre, puoi aggiungere altri utenti come revisori per ricevere feedback sulle modifiche apportate al codice. Il PR attiverà Cloud Build che eseguirà test sul repository.
In base alle modifiche apportate al codice, i revisori del codice ti forniranno commenti e ti chiederanno se sia necessario apportare modifiche in base alle best practice e alla documentazione. L'amministratore esaminerà le tue modifiche al codice, si assicurerà che il codice sia conforme al repository e potrebbe chiederti nuovamente di apportare alcune modifiche prima di unire il codice nel repository principale.
Esegui questi passaggi per eseguire il commit del codice nel ramo creato con fork ed eseguire il push del codice al ramo creato con fork:
- Il primo passaggio consiste nell'aggiungere i file modificati al repository locale.
$ 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
- I file sono ora in fase temporanea. Successivamente, eseguirai il commit delle modifiche.
$ 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.
- Esegui il push delle modifiche sottoposte a commit nel tuo repository locale in GitHub per la creazione di una richiesta di pull (PR).
$ git push -u origin master
# Pushes the changes in your local repository up to the remote
# repository you specified as the origin
Le modifiche al codice sono pronte per una richiesta di pull.
Esegui questi passaggi per generare un PR per il repository terraform-google-modules/terraform-google-cloud-storage :
- Nel browser web, vai alla pagina principale del repository.
- Nel menu Ramo, scegli il fork che contiene i commit.
- A destra del "Ramo" fai clic su "Nuova richiesta di pull".
- Utilizza la "base" di base menu a discesa per selezionare il ramo in cui desideri unire le modifiche (di solito è "principale" poiché hai eseguito il commit delle modifiche al codice nel fork.
- Inserisci un titolo e una descrizione per la richiesta di pull in modo da descrivere le modifiche al codice. Sii il più specifico possibile, ma conciso.
- Per creare una richiesta di pull pronta per la revisione, fai clic su "Crea richiesta di pull".
- Vedrai in esecuzione i trigger di Cloud Build, che vengono attivati a causa del PR.
Hai eseguito correttamente il push della prima modifica del codice al ramo creato con fork e hai aumentato la tua prima PR CFT rispetto al ramo master.
12. Complimenti
Congratulazioni. Hai aggiunto correttamente una funzionalità a un modulo CFT e inviato un PR per la revisione.
Hai aggiunto una funzionalità a un modulo CFT, l'hai testata localmente tramite un esempio ed eseguito test prima di eseguire il commit del codice su GitHub. Infine, hai inviato un PR per la revisione e l'unione finale nel CFT.
Ora conosci i passaggi importanti per iniziare a utilizzare Cloud Foundation Toolkit.