Skip to content

saif-utilities / naming

This module provides organized path structure for cloud resource naming. It contains no functionality itself - use the specific resource modules directly.

Architecture

modules/naming/
├── base/                    # Provider-agnostic core naming logic
├── azure/                   # Azure-specific resource modules (path only)
│   ├── static/              # Static configuration data (functional)
│   └── servicebus/          # Service Bus resources (path only)
│       └── namespace/       # Service Bus Namespace naming (functional)
└── string_utilities/        # String casing utilities (functional)
    └── casing/              # String casing transformations (functional)

Direct Module Usage

Always call specific functional modules directly:

Azure Static Configuration

module "static_config" {
  source = "app.terraform.io/SAIFCorp/utilities/saif//modules/naming/static"
}

# Access static data
locals {
  organization_name = module.static_config.organization_name
  environments      = module.static_config.Environments
  business_domains  = module.static_config.BusinessDomains
  tenants          = module.static_config.tenants
  services         = module.static_config.Services
}

Azure ServiceBus Namespace

module "servicebus_namespace_naming" {
  source = "app.terraform.io/SAIFCorp/utilities/saif//modules/naming/azure/servicebus/namespace"

  environment_short_name = "prod"
  tenant               = "mycompany"
  suffix               = ["001"]
}

resource "azurerm_servicebus_namespace" "main" {
  name                = module.servicebus_namespace_naming.name
  location            = "East US"
  resource_group_name = "my-resource-group"
  sku                 = "Standard"
}

Variables

Static Module

The static module requires no input variables - it provides read-only configuration data.

Naming Modules

All naming modules share these core variables:

Variable Type Description Default
Environment string The environment for the resources (fallback value) ""
environment_short_name string The short name of the environment (takes precedence) ""
tenant string The tenant for the resources ""
project_id string The project id for the resources ""
prefix list(string) List of prefix components to add to resource names []
suffix list(string) List of suffix components to add to resource names []
unique_length number Max length of the uniqueness suffix 4
unique_include_numbers bool Include numbers in unique generation true

Note: The base module uses environment_short_name if it's not empty, otherwise falls back to Environment. This allows for flexibility in providing either short names (e.g., "prod") or full names (e.g., "production").

Outputs

Static Module Outputs

The static module provides organization-wide configuration data:

Output Description
organization_name Organization name (SAIF)
Owners Team ownership information with names, short names, and descriptions
tenantId tenant identifier
Subscriptions Available subscription configurations
SandboxSubscriptions Sandbox-specific subscription configurations
TeamSubscriptions Team-owned development subscription configurations
BusinessDomains Business domain definitions
Environments Environment configurations (dev, test, uat, prod, etc.)
tenants tenant configurations
OktaEnvironments Okta-specific environment settings
Services Service definitions including Azure service plans
ApiTypes API type definitions
ApplicationTypes Application type definitions
Azure_AppServicePlans Azure App Service Plan configurations
SubDomain_External External subdomain configurations
SubDomain_Internal Internal subdomain configurations

Resource Output Structure

Each naming module output includes:

Property Description
name Standard name (kebab-case format)
name_unique Name with unique suffix (kebab-case format)
name_casings Object with all casing formats
name_casings.Pascal Pascal case names ({ name, name_unique })
name_casings.Camel Camel case names ({ name, name_unique })
name_casings.Kebab Kebab case names ({ name, name_unique })
name_casings.Snake Snake case names ({ name, name_unique })
slug Resource type abbreviation (if used)
dashes Whether dashes are used in formatting
scope Uniqueness scope setting
regex Name validation pattern used

Adding New Resources

Adding Azure Resources

To add a new Azure resource, create the module structure:

# Create directory structure
mkdir -p modules/naming/azure/new_resource
cd modules/naming/azure/new_resource

# Create main.tf
cat > main.tf << 'EOF'
module "naming_base" {
  source = "../../base"

  resource_config = {
    slug   = ""                    # Resource abbreviation or "" for none
    dashes = true                  # Whether to allow dashes
    scope  = "global"              # global, resource_group, or subscription
    regex  = "^[a-zA-Z][a-zA-Z0-9-]{4,48}[a-zA-Z0-9]$"  # Validation pattern
  }

  Environment            = var.Environment
  environment_short_name   = var.environment_short_name
  tenant                 = var.tenant
  project_id              = var.project_id
  prefix                 = var.prefix
  suffix                 = var.suffix
  unique_length          = var.unique_length
  unique_include_numbers = var.unique_include_numbers
}
EOF

# Create variables.tf (copy from servicebus/namespace)
# Create output.tf (copy from servicebus/namespace and modify descriptions)

Supported Azure Resources

Current Azure resources:

Resource Module Path Regex Pattern Scope
Service Bus Namespace azure/servicebus/namespace ^[a-zA-Z][a-zA-Z0-9-]{4,48}[a-zA-Z0-9]$ global

Service Bus Namespace Details

  • Length: 6-50 characters
  • Pattern: Must start with a letter, end with letter/number, allow hyphens
  • Scope: Global uniqueness required across all Azure
  • Slug: None (empty string)

Development

Module Structure

Each resource module follows this structure:

resource_name/
├── variables.tf    # Standard variable definitions (same across all modules)
├── main.tf         # Calls base module with resource-specific config
└── output.tf       # Exposes resource naming outputs

Resource Configuration

Each resource must define its configuration in the resource_config object:

resource_config = {
  slug   = "abbreviation"       # Resource abbreviation (use "" for no slug)
  dashes = true                 # Whether dashes are allowed in names
  scope  = "global"            # Uniqueness scope: global, resource_group, subscription
  regex  = "^[pattern]$"       # Complete validation regex (replaces min/max length)
}

Regex Patterns

The regex pattern enforces all naming rules: - Length constraints (min/max are part of the pattern) - Character restrictions (alphanumeric, hyphens, etc.) - Format requirements (start/end character rules)

Example patterns:

# 6-50 chars, start with letter, alphanumeric + hyphens
regex = "^[a-zA-Z][a-zA-Z0-9-]{4,48}[a-zA-Z0-9]$"

# 3-24 chars, lowercase alphanumeric only
regex = "^[a-z0-9]{3,24}$"

# 1-63 chars, DNS-compliant
regex = "^[a-z0-9]([a-z0-9-]*[a-z0-9])?$"

Testing

Test each resource module with various inputs: - Different environments and projects with varying lengths - Long component combinations that test regex validation - Special characters that test pattern compliance - Global resources that need unique suffixes - Edge cases for regex pattern boundaries

Best Practices

  1. Modular Usage: Use resource-specific modules for targeted naming needs
  2. Unique Names: Always use name_unique for globally scoped resources
  3. Consistent Inputs: Use the same naming variables across all your modules
  4. Regex Validation: Design comprehensive regex patterns that enforce all requirements
  5. Documentation: Update documentation when adding new resources
  6. Testing: Validate regex patterns against cloud provider requirements

Contributing

  1. Follow the established module structure when adding resources
  2. Use comprehensive regex patterns for validation
  3. Include thorough testing with edge cases
  4. Update documentation with examples
  5. Maintain consistency with existing patterns

Dependencies

  • ../string_utilities/casing - String casing utilities module
  • Terraform >= 0.13

Providers

No providers.

Inputs

No inputs.

Outputs

No outputs.

Resources


View source on GitHub