Skip to content

ResourceNaming

Utility class for generating consistent and compliant AWS resource names and CloudFormation logical IDs.

This class provides standardized naming conventions for AWS resources that ensure consistency across the organization while handling AWS service-specific naming constraints. It generates both CloudFormation logical IDs and AWS resource names following organizational patterns.

The naming utilities handle: - Organizational naming standards (domain/project/environment patterns) - CloudFormation logical ID requirements (uppercase, underscores) - AWS service name length limitations with intelligent truncation - Hash-based uniqueness preservation when truncation is required - Special handling for different resource types (CodeBuild, CodePipeline, etc.)

All methods are static and can be called without instantiating the class.

Source code in mare_aws_common_lib/helpers/resource_naming.py
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
class ResourceNaming:
    """
    Utility class for generating consistent and compliant AWS resource names and CloudFormation logical IDs.

    This class provides standardized naming conventions for AWS resources that ensure consistency
    across the organization while handling AWS service-specific naming constraints. It generates
    both CloudFormation logical IDs and AWS resource names following organizational patterns.

    The naming utilities handle:
    - Organizational naming standards (domain/project/environment patterns)
    - CloudFormation logical ID requirements (uppercase, underscores)
    - AWS service name length limitations with intelligent truncation
    - Hash-based uniqueness preservation when truncation is required
    - Special handling for different resource types (CodeBuild, CodePipeline, etc.)

    All methods are static and can be called without instantiating the class.
    """

    @staticmethod
    def get_cfn_logical_id(application_helper: ApplicationHelper, resource_type: AWSResourceType, usage: Usage = None, 
                           resource_type_suffix: str = None, git_branch: str = None, target_env: str = None) -> str:
        """
        Generate a CloudFormation logical ID following organizational naming conventions.

        Creates a CloudFormation-compliant logical ID by combining project, resource type,
        usage, environment, and optional components. The resulting ID uses uppercase letters
        and underscores as required by CloudFormation best practices.

        Args:
            application_helper (ApplicationHelper): Helper containing project and environment context
            resource_type (AWSResourceType): Enum specifying the AWS resource type being named
            usage (Usage, optional): Usage context for the resource (e.g., MAIN, WORKER, CACHE).
                Defaults to None.
            resource_type_suffix (str, optional): Additional suffix to append to the resource type
                for uniqueness (e.g., "PRIMARY", "SECONDARY"). Defaults to None.
            git_branch (str, optional): Git branch name to include in the ID for
                branch-specific resources. Defaults to None.
            target_env (str, optional): target environment name to include in the ID for
                environment-specific resources. Defaults to None.

        Returns:
            str: CloudFormation logical ID in uppercase with underscores, following the pattern:
                {PROJECT}_{RESOURCE_TYPE}_{SUFFIX}_{USAGE}_{ENV}_{BRANCH}
                (components are omitted if None)

        Note:
            - Hyphens in input strings are converted to underscores for CloudFormation compatibility
            - The logical ID is always uppercase
            - None values are filtered out, so the final ID only contains provided components
        """
        env = application_helper.get_target_env() if target_env is None else target_env

        component_id_parts = [
            application_helper.get_project(),
            resource_type.name,
            resource_type_suffix.replace("-", "_") if resource_type_suffix else None,
            usage.name.replace("-", "_") if usage else None,
            env,
            git_branch.replace("-", "_") if git_branch else None
        ]

        # Filter out None values and join with underscores
        return "_".join(filter(None, component_id_parts)).upper()

    @staticmethod
    def get_name_for_resource(application_helper: ApplicationHelper, resource_type: AWSResourceType, usage: Usage = None, 
                              resource_name: str = None, git_branch: str = None, max_length: int = None) -> Tuple[str]:
        """
        Generate an AWS resource name following organizational standards with intelligent length handling.

        Creates AWS-compliant resource names by combining domain, project, and resource-specific
        components. Handles AWS service name length limitations through intelligent truncation
        and hash-based uniqueness preservation. Special logic applies for CodeBuild and CodePipeline
        resources which include resource type in their names.

        Args:
            application_helper (ApplicationHelper): Helper containing domain, project, and environment context
            resource_type (AWSResourceType): Enum specifying the AWS resource type being named
            usage (Usage, optional): Usage context for the resource. Only included in names for
                CodeBuild and CodePipeline resources. Defaults to None.
            resource_name (str, optional): Specific name component for the resource (e.g., "api", "worker").
                Defaults to None.
            git_branch (str, optional): Git branch name for branch-specific resources.
                Defaults to None.
            max_length (int, optional): Maximum allowed length for the resource name. If the generated
                name exceeds this limit, intelligent truncation with hash preservation is applied.
                Defaults to None (no length limit).

        Returns:
            Tuple[str, str]: A tuple containing:
                - Generated resource name (truncated if necessary)
                - Original full name (if truncation occurred) or None (if no truncation)

        Naming Pattern:
            - Base pattern: {domain}-{project}-{components}
            - For CodeBuild/CodePipeline: {domain}-{project}-{resource_type}-{usage}-{resource_name}-{branch}
            - For other resources: {domain}-{project}-{resource_name}-{branch}

        Truncation Algorithm:
            When max_length is exceeded:

            1. Generate 8-character MD5 hash of the full name
            2. Calculate available space for the variable components
            3. Truncate the resource name portion to fit
            4. Append hash for uniqueness: {base}-{truncated_name}-{hash}
            5. If base name itself is too long, truncate the domain-project portion

        Note:
            - Underscores in input strings are converted to hyphens for AWS compatibility
            - All names are lowercase
            - Hash preservation ensures truncated names remain unique
            - Original names are preserved as return values for potential tagging
        """
        name_start = f"{application_helper.get_domain()}-{application_helper.get_project()}".lower()

        name_parts = [
            resource_type.name if resource_type in (AWSResourceType.CODEBUILD, AWSResourceType.CODEPIPELINE) else None,
            usage.name.replace("_", "-") if usage and resource_type in (AWSResourceType.CODEBUILD, AWSResourceType.CODEPIPELINE) else None,
            resource_name.replace("_", "-") if resource_name else None,
            git_branch.replace("_", "-") if git_branch else None
        ]

        # Filter out None values and join with hyphen
        name_end = "-".join(filter(None, name_parts)).lower()

        full_name: str = None
        if name_end:
            full_name = f"{name_start}-{name_end}"
        else:
            full_name = name_start

        # AWS imposes lengths for the names several resources. Check the AWSResourceNameLength enum in the mare_aws_common_lib
        # We automatically handle this by hashing the name and cutting it off
        original_name: str = None
        if max_length is not None and len(full_name) > max_length:
            original_name = full_name
            hash_suffix = hashlib.md5(full_name.encode()).hexdigest()[:8]
            cutoff_length = max_length - len(name_start) - len(hash_suffix) - 2

            if cutoff_length > 0 and name_end:
                name_end = name_end[:cutoff_length].rstrip("-")
                full_name = f"{name_start}-{name_end}-{hash_suffix}"
            else:
                # If even the base name is too long, truncate the project name
                base_cutoff = max_length - len(hash_suffix) - 1
                full_name = f"{name_start[:base_cutoff].rstrip('-')}-{hash_suffix}"

        return (full_name, original_name)

