docs/naming.md
In the AWS Provider, a service identifier should consistently identify an AWS service from code to documentation to provider used by a practitioner. Prominent places you will see service identifiers:
internal/service/<serviceidentifier>)aws_<serviceidentifier>_thing)website/docs/r/<serviceidentifier>_thing)Typically, choosing the AWS Provider identifier for a service is simple. AWS consistently uses one name and we use that name as the identifier. However, some services are not simple. To provide consistency, and to help contributors and practitioners know what to expect, we provide this rule for defining a service identifier:
aws in CLI commands; e.g., for aws sts get-caller-identity, sts is the command, get-caller-identity is the subcommand)._).With 156+ services having some level of implementation, the following is a summary of how well this rule is currently followed.
For AWS provider service package names, only five packages violate this rule: appautoscaling should be applicationautoscaling, codedeploy should be deploy, elasticsearch should be es, cloudwatchlogs should be logs, and simpledb should be sdb.
For the service identifiers used in resource and data source configuration names (e.g., aws_acmpca_certificate_authority), 32 wholly or partially violate the rule.
appautoscaling should be applicationautoscaling, codedeploy should be deploy, elasticsearch should be es, cloudwatch_log should be logs, simpledb should be sdb, prometheus should be amp, api_gateway should be apigateway, cloudcontrolapi should be cloudcontrol, cognito_identity should be cognitoidentity, cognito should be cognitoidp, config should be configservice, dx should be directconnect, directory_service should be ds, elastic_beanstalk should be elasticbeanstalk, cloudwatch_event should be events, kinesis_firehose should be firehose, msk should be kafka, mskconnect should be kafkaconnect, kinesis_analytics should be kinesisanalytics, kinesis_video should be kinesisvideo, lex should be lexmodels, media_convert should be mediaconvert, media_package should be mediapackage, media_store should be mediastore, route53_resolver should be route53resolver, relevant s3 should be s3control, serverlessapplicationrepository should be serverlessrepo, and service_discovery should be servicediscovery.Package names are not seen or used by practitioners. However, they should still be carefully considered.
internal/service), use the AWS Provider service identifier as the package name._).helper. These names convey zero information. Everything in the AWS Provider is helping something or someone do something so the name helper doesn't narrow down the purpose of the package within the codebase.verify is a good name because it tells you what the package does and allows a broad set of validation, comparison, and checking functionality.When creating a new resource or data source, it is important to get names right. Once practitioners rely on names, we can only change them through breaking changes. If you are unsure about what to call a resource or data source, discuss it with the community and maintainers.
CreateExperiment, GetExperiment, UpdateExperiment, and DeleteExperiment. Thus, the resource (or data source) name is "Experiment."aws_imagebuilder_image_pipeline) by joining these three parts with underscores:
aws prefiximagebuilder)image_pipeline)Resource<ResourceName>(), with the resource name in Mixed Caps. Do not include the service name or identifier. For example, define ResourceImagePipeline() in a file called internal/service/imagebuilder/image_pipeline.go.DataSource<ResourceName>(), with the data source name in Mixed Caps. Do not include the service name or identifier. For example, define DataSourceImagePipeline() in a file called internal/service/imagebuilder/image_pipeline_data_source.go.File names should follow Go and Markdown conventions with these additional points.
website/docs/r directory. Data source markdown goes in the website/docs/d directory._)..html.markdown as the extension.A correct example is accessanalyzer_analyzer.html.markdown. An incorrect example is service_discovery_instance.html.markdown because the service identifier should not include an underscore.
internal/service/<service> directory._data_source after the data source name (e.g., application_data_source.go)._test.go (e.g., custom_domain_association_test.go)..go extension.consts.go (service-wide constants), find.go (finders), flex.go (FLatteners and EXpanders), generate.go (directives for code generation), id.go (ID creators and parsers), status.go (status functions), sweep.go (sweepers), tags_gen.go (generated tag code), validate.go (validators), and wait.go (waiters).!!! note Mixed Caps is different than camel case, Pascal case, or snake case!
Idiomatic Go uses Mixed Caps for multiword names in code. Mixed caps is similar to camel case except initialisms and abbreviations in mixed caps should be the correct, human-readable case, such as VPCEndpoint not VpcEndpoint. After all, names in code are for humans.
An acronym such as "VPC" should either be all capitalized ("VPC") or all lowercase ("vpc"), never "Vpc" or "vPC." Similarly, in mixedCaps, "DynamoDB" should either be "DynamoDB" or "dynamoDB", depending on whether an initial cap is needed or not, and never "dynamoDb" or "DynamoDb."
For more details on capitalizations we enforce with CI Semgrep tests, see the Caps List.
In general, follow Go best practices for good function naming. This rule is for functions defined outside of the test context (i.e., not in a file ending with _test.go). For test functions, see Test Support Functions or Acceptance Test Configurations below.
_test (.test) package.FindVPCEndpointByID() is used outside the internal/service/ec2 package but where it is used, the call is tfec2.FindVPCEndpointByID().)resource<ResourceName><CRUDFunction>. For example, resourceImageRecipeUpdate(), resourceBaiduChannelRead().dataSource<DataSourceName>Read. For example, dataSourceBrokerRead(), dataSourceEngineVersionRead().expandAppCampaignHook().In general, follow Go best practices for good variable and constant naming.
_test (.test) package.PropagationTimeout is widely used outside of IAM but each instance is through the package import alias, tfiam.PropagationTimeout. "IAM" is unnecessary in the constant name.)roleStatusNotFound or RoleStatusNotFound, if used outside the service's package.!!! note Give priority to constants from the AWS SDK for Go rather than defining new constants for the same values.
With about 6000 acceptance and unit tests, following these naming conventions is essential to organization and (human) context switching between services.
There are three types of tests in the AWS Provider: (regular) acceptance tests, serialized acceptance tests, and unit tests. All are functions that take a variable of type *testing.T. Acceptance tests and unit tests have exported (i.e., capitalized) names while serialized tests do not. Serialized tests are called by another exported acceptance test, often ending with _serial. The majority of tests in the AWS provider are acceptance tests.
Acceptance test names have a minimum of two (e.g., TestAccBackupPlan_tags) or a maximum of three (e.g., TestAccDynamoDBTable_Replica_multiple) parts, joined with underscores:
TestAcc), service name (e.g., Backup, DynamoDB), and resource name (e.g., Plan, Table), Mixed Caps without underscores between. Do not include "AWS" or "Aws" in the name.Replica), uppercase, Mixed Caps. Consider a metaphor where tests are chapters in a book. If it is helpful, tests can be grouped together like chapters in a book that are sometimes grouped into parts or sections of the book.basic, tags, or multiple), lowercase, mixedCaps). The identifier should make the test's purpose clear but be concise. For example, the identifier conflictsWithCloudFrontDefaultCertificate (41 characters) conveys no more information than conflictDefaultCertificate (26 characters), since "CloudFront" is implied and "with" is always implicit. Avoid words that convey no meaning or whose meaning is implied. For example, "with" (e.g., _withTags) is not needed because we imply the name is telling us what the test is with. withTags can be simplified to tags.The names of serialized acceptance tests follow the regular acceptance test name rule except for serialized acceptance test names:
testAcc instead of TestAcctestAccApp_basic not testAccAmplifyApp_basic).Unit test names follow the same rule as acceptance test names except for unit test names:
Test, not TestAccExpandListener() should be called TestExpandListener())This rule is for functions defined in the test context (i.e., in a file ending with _test.go) that do not return a string with Terraform configuration. For non-test functions, see Functions above. Or, see Acceptance Test Configurations below.
testAccCheckAMPWorkspaceExists() should be named testAccCheckWorkspaceExists() instead, dropping the service name.testAccCheck<Resource>DestroytestAccCheck<Resource>DisappearstestAccCheck<Resource>ExiststestAccCheck<Resource>NotRecreatedtestAccPreCheck (often, only one PreCheck is needed per service so no resource name is needed)testAccCheck<Resource>RecreatedThis rule is for functions defined in the test context (i.e., in a file ending with _test.go) that return a string with Terraform configuration. For test support functions, see Test Support Functions above. Or, for non-test functions, see Functions above.
!!! note This rule is not widely used currently. However, new functions and functions you change should follow it.
testAccConfig<Resource>_<TestGroup>_<configDescription>
_<TestGroup> is optional. Refer to the Acceptance Test Rule test group discussion.<configDescription> should be the same as the test identifier discussed in the Acceptance Test Rule.