Skip to content

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

Open
@bflad

Description

Community Note

  • Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
  • Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request
  • If you are interested in working on this issue or have submitted a pull request, please leave a comment

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:

  • Find github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation.StringInSlice() call expressions
  • Report if first parameter is a string slice composite literal (NOTE: there will be plenty of false positives which don't provide API enumerations need to be ignored in this codebase and reported to AWS)

Affected File(s)

  • aws/data_source_aws_acm_certificate.go
  • aws/data_source_aws_availability_zones.go
  • aws/data_source_aws_ec2_instance_type_offering.go
  • aws/data_source_aws_ec2_instance_type_offerings.go
  • aws/data_source_aws_glue_script.go
  • aws/data_source_aws_iam_policy_document.go
  • aws/data_source_aws_instances.go
  • aws/data_source_aws_iot_endpoint.go
  • aws/data_source_aws_ram_resource_share.go
  • aws/data_source_aws_route53_resolver_rule.go
  • aws/data_source_aws_route53_resolver_rules.go
  • aws/data_source_aws_ssm_document.go
  • aws/data_source_aws_wafv2_ip_set.go
  • aws/data_source_aws_wafv2_regex_pattern_set.go
  • aws/data_source_aws_wafv2_rule_group.go
  • aws/data_source_aws_wafv2_web_acl.go
  • aws/resource_aws_accessanalyzer_analyzer.go
  • aws/resource_aws_acm_certificate.go
  • aws/resource_aws_acmpca_certificate_authority.go
  • aws/resource_aws_ami.go
  • aws/resource_aws_api_gateway_authorizer.go
  • aws/resource_aws_api_gateway_domain_name.go
  • aws/resource_aws_api_gateway_integration.go
  • aws/resource_aws_api_gateway_method_settings.go
  • aws/resource_aws_api_gateway_rest_api.go
  • aws/resource_aws_api_gateway_stage.go
  • aws/resource_aws_api_gateway_usage_plan.go
  • aws/resource_aws_apigatewayv2_api.go
  • aws/resource_aws_apigatewayv2_authorizer.go
  • aws/resource_aws_apigatewayv2_domain_name.go
  • aws/resource_aws_apigatewayv2_integration.go
  • aws/resource_aws_apigatewayv2_integration_response.go
  • aws/resource_aws_apigatewayv2_route.go
  • aws/resource_aws_apigatewayv2_stage.go
  • aws/resource_aws_appautoscaling_policy.go
  • aws/resource_aws_appmesh_mesh.go
  • aws/resource_aws_appmesh_route.go
  • aws/resource_aws_appmesh_virtual_node.go
  • aws/resource_aws_appmesh_virtual_router.go
  • aws/resource_aws_appsync_datasource.go
  • aws/resource_aws_appsync_function.go
  • aws/resource_aws_appsync_graphql_api.go
  • aws/resource_aws_appsync_resolver.go
  • aws/resource_aws_athena_database.go
  • aws/resource_aws_athena_workgroup.go
  • aws/resource_aws_autoscaling_policy.go
  • aws/resource_aws_backup_selection.go
  • aws/resource_aws_batch_compute_environment.go
  • aws/resource_aws_batch_job_definition.go
  • aws/resource_aws_batch_job_queue.go
  • aws/resource_aws_budgets_budget.go
  • aws/resource_aws_cloudformation_stack_set.go
  • aws/resource_aws_cloudfront_distribution.go
  • aws/resource_aws_cloudhsm2_cluster.go
  • aws/resource_aws_cloudtrail.go
  • aws/resource_aws_cloudwatch_event_permission.go
  • aws/resource_aws_cloudwatch_metric_alarm.go
  • aws/resource_aws_codebuild_project.go
  • aws/resource_aws_codebuild_source_credential.go
  • aws/resource_aws_codebuild_webhook.go
  • aws/resource_aws_codedeploy_app.go
  • aws/resource_aws_codedeploy_deployment_config.go
  • aws/resource_aws_codedeploy_deployment_group.go
  • aws/resource_aws_codepipeline.go
  • aws/resource_aws_codepipeline_webhook.go
  • aws/resource_aws_codestarnotifications_notification_rule.go
  • aws/resource_aws_cognito_identity_pool_roles_attachment.go
  • aws/resource_aws_cognito_identity_provider.go
  • aws/resource_aws_cognito_user_pool.go
  • aws/resource_aws_cognito_user_pool_client.go
  • aws/resource_aws_config_config_rule.go
  • aws/resource_aws_config_organization_custom_rule.go
  • aws/resource_aws_config_organization_managed_rule.go
  • aws/resource_aws_cur_report_definition.go
  • aws/resource_aws_customer_gateway.go
  • aws/resource_aws_datasync_location_smb.go
  • aws/resource_aws_datasync_task.go
  • aws/resource_aws_db_instance.go
  • aws/resource_aws_default_network_acl.go
  • aws/resource_aws_directory_service_directory.go
  • aws/resource_aws_dlm_lifecycle_policy.go
  • aws/resource_aws_dms_endpoint.go
  • aws/resource_aws_dms_event_subscription.go
  • aws/resource_aws_dms_replication_task.go
  • aws/resource_aws_docdb_cluster.go
  • aws/resource_aws_docdb_cluster_parameter_group.go
  • aws/resource_aws_dx_bgp_peer.go
  • aws/resource_aws_dx_hosted_private_virtual_interface.go
  • aws/resource_aws_dx_hosted_public_virtual_interface.go
  • aws/resource_aws_dx_hosted_transit_virtual_interface.go
  • aws/resource_aws_dx_private_virtual_interface.go
  • aws/resource_aws_dx_public_virtual_interface.go
  • aws/resource_aws_dx_transit_virtual_interface.go
  • aws/resource_aws_dynamodb_table.go
  • aws/resource_aws_ec2_availability_zone_group.go
  • aws/resource_aws_ec2_capacity_reservation.go
  • aws/resource_aws_ec2_client_vpn_endpoint.go
  • aws/resource_aws_ec2_fleet.go
  • aws/resource_aws_ec2_traffic_mirror_filter.go
  • aws/resource_aws_ec2_traffic_mirror_filter_rule.go
  • aws/resource_aws_ec2_transit_gateway.go
  • aws/resource_aws_ec2_transit_gateway_vpc_attachment.go
  • aws/resource_aws_ecr_repository.go
  • aws/resource_aws_ecs_capacity_provider.go
  • aws/resource_aws_ecs_cluster.go
  • aws/resource_aws_ecs_service.go
  • aws/resource_aws_ecs_task_definition.go
  • aws/resource_aws_efs_file_system.go
  • aws/resource_aws_eks_cluster.go
  • aws/resource_aws_eks_node_group.go
  • aws/resource_aws_elasticache_cluster.go
  • aws/resource_aws_elasticsearch_domain.go
  • aws/resource_aws_elb.go
  • aws/resource_aws_emr_cluster.go
  • aws/resource_aws_flow_log.go
  • aws/resource_aws_fsx_lustre_file_system.go
  • aws/resource_aws_fsx_windows_file_system.go
  • aws/resource_aws_gamelift_alias.go
  • aws/resource_aws_gamelift_build.go
  • aws/resource_aws_gamelift_fleet.go
  • aws/resource_aws_globalaccelerator_accelerator.go
  • aws/resource_aws_globalaccelerator_endpoint_group.go
  • aws/resource_aws_globalaccelerator_listener.go
  • aws/resource_aws_glue_classifier.go
  • aws/resource_aws_glue_connection.go
  • aws/resource_aws_glue_crawler.go
  • aws/resource_aws_glue_job.go
  • aws/resource_aws_glue_security_configuration.go
  • aws/resource_aws_glue_trigger.go
  • aws/resource_aws_guardduty_ipset.go
  • aws/resource_aws_guardduty_threatintelset.go
  • aws/resource_aws_iam_access_key.go
  • aws/resource_aws_iam_user_ssh_key.go
  • aws/resource_aws_instance.go
  • aws/resource_aws_iot_topic_rule.go
  • aws/resource_aws_kinesis_analytics_application.go
  • aws/resource_aws_kinesis_firehose_delivery_stream.go
  • aws/resource_aws_kinesis_stream.go
  • aws/resource_aws_kms_grant.go
  • aws/resource_aws_kms_key.go
  • aws/resource_aws_lambda_event_source_mapping.go
  • aws/resource_aws_lambda_function.go
  • aws/resource_aws_launch_template.go
  • aws/resource_aws_lb.go
  • aws/resource_aws_lb_listener.go
  • aws/resource_aws_lb_listener_rule.go
  • aws/resource_aws_lb_target_group.go
  • aws/resource_aws_licensemanager_license_configuration.go
  • aws/resource_aws_macie_s3_bucket_association.go
  • aws/resource_aws_media_convert_queue.go
  • aws/resource_aws_mq_broker.go
  • aws/resource_aws_mq_configuration.go
  • aws/resource_aws_msk_cluster.go
  • aws/resource_aws_neptune_cluster.go
  • aws/resource_aws_neptune_cluster_parameter_group.go
  • aws/resource_aws_neptune_parameter_group.go
  • aws/resource_aws_network_acl.go
  • aws/resource_aws_opsworks_application.go
  • aws/resource_aws_opsworks_instance.go
  • aws/resource_aws_opsworks_permission.go
  • aws/resource_aws_organizations_account.go
  • aws/resource_aws_organizations_organization.go
  • aws/resource_aws_organizations_policy.go
  • aws/resource_aws_pinpoint_app.go
  • aws/resource_aws_placement_group.go
  • aws/resource_aws_quicksight_group.go
  • aws/resource_aws_quicksight_user.go
  • aws/resource_aws_rds_cluster.go
  • aws/resource_aws_rds_cluster_endpoint.go
  • aws/resource_aws_rds_global_cluster.go
  • aws/resource_aws_resourcegroups_group.go
  • aws/resource_aws_route53_health_check.go
  • aws/resource_aws_route53_record.go
  • aws/resource_aws_route53_resolver_endpoint.go
  • aws/resource_aws_route53_resolver_rule.go
  • aws/resource_aws_s3_bucket.go
  • aws/resource_aws_s3_bucket_analytics_configuration.go
  • aws/resource_aws_s3_bucket_inventory.go
  • aws/resource_aws_s3_bucket_object.go
  • aws/resource_aws_sagemaker_notebook_instance.go
  • aws/resource_aws_security_group_rule.go
  • aws/resource_aws_service_discovery_service.go
  • aws/resource_aws_ses_event_destination.go
  • aws/resource_aws_ses_identity_notification_topic.go
  • aws/resource_aws_ses_receipt_filter.go
  • aws/resource_aws_sns_sms_preferences.go
  • aws/resource_aws_sns_topic_subscription.go
  • aws/resource_aws_spot_fleet_request.go
  • aws/resource_aws_spot_instance_request.go
  • aws/resource_aws_ssm_association.go
  • aws/resource_aws_ssm_document.go
  • aws/resource_aws_ssm_maintenance_window_target.go
  • aws/resource_aws_ssm_maintenance_window_task.go
  • aws/resource_aws_ssm_parameter.go
  • aws/resource_aws_storagegateway_gateway.go
  • aws/resource_aws_storagegateway_nfs_file_share.go
  • aws/resource_aws_storagegateway_smb_file_share.go
  • aws/resource_aws_transfer_server.go
  • aws/resource_aws_vpc.go
  • aws/resource_aws_vpc_endpoint.go
  • aws/resource_aws_waf_byte_match_set.go
  • aws/resource_aws_waf_ipset.go
  • aws/resource_aws_waf_web_acl.go
  • aws/resource_aws_waf_xss_match_set.go
  • aws/resource_aws_wafregional_web_acl.go
  • aws/resource_aws_wafregional_xss_match_set.go
  • aws/resource_aws_wafv2_ip_set.go
  • aws/resource_aws_wafv2_regex_pattern_set.go
  • aws/resource_aws_wafv2_rule_group.go
  • aws/resource_aws_wafv2_web_acl.go
  • aws/resource_aws_workspaces_workspace.go
  • aws/validators.go
  • aws/wafv2_helper.go

Definition of Done

  • Create awsproviderlint check
  • All reports of new awsproviderlint check either handled or comment ignored for cases where AWS API models do not have enumeration types

References

Metadata

Assignees

No one assigned

    Labels

    enhancementRequests to existing resources that expand the functionality or scope.linterPertains to changes to or issues with the various linters.providerPertains to the provider itself, rather than any interaction with AWS.technical-debtAddresses areas of the codebase that need refactoring or redesign.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions