Questo documento fornisce consigli per esprimere le dipendenze tra le risorse nella configurazione di Terraform.
Favorire le dipendenze implicite rispetto a quelle 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, la risorsa B viene creata prima della risorsa A.
Le dipendenze della configurazione di Terraform possono essere stabilite tramite
dichiarazioni di dipendenza implicite ed esplicite.
Le dipendenze implicite vengono dichiarate tramite
riferimento a espressioni, mentre quelle esplicite vengono specificate utilizzando
l'argomento meta
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 di 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, evitando potenzialmente le modifiche alla risorsa dipendente se questi campi specifici rimangono invariati all'interno della dipendenza.
Rispetto alle dipendenze implicite, le dipendenze esplicite forniscono informazioni meno 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 da Terraform e su come Terraform determina se le risorse richiedono aggiornamenti o sostituzioni.
Consigliamo di utilizzare le dipendenze esplicite con l'argomento meta depends_on
solo come ultima risorsa quando una dipendenza tra due risorse è nascosta e non può essere espressa tramite dipendenze implicite.
Nell'esempio seguente, i servizi di progetto richiesti devono essere attivati prima di creare un set di dati BigQuery. Questa dipendenza viene dichiarata esplicitamente:
Non consigliato:
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 attributo di output project_id
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. Inoltre, riduce la necessità di apportare modifiche in più punti, il che a sua volta riduce il rischio di errori.
Fai riferimento agli attributi di output delle risorse dipendenti
Quando crei dipendenze implicite facendo riferimento ai valori delle risorse a monte, assicurati di fare riferimento solo agli attributi di output, in particolare ai valori che non sono ancora noti. In questo modo, Terraform attenderà la creazione delle risorse a monte prima di eseguire il provisioning della risorsa corrente.
Nel seguente esempio, la risorsa google_storage_bucket_object
fa riferimento all'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
. Ciò sventa 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
. Poiché il campo id
è un attributo di output, il relativo valore viene impostato solo dopo l'esecuzione della creazione della sua
risorsa. 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 il seguente esempio in cui module_a
prende il nome del
file generato 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, un esame dell'attributo output della risorsa local_file
rivela che non esistono campi evidenti che puoi utilizzare al posto dell'argomento di input del nome file.
Non consigliato:
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 l'utilizzo delle Google Cloud risorse.