terraform-module — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited terraform-module (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Ask:
Create the standard module layout:
modules/
my-service/
main.tf # Primary resource definitions
variables.tf # Input variable declarations
outputs.tf # Output value declarations
versions.tf # Provider and terraform version constraints
locals.tf # Local values and computed expressions
data.tf # Data sources
README.md # Module documentationversions.tf (always include):
terraform {
required_version = ">= 1.5"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}Define variables with descriptions, types, and validation:
variable "environment" {
description = "Deployment environment (dev, staging, production)"
type = string
validation {
condition = contains(["dev", "staging", "production"], var.environment)
error_message = "Environment must be dev, staging, or production."
}
}
variable "service_name" {
description = "Name of the service, used for resource naming and tagging"
type = string
validation {
condition = can(regex("^[a-z][a-z0-9-]{2,28}$", var.service_name))
error_message = "Service name must be lowercase, start with a letter, 3-29 chars."
}
}
variable "vpc_config" {
description = "VPC configuration for the service"
type = object({
vpc_id = string
private_subnet_ids = list(string)
public_subnet_ids = list(string)
})
}
variable "tags" {
description = "Additional tags to apply to all resources"
type = map(string)
default = {}
}Rules:
description to every variablevalidation blocks for constrained inputsApply Well-Architected Framework principles:
Security:
Reliability:
Cost Optimization:
locals for environment-based sizinglocals {
name_prefix = "${var.service_name}-${var.environment}"
common_tags = merge(var.tags, {
Environment = var.environment
Service = var.service_name
ManagedBy = "terraform"
})
sizing = {
dev = { instance_class = "db.t3.micro", min_capacity = 1 }
staging = { instance_class = "db.t3.small", min_capacity = 1 }
production = { instance_class = "db.r6g.large", min_capacity = 2 }
}
}VPC Module:
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = merge(local.common_tags, { Name = "${local.name_prefix}-vpc" })
}
resource "aws_subnet" "private" {
count = length(var.availability_zones)
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 4, count.index)
availability_zone = var.availability_zones[count.index]
tags = merge(local.common_tags, {
Name = "${local.name_prefix}-private-${count.index + 1}"
Tier = "private"
})
}ECS Fargate Service:
resource "aws_ecs_service" "main" {
name = local.name_prefix
cluster = var.ecs_cluster_id
task_definition = aws_ecs_task_definition.main.arn
desired_count = local.sizing[var.environment].min_capacity
launch_type = "FARGATE"
network_configuration {
subnets = var.vpc_config.private_subnet_ids
security_groups = [aws_security_group.service.id]
assign_public_ip = false
}
load_balancer {
target_group_arn = aws_lb_target_group.main.arn
container_name = var.service_name
container_port = var.container_port
}
deployment_circuit_breaker {
enable = true
rollback = true
}
}S3 Bucket with Security:
resource "aws_s3_bucket" "main" {
bucket = "${local.name_prefix}-${var.bucket_purpose}"
tags = local.common_tags
}
resource "aws_s3_bucket_versioning" "main" {
bucket = aws_s3_bucket.main.id
versioning_configuration { status = "Enabled" }
}
resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
bucket = aws_s3_bucket.main.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
}
}
}
resource "aws_s3_bucket_public_access_block" "main" {
bucket = aws_s3_bucket.main.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}Expose values needed by other modules:
output "service_url" {
description = "URL of the deployed service"
value = "https://${aws_lb.main.dns_name}"
}
output "security_group_id" {
description = "Security group ID of the service, for use in ingress rules"
value = aws_security_group.service.id
}
output "iam_role_arn" {
description = "IAM role ARN of the ECS task, for granting additional permissions"
value = aws_iam_role.task.arn
}Show how to use the module:
module "api_service" {
source = "./modules/ecs-service"
service_name = "api"
environment = var.environment
vpc_config = module.vpc.config
container_image = "${var.ecr_registry}/api:${var.image_tag}"
container_port = 8080
tags = var.tags
}User says: "Create a Terraform module for a Lambda function with API Gateway"
Response:
~> constraintslocals for computed values and naming conventionsvalidation blocksfor_each over count when resources have meaningful identifiers~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.