# AWS and Terraform Naming Best Practices

> Terraform and AWS resource naming should follow a company standard. Each company has different requirements and the standard should be adjusted.

- Source: https://www.itwonderlab.com/aws-and-terraform-naming-best-practices/
- Published: 2023-09-07
- Updated: 2026-10-05
- Author: Javier Ruiz Jiménez (https://www.javierruizjimenez.com/)
- Site: IT Wonder Lab (https://www.itwonderlab.com/)

---

## Terraform patterns

Terraform and AWS resource naming should follow a company standard. Each company has different requirements and the standard should be adjusted.

**Best Practice: Terraform Naming Patterns**: Name each Terraform variable following a pattern of elements that indicate all the information.

### Terraform variable naming

#### AWS Component / Service

Follow this pattern. Use lowercase and underscores as a separator.

-   **Provider**: a prefix specifying the name of the provider, in this case, `aws` (AWS in lowercase)
-   **Resource**: a short name identifying the resource, in this case:
    
    -   **sn**: for a [subnet](https://www.itwonderlab.com/aws-subnets/)
    -   **rt**: for routing table
    
    -   **igw**: for Internet gateway
    -   **ir**: for Internet route
    -   **rds\_sn**: RDS Subnet
    -   **rds-mariadb:** for RDS MariaDB type of resource
    -   **sg-rds-mariadb**: for RDS [Security Group](https://www.itwonderlab.com/aws-security-groups/) for MariaDB type of resource
    -   **sr-rds-mariadb**: for RDS Security Rule for MariaDB type of resource
    -   **ec2**: for an EC2 Instance
    -   **sg-ec2**: for an EC2 Security Group
    -   **sr-ec2**: for an EC2 Security Rule
-   **Environment**: for resources that are not to be shared between environments, a 3-letter acronym for the environment:
    -   **pro**: production
    -   **pre**: pre-production
    -   **dev**: development
-   **Visibility**: for resources that can be either public or private, a 3-letter acronym for the visibility:
    -   **pub**: for public resources
    -   **pri**: for private resources
-   **Unique ID/Name**: a unique number or name related to the resource.
    
    -   **For Networks**: In this case, the third octet in the IP address (172.21.NN.0) is used because it is different in all the subnets. The idea behind having a unique ID on the names is to be able to see errors from copy/paste easily by detecting anti-patterns.
    -   **For Databases**: Use the DB resource number: e.g. this will be the RDS MariaDB **01** for Public Zones and Pro-Environment. We might have a new RDS DB in the future, adding a number now will make it easier to grow the infrastructure later on.
    
    -   **For Database security group**: Use a number, e.g. this will be the RDS MariaDB security group 01 for Public Zones and Pro Environment. We might have new security groups in the future, adding a number now will make it easier to grow the infrastructure later on.
    -   **For Database security rules**: Description of the purpose of the rule: Using a description like `instances_to_db_port` explains the intended usage of the rule. In this case, it is a rule to allow access from the EC2 instances to the RDS Database port.
    -   **For EC2**: Use a name and number, e.g. this will be an EC2 instance for WordPress wp number 01 for Public Zones and Pro-Environment. We might have new EC2 instances for WP in the future, adding a number now will make it easier to grow the infrastructure later on.
    -   **EC2 security group**: use a number, e.g. this will be the EC2 security group 01 for Public Zones and Pro-Environment for wp. We might have new security groups in the future, adding a number now will make it easier to grow the infrastructure later on.

Examples:

-   aws\_sn\_za\_pro\_pub\_32 = { …}
-   aws\_rds\_mariadb\_pro\_pub\_01 = { …}
-   aws\_sg\_rds\_mariadb\_pro\_pub\_01 = { …}
-   aws\_sr\_rds\_mariadb\_pro\_pub\_01\_instances\_to\_db\_port = { …}
-   aws\_ec2\_pro\_pub\_wp\_01 = { …}

### Resource naming patterns

The name of each resource should follow a pattern. Use lowercase and a dash as a separator.

-   **Cloud**: a prefix specifying the unique name of this cloud across all available clouds and providers. In this case, the prefix will be **ditwl** which stands for **D**emo **IT W**onder **L**ab in lowercase.
-   **Resource**: a short name identifying the resource, in this case, sn stands for subnet
-   **Environment**: for resources that are not to be shared between environments, a 3-letter acronym for the environment:
    -   **pro**: production
    -   **pre**: pre-production
    -   **dev**: development
-   **Visibility**: for resources that can be either public or private, a 3-letter acronym for the visibility:
    -   **pub**: for public resources
    -   **pri**: for private resources
-   **Unique ID**: a unique number related to the resource.  
    In this case, the third octet in the IP address (172.21.NN.0) is used because it is different in all the subnets.  
    The idea behind having a unique ID on the names is to be able to see errors from copy/paste easily by detecting anti-patterns.  
      
    **It is important to have a unique prefix so that external elements (like a Monitoring System) can differentiate each element in multi cloud/client environments**.

Example:

```hcl
name = "ditwl-sn-za-pro-pub-32"
```

Using a consistent pattern allows the name to include all the needed information to understand its purpose, making the description almost unnecessary.

> [!NOTE]
> In [AWS with Terraform: The Essential Guide](https://www.itwonderlab.com/aws-terraform-tutorial-terraform-basics/) the labels of the Terraform resources use the same pattern as the names, with dashes (for example `aws_subnet.ditwl-sn-za-pro-pub-00`), which is valid in HCL. Use the same names for tags, see [AWS Tagging Best Practices](https://www.itwonderlab.com/aws-resource-tagging/).
