hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.63k stars 9.01k forks source link

Refactor AWS Go SDK Enumeration Validations To Use Values Functions (AWSV001 linter) #14601

Open bflad opened 3 years ago

bflad commented 3 years ago

Community Note

Description

Previously, the AWS Go SDK received service API models with enumeration types and only created individual Go constants for all elements, e.g.

const (
  // EnvironmentTypeWindowsContainer is a EnvironmentType enum value
  EnvironmentTypeWindowsContainer = "WINDOWS_CONTAINER"

  // EnvironmentTypeLinuxContainer is a EnvironmentType enum value
  EnvironmentTypeLinuxContainer = "LINUX_CONTAINER"

  // EnvironmentTypeLinuxGpuContainer is a EnvironmentType enum value
  EnvironmentTypeLinuxGpuContainer = "LINUX_GPU_CONTAINER"

  // EnvironmentTypeArmContainer is a EnvironmentType enum value
  EnvironmentTypeArmContainer = "ARM_CONTAINER"

  // EnvironmentTypeWindowsServer2019Container is a EnvironmentType enum value
  EnvironmentTypeWindowsServer2019Container = "WINDOWS_SERVER_2019_CONTAINER"
)

In the Terraform AWS Provider codebase, we frequently implemented schema validation by manually listing out all the constants, e.g.

ValidateFunc: validation.StringInSlice([]string{
  codebuild.EnvironmentTypeLinuxContainer,
  codebuild.EnvironmentTypeLinuxGpuContainer,
  codebuild.EnvironmentTypeWindowsContainer,
  codebuild.EnvironmentTypeArmContainer,
}, false),

These upfront validations are valuable to operators over finding configuration errors when making the API requests, potentially very far into creating their infrastructure or otherwise causing unexpected changes/downtime. Given the consequences, we have found over time that many operators have come to expect us to support this upfront validation at the expense of maintaining them with a slight delay as AWS service APIs support additional values.

As of AWS Go SDK v1.34.3 (releasing later today), there is now the ability to call an enumeration-named function ({ENUM}_Values()), which returns the slice of all elements, e.g.

ValidateFunc: validation.StringInSlice(codebuild.EnvironmentType_Values(), false),

This will lower the maintenance burden of this validation, but at the slight human cost of making value additions over time less visible (we generally update the AWS Go SDK regularly, but providing an exact Terraform AWS Provider version that contains a new value will now require additional effort) and less tested (since we generally prefer even simple validation additions such as these to be acceptance tested in some form). The benefits seem to outweigh the tradeoffs though in this case.

We can create a linter check for this with a design of:

Affected File(s)

Definition of Done

References

PatMyron commented 2 years ago

thousands have been mapped here: https://github.com/terraform-linters/tflint-ruleset-aws/tree/master/rules/models/mappings worth investigating upstreaming @wata727