terraform-module-library

Par wshobson · agents

Créez des modules Terraform réutilisables pour les infrastructures AWS, Azure, GCP et OCI en suivant les meilleures pratiques d'infrastructure-as-code. À utiliser lors de la création de modules d'infrastructure, de la standardisation du provisionnement cloud ou de l'implémentation de composants IaC réutilisables.

npx skills add https://github.com/wshobson/agents --skill terraform-module-library

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

  1. Utiliser le versioning sémantique pour les modules
  2. Documenter toutes les variables avec des descriptions
  3. Fournir des exemples dans le répertoire examples/
  4. Utiliser des blocs de validation pour la validation des entrées
  5. Exporter les attributs importants pour la composition de modules
  6. Épingler les versions de fournisseurs dans versions.tf
  7. Utiliser locals pour les valeurs calculées
  8. Implémenter des ressources conditionnelles avec count/for_each
  9. Tester les modules avec Terratest
  10. 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 architecturales
  • cost-optimization - Pour les conceptions rentables

Skills similaires