Questo tutorial spiega come gestire l'Infrastructure as Code con Terraform e Cloud Build utilizzando la popolare metodologia GitOps. Il termine GitOps è stato coniato per la prima volta da Weaveworks e il suo concetto chiave è l'utilizzo di un repository Git per archiviare lo stato desiderato dell'ambiente. Terraform è uno strumento HashiCorp che consente di creare, modificare e migliorare l'infrastruttura cloud in modo prevedibile utilizzando codice. In questo tutorial utilizzerai Cloud Build, un servizio di integrazione continua di Google Cloud, per applicare automaticamente i manifest Terraform al tuo ambiente.
Questo tutorial è rivolto agli sviluppatori e agli operatori che cercano una strategia elegante per apportare modifiche all'infrastruttura in modo prevedibile. In questo articolo si presuppone che tu abbia dimestichezza con Google Cloud, Linux e GitHub.
Lo stato State of DevOps segnala le funzionalità identificate che favoriscono le prestazioni relative alla distribuzione del software. Questo tutorial ti aiuterà a utilizzare le seguenti funzionalità:
Architettura
Per dimostrare in che modo questo tutorial applica le pratiche GitOps per la gestione delle esecuzioni di Terraform, considera il seguente diagramma dell'architettura. Tieni presente che utilizza rami GitHub, dev
e prod
, per rappresentare gli ambienti reali. Questi ambienti sono definiti dalle reti Virtual Private Cloud (VPC), rispettivamente dev
e prod
, in un progetto Google Cloud.
Il processo inizia quando esegui il push del codice Terraform nel ramo dev
o prod
. In questo scenario, Cloud Build attiva e quindi applica
i manifest Terraform per raggiungere lo stato desiderato nel rispettivo ambiente.
D'altra parte, quando esegui il push del codice Terraform in qualsiasi altro ramo, ad esempio in un ramo di funzionalità, Cloud Build viene eseguito per eseguire terraform plan
, ma non viene applicato nulla a nessun ambiente.
Idealmente, sviluppatori o operatori devono fare proposte di infrastruttura a
filiali non protette
e poi inviarle tramite
richieste pull.
L'app GitHub di Cloud Build, discussa più avanti in questo tutorial, attiva automaticamente i job di build e collega i report terraform plan
a queste richieste di pull. In questo modo, puoi discutere ed esaminare le potenziali modifiche con i collaboratori e aggiungere commit di follow-up prima che le modifiche vengano unite nel ramo di base.
Se non vengono segnalati dubbi, devi prima unire le modifiche al ramo dev
. Questa unione attiva il deployment dell'infrastruttura nell'ambiente dev
, consentendoti di testare l'ambiente. Dopo aver eseguito il test e aver verificato con certezza gli elementi di cui è stato eseguito il deployment, devi unire il ramo dev
al ramo prod
per attivare l'installazione dell'infrastruttura nell'ambiente di produzione.
Obiettivi
- Configura il repository GitHub.
- Configura Terraform per archiviare lo stato in un bucket Cloud Storage.
- Concedi le autorizzazioni al tuo account di servizio Cloud Build.
- Connetti Cloud Build al tuo repository GitHub.
- Modificare la configurazione dell'ambiente in un ramo di funzionalità.
- Promuovere le modifiche all'ambiente di sviluppo.
- Promuovere le modifiche all'ambiente di produzione.
Costi
In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:
Per generare una stima dei costi in base all'utilizzo previsto,
utilizza il Calcolatore prezzi.
Una volta completate le attività descritte in questo documento, puoi evitare la fatturazione continua eliminando le risorse che hai creato. Per ulteriori informazioni, consulta la pagina Pulizia.
Prerequisiti
- Accedi al tuo account Google Cloud. Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti gratuiti per l'esecuzione, il test e il deployment dei carichi di lavoro.
-
Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.
-
Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.
-
Nella pagina del selettore di progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.
-
Assicurati che la fatturazione sia attivata per il tuo progetto Google Cloud.
-
Nella console Google Cloud, attiva Cloud Shell.
Nella parte inferiore della console Google Cloud viene avviata una sessione di Cloud Shell che mostra un prompt della riga di comando. Cloud Shell è un ambiente shell con Google Cloud CLI già installato e con valori già impostati per il progetto attuale. L'inizializzazione della sessione può richiedere alcuni secondi.
- In Cloud Shell, recupera l'ID del progetto appena selezionato:
gcloud config get-value project
Se questo comando non restituisce l'ID progetto, configura Cloud Shell in modo che utilizzi il tuo progetto. SostituisciPROJECT_ID
con l'ID progetto.gcloud config set project PROJECT_ID
- Abilita le API richieste:
gcloud services enable cloudbuild.googleapis.com compute.googleapis.com
Il completamento di questo passaggio potrebbe richiedere alcuni minuti. - Se non hai mai utilizzato Git in Cloud Shell, configuralo con il tuo nome e il tuo indirizzo email:
git config --global user.email "YOUR_EMAIL_ADDRESS" git config --global user.name "YOUR_NAME"
Git utilizza queste informazioni per identificarti come autore dei commit che crei in Cloud Shell.
Configurazione del repository GitHub
In questo tutorial utilizzerai un singolo repository Git per definire la tua infrastruttura cloud. Puoi orchestrare questa infrastruttura utilizzando rami diversi corrispondenti ad ambienti diversi:
- Il ramo
dev
contiene le ultime modifiche applicate all'ambiente di sviluppo. - Il ramo
prod
contiene le ultime modifiche applicate all'ambiente di produzione.
Con questa infrastruttura, puoi sempre fare riferimento al repository per sapere quale configurazione è prevista in ogni ambiente e proporre nuove modifiche unendole prima nell'ambiente dev
. Successivamente, promuovi le modifiche unendo il ramo dev
al ramo prod
successivo.
Per iniziare, crea il fork del repository solutions-terraform-cloudbuild-gitops.
- Su GitHub, vai alla pagina https://github.com/GoogleCloudPlatform/solutions-terraform-cloudbuild-gitops.git.
Nell'angolo in alto a destra della pagina, fai clic su Forchetta.
Ora hai una copia del repository
solutions-terraform-cloudbuild-gitops
con file di origine.In Cloud Shell, clona questo repository creato con fork, sostituendo
YOUR_GITHUB_USERNAME
con il tuo nome utente GitHub:cd ~ git clone https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops.git cd ~/solutions-terraform-cloudbuild-gitops
Il codice in questo repository è strutturato come segue:
La cartella
environments/
contiene sottocartelle che rappresentano ambienti, comedev
eprod
, che forniscono una separazione logica tra i carichi di lavoro in diverse fasi di maturità, sviluppo e produzione, rispettivamente. Nonostante sia una buona pratica avere questi ambienti il più simili possibile, ogni sottocartella ha la propria configurazione Terraform per garantire che possano avere impostazioni univoche, se necessario.La cartella
modules/
contiene moduli Terraform incorporati. Questi moduli rappresentano raggruppamenti logici di risorse correlate e vengono utilizzati per condividere il codice in diversi ambienti.Il file
cloudbuild.yaml
è un file di configurazione di compilazione che contiene istruzioni per Cloud Build, ad esempio come eseguire attività in base a un insieme di passaggi. Questo file specifica un'esecuzione condizionale in base al ramo da cui Cloud Build recupera il codice, ad esempio:Per i rami
dev
eprod
, vengono eseguiti i seguenti passaggi:terraform init
terraform plan
terraform apply
Per qualsiasi altro ramo, vengono eseguiti i seguenti passaggi:
terraform init
per tutte leenvironments
sottocartelleterraform plan
per tutte leenvironments
sottocartelle
Per garantire che le modifiche proposte siano appropriate per ogni ambiente, terraform init
e terraform plan
vengono eseguiti per tutte le environments
cartelle secondarie. Prima di unire la richiesta di pull, puoi rivedere i piani per assicurarti che l'accesso non venga concesso a entità non autorizzate, ad esempio.
Configurazione di Terraform per l'archiviazione dello stato in un bucket Cloud Storage
Per impostazione predefinita, Terraform archivia lo state localmente in un file denominato terraform.tfstate
. Questa configurazione predefinita può complicare l'utilizzo di Terraform per i team, soprattutto quando molti utenti eseguono Terraform contemporaneamente e ogni macchina ha la propria comprensione dell'infrastruttura attuale.
Per aiutarti a evitare questi problemi, questa sezione configura uno stato remoto che rimanda a un bucket Cloud Storage. Lo stato remoto è una funzionalità dei backend e, in questo tutorial, è configurato nei file backend.tf
, ad esempio:
Nei passaggi seguenti, creerai un bucket Cloud Storage e modificherai alcuni file in modo che rimandino al nuovo bucket e al tuo progetto Google Cloud.
In Cloud Shell, crea il bucket Cloud Storage:
PROJECT_ID=$(gcloud config get-value project) gsutil mb gs://${PROJECT_ID}-tfstate
Abilita il controllo delle versioni degli oggetti per conservare la cronologia dei tuoi deployment:
gsutil versioning set on gs://${PROJECT_ID}-tfstate
L'abilitazione del controllo delle versioni degli oggetti aumenta i costi di archiviazione, che puoi ridurre configurando Gestione del ciclo di vita degli oggetti per eliminare le versioni dello stato precedente.
Sostituisci il segnaposto
PROJECT_ID
con l'ID progetto nei fileterraform.tfvars
ebackend.tf
:cd ~/solutions-terraform-cloudbuild-gitops sed -i s/PROJECT_ID/$PROJECT_ID/g environments/*/terraform.tfvars sed -i s/PROJECT_ID/$PROJECT_ID/g environments/*/backend.tf
Su OS X/MacOS, potrebbe essere necessario aggiungere due virgolette (
""
) doposed -i
, come indicato di seguito:cd ~/solutions-terraform-cloudbuild-gitops sed -i "" s/PROJECT_ID/$PROJECT_ID/g environments/*/terraform.tfvars sed -i "" s/PROJECT_ID/$PROJECT_ID/g environments/*/backend.tf
Controlla se tutti i file sono stati aggiornati:
git status
L'output sarà simile al seguente:
On branch dev Your branch is up-to-date with 'origin/dev'. Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: environments/dev/backend.tf modified: environments/dev/terraform.tfvars modified: environments/prod/backend.tf modified: environments/prod/terraform.tfvars no changes added to commit (use "git add" and/or "git commit -a")
Esegui il commit e il push delle modifiche:
git add --all git commit -m "Update project IDs and buckets" git push origin dev
A seconda della configurazione di GitHub, dovrai autenticarti per eseguire il push delle modifiche precedenti.
Concessione delle autorizzazioni all'account di servizio Cloud Build
Per consentire all'account di servizio Cloud Build di eseguire script Terraform con l'obiettivo di gestire le risorse Google Cloud, devi concedergli l'accesso appropriato al tuo progetto. Per semplicità, in questo tutorial viene concesso l'accesso come editor di progetto. Tuttavia, quando il ruolo Editor di progetto ha un'autorizzazione per l'utilizzo su vasta scala, negli ambienti di produzione devi seguire le best practice per la sicurezza IT della tua azienda, fornendo in genere l'accesso con privilegi minimi.
In Cloud Shell, recupera l'email per l'account di servizio Cloud Build del tuo progetto:
CLOUDBUILD_SA="$(gcloud projects describe $PROJECT_ID \ --format 'value(projectNumber)')@cloudbuild.gserviceaccount.com"
Concedi l'accesso richiesto al tuo account di servizio Cloud Build:
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$CLOUDBUILD_SA --role roles/editor
Connessione diretta di Cloud Build al repository GitHub
Questa sezione mostra come installare l'app GitHub di Cloud Build. Questa installazione consente di connettere il repository GitHub al progetto Google Cloud in modo che Cloud Build possa applicare automaticamente i manifest Terraform ogni volta che crei un nuovo ramo o esegui il push del codice in GitHub.
I passaggi seguenti forniscono istruzioni per installare l'app solo per il repository solutions-terraform-cloudbuild-gitops
, ma puoi scegliere di installare l'app per altri o tutti i repository.
Vai alla pagina GitHub Marketplace per l'app Cloud Build:
Apri la pagina dell'app Cloud Build
- Se è la prima volta che configuri un'app in GitHub: fai clic su Configura con Google Cloud Build nella parte inferiore della pagina. Quindi, fai clic su Concedi a questa app l'accesso al tuo account GitHub.
- Se non è la prima volta che configuri un'app in GitHub: fai clic su Configura l'accesso. Si apre la pagina Applicazioni del tuo account personale.
Fai clic su Configura nella riga Cloud Build.
Seleziona Seleziona solo repository, quindi seleziona
solutions-terraform-cloudbuild-gitops
per connetterti al repository.Fai clic su Salva o Installa: l'etichetta del pulsante cambia in base al flusso di lavoro. Ti reindirizzeremo a Google Cloud per continuare l'installazione.
Accedi con il tuo account Google Cloud. Se richiesto, autorizza l'integrazione di Cloud Build con GitHub.
Nella pagina Cloud Build, seleziona il tuo progetto. Viene visualizzata una procedura guidata.
Nella sezione Seleziona repository, seleziona il tuo account GitHub e il repository
solutions-terraform-cloudbuild-gitops
.Se accetti i Termini e condizioni, seleziona la casella di controllo e fai clic su Connetti.
Nella sezione Crea un attivatore, fai clic su Crea un attivatore:
- Aggiungi un nome per l'attivatore, ad esempio
push-to-branch
. Prendi nota del nome di questo trigger perché ti servirà in un secondo momento. - Nella sezione Evento, seleziona Push al ramo.
- Nella sezione Origine, seleziona
.*
nel campo Ramo. - Fai clic su Crea.
- Aggiungi un nome per l'attivatore, ad esempio
L'app GitHub di Cloud Build è ora configurata e il repository GitHub è collegato al tuo progetto Google Cloud. D'ora in poi, le modifiche al repository GitHub attivano le esecuzioni di Cloud Build, che riportano i risultati a GitHub utilizzando i controlli GitHub.
Modifica della configurazione dell'ambiente in un nuovo ramo di funzionalità
A questo punto, hai configurato la maggior parte del tuo ambiente. È arrivato quindi il momento di apportare modifiche al codice nel tuo ambiente di sviluppo.
Su GitHub, vai alla pagina principale del repository creato con fork.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Assicurati di essere nel ramo
dev
.Per aprire il file e modificarlo, vai al file
modules/firewall/main.tf
e fai clic sull'icona a forma di matita.Alla riga 30, correggi l'errore ortografico di
"http-server2"
nel campotarget_tags
.Il valore deve essere
"http-server"
.Aggiungi un messaggio di commit in fondo alla pagina, ad esempio "Correzione della destinazione del firewall http" e seleziona Crea un nuovo ramo per questo commit e avvia una richiesta di pull.
Fai clic su Proponi modifiche.
Nella pagina successiva, fai clic su Crea richiesta di pull per aprire una nuova richiesta di pull con la tua modifica.
Dopo l'apertura della richiesta di pull, viene avviato automaticamente un job di Cloud Build.
Fai clic su Mostra tutti i controlli e attendi che il segno di spunta diventi verde.
Fai clic su Dettagli per visualizzare ulteriori informazioni, tra cui l'output del
terraform plan
al link Visualizza altri dettagli su Google Cloud Build.
Non unire ancora la richiesta di pull.
Tieni presente che il job Cloud Build ha eseguito la pipeline definita nel
file cloudbuild.yaml
. Come già detto, questa pipeline ha comportamenti
diversi a seconda del ramo recuperato. La build controlla se la variabile $BRANCH_NAME
corrisponde a qualsiasi cartella di ambiente. Se è così, Cloud Build esegue terraform plan
per quell'ambiente.
In caso contrario, Cloud Build esegue terraform plan
per tutti gli ambienti,
per assicurarsi che la modifica proposta sia appropriata per tutti gli ambienti. Se uno di questi piani non viene eseguito, la build non va a buon fine.
Analogamente, il comando terraform apply
viene eseguito per i rami di ambiente, ma viene completamente ignorato in tutti gli altri casi. In questa sezione hai inviato una modifica del codice a un nuovo ramo, quindi non sono stati applicati deployment dell'infrastruttura al tuo progetto Google Cloud.
Forza l'esecuzione di Cloud Build prima dell'unione dei rami
Per assicurarti che le unioni possano essere applicate solo quando le rispettive esecuzioni di Cloud Build hanno esito positivo, procedi con i seguenti passaggi:
Su GitHub, vai alla pagina principale del repository creato con fork.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Sotto il nome del repository, fai clic su Impostazioni.
Nel menu a sinistra, fai clic su rami.
In Regole di protezione dei rami, fai clic su Aggiungi regola.
In Pattern nome ramo, digita
dev
.Nella sezione Proteggi i rami corrispondenti, seleziona Richiedi il superamento dei controlli di stato prima dell'unione.
Cerca il nome del trigger di Cloud Build creato in precedenza.
Fai clic su Crea.
Ripeti i passaggi 3-7, impostando Pattern nome ramo su
prod
.
Questa configurazione è importante per
proteggere
entrambi i rami dev
e prod
. Questo significa che i commit devono prima essere
inviati tramite push a un altro ramo e solo allora possono essere uniti al ramo protetto. In questo tutorial, la protezione richiede che l'esecuzione di Cloud Build abbia esito positivo affinché l'unione sia consentita.
Promozione di modifiche all'ambiente di sviluppo
Hai una richiesta pull in attesa di unione. È il momento di applicare lo stato
desiderato all'ambiente dev
.
Su GitHub, vai alla pagina principale del repository creato con fork.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Sotto il nome del repository, fai clic su Richieste di pull.
Fai clic sulla richiesta di pull appena creata.
Fai clic su Unisci richiesta di pull, quindi su Conferma unione.
Controlla che sia stato attivato un nuovo Cloud Build:
Apri la build e controlla i log.
Al termine della build, vedrai qualcosa di simile a questo:
Step #3 - "tf apply": external_ip = EXTERNAL_IP_VALUE Step #3 - "tf apply": firewall_rule = dev-allow-http Step #3 - "tf apply": instance_name = dev-apache2-instance Step #3 - "tf apply": network = dev Step #3 - "tf apply": subnet = dev-subnet-01
Copia
EXTERNAL_IP_VALUE
e apri l'indirizzo in un browser web.http://EXTERNAL_IP_VALUE
Questo provisioning potrebbe richiedere alcuni secondi per avviare la VM e propagare la regola firewall. Infine, vedrai Ambiente: dev nel browser web.
Vai al file di stato di Terraform nel bucket Cloud Storage.
https://storage.cloud.google.com/PROJECT_ID-tfstate/env/dev/default.tfstate
Promozione di modifiche all'ambiente di produzione
Ora che il tuo ambiente di sviluppo è stato testato, puoi promuovere il codice dell'infrastruttura in produzione.
Su GitHub, vai alla pagina principale del repository creato con fork.
https://github.com/YOUR_GITHUB_USERNAME/solutions-terraform-cloudbuild-gitops
Sotto il nome del repository, fai clic su Richieste di pull.
Fai clic su Nuova richiesta di pull.
Per il repository di base, seleziona il repository appena creato.
Per base, seleziona
prod
dal tuo repository di base. Per confronta, selezionadev
.Fai clic su Crea richiesta di pull.
Per titolo, inserisci un titolo come
Promoting networking changes
, quindi fai clic su Crea richiesta di pull.Esamina le modifiche proposte, inclusi i dettagli
terraform plan
di Cloud Build, quindi fai clic su Unisci richiesta di pull.Fai clic su Conferma unione.
Nella console Google Cloud, apri la pagina Cronologia build per vedere le modifiche che vengono applicate all'ambiente di produzione:
Attendi il completamento della build, quindi controlla i log.
Alla fine dei log, vedrai qualcosa di simile a questo:
Step #3 - "tf apply": external_ip = EXTERNAL_IP_VALUE Step #3 - "tf apply": firewall_rule = prod-allow-http Step #3 - "tf apply": instance_name = prod-apache2-instance Step #3 - "tf apply": network = prod Step #3 - "tf apply": subnet = prod-subnet-01
Copia
EXTERNAL_IP_VALUE
e apri l'indirizzo in un browser web.http://EXTERNAL_IP_VALUE
Questo provisioning potrebbe richiedere alcuni secondi per avviare la VM e propagare la regola firewall. Al termine, vedrai Ambiente: prod nel browser web.
Vai al file di stato di Terraform nel bucket Cloud Storage.
https://storage.cloud.google.com/PROJECT_ID-tfstate/env/prod/default.tfstate
Hai configurato correttamente una pipeline serverless Infrastructure as Code su Cloud Build. In futuro, ti consigliamo di provare quanto segue:
- Aggiungi deployment per casi d'uso separati.
- Crea ambienti aggiuntivi per riflettere le tue esigenze.
- Utilizza un progetto per ambiente anziché un VPC per ambiente.
esegui la pulizia
Dopo aver completato il tutorial, pulisci le risorse che hai creato su Google Cloud in modo che non ti vengano addebitati costi in futuro.
Elimina il progetto
- Nella console Google Cloud, vai alla pagina Gestisci risorse.
- Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
- Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.
Eliminazione del repository GitHub
Per evitare di bloccare le nuove richieste di pull sul tuo repository GitHub, puoi eliminare le regole di protezione dei rami:
- In GitHub, vai alla pagina principale del repository creato con fork.
- Sotto il nome del repository, fai clic su Impostazioni.
- Nel menu a sinistra, fai clic su rami.
- Nella sezione Regole di protezione dei rami, fai clic sul pulsante Elimina per entrambe le righe
dev
eprod
.
Se vuoi, puoi disinstallare completamente l'app Cloud Build da GitHub:
Vai alle impostazioni Applicazioni di GitHub.
Nella scheda App GitHub installate, fai clic su Configura nella riga Cloud Build. Nella sezione Zona pericolosa, fai clic sul pulsante Disinstalla nella riga Disinstalla Google Cloud Builder.
Nella parte superiore della pagina viene visualizzato il messaggio "Fatto. È stato messo in coda un job per la disinstallazione di Google Cloud Build."
Nella scheda App GitHub autorizzate, fai clic sul pulsante Revoca nella riga Google Cloud Build, quindi su Ho capito, revoco l'accesso nel popup.
Se non vuoi conservare il repository GitHub:
- In GitHub, vai alla pagina principale del repository creato con fork.
- Sotto il nome del repository, fai clic su Impostazioni.
- Scorri verso il basso fino alla Zona pericolosa.
- Fai clic su Elimina questo repository e segui i passaggi di conferma.
Passaggi successivi
- Prendi in considerazione l'utilizzo di modelli di Cloud Foundation Toolkit per creare rapidamente una base ripetibile di livello enterprise in Google Cloud.
- Guarda il video Ripetibile Google Cloud Environments at Scale With Cloud Build Infra-As-Code Pipelines di Next'19 sul flusso di lavoro GitOps descritto in questo tutorial.
- Guarda il tutorial sulla distribuzione continua in stile GitOps con Cloud Build.
- Dai un'occhiata alle funzionalità più avanzate di Cloud Build: Configurazione dell'ordine dei passi di build, Creazione, test e deployment degli artefatti e Creazione di passi di build personalizzati.
- Dai un'occhiata al blog su come garantire la scalabilità e la conformità del tuo deployment Terraform con Cloud Build.
- Leggi le nostre risorse su DevOps.
- Scopri di più sulle funzionalità DevOps correlate a questo tutorial:
- Esegui il controllo rapido di DevOps per comprendere la tua posizione rispetto al resto del settore.