Terraform
1. Blocchi di Controllo e Infrastruttura¶
Questi blocchi istruiscono il motore core di Terraform su come interfacciarsi con l'esterno, dove salvare i dati di stato e quali componenti reali o logici istanziare.
| Costrutto | Ambito | Funzione |
|---|---|---|
terraform {} |
Motore | Configurazione globale di Terraform, vincoli di versione della CLI e dichiarazione dei provider richiesti. |
backend |
Stato | Configurazione (interna a terraform {}) per l'archiviazione remota e sicura del file .tfstate con supporto allo state locking. |
provider {} |
API | Inizializzazione dei plug-in e traduzione del codice HCL in chiamate API specifiche (gestione credenziali e regioni). |
module {} |
Astrazione | Invocazione di blocchi di codice riutilizzabili archiviati localmente o in repository remoti per evitare duplicazioni. |
resource {} |
Infrastruttura | Dichiarazione e configurazione dei singoli oggetti reali o logici da creare ed elaborare nel Cloud provider. |
data {} |
Query | Sorgente dati in sola lettura per interrogare le API Cloud e recuperare attributi di risorse preesistenti. |
2. Blocchi di Flusso Dati (Variabili e Computazione)¶
Questi costrutti governano il passaggio e la manipolazione delle informazioni logiche all'interno del codice, rendendo l'infrastruttura dinamica e parametrizzabile.
| Costrutto | Ambito | Funzione |
|---|---|---|
variable |
Input | Argomenti di ingresso per parametrizzare il codice dall'esterno (es. inseriti via CLI o file .tfvars). |
locals |
Interno | Espressioni logiche, costanti e computazioni locali non esportabili, usate per manipolare dati internamente. |
output |
Output | Valori esposti al termine dell'esecuzione o passati ad altri moduli (es. stringhe di connessione, indirizzi IP). |
2. Comandi Principali della CLI di Terraform¶
Questi comandi consentono di gestire il ciclo di vita dell'infrastruttura, dall'inizializzazione della directory di lavoro fino alla distruzione delle risorse gestite.
| Costrutto | Ambito | Funzione |
|---|---|---|
terraform init |
Inizializzazione | Scarica i provider specificati, inizializza il backend per lo stato e configura la directory di lavoro. |
terraform validate |
Verifica | Esegue un'analisi sintattica e strutturale dei file di configurazione per verificarne la correttozza formale. |
terraform plan |
Pianificazione | Genera e mostra il piano di esecuzione, confrontando lo stato reale con la configurazione desiderata senza applicare modifiche. |
terraform apply |
Esecuzione | Applica le modifiche pianificate sul target provider per raggiungere lo stato desiderato e aggiorna il file .tfstate. |
terraform destroy |
Rimozione | Elimina tutte le risorse gestite dalla configurazione corrente, distruggendo l'infrastruttura associata. |
terraform state |
Gestione Stato | Consente l'ispezione e la manipolazione avanzata del file .tfstate (es. rimozione o spostamento di risorse senza modificarle fisicamente). |
terraform output |
Query | Estrae e visualizza i valori delle variabili di output definiti nella configurazione corrente. |
terraform fmt |
Formattazione | Riformatta automaticamente i file di configurazione HCL secondo gli standard estetici nativi di Terraform. |
| --- | ||
| ### 3. Alberatura e Struttura dei File del Progetto |
Di seguito viene illustrata l'organizzazione dei file all'interno del repository, basata sul principio di separazione degli ambienti e riutilizzo dei moduli.
Alberatura del Progetto: Multi-Ambiente con Modulo VPC¶
├── modules/
│ └── vpc/ # Il codice statico viene convertito in modulo
│ ├── main.tf # Contiene le risorse: vpc, subnet, igw, route tables, sg
│ ├── variables.tf # Definisce le variabili di input (cidr, ambiente, azs, ecc.)
│ └── outputs.tf # Esporta gli ID generati (vpc_id, subnet_ids)
│
└── environments/
│
└── prod/ # Ambiente di Produzione (Stato totalmente isolato)
├── main.tf # Inizializza il motore, il provider e invoca il modulo vpc
└── terraform.tfvars # File con i valori IP e tag specifici per la Produzione
└── outputs.tf # Esporta gli ID generati (vpc_id, subnet_ids)
Esempi¶
modules/vpc/main.tf¶
resource "aws_vpc" "vpc_core" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
lifecycle {
prevent_destroy = true
}
tags = {
Name = var.nome_progetto
Environment = var.ambiente
}
}
resource "aws_subnet" "subnet_pub_1a" {
vpc_id = aws_vpc.vpc_core.id
cidr_block = var.subnet_pub_1a_cidr
availability_zone = "us-east-1a"
lifecycle {
prevent_destroy = true
}
tags = {
Name = "${var.nome_progetto}-subnet-pub-1a"
Environment = var.ambiente
}
}
resource "aws_subnet" "subnet_priv_1a" {
vpc_id = aws_vpc.vpc_core.id
cidr_block = var.subnet_priv_1a_cidr
availability_zone = "us-east-1a"
lifecycle {
prevent_destroy = true
}
tags = {
Name = "${var.nome_progetto}-subnet-priv-1a"
Environment = var.ambiente
}
}
resource "aws_subnet" "subnet_priv_1b" {
vpc_id = aws_vpc.vpc_core.id
cidr_block = var.subnet_priv_1b_cidr
availability_zone = "us-east-1b"
lifecycle {
prevent_destroy = true
}
tags = {
Name = "${var.nome_progetto}-subnet-priv-1b"
Environment = var.ambiente
}
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.vpc_core.id
lifecycle {
prevent_destroy = true
}
tags = {
Name = "${var.nome_progetto}-igw"
Environment = var.ambiente
}
}
resource "aws_default_route_table" "default_rt" {
default_route_table_id = aws_vpc.vpc_core.default_route_table_id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
tags = {
Name = "${var.nome_progetto}-main-rt"
Environment = var.ambiente
}
}
resource "aws_route_table" "private_rt" {
vpc_id = aws_vpc.vpc_core.id
tags = {
Name = "${var.nome_progetto}-private-rt"
Environment = var.ambiente
}
}
resource "aws_route_table_association" "priv_1a_association" {
subnet_id = aws_subnet.subnet_priv_1a.id
route_table_id = aws_route_table.private_rt.id
}
resource "aws_route_table_association" "priv_1b_association" {
subnet_id = aws_subnet.subnet_priv_1b.id
route_table_id = aws_route_table.private_rt.id
}
resource "aws_default_security_group" "default_sg" {
vpc_id = aws_vpc.vpc_core.id
ingress {
protocol = "tcp"
from_port = 22
to_port = 22
cidr_blocks = [var.vpc_cidr]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "${var.nome_progetto}-default-sg"
Environment = var.ambiente
}
}
modules/vpc/variables.tf¶
variable "nome_progetto" {
type = string
description = "Prefisso utilizzato per il naming delle risorse"
}
variable "ambiente" {
type = string
description = "Identificativo dell'ambiente operativo (es. staging, prod)"
}
variable "vpc_cidr" {
type = string
description = "Blocco CIDR principale per la VPC"
}
variable "subnet_pub_1a_cidr" {
type = string
description = "Blocco CIDR per la subnet pubblica 1a"
}
variable "subnet_priv_1a_cidr" {
type = string
description = "Blocco CIDR per la subnet privata 1a"
}
variable "subnet_priv_1b_cidr" {
type = string
description = "Blocco CIDR per la subnet privata 1b"
}
modules/vpc/outputs.tf¶
output "vpc_id" {
value = aws_vpc.vpc_core.id
description = "ID della VPC creata"
}
output "public_subnet_id" {
value = aws_subnet.subnet_pub_1a.id
description = "ID della subnet pubblica 1a"
}
output "private_subnet_ids" {
value = [aws_subnet.subnet_priv_1a.id, aws_subnet.subnet_priv_1b.id]
description = "Lista degli ID delle subnet private"
}
environments/staging/main.tf¶
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "http" {
lock_method = "POST"
unlock_method = "DELETE"
}
}
provider "aws" {
region = "us-east-1"
}
variable "nome_progetto" {}
variable "ambiente" {}
variable "vpc_cidr" {}
variable "subnet_pub_1a_cidr" {}
variable "subnet_priv_1a_cidr" {}
variable "subnet_priv_1b_cidr" {}
module "vpc" {
source = "../../modules/vpc"
nome_progetto = var.nome_progetto
ambiente = var.ambiente
vpc_cidr = var.vpc_cidr
subnet_pub_1a_cidr = var.subnet_pub_1a_cidr
subnet_priv_1a_cidr = var.subnet_priv_1a_cidr
subnet_priv_1b_cidr = var.subnet_priv_1b_cidr
}
environments/staging/terraform.tfvars¶
nome_progetto = "test-staging"
ambiente = "staging"
vpc_cidr = "172.16.100.0/23"
subnet_pub_1a_cidr = "172.16.100.0/24"
subnet_priv_1a_cidr = "172.16.101.0/25"
subnet_priv_1b_cidr = "172.16.101.128/25"
environments/staging/output.tf¶
output "staging_vpc_id" {
value = module.vpc.vpc_id
description = "ID della VPC estratto dal modulo per l'ambiente di Staging"
}
output "staging_private_subnet_ids" {
value = module.vpc.private_subnet_ids
description = "Lista ID subnet private per lo Staging"
}