Refactor AWS Go SDK Enumeration Validations To Use Values Functions (AWSV001 linter) #14601
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