Introduzione
Strutturare i progetti Terraform in modo adeguato secondo i loro casi d’uso e la complessità percorsa è essenziale per assicurare la loro manutenibilità e estensibilità nelle operazioni giornaliere. Un approcio sistematico per l’organizzazione corretta dei file di codice è necessario per assicurare che il progetto rimanga scalabile durante la distribuzione e utilizzabile da te e dal tuo team.
In questo tutorial, imparerai come strutturare i progetti Terraform secondo il loro scopo generale e complessità. Poi, creerai un progetto con una semplice struttura utilizzando le caratteristiche più comuni di Terraform: variabili, locali, fonti di dati e provider. Alla fine, il tuo progetto deployerà un server Ubuntu 20.04 (Droplet) su DigitalOcean, installerà un server web Apache e indirizzerà il tuo dominio al server web.
Prerequisiti
-
Un token di accesso personale a DigitalOcean, che puoi creare attraverso il pannello di controllo di DigitalOcean. Puoi trovare le istruzioni negli documenti del prodotto DigitalOcean, in Come creare un token di accesso personale.
-
Un chiave SSH senza password aggiunta al tuo account DigitalOcean, che puoi creare seguendo le istruzioni del Guida sul Come Usare le Chiavi SSH con i Droplet di DigitalOcean.
-
Terraform installato su macchina locale. Per le istruzioni per il tuo sistema operativo, vedi Step 1 della Guida sul Come Utilizzare Terraform con DigitalOcean.
-
Python 3 installato sul tuo computer locale. Puoi completare Step 1 di Come installare e configurare un ambiente di programmazione locale per Python 3 per il tuo sistema operativo.
-
Un nome di dominio registrato completamente aggiunto alla tua account DigitalOcean. Per istruzioni su come farlo, visita le documentazioni ufficiali.
Nota: Questo tutorial è stato testato specificamente con Terraform 1.0.2
.
Comprendere la struttura di un progetto Terraform
Nella sezione attuale, ti spiegherò cosa considera Terraform come progetto, come organizzare il codice dell’infrastruttura e quando scegliere quale approccio. Ti spiego anche come funziona Terraform con i lavori spaziali, cosa fanno e come Terraform conserva lo stato.
Un risorsa è un’entità di un servizio nell’ambiente cloud (come un Droplet DigitalOcean) dichiarata nel codice di Terraform che viene creata secondo le proprietà specificate e deducite. Piu risorse costituiscono l’infrastruttura con le loro interazioni reciproche.
Terraform usa una lingua di programmazione specializzata per definire l’infrastruttura chiamata Linguaggio di configurazione Hashicorp (HCL). Il codice HCL viene generalmente salvato in file con estensione tf
. Un progetto Terraform è qualsiasi direttorio che contiene file tf
e che ha avuto l’initiale utilizzando il comando init
, che imposta le cache di Terraform e il contesto locale di stato.
Il statello di Terraform è il meccanismo che gli consente di tenere traccia delle risorse che sono effettivamente deployate in cloud. Lo statello è memorizzato in backend (localmente su disco o remoto su un servizio di archiviazione cloud o software specializzato per la gestione dello statello). Puoi leggere più dettagli sulle diverse backend nella documentazione di Terraform.
Il progetto spazi di lavoro consente di avere più stati nello stesso back-end, legati alla stessa configurazione. Questo permette di deploy più istanze distinte dello stesso infrastruttura. Ogni progetto inizia con un spazio di lavoro chiamato default
. Se non crea o si passa ad altri, questo sarà usato.
Moduli in Terraform (simili a librerie in altri linguaggi di programmazione) sono contenitori di codice parametrizati che accogliano diverse declarazioni risorse. Permettono di abstrazionare una parte comune dell’infrastruttura e riusarla più tardi con input diversi.
Un progetto Terraform può anche includere file esterni al codice per uso con dati dinamici di input, che possono interpretare l’output JSON di un comando CLI e offrire il suo utilizzo per le declarazioni risorse. Nell’ambito di questo tutorial, faremo questo con un script Python.
Ora che sappiate cosa consiste un progetto Terraform, rivediamo due approcci generali allo strutturare del progetto.
Struzione semplice
Una semplice struttura è adatta a piccoli progetti e a progetti di test, con pochi risorse di diversi tipi e variabili. Ha pochi file di configurazione, generalmente uno per tipo di risorsa (o più file ausiliari insieme al principale), e nessun modulo personalizzato, perché la maggior parte delle risorse è unica e non ci sono abbastanza per essere generalizzate e riutilizzate. Seguendo questo approcio, la maggior parte del codice viene memorizzata nella stessa directory, vicino l’una all’altra. questi progetti spesso hanno pochi variabili (come una chiave API per accedere al cloud) e potrebbero utilizzare input dati dinamici e altre funzionalità di Terraform e HCL, sebbene non in modo prominente.
Come esempio della struttura file di questo approcio, questo è come il progetto che costruirai in questo tutorial apparirà all’ultimo:
.
└── tf/
├── versions.tf
├── variables.tf
├── provider.tf
├── droplets.tf
├── dns.tf
├── data-sources.tf
└── external/
└── name-generator.py
Poiché questo progetto deployerà un server web Apache Droplet e configurerà i record DNS, le definizioni delle variabili del progetto, il provider Terraform DigitalOcean, il Droplet e i record DNS saranno memorizzati nei rispettivi file. Le versioni minimamente richieste di Terraform e del provider DigitalOcean verranno specificate in versions.tf
, mentre il script Python che generherà un nome per il Droplet (e sarà utilizzato come sorgente dati dinamica in data-sources.tf
) sarà memorizzato nella cartella external
, per separarlo dal codice HCL.
Struttura Complessa
Contrariamente alla semplice struttura, questo approcio è adatto a progetti di grandi dimensioni, con sottodirectory strutturate chiaramente e contenenti molti moduli di varia complessità oltre al codice solito. questi moduli possono dipendere l’uno dall’altro. In combinazione con i sistemi di controllo della versione, questi progetti possono fare un ampio uso di spazi di lavoro. Questo approcio è adatto a progetti più grandi che gestiscono molte app, reutilizzando il codice il più possibile.
Le istanze di infrastruttura di sviluppo, di staging, della qualità dell’assicurazione e della produzione possono anche essere ospitate nella stessa directory di progetto, in directory diverse, affidandosi a moduli comuni, eliminando così il codice duplicato e rendendo il progetto la fonte centrale della verità. Ecco la struttura del file di un esempio di progetto con una struttura più complessa, contenente molte app di distribuzione, moduli Terraform e ambienti cloud di destinazione:
.
└── tf/
├── modules/
│ ├── network/
│ │ ├── main.tf
│ │ ├── dns.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ └── spaces/
│ ├── main.tf
│ ├── outputs.tf
│ └── variables.tf
└── applications/
├── backend-app/
│ ├── env/
│ │ ├── dev.tfvars
│ │ ├── staging.tfvars
│ │ ├── qa.tfvars
│ │ └── production.tfvars
│ └── main.tf
└── frontend-app/
├── env/
│ ├── dev.tfvars
│ ├── staging.tfvars
│ ├── qa.tfvars
│ └── production.tfvars
└── main.tf
Questo approcio viene approfondito nella serie Come gestire l’infrastruttura con Terraform.
Ora sai cosa è un progetto Terraform, come strutturarlo meglio in base alla percepita complessità e qual è il ruolo degli spazi di lavoro di Terraform. Nei prossimi passi, creerai un progetto con una struttura semplice che fornirà una Droplet con un server web Apache installato e i record DNS impostati per il tuo dominio. Inizierai il tuo progetto con il provider DigitalOcean e le variabili, quindi procederai a definire la Droplet, una risorsa dinamica per fornire il suo nome e un record DNS per la distribuzione.
Prima di tutto – Impostazione del tuo progetto iniziale
Nella sezione successiva, aggiungerai il provider DigitalOcean di Terraform al tuo progetto, definirai le variabili del progetto e dichiarare un’istanza del provider DigitalOcean, così che Terraform sarà in grado di connettersi al tuo account.
Abbiamo cominciato creando una directory per il tuo progetto Terraform con il comando seguente:
Trovi l’indirizzo della cartella:
Per adottare un approccio organizzativo semplice, ti serviranno i file separati per la definizione del provider, delle variabili, dell’unità di calcolo e dei record DNS. Prima di tutto, devi aggiungere il provider DigitalOcean al tuo progetto come provider richiesto.
Crea un file chiamato versions.tf
e lo apriti per modificarlo eseguendo:
Aggiungi le seguenti linee:
Nella terraform
blocco, elencate i provider richiesti (DigitalOcean, versione 2.x
). Quando hai finito, salva e chiudi il file.
Poi, definisci le variabili che il tuo progetto esporrà nel file variables.tf
seguendo l’approccio di archiviazione differenti tipologie di risorse in file di codice separati:
Aggiungi le seguenti variabili:
Salva e chiudi il file.
Il
Procediamo ad definire l’istanza del provider DigitalOcean per questo progetto. Vi salverà in un file denominato
Aggiungi il provider:
Salva e uscita quando hai finito. Hai definito il provider digitalocean
, che corrisponde al provider richiesto precedentemente in
Nel passo successivo, hai creato una directory per il tuo progetto, hai richiesto che il provider DigitalOcean sia disponibile, dichiarato le variabili del progetto, e impostato la connessione all’istanza del provider DigitalOcean utilizzando un token di autenticazione che verra fornito più tardi. Ora scriverai un script Python che generera dati dinamici per le definizioni del tuo progetto.
Passo 2 — Creare un Script Python per i Dati Dinamici
Prima di procedere con la definizione del Droplet, creerai un script Python che generi il nome del Droplet dinamicamente e dichiara una risorsa dati per analizzarlo. Il nome sarà generato concatenando una stringa costante (
Avrai creato il file chiamato
La directory
Crea
Aggiungi il seguente codice:
Questo script Python importa i moduli
Una volta fatto, salva e chiudi il file.
Nota: Progetti strutturati grandi e complessi richiedono un maggior numero di considerazioni riguardo alla creazione e all’uso delle fonti esterni di dati, soprattutto in termini di portabilità e gestione degli errori. Terraform attende che il programma eseguito scriva un messaggio di errore leggibile da essere scritto su stderr
e uscire in modo gradevole con uno stato non zero, cosa che non viene mostrata in questo passaggio a causa della semplicità dell’attività. Inoltre, attende che il programma non abbia effetti collaterali, cosicché può essere eseguito più volte di necessità.
Per ulteriore informazione su ciò che Terraform attende, visita le doc officiali riguardanti le fonti di dati.
Ora che il script è pronto, puoi definire la fonte dati, che estrerà i dati dal script. Salverai la fonte dati in un file chiamato data-sources.tf
nella root del tuo progetto, secondo l’approcio di strutturazione semplice.
Crealo per la modifica eseguendo:
Aggiungi la seguente definizione:
Salva e chiudi il file.
Questa fonte dati si chiama droplet_name
e esegue il script name-generator.py
utilizzando Python 3, che si trova nella directory external
che hai appena creato. automaticamente analizza il suo output e fornisce i dati deserializzati sotto il suo attributo result
per l’uso nelle definizioni di altri risorse.
Dichiarata ora la fonte dati, puoi definire il Droplet su cui Apache avvierà.
Passo 3 — Definizione della goccia
Nel passo attuale, scriverai la definizione del risorse Goccia e la salverai in un file di codice dedicato alle Gocce, secondo l’approccio semplificato di strutturazione. Il nome della tua Goccia sarà diverso ogni volta che viene deployata, derivando dall’origine dati dinamica che hai appena creato.
Crea e apri il file droplets.tf
per la modifica:
Aggiungi la seguente definizione risorsa Goccia:
Prima di tutto, dichiari una risorsa chiave SSH DigitalOcean chiamata ssh_key
, che recupera una chiave dal tuo account. Fai sì che il codice accanto al punto rosso corrisponda al nome della tua chiave SSH. Assicura te che sia diverso da quello che hai creato.
Poiché, dichiari una risorsa Droplet chiamata web
. Il suo nome effettivo nel cloud è diverso, poiché viene richiesto dalla droplet_name
risorsa esterna. Per avviare la Goccia con una chiave SSH ogni volta che viene deployata, viene passato l’ID della ssh_key
, così che DigitalOcean sappia applicare quale chiave.
Per ora questo è tutto quanto ti serve riguardo droplet.tf
, quindi salvati e chiuditi il file quando hai finito.
Ora scriverai la configurazione per il record DNS che puntarà il dominio alla Goccia appena dichiarata.
Step 4 — Definizione dei Record DNS
L’ultimo passo del processo è configurare il record DNS che indica la Droplet dalla tua dominio.
Salverai la configurazione DNS in un file chiamato dns.tf
, poiché rappresenta un tipo di risorsa separato da quelli creati negli step precedenti. Crea e apri il file per la modifica:
Aggiungi le seguenti righe:
Questo codice dichiara un record DNS di DigitalOcean alla tua dominio (passato utilizzando la variabile), del tipo A
. Il record ha un nome di @
, che è un segnaposto di routing verso il dominio stesso e l’indirizzo IP della Droplet come suo value
. Puoi sostituire il valore name
con qualcos’altro, il che creerà un sotto dominio.
Una volta fatto, salva e chiudi il file.
Ora che hai configurato la Droplet, la fonte dati del nome generatore e un record DNS, passerai al deploy del progetto nel cloud.
Step 5 — Pianificazione e Applicazione della Configurazione
In questa sezione, inizializzerai il tuo progetto Terraform, lo deployeremo in cloud e verificheremo che tutto sia stato fornito correttamente.
Ora che l’infrastruttura del progetto è definita completamente, il solo passo rimasto prima del deploy è quello di inizializzare il progetto Terraform. Fai così eseguendo il seguente comando:
Riceverai il seguente output:
OutputInitializing the backend...
Initializing provider plugins...
- Finding digitalocean/digitalocean versions matching "~> 2.0"...
- Finding latest version of hashicorp/external...
- Installing digitalocean/digitalocean v2.10.1...
- Installed digitalocean/digitalocean v2.10.1 (signed by a HashiCorp partner, key ID F82037E524B9C0E8)
- Installing hashicorp/external v2.1.0...
- Installed hashicorp/external v2.1.0 (signed by HashiCorp)
Partner and community providers are signed by their developers.
If you'd like to know more about provider signing, you can read about it here:
https://www.terraform.io/docs/cli/plugins/signing.html
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.
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.
Ora sarai in grado di deployare il tuo Droplet con un nome generato dinamicamente e un dominio accompagnatore nel tuo account DigitalOcean.
Inizia definendo il nome del dominio, l’impronta digitale dell’SSH e il tuo token di accesso personale come variabili di ambiente, così non dovrai copiare i valori ogni volta che esegui Terraform. Esegui i seguenti comandi, sostituendo i valori evidenziati:
Puoi trovare il tuo token API nel tuo Pannello di controllo DigitalOcean.
Esegui il comando plan
con i valori delle variabili passate per vedere quali passi Terraform assume per deployare il tuo progetto:
L’output sarà simile al seguente:
OutputTerraform used the selected providers to generate the following execution plan. Resource
actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# digitalocean_droplet.web verrà creato
+ resource "digitalocean_droplet" "web" {
+ backups = false
+ created_at = (known after apply)
+ disk = (known after apply)
+ id = (known after apply)
+ image = "ubuntu-20-04-x64"
+ ipv4_address = (known after apply)
+ ipv4_address_private = (known after apply)
+ ipv6 = false
+ ipv6_address = (known after apply)
+ locked = (known after apply)
+ memory = (known after apply)
+ monitoring = false
+ name = "web-1625908814"
+ price_hourly = (known after apply)
+ price_monthly = (known after apply)
+ private_networking = (known after apply)
+ region = "fra1"
+ resize_disk = true
+ size = "s-1vcpu-1gb"
+ ssh_keys = [
+ "...",
]
+ status = (known after apply)
+ urn = (known after apply)
+ vcpus = (known after apply)
+ volume_ids = (known after apply)
+ vpc_uuid = (known after apply)
}
# digitalocean_record.www verrà creato
+ resource "digitalocean_record" "www" {
+ domain = "your_domain'"
+ fqdn = (known after apply)
+ id = (known after apply)
+ name = "@"
+ ttl = (known after apply)
+ type = "A"
+ value = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
...
Le righe che iniziano con un +
verde indicano che Terraform creerà ciascuna delle risorse seguenti dopo—esattamente ciò che dovrebbe accadere, così puoi applicare la configurazione:
L’output sarà lo stesso di prima, a parte che questa volta ti sarà chiesto di confermare:
OutputPlan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: `yes`
Inserisci yes
, e Terraform provisionerà il tuo Droplet e il record DNS:
Outputdigitalocean_droplet.web: Creating...
...
digitalocean_droplet.web: Creation complete after 33s [id=204432105]
digitalocean_record.www: Creating...
digitalocean_record.www: Creation complete after 1s [id=110657456]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Terraform ha registrato ora le risorse deployate nel suo stato. Per confermare che i record DNS e il Dropletto siano stati collegati correttamente, puoi estrarre l’indirizzo IP del Dropletto dallo stato locale e verificarlo se coincide con i record DNS pubblici per il tuo dominio. Eseguire il comando seguente per ottenere l’indirizzo IP del Dropletto:
Riceverai l’indirizzo IP del Dropletto:
Outputipv4_address = "your_Droplet_IP"
...
Puoi controllare gli record A pubblici eseguendo:
L’output mostrera l’indirizzo IP al quale è associata la A record:
OutputAddress: your_Droplet_IP
Sono lo stesso, come dovrebbero essere, significa che il Dropletto e i record DNS sono stati provvisti correttamente.
Per far avvenire le modifiche nell’ultimo passaggio devi distruggere le risorse deployate eseguendo:
Quando vi sarà richiesto, inserire yes
.
Nel passo attuale, hai creato la tua infrastettura e l’applicato al tuo account DigitalOcean. Ora modifierai questa infrastettura per installare automaticamente il server Web Apache sul Dropletto provvisoriamente usando i provisioner di Terraform.
Step 6 — Running Code Using Provisioners
Ora si imposterà l’installazione dell’Apache sui tuoi Dropletti utilizzando il provisioner remote-exec
per eseguire comandi personalizzati.
I provisionatori di Terraform possono essere usati per eseguire azioni specifiche su risorse remote creato (il provisionatore remote-exec
) o sulla macchina locale dove è stato eseguito il codice (usando il provisionatore local-exec
). Se un provisioner fallisce, il nodo viene marcato come tainted nello stato attuale, che significa che verrà eliminato e ricreato durante la prossima esecuzione.
Per connettersi ad un Droplet provvisorio, Terraform ha bisogno della chiave privata SSH del Droplet impostato. Il modo migliore per passare la posizione della chiave privata è utilizzando le variabili, quindi apri variables.tf
per l’editing:
Aggiungi la riga rossa accennata:
Ora hai aggiunto una nuova variabile, chiamata private_key
, al tuo progetto. Salva e chiudi il file.
Successivamente, aggiungere i dati di connessione e dichiarazioni del provisioner remoto al configurazione del Droplet. Apri droplets.tf
per l’editing eseguendo:
Estendere l’esistente blocco di codice con le righe rosse accennate:
Il blocco connection
specifica come Terraform dovrebbe connettersi al target Droplet. Il blocco provisioner
contiene l’array dei comandi, all’interno dell’parametro inline
, che eseguirà dopo la provisioning. Cioè, aggiornamento cache del pacchettario e installazione di Apache. Salva e esci quando hai finito.
Puoi creare anche un’ambiente temporaneo per la posizione della chiave:
Nota: Il tuo chiave privata e qualsiasi altro file che desideri caricare all’interno di Terraform devono essere inseriti nel progetto. Puoi consultare il tutorial ComeConfigurare l’Autenticazione basata su Chiavi SSH su un Servizio Linux per ulteriori informazioni sull’installazione della chiave SSH su Ubuntu 20.04 o altri distribuzioni.
Tenta di applicare la configurazione nuovamente:
Inserisci sì
quando viene richiesto. Riceverai un output simile al precedente, ma seguito da una lungaOutput dal provveditore remote-exec
.
Outputdigitalocean_droplet.web: Creating...
digitalocean_droplet.web: Still creating... [10s elapsed]
digitalocean_droplet.web: Still creating... [20s elapsed]
digitalocean_droplet.web: Still creating... [30s elapsed]
digitalocean_droplet.web: Provisioning with 'remote-exec'...
digitalocean_droplet.web (remote-exec): Connecting to remote host via SSH...
digitalocean_droplet.web (remote-exec): Host: ...
digitalocean_droplet.web (remote-exec): User: root
digitalocean_droplet.web (remote-exec): Password: false
digitalocean_droplet.web (remote-exec): Private key: true
digitalocean_droplet.web (remote-exec): Certificate: false
digitalocean_droplet.web (remote-exec): SSH Agent: false
digitalocean_droplet.web (remote-exec): Checking Host Key: false
digitalocean_droplet.web (remote-exec): Connected!
...
digitalocean_droplet.web: Creation complete after 1m5s [id=204442200]
digitalocean_record.www: Creating...
digitalocean_record.www: Creation complete after 1s [id=110666268]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Puoi ora navigare al tuo dominio tramite un browser Web. Troverai la pagina di benvenuto predefinita di Apache.
Questo significa che Apache è stato installato correttamente e che Terraform ha provvisto tutto correttamente.
Per distruggere le risorse deployate, eseguire il comando seguente e inserire sì
quando viene richiesto:
Hai ora completato un piccolo progetto con struttura semplice che deploya il servizio web su un Droplet e imposta i record DNS per il dominio desiderato.
Conclusione
Hai appena imparato due approcchi generali per strutturare i tuoi progetti Terraform in funzione della loro complessità. Seguendo l’approcchio semplice per la strutturazione e utilizzando il provisioner remote-exec
per eseguire comandi, hai poi deployato un Droplet che esegue Apache con记录 DNS per il tuo dominio.
Per riferimento, ecco la struttura del file del progetto creato in questo tutorial:
.
└── tf/
├── versions.tf
├── variables.tf
├── provider.tf
├── droplets.tf
├── dns.tf
├── data-sources.tf
└── external/
└── name-generator.py
Le risorse definite (il Droplet, il record DNS e la sorgente dati dinamica, il provider DigitalOcean e le variabili) sono memorizzate ciascuna in un file separato, secondo la semplice struttura di progetto descritta nella prima sezione di questo tutorial.
Per informazioni aggiuntive sui provisioner di Terraform e i loro parametri, visita la documentazione ufficiale.
Questo tutorial è parte della serie Come Gestire l’Infrastruttura con Terraform. La serie copre una varietà di argomenti di Terraform, dalla prima installazione di Terraform a gestire progetti complessi.
Source:
https://www.digitalocean.com/community/tutorials/how-to-structure-a-terraform-project