Questo documento fornisce consigli per esprimere le dipendenze tra le risorse nella configurazione di Terraform.
Prediligi le dipendenze implicite rispetto alle dipendenze esplicite
Le dipendenze delle risorse si verificano quando una risorsa dipende dall'esistenza di altre risorse. Terraform deve essere in grado di comprendere queste dipendenze per garantire che le risorse vengano create nell'ordine corretto. Ad esempio, se la risorsa A ha una dipendenza dalla risorsa B, che viene creata prima della risorsa A.
Le dipendenze di configurazione di Terraform possono essere stabilite
dichiarazioni di dipendenza implicite ed esplicite.
Le dipendenze implicite vengono dichiarate
riferimenti alle espressioni,
mentre le dipendenze esplicite sono specificate mediante
depends_on
. L'argomento depends_on
specifica che Terraform deve completare
tutte le azioni sugli oggetti da cui dipende una risorsa o un modulo, prima
e procedere con l'oggetto dipendente.
Sebbene entrambi gli approcci garantiscano un ordine corretto delle operazioni, le dipendenze implicite spesso portano a una maggiore efficienza nella pianificazione di aggiornamenti e sostituzione delle risorse. Questo perché Terraform può monitorare in modo intelligente i campi specifici coinvolti in una dipendenza implicita, evitare potenzialmente modifiche alla risorsa dipendente se quei campi specifici a rimanere inalterate all'interno della dipendenza.
Rispetto alle dipendenze implicite, quelle esplicite comunicano meno informazioni specifiche. Ciò significa che Terraform può formulare piani più conservativi per la creazione, l'aggiornamento e la sostituzione delle risorse solo in assenza di conoscenza dei particolari attributi che costituiscono la dipendenza. In pratica, questo influisce sulla sequenza in cui le risorse vengono create Terraform e come Terraform determina se le risorse richiedono aggiornamenti sostituzioni.
Ti consigliamo di utilizzare dipendenze esplicite con il metaargomento depends_on
solo come ultima risorsa quando una dipendenza tra due risorse è nascosta
non possono essere espresse tramite dipendenze implicite.
Nell'esempio seguente, i servizi di progetto richiesti devono essere abilitati prima creando un set di dati BigQuery. Questa dipendenza è dichiarata esplicitamente:
Sconsigliato:
module "project_services" {
source = "terraform-google-modules/project-factory/google//modules/project_services"
version = "~> 14.4"
project_id = var.project_id
activate_apis = [
"bigquery.googleapis.com",
"bigquerystorage.googleapis.com",
]
}
module "bigquery" {
source = "terraform-google-modules/bigquery/google"
version = "~> 5.4"
dataset_id = "demo_dataset"
dataset_name = "demo_dataset"
project_id = var.project_id
depends_on = [module.project_services] # <- explicit dependency
}
L'esempio seguente sostituisce la dipendenza esplicita con una dipendenza implicita
facendo riferimento all'argomento project_id
come output project_id
attributo della risorsa project_services
:
Consigliato:
module "bigquery" {
source = "terraform-google-modules/bigquery/google"
version = "~> 5.4"
dataset_id = "demo_dataset"
dataset_name = "demo_dataset"
project_id = module.project_services.project_id # <- implicit dependency
}
L'utilizzo delle dipendenze implicite consente dichiarazioni precise delle dipendenze, ad esempio la specifica delle informazioni esatte da raccogliere da un oggetto a monte. In questo modo si riduce anche la necessità di apportare modifiche in più posizioni, il che a sua volta riduce il rischio di errori.
Riferimento per gli attributi di output delle risorse dipendenti
Quando crei dipendenze implicite facendo riferimento ai valori upstream assicurati di fare riferimento solo agli attributi di output, in particolare valori non ancora noti. Questo assicura che Terraform attenda la creazione delle risorse upstream prima di eseguire il provisioning della risorsa attuale.
Nell'esempio seguente, la risorsa google_storage_bucket_object
fa riferimento
l'argomento name della risorsa google_storage_bucket
. Gli argomenti hanno valori noti durante la fase di pianificazione di Terraform. Ciò significa che quando Terraform crea la risorsa google_storage_bucket_object
, non attende la creazione della risorsa google_storage_bucket
perché il riferimento a un argomento noto (il nome del bucket) non crea una dipendenza implicita tra google_storage_bucket_object
e google_storage_bucket
. Questo sconfigge
lo scopo della dichiarazione di dipendenza implicita tra le due risorse.
Non consigliato:
# Cloud Storage bucket
resource "google_storage_bucket" "bucket" {
name = "demo-bucket"
location = "US"
}
resource "google_storage_bucket_object" "bucket_object" {
name = "demo-object"
source = "./test.txt"
bucket = google_storage_bucket.bucket.name # name is an input argument
}
La risorsa google_storage_bucket_object
deve invece fare riferimento all'attributo output id
della risorsa google_storage_bucket_object
. Dal id
è un attributo di output, il suo valore viene impostato solo dopo la creazione del
la risorsa è stata eseguita. Pertanto, Terraform attenderà il completamento della creazione della risorsa google_storage_bucket_object
prima di iniziare la creazione della risorsa google_storage_bucket_object
.
Consigliato:
resource "google_storage_bucket_object" "bucket_object" {
name = "demo-object"
source = "./test.txt"
bucket = google_storage_bucket.bucket.id # id is an output attribute
}
A volte non è presente un attributo di output evidente a cui fare riferimento. Ad esempio:
considera l'esempio seguente in cui module_a
prende il nome della risorsa generata
come input. All'interno di module_a
, il nome del file viene utilizzato per leggerlo. Se lo esegui così com'è, verrà generata un'eccezione no such file or directory
, causata dal tentativo di Terraform di leggere il file durante la fase di pianificazione, quando il file non è ancora stato creato. In questo caso,
dell'attributo output della risorsa local_file
rivela che
non ci sono campi evidenti che puoi usare al posto dell'input del nome file
.
Sconsigliato:
resource "local_file" "generated_file" {
filename = "./generated_file.text"
content = templatefile("./template.tftpl", {
project_id = var.project_id
})
}
module "module_a" {
source = "./modules/module-a"
root_config_file_path = local_file.generated_file.filename
}
Puoi risolvere il problema introducendo una dipendenza esplicita. Come best practice, assicurati di aggiungere un commento sul motivo per cui è necessaria la dipendenza esplicita:
Consigliato:
module "module_a" {
source = "./modules/module-a"
root_config_file_path = local_file.generated_file.filename
depends_on = [local_file.generated_file] # waiting for generated_file to be created
}
Passaggi successivi
- Scopri le best practice per la comunicazione tra configurazioni.
- Scopri le best practice per lavorare con le risorse Google Cloud.