Bibliothèque de modules Terraform
Modèles de modules Terraform prêts pour la production pour l'infrastructure AWS, Azure, GCP et OCI.
Objectif
Créer des modules Terraform réutilisables et bien testés pour les modèles courants d'infrastructure cloud sur plusieurs fournisseurs de services.
Quand l'utiliser
- Créer des composants d'infrastructure réutilisables
- Standardiser le provisionnement des ressources cloud
- Implémenter les bonnes pratiques d'infrastructure as code
- Créer des modules compatibles multi-cloud
- Établir les normes Terraform de l'organisation
Structure des modules
terraform-modules/
├── aws/
│ ├── vpc/
│ ├── eks/
│ ├── rds/
│ └── s3/
├── azure/
│ ├── vnet/
│ ├── aks/
│ └── storage/
├── gcp/
│ ├── vpc/
│ ├── gke/
│ └── cloud-sql/
└── oci/
├── vcn/
├── oke/
└── object-storage/
Modèle de module standard
module-name/
├── main.tf # Ressources principales
├── variables.tf # Variables d'entrée
├── outputs.tf # Valeurs de sortie
├── versions.tf # Versions de fournisseurs
├── README.md # Documentation
├── examples/ # Exemples d'utilisation
│ └── complete/
│ ├── main.tf
│ └── variables.tf
└── tests/ # Fichiers Terratest
└── module_test.go
Exemple de module AWS VPC
main.tf:
resource "aws_vpc" "main" {
cidr_block = var.cidr_block
enable_dns_hostnames = var.enable_dns_hostnames
enable_dns_support = var.enable_dns_support
tags = merge(
{
Name = var.name
},
var.tags
)
}
resource "aws_subnet" "private" {
count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
tags = merge(
{
Name = "${var.name}-private-${count.index + 1}"
Tier = "private"
},
var.tags
)
}
resource "aws_internet_gateway" "main" {
count = var.create_internet_gateway ? 1 : 0
vpc_id = aws_vpc.main.id
tags = merge(
{
Name = "${var.name}-igw"
},
var.tags
)
}
variables.tf:
variable "name" {
description = "Name of the VPC"
type = string
}
variable "cidr_block" {
description = "CIDR block for VPC"
type = string
validation {
condition = can(regex("^([0-9]{1,3}\\.){3}[0-9]{1,3}/[0-9]{1,2}$", var.cidr_block))
error_message = "CIDR block must be valid IPv4 CIDR notation."
}
}
variable "availability_zones" {
description = "List of availability zones"
type = list(string)
}
variable "private_subnet_cidrs" {
description = "CIDR blocks for private subnets"
type = list(string)
default = []
}
variable "enable_dns_hostnames" {
description = "Enable DNS hostnames in VPC"
type = bool
default = true
}
variable "tags" {
description = "Additional tags"
type = map(string)
default = {}
}
outputs.tf:
output "vpc_id" {
description = "ID of the VPC"
value = aws_vpc.main.id
}
output "private_subnet_ids" {
description = "IDs of private subnets"
value = aws_subnet.private[*].id
}
output "vpc_cidr_block" {
description = "CIDR block of VPC"
value = aws_vpc.main.cidr_block
}
Bonnes pratiques
- Utiliser le versioning sémantique pour les modules
- Documenter toutes les variables avec des descriptions
- Fournir des exemples dans le répertoire examples/
- Utiliser des blocs de validation pour la validation des entrées
- Exporter les attributs importants pour la composition de modules
- Épingler les versions de fournisseurs dans versions.tf
- Utiliser locals pour les valeurs calculées
- Implémenter des ressources conditionnelles avec count/for_each
- Tester les modules avec Terratest
- Tagger toutes les ressources de manière cohérente
Référence: Voir references/aws-modules.md et references/oci-modules.md
Composition de modules
module "vpc" {
source = "../../modules/aws/vpc"
name = "production"
cidr_block = "10.0.0.0/16"
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
private_subnet_cidrs = [
"10.0.1.0/24",
"10.0.2.0/24",
"10.0.3.0/24"
]
tags = {
Environment = "production"
ManagedBy = "terraform"
}
}
module "rds" {
source = "../../modules/aws/rds"
identifier = "production-db"
engine = "postgres"
engine_version = "15.3"
instance_class = "db.t3.large"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnet_ids
tags = {
Environment = "production"
}
}
Tests
// tests/vpc_test.go
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
)
func TestVPCModule(t *testing.T) {
terraformOptions := &terraform.Options{
TerraformDir: "../examples/complete",
}
defer terraform.Destroy(t, terraformOptions)
terraform.InitAndApply(t, terraformOptions)
vpcID := terraform.Output(t, terraformOptions, "vpc_id")
assert.NotEmpty(t, vpcID)
}
Skills connexes
multi-cloud-architecture- Pour les décisions architecturalescost-optimization- Pour les conceptions rentables