Functions

get_cfn_logical_id(application_helper, resource_type, usage=None, resource_type_suffix=None, git_branch=None, target_env=None) staticmethod

Generate a CloudFormation logical ID following organizational naming conventions.

Creates a CloudFormation-compliant logical ID by combining project, resource type, usage, environment, and optional components. The resulting ID uses uppercase letters and underscores as required by CloudFormation best practices.

Parameters:

Name Type Description Default
application_helper ApplicationHelper

Helper containing project and environment context

required
resource_type AWSResourceType

Enum specifying the AWS resource type being named

required
usage Usage

Usage context for the resource (e.g., MAIN, WORKER, CACHE). Defaults to None.

None
resource_type_suffix str

Additional suffix to append to the resource type for uniqueness (e.g., "PRIMARY", "SECONDARY"). Defaults to None.

None
git_branch str

Git branch name to include in the ID for branch-specific resources. Defaults to None.

None
target_env str

target environment name to include in the ID for environment-specific resources. Defaults to None.

None

Returns:

Name Type Description
str str

CloudFormation logical ID in uppercase with underscores, following the pattern: {PROJECT}{RESOURCE_TYPE}{USAGE} (components are omitted if None)}_{BRANCH

Note
  • Hyphens in input strings are converted to underscores for CloudFormation compatibility
  • The logical ID is always uppercase
  • None values are filtered out, so the final ID only contains provided components
Source code in mare_aws_common_lib/helpers/resource_naming.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
@staticmethod
def get_cfn_logical_id(application_helper: ApplicationHelper, resource_type: AWSResourceType, usage: Usage = None, 
                       resource_type_suffix: str = None, git_branch: str = None, target_env: str = None) -> str:
    """
    Generate a CloudFormation logical ID following organizational naming conventions.

    Creates a CloudFormation-compliant logical ID by combining project, resource type,
    usage, environment, and optional components. The resulting ID uses uppercase letters
    and underscores as required by CloudFormation best practices.

    Args:
        application_helper (ApplicationHelper): Helper containing project and environment context
        resource_type (AWSResourceType): Enum specifying the AWS resource type being named
        usage (Usage, optional): Usage context for the resource (e.g., MAIN, WORKER, CACHE).
            Defaults to None.
        resource_type_suffix (str, optional): Additional suffix to append to the resource type
            for uniqueness (e.g., "PRIMARY", "SECONDARY"). Defaults to None.
        git_branch (str, optional): Git branch name to include in the ID for
            branch-specific resources. Defaults to None.
        target_env (str, optional): target environment name to include in the ID for
            environment-specific resources. Defaults to None.

    Returns:
        str: CloudFormation logical ID in uppercase with underscores, following the pattern:
            {PROJECT}_{RESOURCE_TYPE}_{SUFFIX}_{USAGE}_{ENV}_{BRANCH}
            (components are omitted if None)

    Note:
        - Hyphens in input strings are converted to underscores for CloudFormation compatibility
        - The logical ID is always uppercase
        - None values are filtered out, so the final ID only contains provided components
    """
    env = application_helper.get_target_env() if target_env is None else target_env

    component_id_parts = [
        application_helper.get_project(),
        resource_type.name,
        resource_type_suffix.replace("-", "_") if resource_type_suffix else None,
        usage.name.replace("-", "_") if usage else None,
        env,
        git_branch.replace("-", "_") if git_branch else None
    ]

    # Filter out None values and join with underscores
    return "_".join(filter(None, component_id_parts)).upper()

get_name_for_resource(application_helper, resource_type, usage=None, resource_name=None, git_branch=None, max_length=None) staticmethod

Generate an AWS resource name following organizational standards with intelligent length handling.

Creates AWS-compliant resource names by combining domain, project, and resource-specific components. Handles AWS service name length limitations through intelligent truncation and hash-based uniqueness preservation. Special logic applies for CodeBuild and CodePipeline resources which include resource type in their names.

Parameters:

Name Type Description Default
application_helper ApplicationHelper

Helper containing domain, project, and environment context

required
resource_type AWSResourceType

Enum specifying the AWS resource type being named

required
usage Usage

Usage context for the resource. Only included in names for CodeBuild and CodePipeline resources. Defaults to None.

None
resource_name str

Specific name component for the resource (e.g., "api", "worker"). Defaults to None.

None
git_branch str

Git branch name for branch-specific resources. Defaults to None.

None
max_length int

Maximum allowed length for the resource name. If the generated name exceeds this limit, intelligent truncation with hash preservation is applied. Defaults to None (no length limit).

None

Returns:

Type Description
Tuple[str]

Tuple[str, str]: A tuple containing: - Generated resource name (truncated if necessary) - Original full name (if truncation occurred) or None (if no truncation)

Naming Pattern
  • Base pattern: {domain}-{project}-{components}
  • For CodeBuild/CodePipeline: {domain}-{project}-{resource_type}-{usage}-{resource_name}-{branch}
  • For other resources: {domain}-{project}-{resource_name}-{branch}
Truncation Algorithm

When max_length is exceeded:

  1. Generate 8-character MD5 hash of the full name
  2. Calculate available space for the variable components
  3. Truncate the resource name portion to fit
  4. Append hash for uniqueness: {base}-{truncated_name}-{hash}
  5. If base name itself is too long, truncate the domain-project portion
Note
  • Underscores in input strings are converted to hyphens for AWS compatibility
  • All names are lowercase
  • Hash preservation ensures truncated names remain unique
  • Original names are preserved as return values for potential tagging
Source code in mare_aws_common_lib/helpers/resource_naming.py
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
@staticmethod
def get_name_for_resource(application_helper: ApplicationHelper, resource_type: AWSResourceType, usage: Usage = None, 
                          resource_name: str = None, git_branch: str = None, max_length: int = None) -> Tuple[str]:
    """
    Generate an AWS resource name following organizational standards with intelligent length handling.

    Creates AWS-compliant resource names by combining domain, project, and resource-specific
    components. Handles AWS service name length limitations through intelligent truncation
    and hash-based uniqueness preservation. Special logic applies for CodeBuild and CodePipeline
    resources which include resource type in their names.

    Args:
        application_helper (ApplicationHelper): Helper containing domain, project, and environment context
        resource_type (AWSResourceType): Enum specifying the AWS resource type being named
        usage (Usage, optional): Usage context for the resource. Only included in names for
            CodeBuild and CodePipeline resources. Defaults to None.
        resource_name (str, optional): Specific name component for the resource (e.g., "api", "worker").
            Defaults to None.
        git_branch (str, optional): Git branch name for branch-specific resources.
            Defaults to None.
        max_length (int, optional): Maximum allowed length for the resource name. If the generated
            name exceeds this limit, intelligent truncation with hash preservation is applied.
            Defaults to None (no length limit).

    Returns:
        Tuple[str, str]: A tuple containing:
            - Generated resource name (truncated if necessary)
            - Original full name (if truncation occurred) or None (if no truncation)

    Naming Pattern:
        - Base pattern: {domain}-{project}-{components}
        - For CodeBuild/CodePipeline: {domain}-{project}-{resource_type}-{usage}-{resource_name}-{branch}
        - For other resources: {domain}-{project}-{resource_name}-{branch}

    Truncation Algorithm:
        When max_length is exceeded:

        1. Generate 8-character MD5 hash of the full name
        2. Calculate available space for the variable components
        3. Truncate the resource name portion to fit
        4. Append hash for uniqueness: {base}-{truncated_name}-{hash}
        5. If base name itself is too long, truncate the domain-project portion

    Note:
        - Underscores in input strings are converted to hyphens for AWS compatibility
        - All names are lowercase
        - Hash preservation ensures truncated names remain unique
        - Original names are preserved as return values for potential tagging
    """
    name_start = f"{application_helper.get_domain()}-{application_helper.get_project()}".lower()

    name_parts = [
        resource_type.name if resource_type in (AWSResourceType.CODEBUILD, AWSResourceType.CODEPIPELINE) else None,
        usage.name.replace("_", "-") if usage and resource_type in (AWSResourceType.CODEBUILD, AWSResourceType.CODEPIPELINE) else None,
        resource_name.replace("_", "-") if resource_name else None,
        git_branch.replace("_", "-") if git_branch else None
    ]

    # Filter out None values and join with hyphen
    name_end = "-".join(filter(None, name_parts)).lower()

    full_name: str = None
    if name_end:
        full_name = f"{name_start}-{name_end}"
    else:
        full_name = name_start

    # AWS imposes lengths for the names several resources. Check the AWSResourceNameLength enum in the mare_aws_common_lib
    # We automatically handle this by hashing the name and cutting it off
    original_name: str = None
    if max_length is not None and len(full_name) > max_length:
        original_name = full_name
        hash_suffix = hashlib.md5(full_name.encode()).hexdigest()[:8]
        cutoff_length = max_length - len(name_start) - len(hash_suffix) - 2

        if cutoff_length > 0 and name_end:
            name_end = name_end[:cutoff_length].rstrip("-")
            full_name = f"{name_start}-{name_end}-{hash_suffix}"
        else:
            # If even the base name is too long, truncate the project name
            base_cutoff = max_length - len(hash_suffix) - 1
            full_name = f"{name_start[:base_cutoff].rstrip('-')}-{hash_suffix}"

    return (full_name, original_name)