From e0fc1a55b9526b8639403f852c968d17c89ed774 Mon Sep 17 00:00:00 2001 From: Ricardo Rosales Date: Tue, 18 May 2021 22:49:11 -0500 Subject: [PATCH 1/6] Creating aws_ec2_managed_prefix_list_entry resource --- aws/internal/service/ec2/id.go | 18 + aws/internal/service/ec2/waiter/waiter.go | 2 + aws/provider.go | 1135 +++++++++-------- aws/resource_aws_ec2_managed_prefix_list.go | 1 + ...ource_aws_ec2_managed_prefix_list_entry.go | 278 ++++ ..._aws_ec2_managed_prefix_list_entry_test.go | 431 +++++++ .../r/ec2_managed_prefix_list.html.markdown | 6 + ...c2_managed_prefix_list_entry.html.markdown | 63 + 8 files changed, 1367 insertions(+), 567 deletions(-) create mode 100644 aws/resource_aws_ec2_managed_prefix_list_entry.go create mode 100644 aws/resource_aws_ec2_managed_prefix_list_entry_test.go create mode 100644 website/docs/r/ec2_managed_prefix_list_entry.html.markdown diff --git a/aws/internal/service/ec2/id.go b/aws/internal/service/ec2/id.go index cf5cb8a0cb38..30728ae105c3 100644 --- a/aws/internal/service/ec2/id.go +++ b/aws/internal/service/ec2/id.go @@ -71,6 +71,24 @@ func ClientVpnRouteParseID(id string) (string, string, string, error) { "target-subnet-id"+clientVpnRouteIDSeparator+"destination-cidr-block", id) } +const managedPrefixListEntryIDSeparator = "," + +func ManagedPrefixListEntryCreateID(prefixListID, cidrBlock string) string { + parts := []string{prefixListID, cidrBlock} + id := strings.Join(parts, managedPrefixListEntryIDSeparator) + return id +} + +func ManagedPrefixListEntryParseID(id string) (string, string, error) { + parts := strings.Split(id, managedPrefixListEntryIDSeparator) + if len(parts) == 2 && parts[0] != "" && parts[1] != "" { + return parts[0], parts[1], nil + } + + return "", "", + fmt.Errorf("unexpected format for ID (%q), expected prefix-list-id"+managedPrefixListEntryIDSeparator+"cidr-block", id) +} + // RouteCreateID returns a route resource ID. func RouteCreateID(routeTableID, destination string) string { return fmt.Sprintf("r-%s%d", routeTableID, hashcode.String(destination)) diff --git a/aws/internal/service/ec2/waiter/waiter.go b/aws/internal/service/ec2/waiter/waiter.go index 9852cf0115c2..e96442eda81e 100644 --- a/aws/internal/service/ec2/waiter/waiter.go +++ b/aws/internal/service/ec2/waiter/waiter.go @@ -257,6 +257,8 @@ func InstanceIamInstanceProfileUpdated(conn *ec2.EC2, instanceID string, expecte return nil, err } +const ManagedPrefixListEntryCreateTimeout = 5 * time.Minute + const ( NetworkAclPropagationTimeout = 2 * time.Minute NetworkAclEntryPropagationTimeout = 5 * time.Minute diff --git a/aws/provider.go b/aws/provider.go index 35054b23bc7f..db0dbc512eec 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -466,573 +466,574 @@ func Provider() *schema.Provider { }, ResourcesMap: map[string]*schema.Resource{ - "aws_accessanalyzer_analyzer": resourceAwsAccessAnalyzerAnalyzer(), - "aws_acm_certificate": resourceAwsAcmCertificate(), - "aws_acm_certificate_validation": resourceAwsAcmCertificateValidation(), - "aws_acmpca_certificate_authority": resourceAwsAcmpcaCertificateAuthority(), - "aws_acmpca_certificate_authority_certificate": resourceAwsAcmpcaCertificateAuthorityCertificate(), - "aws_acmpca_certificate": resourceAwsAcmpcaCertificate(), - "aws_ami": resourceAwsAmi(), - "aws_ami_copy": resourceAwsAmiCopy(), - "aws_ami_from_instance": resourceAwsAmiFromInstance(), - "aws_ami_launch_permission": resourceAwsAmiLaunchPermission(), - "aws_amplify_app": resourceAwsAmplifyApp(), - "aws_amplify_backend_environment": resourceAwsAmplifyBackendEnvironment(), - "aws_amplify_branch": resourceAwsAmplifyBranch(), - "aws_amplify_domain_association": resourceAwsAmplifyDomainAssociation(), - "aws_amplify_webhook": resourceAwsAmplifyWebhook(), - "aws_api_gateway_account": resourceAwsApiGatewayAccount(), - "aws_api_gateway_api_key": resourceAwsApiGatewayApiKey(), - "aws_api_gateway_authorizer": resourceAwsApiGatewayAuthorizer(), - "aws_api_gateway_base_path_mapping": resourceAwsApiGatewayBasePathMapping(), - "aws_api_gateway_client_certificate": resourceAwsApiGatewayClientCertificate(), - "aws_api_gateway_deployment": resourceAwsApiGatewayDeployment(), - "aws_api_gateway_documentation_part": resourceAwsApiGatewayDocumentationPart(), - "aws_api_gateway_documentation_version": resourceAwsApiGatewayDocumentationVersion(), - "aws_api_gateway_domain_name": resourceAwsApiGatewayDomainName(), - "aws_api_gateway_gateway_response": resourceAwsApiGatewayGatewayResponse(), - "aws_api_gateway_integration": resourceAwsApiGatewayIntegration(), - "aws_api_gateway_integration_response": resourceAwsApiGatewayIntegrationResponse(), - "aws_api_gateway_method": resourceAwsApiGatewayMethod(), - "aws_api_gateway_method_response": resourceAwsApiGatewayMethodResponse(), - "aws_api_gateway_method_settings": resourceAwsApiGatewayMethodSettings(), - "aws_api_gateway_model": resourceAwsApiGatewayModel(), - "aws_api_gateway_request_validator": resourceAwsApiGatewayRequestValidator(), - "aws_api_gateway_resource": resourceAwsApiGatewayResource(), - "aws_api_gateway_rest_api": resourceAwsApiGatewayRestApi(), - "aws_api_gateway_rest_api_policy": resourceAwsApiGatewayRestApiPolicy(), - "aws_api_gateway_stage": resourceAwsApiGatewayStage(), - "aws_api_gateway_usage_plan": resourceAwsApiGatewayUsagePlan(), - "aws_api_gateway_usage_plan_key": resourceAwsApiGatewayUsagePlanKey(), - "aws_api_gateway_vpc_link": resourceAwsApiGatewayVpcLink(), - "aws_apigatewayv2_api": resourceAwsApiGatewayV2Api(), - "aws_apigatewayv2_api_mapping": resourceAwsApiGatewayV2ApiMapping(), - "aws_apigatewayv2_authorizer": resourceAwsApiGatewayV2Authorizer(), - "aws_apigatewayv2_deployment": resourceAwsApiGatewayV2Deployment(), - "aws_apigatewayv2_domain_name": resourceAwsApiGatewayV2DomainName(), - "aws_apigatewayv2_integration": resourceAwsApiGatewayV2Integration(), - "aws_apigatewayv2_integration_response": resourceAwsApiGatewayV2IntegrationResponse(), - "aws_apigatewayv2_model": resourceAwsApiGatewayV2Model(), - "aws_apigatewayv2_route": resourceAwsApiGatewayV2Route(), - "aws_apigatewayv2_route_response": resourceAwsApiGatewayV2RouteResponse(), - "aws_apigatewayv2_stage": resourceAwsApiGatewayV2Stage(), - "aws_apigatewayv2_vpc_link": resourceAwsApiGatewayV2VpcLink(), - "aws_app_cookie_stickiness_policy": resourceAwsAppCookieStickinessPolicy(), - "aws_appautoscaling_target": resourceAwsAppautoscalingTarget(), - "aws_appautoscaling_policy": resourceAwsAppautoscalingPolicy(), - "aws_appautoscaling_scheduled_action": resourceAwsAppautoscalingScheduledAction(), - "aws_appconfig_application": resourceAwsAppconfigApplication(), - "aws_appconfig_configuration_profile": resourceAwsAppconfigConfigurationProfile(), - "aws_appconfig_deployment": resourceAwsAppconfigDeployment(), - "aws_appconfig_deployment_strategy": resourceAwsAppconfigDeploymentStrategy(), - "aws_appconfig_environment": resourceAwsAppconfigEnvironment(), - "aws_appconfig_hosted_configuration_version": resourceAwsAppconfigHostedConfigurationVersion(), - "aws_appmesh_gateway_route": resourceAwsAppmeshGatewayRoute(), - "aws_appmesh_mesh": resourceAwsAppmeshMesh(), - "aws_appmesh_route": resourceAwsAppmeshRoute(), - "aws_appmesh_virtual_gateway": resourceAwsAppmeshVirtualGateway(), - "aws_appmesh_virtual_node": resourceAwsAppmeshVirtualNode(), - "aws_appmesh_virtual_router": resourceAwsAppmeshVirtualRouter(), - "aws_appmesh_virtual_service": resourceAwsAppmeshVirtualService(), - "aws_apprunner_auto_scaling_configuration_version": resourceAwsAppRunnerAutoScalingConfigurationVersion(), - "aws_apprunner_connection": resourceAwsAppRunnerConnection(), - "aws_apprunner_custom_domain_association": resourceAwsAppRunnerCustomDomainAssociation(), - "aws_apprunner_service": resourceAwsAppRunnerService(), - "aws_appstream_stack": resourceAwsAppStreamStack(), - "aws_appstream_fleet": resourceAwsAppStreamFleet(), - "aws_appsync_api_key": resourceAwsAppsyncApiKey(), - "aws_appsync_datasource": resourceAwsAppsyncDatasource(), - "aws_appsync_function": resourceAwsAppsyncFunction(), - "aws_appsync_graphql_api": resourceAwsAppsyncGraphqlApi(), - "aws_appsync_resolver": resourceAwsAppsyncResolver(), - "aws_athena_database": resourceAwsAthenaDatabase(), - "aws_athena_named_query": resourceAwsAthenaNamedQuery(), - "aws_athena_workgroup": resourceAwsAthenaWorkgroup(), - "aws_autoscaling_attachment": resourceAwsAutoscalingAttachment(), - "aws_autoscaling_group": resourceAwsAutoscalingGroup(), - "aws_autoscaling_group_tag": resourceAwsAutoscalingGroupTag(), - "aws_autoscaling_lifecycle_hook": resourceAwsAutoscalingLifecycleHook(), - "aws_autoscaling_notification": resourceAwsAutoscalingNotification(), - "aws_autoscaling_policy": resourceAwsAutoscalingPolicy(), - "aws_autoscaling_schedule": resourceAwsAutoscalingSchedule(), - "aws_autoscalingplans_scaling_plan": resourceAwsAutoScalingPlansScalingPlan(), - "aws_backup_global_settings": resourceAwsBackupGlobalSettings(), - "aws_backup_plan": resourceAwsBackupPlan(), - "aws_backup_region_settings": resourceAwsBackupRegionSettings(), - "aws_backup_selection": resourceAwsBackupSelection(), - "aws_backup_vault": resourceAwsBackupVault(), - "aws_backup_vault_notifications": resourceAwsBackupVaultNotifications(), - "aws_backup_vault_policy": resourceAwsBackupVaultPolicy(), - "aws_budgets_budget": resourceAwsBudgetsBudget(), - "aws_budgets_budget_action": resourceAwsBudgetsBudgetAction(), - "aws_chime_voice_connector": resourceAwsChimeVoiceConnector(), - "aws_chime_voice_connector_group": resourceAwsChimeVoiceConnectorGroup(), - "aws_chime_voice_connector_logging": resourceAwsChimeVoiceConnectorLogging(), - "aws_chime_voice_connector_streaming": resourceAwsChimeVoiceConnectorStreaming(), - "aws_chime_voice_connector_origination": resourceAwsChimeVoiceConnectorOrigination(), - "aws_chime_voice_connector_termination": resourceAwsChimeVoiceConnectorTermination(), - "aws_cloud9_environment_ec2": resourceAwsCloud9EnvironmentEc2(), - "aws_cloudformation_stack": resourceAwsCloudFormationStack(), - "aws_cloudformation_stack_set": resourceAwsCloudFormationStackSet(), - "aws_cloudformation_stack_set_instance": resourceAwsCloudFormationStackSetInstance(), - "aws_cloudformation_type": resourceAwsCloudFormationType(), - "aws_cloudfront_cache_policy": resourceAwsCloudFrontCachePolicy(), - "aws_cloudfront_distribution": resourceAwsCloudFrontDistribution(), - "aws_cloudfront_function": resourceAwsCloudFrontFunction(), - "aws_cloudfront_key_group": resourceAwsCloudFrontKeyGroup(), - "aws_cloudfront_monitoring_subscription": resourceAwsCloudFrontMonitoringSubscription(), - "aws_cloudfront_origin_access_identity": resourceAwsCloudFrontOriginAccessIdentity(), - "aws_cloudfront_origin_request_policy": resourceAwsCloudFrontOriginRequestPolicy(), - "aws_cloudfront_public_key": resourceAwsCloudFrontPublicKey(), - "aws_cloudfront_realtime_log_config": resourceAwsCloudFrontRealtimeLogConfig(), - "aws_cloudtrail": resourceAwsCloudTrail(), - "aws_cloudwatch_event_bus": resourceAwsCloudWatchEventBus(), - "aws_cloudwatch_event_bus_policy": resourceAwsCloudWatchEventBusPolicy(), - "aws_cloudwatch_event_permission": resourceAwsCloudWatchEventPermission(), - "aws_cloudwatch_event_rule": resourceAwsCloudWatchEventRule(), - "aws_cloudwatch_event_target": resourceAwsCloudWatchEventTarget(), - "aws_cloudwatch_event_archive": resourceAwsCloudWatchEventArchive(), - "aws_cloudwatch_event_connection": resourceAwsCloudWatchEventConnection(), - "aws_cloudwatch_event_api_destination": resourceAwsCloudWatchEventApiDestination(), - "aws_cloudwatch_log_destination": resourceAwsCloudWatchLogDestination(), - "aws_cloudwatch_log_destination_policy": resourceAwsCloudWatchLogDestinationPolicy(), - "aws_cloudwatch_log_group": resourceAwsCloudWatchLogGroup(), - "aws_cloudwatch_log_metric_filter": resourceAwsCloudWatchLogMetricFilter(), - "aws_cloudwatch_log_resource_policy": resourceAwsCloudWatchLogResourcePolicy(), - "aws_cloudwatch_log_stream": resourceAwsCloudWatchLogStream(), - "aws_cloudwatch_log_subscription_filter": resourceAwsCloudwatchLogSubscriptionFilter(), - "aws_config_aggregate_authorization": resourceAwsConfigAggregateAuthorization(), - "aws_config_config_rule": resourceAwsConfigConfigRule(), - "aws_config_configuration_aggregator": resourceAwsConfigConfigurationAggregator(), - "aws_config_configuration_recorder": resourceAwsConfigConfigurationRecorder(), - "aws_config_configuration_recorder_status": resourceAwsConfigConfigurationRecorderStatus(), - "aws_config_conformance_pack": resourceAwsConfigConformancePack(), - "aws_config_delivery_channel": resourceAwsConfigDeliveryChannel(), - "aws_config_organization_conformance_pack": resourceAwsConfigOrganizationConformancePack(), - "aws_config_organization_custom_rule": resourceAwsConfigOrganizationCustomRule(), - "aws_config_organization_managed_rule": resourceAwsConfigOrganizationManagedRule(), - "aws_config_remediation_configuration": resourceAwsConfigRemediationConfiguration(), - "aws_cognito_identity_pool": resourceAwsCognitoIdentityPool(), - "aws_cognito_identity_pool_roles_attachment": resourceAwsCognitoIdentityPoolRolesAttachment(), - "aws_cognito_identity_provider": resourceAwsCognitoIdentityProvider(), - "aws_cognito_resource_server": resourceAwsCognitoResourceServer(), - "aws_cognito_user_group": resourceAwsCognitoUserGroup(), - "aws_cognito_user_pool": resourceAwsCognitoUserPool(), - "aws_cognito_user_pool_client": resourceAwsCognitoUserPoolClient(), - "aws_cognito_user_pool_domain": resourceAwsCognitoUserPoolDomain(), - "aws_cognito_user_pool_ui_customization": resourceAwsCognitoUserPoolUICustomization(), - "aws_cloudhsm_v2_cluster": resourceAwsCloudHsmV2Cluster(), - "aws_cloudhsm_v2_hsm": resourceAwsCloudHsmV2Hsm(), - "aws_cloudwatch_composite_alarm": resourceAwsCloudWatchCompositeAlarm(), - "aws_cloudwatch_metric_alarm": resourceAwsCloudWatchMetricAlarm(), - "aws_cloudwatch_dashboard": resourceAwsCloudWatchDashboard(), - "aws_cloudwatch_metric_stream": resourceAwsCloudWatchMetricStream(), - "aws_cloudwatch_query_definition": resourceAwsCloudWatchQueryDefinition(), - "aws_codedeploy_app": resourceAwsCodeDeployApp(), - "aws_codedeploy_deployment_config": resourceAwsCodeDeployDeploymentConfig(), - "aws_codedeploy_deployment_group": resourceAwsCodeDeployDeploymentGroup(), - "aws_codecommit_repository": resourceAwsCodeCommitRepository(), - "aws_codecommit_trigger": resourceAwsCodeCommitTrigger(), - "aws_codeartifact_domain": resourceAwsCodeArtifactDomain(), - "aws_codeartifact_domain_permissions_policy": resourceAwsCodeArtifactDomainPermissionsPolicy(), - "aws_codeartifact_repository": resourceAwsCodeArtifactRepository(), - "aws_codeartifact_repository_permissions_policy": resourceAwsCodeArtifactRepositoryPermissionsPolicy(), - "aws_codebuild_project": resourceAwsCodeBuildProject(), - "aws_codebuild_report_group": resourceAwsCodeBuildReportGroup(), - "aws_codebuild_source_credential": resourceAwsCodeBuildSourceCredential(), - "aws_codebuild_webhook": resourceAwsCodeBuildWebhook(), - "aws_codepipeline": resourceAwsCodePipeline(), - "aws_codepipeline_webhook": resourceAwsCodePipelineWebhook(), - "aws_codestarconnections_connection": resourceAwsCodeStarConnectionsConnection(), - "aws_codestarconnections_host": resourceAwsCodeStarConnectionsHost(), - "aws_codestarnotifications_notification_rule": resourceAwsCodeStarNotificationsNotificationRule(), - "aws_connect_contact_flow": resourceAwsConnectContactFlow(), - "aws_connect_instance": resourceAwsConnectInstance(), - "aws_cur_report_definition": resourceAwsCurReportDefinition(), - "aws_customer_gateway": resourceAwsCustomerGateway(), - "aws_datapipeline_pipeline": resourceAwsDataPipelinePipeline(), - "aws_datasync_agent": resourceAwsDataSyncAgent(), - "aws_datasync_location_efs": resourceAwsDataSyncLocationEfs(), - "aws_datasync_location_fsx_windows_file_system": resourceAwsDataSyncLocationFsxWindowsFileSystem(), - "aws_datasync_location_nfs": resourceAwsDataSyncLocationNfs(), - "aws_datasync_location_s3": resourceAwsDataSyncLocationS3(), - "aws_datasync_location_smb": resourceAwsDataSyncLocationSmb(), - "aws_datasync_task": resourceAwsDataSyncTask(), - "aws_dax_cluster": resourceAwsDaxCluster(), - "aws_dax_parameter_group": resourceAwsDaxParameterGroup(), - "aws_dax_subnet_group": resourceAwsDaxSubnetGroup(), - "aws_db_cluster_snapshot": resourceAwsDbClusterSnapshot(), - "aws_db_event_subscription": resourceAwsDbEventSubscription(), - "aws_db_instance": resourceAwsDbInstance(), - "aws_db_instance_role_association": resourceAwsDbInstanceRoleAssociation(), - "aws_db_option_group": resourceAwsDbOptionGroup(), - "aws_db_parameter_group": resourceAwsDbParameterGroup(), - "aws_db_proxy": resourceAwsDbProxy(), - "aws_db_proxy_default_target_group": resourceAwsDbProxyDefaultTargetGroup(), - "aws_db_proxy_endpoint": resourceAwsDbProxyEndpoint(), - "aws_db_proxy_target": resourceAwsDbProxyTarget(), - "aws_db_security_group": resourceAwsDbSecurityGroup(), - "aws_db_snapshot": resourceAwsDbSnapshot(), - "aws_db_subnet_group": resourceAwsDbSubnetGroup(), - "aws_devicefarm_project": resourceAwsDevicefarmProject(), - "aws_directory_service_directory": resourceAwsDirectoryServiceDirectory(), - "aws_directory_service_conditional_forwarder": resourceAwsDirectoryServiceConditionalForwarder(), - "aws_directory_service_log_subscription": resourceAwsDirectoryServiceLogSubscription(), - "aws_dlm_lifecycle_policy": resourceAwsDlmLifecyclePolicy(), - "aws_dms_certificate": resourceAwsDmsCertificate(), - "aws_dms_endpoint": resourceAwsDmsEndpoint(), - "aws_dms_event_subscription": resourceAwsDmsEventSubscription(), - "aws_dms_replication_instance": resourceAwsDmsReplicationInstance(), - "aws_dms_replication_subnet_group": resourceAwsDmsReplicationSubnetGroup(), - "aws_dms_replication_task": resourceAwsDmsReplicationTask(), - "aws_docdb_cluster": resourceAwsDocDBCluster(), - "aws_docdb_cluster_instance": resourceAwsDocDBClusterInstance(), - "aws_docdb_cluster_parameter_group": resourceAwsDocDBClusterParameterGroup(), - "aws_docdb_cluster_snapshot": resourceAwsDocDBClusterSnapshot(), - "aws_docdb_subnet_group": resourceAwsDocDBSubnetGroup(), - "aws_dx_bgp_peer": resourceAwsDxBgpPeer(), - "aws_dx_connection": resourceAwsDxConnection(), - "aws_dx_connection_association": resourceAwsDxConnectionAssociation(), - "aws_dx_gateway": resourceAwsDxGateway(), - "aws_dx_gateway_association": resourceAwsDxGatewayAssociation(), - "aws_dx_gateway_association_proposal": resourceAwsDxGatewayAssociationProposal(), - "aws_dx_hosted_private_virtual_interface": resourceAwsDxHostedPrivateVirtualInterface(), - "aws_dx_hosted_private_virtual_interface_accepter": resourceAwsDxHostedPrivateVirtualInterfaceAccepter(), - "aws_dx_hosted_public_virtual_interface": resourceAwsDxHostedPublicVirtualInterface(), - "aws_dx_hosted_public_virtual_interface_accepter": resourceAwsDxHostedPublicVirtualInterfaceAccepter(), - "aws_dx_hosted_transit_virtual_interface": resourceAwsDxHostedTransitVirtualInterface(), - "aws_dx_hosted_transit_virtual_interface_accepter": resourceAwsDxHostedTransitVirtualInterfaceAccepter(), - "aws_dx_lag": resourceAwsDxLag(), - "aws_dx_private_virtual_interface": resourceAwsDxPrivateVirtualInterface(), - "aws_dx_public_virtual_interface": resourceAwsDxPublicVirtualInterface(), - "aws_dx_transit_virtual_interface": resourceAwsDxTransitVirtualInterface(), - "aws_dynamodb_table": resourceAwsDynamoDbTable(), - "aws_dynamodb_table_item": resourceAwsDynamoDbTableItem(), - "aws_dynamodb_tag": resourceAwsDynamodbTag(), - "aws_dynamodb_global_table": resourceAwsDynamoDbGlobalTable(), - "aws_dynamodb_kinesis_streaming_destination": resourceAwsDynamoDbKinesisStreamingDestination(), - "aws_ebs_default_kms_key": resourceAwsEbsDefaultKmsKey(), - "aws_ebs_encryption_by_default": resourceAwsEbsEncryptionByDefault(), - "aws_ebs_snapshot": resourceAwsEbsSnapshot(), - "aws_ebs_snapshot_copy": resourceAwsEbsSnapshotCopy(), - "aws_ebs_snapshot_import": resourceAwsEbsSnapshotImport(), - "aws_ebs_volume": resourceAwsEbsVolume(), - "aws_ec2_availability_zone_group": resourceAwsEc2AvailabilityZoneGroup(), - "aws_ec2_capacity_reservation": resourceAwsEc2CapacityReservation(), - "aws_ec2_carrier_gateway": resourceAwsEc2CarrierGateway(), - "aws_ec2_client_vpn_authorization_rule": resourceAwsEc2ClientVpnAuthorizationRule(), - "aws_ec2_client_vpn_endpoint": resourceAwsEc2ClientVpnEndpoint(), - "aws_ec2_client_vpn_network_association": resourceAwsEc2ClientVpnNetworkAssociation(), - "aws_ec2_client_vpn_route": resourceAwsEc2ClientVpnRoute(), - "aws_ec2_fleet": resourceAwsEc2Fleet(), - "aws_ec2_local_gateway_route": resourceAwsEc2LocalGatewayRoute(), - "aws_ec2_local_gateway_route_table_vpc_association": resourceAwsEc2LocalGatewayRouteTableVpcAssociation(), - "aws_ec2_managed_prefix_list": resourceAwsEc2ManagedPrefixList(), - "aws_ec2_tag": resourceAwsEc2Tag(), - "aws_ec2_traffic_mirror_filter": resourceAwsEc2TrafficMirrorFilter(), - "aws_ec2_traffic_mirror_filter_rule": resourceAwsEc2TrafficMirrorFilterRule(), - "aws_ec2_traffic_mirror_target": resourceAwsEc2TrafficMirrorTarget(), - "aws_ec2_traffic_mirror_session": resourceAwsEc2TrafficMirrorSession(), - "aws_ec2_transit_gateway": resourceAwsEc2TransitGateway(), - "aws_ec2_transit_gateway_peering_attachment": resourceAwsEc2TransitGatewayPeeringAttachment(), - "aws_ec2_transit_gateway_peering_attachment_accepter": resourceAwsEc2TransitGatewayPeeringAttachmentAccepter(), - "aws_ec2_transit_gateway_prefix_list_reference": resourceAwsEc2TransitGatewayPrefixListReference(), - "aws_ec2_transit_gateway_route": resourceAwsEc2TransitGatewayRoute(), - "aws_ec2_transit_gateway_route_table": resourceAwsEc2TransitGatewayRouteTable(), - "aws_ec2_transit_gateway_route_table_association": resourceAwsEc2TransitGatewayRouteTableAssociation(), - "aws_ec2_transit_gateway_route_table_propagation": resourceAwsEc2TransitGatewayRouteTablePropagation(), - "aws_ec2_transit_gateway_vpc_attachment": resourceAwsEc2TransitGatewayVpcAttachment(), - "aws_ec2_transit_gateway_vpc_attachment_accepter": resourceAwsEc2TransitGatewayVpcAttachmentAccepter(), - "aws_ecr_lifecycle_policy": resourceAwsEcrLifecyclePolicy(), - "aws_ecrpublic_repository": resourceAwsEcrPublicRepository(), - "aws_ecr_registry_policy": resourceAwsEcrRegistryPolicy(), - "aws_ecr_replication_configuration": resourceAwsEcrReplicationConfiguration(), - "aws_ecr_repository": resourceAwsEcrRepository(), - "aws_ecr_repository_policy": resourceAwsEcrRepositoryPolicy(), - "aws_ecs_capacity_provider": resourceAwsEcsCapacityProvider(), - "aws_ecs_cluster": resourceAwsEcsCluster(), - "aws_ecs_service": resourceAwsEcsService(), - "aws_ecs_tag": resourceAwsEcsTag(), - "aws_ecs_task_definition": resourceAwsEcsTaskDefinition(), - "aws_efs_access_point": resourceAwsEfsAccessPoint(), - "aws_efs_backup_policy": resourceAwsEfsBackupPolicy(), - "aws_efs_file_system": resourceAwsEfsFileSystem(), - "aws_efs_file_system_policy": resourceAwsEfsFileSystemPolicy(), - "aws_efs_mount_target": resourceAwsEfsMountTarget(), - "aws_egress_only_internet_gateway": resourceAwsEgressOnlyInternetGateway(), - "aws_eip": resourceAwsEip(), - "aws_eip_association": resourceAwsEipAssociation(), - "aws_eks_cluster": resourceAwsEksCluster(), - "aws_eks_addon": resourceAwsEksAddon(), - "aws_eks_fargate_profile": resourceAwsEksFargateProfile(), - "aws_eks_identity_provider_config": resourceAwsEksIdentityProviderConfig(), - "aws_eks_node_group": resourceAwsEksNodeGroup(), - "aws_elasticache_cluster": resourceAwsElasticacheCluster(), - "aws_elasticache_global_replication_group": resourceAwsElasticacheGlobalReplicationGroup(), - "aws_elasticache_parameter_group": resourceAwsElasticacheParameterGroup(), - "aws_elasticache_replication_group": resourceAwsElasticacheReplicationGroup(), - "aws_elasticache_security_group": resourceAwsElasticacheSecurityGroup(), - "aws_elasticache_subnet_group": resourceAwsElasticacheSubnetGroup(), - "aws_elasticache_user": resourceAwsElasticacheUser(), - "aws_elasticache_user_group": resourceAwsElasticacheUserGroup(), - "aws_elastic_beanstalk_application": resourceAwsElasticBeanstalkApplication(), - "aws_elastic_beanstalk_application_version": resourceAwsElasticBeanstalkApplicationVersion(), - "aws_elastic_beanstalk_configuration_template": resourceAwsElasticBeanstalkConfigurationTemplate(), - "aws_elastic_beanstalk_environment": resourceAwsElasticBeanstalkEnvironment(), - "aws_elasticsearch_domain": resourceAwsElasticSearchDomain(), - "aws_elasticsearch_domain_policy": resourceAwsElasticSearchDomainPolicy(), - "aws_elasticsearch_domain_saml_options": resourceAwsElasticSearchDomainSAMLOptions(), - "aws_elastictranscoder_pipeline": resourceAwsElasticTranscoderPipeline(), - "aws_elastictranscoder_preset": resourceAwsElasticTranscoderPreset(), - "aws_elb": resourceAwsElb(), - "aws_elb_attachment": resourceAwsElbAttachment(), - "aws_emr_cluster": resourceAwsEMRCluster(), - "aws_emr_instance_group": resourceAwsEMRInstanceGroup(), - "aws_emr_instance_fleet": resourceAwsEMRInstanceFleet(), - "aws_emr_managed_scaling_policy": resourceAwsEMRManagedScalingPolicy(), - "aws_emr_security_configuration": resourceAwsEMRSecurityConfiguration(), - "aws_flow_log": resourceAwsFlowLog(), - "aws_fsx_backup": resourceAwsFsxBackup(), - "aws_fsx_lustre_file_system": resourceAwsFsxLustreFileSystem(), - "aws_fsx_ontap_file_system": resourceAwsFsxOntapFileSystem(), - "aws_fsx_windows_file_system": resourceAwsFsxWindowsFileSystem(), - "aws_fms_admin_account": resourceAwsFmsAdminAccount(), - "aws_fms_policy": resourceAwsFmsPolicy(), - "aws_gamelift_alias": resourceAwsGameliftAlias(), - "aws_gamelift_build": resourceAwsGameliftBuild(), - "aws_gamelift_fleet": resourceAwsGameliftFleet(), - "aws_gamelift_game_session_queue": resourceAwsGameliftGameSessionQueue(), - "aws_glacier_vault": resourceAwsGlacierVault(), - "aws_glacier_vault_lock": resourceAwsGlacierVaultLock(), - "aws_globalaccelerator_accelerator": resourceAwsGlobalAcceleratorAccelerator(), - "aws_globalaccelerator_endpoint_group": resourceAwsGlobalAcceleratorEndpointGroup(), - "aws_globalaccelerator_listener": resourceAwsGlobalAcceleratorListener(), - "aws_glue_catalog_database": resourceAwsGlueCatalogDatabase(), - "aws_glue_catalog_table": resourceAwsGlueCatalogTable(), - "aws_glue_classifier": resourceAwsGlueClassifier(), - "aws_glue_connection": resourceAwsGlueConnection(), - "aws_glue_dev_endpoint": resourceAwsGlueDevEndpoint(), - "aws_glue_crawler": resourceAwsGlueCrawler(), - "aws_glue_data_catalog_encryption_settings": resourceAwsGlueDataCatalogEncryptionSettings(), - "aws_glue_job": resourceAwsGlueJob(), - "aws_glue_ml_transform": resourceAwsGlueMLTransform(), - "aws_glue_partition": resourceAwsGluePartition(), - "aws_glue_registry": resourceAwsGlueRegistry(), - "aws_glue_resource_policy": resourceAwsGlueResourcePolicy(), - "aws_glue_schema": resourceAwsGlueSchema(), - "aws_glue_security_configuration": resourceAwsGlueSecurityConfiguration(), - "aws_glue_trigger": resourceAwsGlueTrigger(), - "aws_glue_user_defined_function": resourceAwsGlueUserDefinedFunction(), - "aws_glue_workflow": resourceAwsGlueWorkflow(), - "aws_guardduty_detector": resourceAwsGuardDutyDetector(), - "aws_guardduty_filter": resourceAwsGuardDutyFilter(), - "aws_guardduty_invite_accepter": resourceAwsGuardDutyInviteAccepter(), - "aws_guardduty_ipset": resourceAwsGuardDutyIpset(), - "aws_guardduty_member": resourceAwsGuardDutyMember(), - "aws_guardduty_organization_admin_account": resourceAwsGuardDutyOrganizationAdminAccount(), - "aws_guardduty_organization_configuration": resourceAwsGuardDutyOrganizationConfiguration(), - "aws_guardduty_publishing_destination": resourceAwsGuardDutyPublishingDestination(), - "aws_guardduty_threatintelset": resourceAwsGuardDutyThreatintelset(), - "aws_iam_access_key": resourceAwsIamAccessKey(), - "aws_iam_account_alias": resourceAwsIamAccountAlias(), - "aws_iam_account_password_policy": resourceAwsIamAccountPasswordPolicy(), - "aws_iam_group_policy": resourceAwsIamGroupPolicy(), - "aws_iam_group": resourceAwsIamGroup(), - "aws_iam_group_membership": resourceAwsIamGroupMembership(), - "aws_iam_group_policy_attachment": resourceAwsIamGroupPolicyAttachment(), - "aws_iam_instance_profile": resourceAwsIamInstanceProfile(), - "aws_iam_openid_connect_provider": resourceAwsIamOpenIDConnectProvider(), - "aws_iam_policy": resourceAwsIamPolicy(), - "aws_iam_policy_attachment": resourceAwsIamPolicyAttachment(), - "aws_iam_role_policy_attachment": resourceAwsIamRolePolicyAttachment(), - "aws_iam_role_policy": resourceAwsIamRolePolicy(), - "aws_iam_role": resourceAwsIamRole(), - "aws_iam_saml_provider": resourceAwsIamSamlProvider(), - "aws_iam_server_certificate": resourceAwsIAMServerCertificate(), - "aws_iam_service_linked_role": resourceAwsIamServiceLinkedRole(), - "aws_iam_user_group_membership": resourceAwsIamUserGroupMembership(), - "aws_iam_user_policy_attachment": resourceAwsIamUserPolicyAttachment(), - "aws_iam_user_policy": resourceAwsIamUserPolicy(), - "aws_iam_user_ssh_key": resourceAwsIamUserSshKey(), - "aws_iam_user": resourceAwsIamUser(), - "aws_iam_user_login_profile": resourceAwsIamUserLoginProfile(), - "aws_imagebuilder_component": resourceAwsImageBuilderComponent(), - "aws_imagebuilder_distribution_configuration": resourceAwsImageBuilderDistributionConfiguration(), - "aws_imagebuilder_image": resourceAwsImageBuilderImage(), - "aws_imagebuilder_image_pipeline": resourceAwsImageBuilderImagePipeline(), - "aws_imagebuilder_image_recipe": resourceAwsImageBuilderImageRecipe(), - "aws_imagebuilder_infrastructure_configuration": resourceAwsImageBuilderInfrastructureConfiguration(), - "aws_inspector_assessment_target": resourceAWSInspectorAssessmentTarget(), - "aws_inspector_assessment_template": resourceAWSInspectorAssessmentTemplate(), - "aws_inspector_resource_group": resourceAWSInspectorResourceGroup(), - "aws_instance": resourceAwsInstance(), - "aws_internet_gateway": resourceAwsInternetGateway(), - "aws_iot_certificate": resourceAwsIotCertificate(), - "aws_iot_policy": resourceAwsIotPolicy(), - "aws_iot_policy_attachment": resourceAwsIotPolicyAttachment(), - "aws_iot_thing": resourceAwsIotThing(), - "aws_iot_thing_principal_attachment": resourceAwsIotThingPrincipalAttachment(), - "aws_iot_thing_type": resourceAwsIotThingType(), - "aws_iot_topic_rule": resourceAwsIotTopicRule(), - "aws_iot_role_alias": resourceAwsIotRoleAlias(), - "aws_key_pair": resourceAwsKeyPair(), - "aws_kinesis_analytics_application": resourceAwsKinesisAnalyticsApplication(), - "aws_kinesisanalyticsv2_application": resourceAwsKinesisAnalyticsV2Application(), - "aws_kinesisanalyticsv2_application_snapshot": resourceAwsKinesisAnalyticsV2ApplicationSnapshot(), - "aws_kinesis_firehose_delivery_stream": resourceAwsKinesisFirehoseDeliveryStream(), - "aws_kinesis_stream": resourceAwsKinesisStream(), - "aws_kinesis_stream_consumer": resourceAwsKinesisStreamConsumer(), - "aws_kinesis_video_stream": resourceAwsKinesisVideoStream(), - "aws_kms_alias": resourceAwsKmsAlias(), - "aws_kms_external_key": resourceAwsKmsExternalKey(), - "aws_kms_grant": resourceAwsKmsGrant(), - "aws_kms_key": resourceAwsKmsKey(), - "aws_kms_ciphertext": resourceAwsKmsCiphertext(), - "aws_lakeformation_data_lake_settings": resourceAwsLakeFormationDataLakeSettings(), - "aws_lakeformation_permissions": resourceAwsLakeFormationPermissions(), - "aws_lakeformation_resource": resourceAwsLakeFormationResource(), - "aws_lambda_alias": resourceAwsLambdaAlias(), - "aws_lambda_code_signing_config": resourceAwsLambdaCodeSigningConfig(), - "aws_lambda_event_source_mapping": resourceAwsLambdaEventSourceMapping(), - "aws_lambda_function_event_invoke_config": resourceAwsLambdaFunctionEventInvokeConfig(), - "aws_lambda_function": resourceAwsLambdaFunction(), - "aws_lambda_layer_version": resourceAwsLambdaLayerVersion(), - "aws_lambda_permission": resourceAwsLambdaPermission(), - "aws_lambda_provisioned_concurrency_config": resourceAwsLambdaProvisionedConcurrencyConfig(), - "aws_launch_configuration": resourceAwsLaunchConfiguration(), - "aws_launch_template": resourceAwsLaunchTemplate(), - "aws_lex_bot": resourceAwsLexBot(), - "aws_lex_bot_alias": resourceAwsLexBotAlias(), - "aws_lex_intent": resourceAwsLexIntent(), - "aws_lex_slot_type": resourceAwsLexSlotType(), - "aws_licensemanager_association": resourceAwsLicenseManagerAssociation(), - "aws_licensemanager_license_configuration": resourceAwsLicenseManagerLicenseConfiguration(), - "aws_lightsail_domain": resourceAwsLightsailDomain(), - "aws_lightsail_instance": resourceAwsLightsailInstance(), - "aws_lightsail_instance_public_ports": resourceAwsLightsailInstancePublicPorts(), - "aws_lightsail_key_pair": resourceAwsLightsailKeyPair(), - "aws_lightsail_static_ip": resourceAwsLightsailStaticIp(), - "aws_lightsail_static_ip_attachment": resourceAwsLightsailStaticIpAttachment(), - "aws_lb_cookie_stickiness_policy": resourceAwsLBCookieStickinessPolicy(), - "aws_load_balancer_policy": resourceAwsLoadBalancerPolicy(), - "aws_load_balancer_backend_server_policy": resourceAwsLoadBalancerBackendServerPolicies(), - "aws_load_balancer_listener_policy": resourceAwsLoadBalancerListenerPolicies(), - "aws_lb_ssl_negotiation_policy": resourceAwsLBSSLNegotiationPolicy(), - "aws_macie2_account": resourceAwsMacie2Account(), - "aws_macie2_classification_job": resourceAwsMacie2ClassificationJob(), - "aws_macie2_custom_data_identifier": resourceAwsMacie2CustomDataIdentifier(), - "aws_macie2_findings_filter": resourceAwsMacie2FindingsFilter(), - "aws_macie2_invitation_accepter": resourceAwsMacie2InvitationAccepter(), - "aws_macie2_member": resourceAwsMacie2Member(), - "aws_macie2_organization_admin_account": resourceAwsMacie2OrganizationAdminAccount(), - "aws_macie_member_account_association": resourceAwsMacieMemberAccountAssociation(), - "aws_macie_s3_bucket_association": resourceAwsMacieS3BucketAssociation(), - "aws_main_route_table_association": resourceAwsMainRouteTableAssociation(), - "aws_mq_broker": resourceAwsMqBroker(), - "aws_mq_configuration": resourceAwsMqConfiguration(), - "aws_media_convert_queue": resourceAwsMediaConvertQueue(), - "aws_media_package_channel": resourceAwsMediaPackageChannel(), - "aws_media_store_container": resourceAwsMediaStoreContainer(), - "aws_media_store_container_policy": resourceAwsMediaStoreContainerPolicy(), - "aws_msk_cluster": resourceAwsMskCluster(), - "aws_msk_configuration": resourceAwsMskConfiguration(), - "aws_msk_scram_secret_association": resourceAwsMskScramSecretAssociation(), - "aws_mwaa_environment": resourceAwsMwaaEnvironment(), - "aws_nat_gateway": resourceAwsNatGateway(), - "aws_network_acl": resourceAwsNetworkAcl(), - "aws_default_network_acl": resourceAwsDefaultNetworkAcl(), - "aws_neptune_cluster": resourceAwsNeptuneCluster(), - "aws_neptune_cluster_endpoint": resourceAwsNeptuneClusterEndpoint(), - "aws_neptune_cluster_instance": resourceAwsNeptuneClusterInstance(), - "aws_neptune_cluster_parameter_group": resourceAwsNeptuneClusterParameterGroup(), - "aws_neptune_cluster_snapshot": resourceAwsNeptuneClusterSnapshot(), - "aws_neptune_event_subscription": resourceAwsNeptuneEventSubscription(), - "aws_neptune_parameter_group": resourceAwsNeptuneParameterGroup(), - "aws_neptune_subnet_group": resourceAwsNeptuneSubnetGroup(), - "aws_network_acl_rule": resourceAwsNetworkAclRule(), - "aws_network_interface": resourceAwsNetworkInterface(), - "aws_network_interface_attachment": resourceAwsNetworkInterfaceAttachment(), - "aws_networkfirewall_firewall": resourceAwsNetworkFirewallFirewall(), - "aws_networkfirewall_firewall_policy": resourceAwsNetworkFirewallFirewallPolicy(), - "aws_networkfirewall_logging_configuration": resourceAwsNetworkFirewallLoggingConfiguration(), - "aws_networkfirewall_resource_policy": resourceAwsNetworkFirewallResourcePolicy(), - "aws_networkfirewall_rule_group": resourceAwsNetworkFirewallRuleGroup(), - "aws_opsworks_application": resourceAwsOpsworksApplication(), - "aws_opsworks_stack": resourceAwsOpsworksStack(), - "aws_opsworks_java_app_layer": resourceAwsOpsworksJavaAppLayer(), - "aws_opsworks_haproxy_layer": resourceAwsOpsworksHaproxyLayer(), - "aws_opsworks_static_web_layer": resourceAwsOpsworksStaticWebLayer(), - "aws_opsworks_php_app_layer": resourceAwsOpsworksPhpAppLayer(), - "aws_opsworks_rails_app_layer": resourceAwsOpsworksRailsAppLayer(), - "aws_opsworks_nodejs_app_layer": resourceAwsOpsworksNodejsAppLayer(), - "aws_opsworks_memcached_layer": resourceAwsOpsworksMemcachedLayer(), - "aws_opsworks_mysql_layer": resourceAwsOpsworksMysqlLayer(), - "aws_opsworks_ganglia_layer": resourceAwsOpsworksGangliaLayer(), - "aws_opsworks_custom_layer": resourceAwsOpsworksCustomLayer(), - "aws_opsworks_instance": resourceAwsOpsworksInstance(), - "aws_opsworks_user_profile": resourceAwsOpsworksUserProfile(), - "aws_opsworks_permission": resourceAwsOpsworksPermission(), - "aws_opsworks_rds_db_instance": resourceAwsOpsworksRdsDbInstance(), - "aws_organizations_organization": resourceAwsOrganizationsOrganization(), - "aws_organizations_account": resourceAwsOrganizationsAccount(), - "aws_organizations_delegated_administrator": resourceAwsOrganizationsDelegatedAdministrator(), - "aws_organizations_policy": resourceAwsOrganizationsPolicy(), - "aws_organizations_policy_attachment": resourceAwsOrganizationsPolicyAttachment(), - "aws_organizations_organizational_unit": resourceAwsOrganizationsOrganizationalUnit(), - "aws_placement_group": resourceAwsPlacementGroup(), - "aws_prometheus_workspace": resourceAwsPrometheusWorkspace(), - "aws_proxy_protocol_policy": resourceAwsProxyProtocolPolicy(), - "aws_qldb_ledger": resourceAwsQLDBLedger(), - "aws_quicksight_group": resourceAwsQuickSightGroup(), - "aws_quicksight_group_membership": resourceAwsQuickSightGroupMembership(), - "aws_quicksight_user": resourceAwsQuickSightUser(), - "aws_ram_principal_association": resourceAwsRamPrincipalAssociation(), - "aws_ram_resource_association": resourceAwsRamResourceAssociation(), - "aws_ram_resource_share": resourceAwsRamResourceShare(), - "aws_ram_resource_share_accepter": resourceAwsRamResourceShareAccepter(), - "aws_rds_cluster": resourceAwsRDSCluster(), - "aws_rds_cluster_endpoint": resourceAwsRDSClusterEndpoint(), - "aws_rds_cluster_instance": resourceAwsRDSClusterInstance(), - "aws_rds_cluster_parameter_group": resourceAwsRDSClusterParameterGroup(), - "aws_rds_cluster_role_association": resourceAwsRDSClusterRoleAssociation(), - "aws_rds_global_cluster": resourceAwsRDSGlobalCluster(), - "aws_redshift_cluster": resourceAwsRedshiftCluster(), - "aws_redshift_security_group": resourceAwsRedshiftSecurityGroup(), - "aws_redshift_parameter_group": resourceAwsRedshiftParameterGroup(), - "aws_redshift_subnet_group": resourceAwsRedshiftSubnetGroup(), - "aws_redshift_snapshot_copy_grant": resourceAwsRedshiftSnapshotCopyGrant(), - "aws_redshift_snapshot_schedule": resourceAwsRedshiftSnapshotSchedule(), - "aws_redshift_snapshot_schedule_association": resourceAwsRedshiftSnapshotScheduleAssociation(), - "aws_redshift_event_subscription": resourceAwsRedshiftEventSubscription(), - "aws_resourcegroups_group": resourceAwsResourceGroupsGroup(), - "aws_route53_delegation_set": resourceAwsRoute53DelegationSet(), - "aws_route53_hosted_zone_dnssec": resourceAwsRoute53HostedZoneDnssec(), - "aws_route53_key_signing_key": resourceAwsRoute53KeySigningKey(), - "aws_route53_query_log": resourceAwsRoute53QueryLog(), - "aws_route53_record": resourceAwsRoute53Record(), - "aws_route53_zone_association": resourceAwsRoute53ZoneAssociation(), - "aws_route53_vpc_association_authorization": resourceAwsRoute53VPCAssociationAuthorization(), - "aws_route53_zone": resourceAwsRoute53Zone(), - "aws_route53_health_check": resourceAwsRoute53HealthCheck(), - "aws_route53_resolver_dnssec_config": resourceAwsRoute53ResolverDnssecConfig(), - "aws_route53_resolver_endpoint": resourceAwsRoute53ResolverEndpoint(), - "aws_route53_resolver_firewall_config": resourceAwsRoute53ResolverFirewallConfig(), - "aws_route53_resolver_firewall_domain_list": resourceAwsRoute53ResolverFirewallDomainList(), - "aws_route53_resolver_firewall_rule": resourceAwsRoute53ResolverFirewallRule(), - "aws_route53_resolver_firewall_rule_group": resourceAwsRoute53ResolverFirewallRuleGroup(), - "aws_route53_resolver_firewall_rule_group_association": resourceAwsRoute53ResolverFirewallRuleGroupAssociation(), - "aws_route53_resolver_query_log_config": resourceAwsRoute53ResolverQueryLogConfig(), - "aws_route53_resolver_query_log_config_association": resourceAwsRoute53ResolverQueryLogConfigAssociation(), - "aws_route53_resolver_rule_association": resourceAwsRoute53ResolverRuleAssociation(), - "aws_route53_resolver_rule": resourceAwsRoute53ResolverRule(), - "aws_route53recoverycontrolconfig_cluster": resourceAwsRoute53RecoveryControlConfigCluster(), - "aws_route53recoverycontrolconfig_control_panel": resourceAwsRoute53RecoveryControlConfigControlPanel(), - "aws_route53recoverycontrolconfig_routing_control": resourceAwsRoute53RecoveryControlConfigRoutingControl(), - "aws_route53recoverycontrolconfig_safety_rule": resourceAwsRoute53RecoveryControlConfigSafetyRule(), - "aws_route53recoveryreadiness_cell": resourceAwsRoute53RecoveryReadinessCell(), - "aws_route53recoveryreadiness_readiness_check": resourceAwsRoute53RecoveryReadinessReadinessCheck(), - "aws_route53recoveryreadiness_recovery_group": resourceAwsRoute53RecoveryReadinessRecoveryGroup(), - "aws_route53recoveryreadiness_resource_set": resourceAwsRoute53RecoveryReadinessResourceSet(), + "aws_accessanalyzer_analyzer": resourceAwsAccessAnalyzerAnalyzer(), + "aws_acm_certificate": resourceAwsAcmCertificate(), + "aws_acm_certificate_validation": resourceAwsAcmCertificateValidation(), + "aws_acmpca_certificate_authority": resourceAwsAcmpcaCertificateAuthority(), + "aws_acmpca_certificate_authority_certificate": resourceAwsAcmpcaCertificateAuthorityCertificate(), + "aws_acmpca_certificate": resourceAwsAcmpcaCertificate(), + "aws_ami": resourceAwsAmi(), + "aws_ami_copy": resourceAwsAmiCopy(), + "aws_ami_from_instance": resourceAwsAmiFromInstance(), + "aws_ami_launch_permission": resourceAwsAmiLaunchPermission(), + "aws_amplify_app": resourceAwsAmplifyApp(), + "aws_amplify_backend_environment": resourceAwsAmplifyBackendEnvironment(), + "aws_amplify_branch": resourceAwsAmplifyBranch(), + "aws_amplify_domain_association": resourceAwsAmplifyDomainAssociation(), + "aws_amplify_webhook": resourceAwsAmplifyWebhook(), + "aws_api_gateway_account": resourceAwsApiGatewayAccount(), + "aws_api_gateway_api_key": resourceAwsApiGatewayApiKey(), + "aws_api_gateway_authorizer": resourceAwsApiGatewayAuthorizer(), + "aws_api_gateway_base_path_mapping": resourceAwsApiGatewayBasePathMapping(), + "aws_api_gateway_client_certificate": resourceAwsApiGatewayClientCertificate(), + "aws_api_gateway_deployment": resourceAwsApiGatewayDeployment(), + "aws_api_gateway_documentation_part": resourceAwsApiGatewayDocumentationPart(), + "aws_api_gateway_documentation_version": resourceAwsApiGatewayDocumentationVersion(), + "aws_api_gateway_domain_name": resourceAwsApiGatewayDomainName(), + "aws_api_gateway_gateway_response": resourceAwsApiGatewayGatewayResponse(), + "aws_api_gateway_integration": resourceAwsApiGatewayIntegration(), + "aws_api_gateway_integration_response": resourceAwsApiGatewayIntegrationResponse(), + "aws_api_gateway_method": resourceAwsApiGatewayMethod(), + "aws_api_gateway_method_response": resourceAwsApiGatewayMethodResponse(), + "aws_api_gateway_method_settings": resourceAwsApiGatewayMethodSettings(), + "aws_api_gateway_model": resourceAwsApiGatewayModel(), + "aws_api_gateway_request_validator": resourceAwsApiGatewayRequestValidator(), + "aws_api_gateway_resource": resourceAwsApiGatewayResource(), + "aws_api_gateway_rest_api": resourceAwsApiGatewayRestApi(), + "aws_api_gateway_rest_api_policy": resourceAwsApiGatewayRestApiPolicy(), + "aws_api_gateway_stage": resourceAwsApiGatewayStage(), + "aws_api_gateway_usage_plan": resourceAwsApiGatewayUsagePlan(), + "aws_api_gateway_usage_plan_key": resourceAwsApiGatewayUsagePlanKey(), + "aws_api_gateway_vpc_link": resourceAwsApiGatewayVpcLink(), + "aws_apigatewayv2_api": resourceAwsApiGatewayV2Api(), + "aws_apigatewayv2_api_mapping": resourceAwsApiGatewayV2ApiMapping(), + "aws_apigatewayv2_authorizer": resourceAwsApiGatewayV2Authorizer(), + "aws_apigatewayv2_deployment": resourceAwsApiGatewayV2Deployment(), + "aws_apigatewayv2_domain_name": resourceAwsApiGatewayV2DomainName(), + "aws_apigatewayv2_integration": resourceAwsApiGatewayV2Integration(), + "aws_apigatewayv2_integration_response": resourceAwsApiGatewayV2IntegrationResponse(), + "aws_apigatewayv2_model": resourceAwsApiGatewayV2Model(), + "aws_apigatewayv2_route": resourceAwsApiGatewayV2Route(), + "aws_apigatewayv2_route_response": resourceAwsApiGatewayV2RouteResponse(), + "aws_apigatewayv2_stage": resourceAwsApiGatewayV2Stage(), + "aws_apigatewayv2_vpc_link": resourceAwsApiGatewayV2VpcLink(), + "aws_app_cookie_stickiness_policy": resourceAwsAppCookieStickinessPolicy(), + "aws_appautoscaling_target": resourceAwsAppautoscalingTarget(), + "aws_appautoscaling_policy": resourceAwsAppautoscalingPolicy(), + "aws_appautoscaling_scheduled_action": resourceAwsAppautoscalingScheduledAction(), + "aws_appconfig_application": resourceAwsAppconfigApplication(), + "aws_appconfig_configuration_profile": resourceAwsAppconfigConfigurationProfile(), + "aws_appconfig_deployment": resourceAwsAppconfigDeployment(), + "aws_appconfig_deployment_strategy": resourceAwsAppconfigDeploymentStrategy(), + "aws_appconfig_environment": resourceAwsAppconfigEnvironment(), + "aws_appconfig_hosted_configuration_version": resourceAwsAppconfigHostedConfigurationVersion(), + "aws_appmesh_gateway_route": resourceAwsAppmeshGatewayRoute(), + "aws_appmesh_mesh": resourceAwsAppmeshMesh(), + "aws_appmesh_route": resourceAwsAppmeshRoute(), + "aws_appmesh_virtual_gateway": resourceAwsAppmeshVirtualGateway(), + "aws_appmesh_virtual_node": resourceAwsAppmeshVirtualNode(), + "aws_appmesh_virtual_router": resourceAwsAppmeshVirtualRouter(), + "aws_appmesh_virtual_service": resourceAwsAppmeshVirtualService(), + "aws_apprunner_auto_scaling_configuration_version": resourceAwsAppRunnerAutoScalingConfigurationVersion(), + "aws_apprunner_connection": resourceAwsAppRunnerConnection(), + "aws_apprunner_custom_domain_association": resourceAwsAppRunnerCustomDomainAssociation(), + "aws_apprunner_service": resourceAwsAppRunnerService(), + "aws_appstream_stack": resourceAwsAppStreamStack(), + "aws_appstream_fleet": resourceAwsAppStreamFleet(), + "aws_appsync_api_key": resourceAwsAppsyncApiKey(), + "aws_appsync_datasource": resourceAwsAppsyncDatasource(), + "aws_appsync_function": resourceAwsAppsyncFunction(), + "aws_appsync_graphql_api": resourceAwsAppsyncGraphqlApi(), + "aws_appsync_resolver": resourceAwsAppsyncResolver(), + "aws_athena_database": resourceAwsAthenaDatabase(), + "aws_athena_named_query": resourceAwsAthenaNamedQuery(), + "aws_athena_workgroup": resourceAwsAthenaWorkgroup(), + "aws_autoscaling_attachment": resourceAwsAutoscalingAttachment(), + "aws_autoscaling_group": resourceAwsAutoscalingGroup(), + "aws_autoscaling_group_tag": resourceAwsAutoscalingGroupTag(), + "aws_autoscaling_lifecycle_hook": resourceAwsAutoscalingLifecycleHook(), + "aws_autoscaling_notification": resourceAwsAutoscalingNotification(), + "aws_autoscaling_policy": resourceAwsAutoscalingPolicy(), + "aws_autoscaling_schedule": resourceAwsAutoscalingSchedule(), + "aws_autoscalingplans_scaling_plan": resourceAwsAutoScalingPlansScalingPlan(), + "aws_backup_global_settings": resourceAwsBackupGlobalSettings(), + "aws_backup_plan": resourceAwsBackupPlan(), + "aws_backup_region_settings": resourceAwsBackupRegionSettings(), + "aws_backup_selection": resourceAwsBackupSelection(), + "aws_backup_vault": resourceAwsBackupVault(), + "aws_backup_vault_notifications": resourceAwsBackupVaultNotifications(), + "aws_backup_vault_policy": resourceAwsBackupVaultPolicy(), + "aws_budgets_budget": resourceAwsBudgetsBudget(), + "aws_budgets_budget_action": resourceAwsBudgetsBudgetAction(), + "aws_chime_voice_connector": resourceAwsChimeVoiceConnector(), + "aws_chime_voice_connector_group": resourceAwsChimeVoiceConnectorGroup(), + "aws_chime_voice_connector_logging": resourceAwsChimeVoiceConnectorLogging(), + "aws_chime_voice_connector_streaming": resourceAwsChimeVoiceConnectorStreaming(), + "aws_chime_voice_connector_origination": resourceAwsChimeVoiceConnectorOrigination(), + "aws_chime_voice_connector_termination": resourceAwsChimeVoiceConnectorTermination(), + "aws_cloud9_environment_ec2": resourceAwsCloud9EnvironmentEc2(), + "aws_cloudformation_stack": resourceAwsCloudFormationStack(), + "aws_cloudformation_stack_set": resourceAwsCloudFormationStackSet(), + "aws_cloudformation_stack_set_instance": resourceAwsCloudFormationStackSetInstance(), + "aws_cloudformation_type": resourceAwsCloudFormationType(), + "aws_cloudfront_cache_policy": resourceAwsCloudFrontCachePolicy(), + "aws_cloudfront_distribution": resourceAwsCloudFrontDistribution(), + "aws_cloudfront_function": resourceAwsCloudFrontFunction(), + "aws_cloudfront_key_group": resourceAwsCloudFrontKeyGroup(), + "aws_cloudfront_monitoring_subscription": resourceAwsCloudFrontMonitoringSubscription(), + "aws_cloudfront_origin_access_identity": resourceAwsCloudFrontOriginAccessIdentity(), + "aws_cloudfront_origin_request_policy": resourceAwsCloudFrontOriginRequestPolicy(), + "aws_cloudfront_public_key": resourceAwsCloudFrontPublicKey(), + "aws_cloudfront_realtime_log_config": resourceAwsCloudFrontRealtimeLogConfig(), + "aws_cloudtrail": resourceAwsCloudTrail(), + "aws_cloudwatch_event_bus": resourceAwsCloudWatchEventBus(), + "aws_cloudwatch_event_bus_policy": resourceAwsCloudWatchEventBusPolicy(), + "aws_cloudwatch_event_permission": resourceAwsCloudWatchEventPermission(), + "aws_cloudwatch_event_rule": resourceAwsCloudWatchEventRule(), + "aws_cloudwatch_event_target": resourceAwsCloudWatchEventTarget(), + "aws_cloudwatch_event_archive": resourceAwsCloudWatchEventArchive(), + "aws_cloudwatch_event_connection": resourceAwsCloudWatchEventConnection(), + "aws_cloudwatch_event_api_destination": resourceAwsCloudWatchEventApiDestination(), + "aws_cloudwatch_log_destination": resourceAwsCloudWatchLogDestination(), + "aws_cloudwatch_log_destination_policy": resourceAwsCloudWatchLogDestinationPolicy(), + "aws_cloudwatch_log_group": resourceAwsCloudWatchLogGroup(), + "aws_cloudwatch_log_metric_filter": resourceAwsCloudWatchLogMetricFilter(), + "aws_cloudwatch_log_resource_policy": resourceAwsCloudWatchLogResourcePolicy(), + "aws_cloudwatch_log_stream": resourceAwsCloudWatchLogStream(), + "aws_cloudwatch_log_subscription_filter": resourceAwsCloudwatchLogSubscriptionFilter(), + "aws_config_aggregate_authorization": resourceAwsConfigAggregateAuthorization(), + "aws_config_config_rule": resourceAwsConfigConfigRule(), + "aws_config_configuration_aggregator": resourceAwsConfigConfigurationAggregator(), + "aws_config_configuration_recorder": resourceAwsConfigConfigurationRecorder(), + "aws_config_configuration_recorder_status": resourceAwsConfigConfigurationRecorderStatus(), + "aws_config_conformance_pack": resourceAwsConfigConformancePack(), + "aws_config_delivery_channel": resourceAwsConfigDeliveryChannel(), + "aws_config_organization_conformance_pack": resourceAwsConfigOrganizationConformancePack(), + "aws_config_organization_custom_rule": resourceAwsConfigOrganizationCustomRule(), + "aws_config_organization_managed_rule": resourceAwsConfigOrganizationManagedRule(), + "aws_config_remediation_configuration": resourceAwsConfigRemediationConfiguration(), + "aws_cognito_identity_pool": resourceAwsCognitoIdentityPool(), + "aws_cognito_identity_pool_roles_attachment": resourceAwsCognitoIdentityPoolRolesAttachment(), + "aws_cognito_identity_provider": resourceAwsCognitoIdentityProvider(), + "aws_cognito_resource_server": resourceAwsCognitoResourceServer(), + "aws_cognito_user_group": resourceAwsCognitoUserGroup(), + "aws_cognito_user_pool": resourceAwsCognitoUserPool(), + "aws_cognito_user_pool_client": resourceAwsCognitoUserPoolClient(), + "aws_cognito_user_pool_domain": resourceAwsCognitoUserPoolDomain(), + "aws_cognito_user_pool_ui_customization": resourceAwsCognitoUserPoolUICustomization(), + "aws_cloudhsm_v2_cluster": resourceAwsCloudHsmV2Cluster(), + "aws_cloudhsm_v2_hsm": resourceAwsCloudHsmV2Hsm(), + "aws_cloudwatch_composite_alarm": resourceAwsCloudWatchCompositeAlarm(), + "aws_cloudwatch_metric_alarm": resourceAwsCloudWatchMetricAlarm(), + "aws_cloudwatch_dashboard": resourceAwsCloudWatchDashboard(), + "aws_cloudwatch_metric_stream": resourceAwsCloudWatchMetricStream(), + "aws_cloudwatch_query_definition": resourceAwsCloudWatchQueryDefinition(), + "aws_codedeploy_app": resourceAwsCodeDeployApp(), + "aws_codedeploy_deployment_config": resourceAwsCodeDeployDeploymentConfig(), + "aws_codedeploy_deployment_group": resourceAwsCodeDeployDeploymentGroup(), + "aws_codecommit_repository": resourceAwsCodeCommitRepository(), + "aws_codecommit_trigger": resourceAwsCodeCommitTrigger(), + "aws_codeartifact_domain": resourceAwsCodeArtifactDomain(), + "aws_codeartifact_domain_permissions_policy": resourceAwsCodeArtifactDomainPermissionsPolicy(), + "aws_codeartifact_repository": resourceAwsCodeArtifactRepository(), + "aws_codeartifact_repository_permissions_policy": resourceAwsCodeArtifactRepositoryPermissionsPolicy(), + "aws_codebuild_project": resourceAwsCodeBuildProject(), + "aws_codebuild_report_group": resourceAwsCodeBuildReportGroup(), + "aws_codebuild_source_credential": resourceAwsCodeBuildSourceCredential(), + "aws_codebuild_webhook": resourceAwsCodeBuildWebhook(), + "aws_codepipeline": resourceAwsCodePipeline(), + "aws_codepipeline_webhook": resourceAwsCodePipelineWebhook(), + "aws_codestarconnections_connection": resourceAwsCodeStarConnectionsConnection(), + "aws_codestarconnections_host": resourceAwsCodeStarConnectionsHost(), + "aws_codestarnotifications_notification_rule": resourceAwsCodeStarNotificationsNotificationRule(), + "aws_connect_contact_flow": resourceAwsConnectContactFlow(), + "aws_connect_instance": resourceAwsConnectInstance(), + "aws_cur_report_definition": resourceAwsCurReportDefinition(), + "aws_customer_gateway": resourceAwsCustomerGateway(), + "aws_datapipeline_pipeline": resourceAwsDataPipelinePipeline(), + "aws_datasync_agent": resourceAwsDataSyncAgent(), + "aws_datasync_location_efs": resourceAwsDataSyncLocationEfs(), + "aws_datasync_location_fsx_windows_file_system": resourceAwsDataSyncLocationFsxWindowsFileSystem(), + "aws_datasync_location_nfs": resourceAwsDataSyncLocationNfs(), + "aws_datasync_location_s3": resourceAwsDataSyncLocationS3(), + "aws_datasync_location_smb": resourceAwsDataSyncLocationSmb(), + "aws_datasync_task": resourceAwsDataSyncTask(), + "aws_dax_cluster": resourceAwsDaxCluster(), + "aws_dax_parameter_group": resourceAwsDaxParameterGroup(), + "aws_dax_subnet_group": resourceAwsDaxSubnetGroup(), + "aws_db_cluster_snapshot": resourceAwsDbClusterSnapshot(), + "aws_db_event_subscription": resourceAwsDbEventSubscription(), + "aws_db_instance": resourceAwsDbInstance(), + "aws_db_instance_role_association": resourceAwsDbInstanceRoleAssociation(), + "aws_db_option_group": resourceAwsDbOptionGroup(), + "aws_db_parameter_group": resourceAwsDbParameterGroup(), + "aws_db_proxy": resourceAwsDbProxy(), + "aws_db_proxy_default_target_group": resourceAwsDbProxyDefaultTargetGroup(), + "aws_db_proxy_endpoint": resourceAwsDbProxyEndpoint(), + "aws_db_proxy_target": resourceAwsDbProxyTarget(), + "aws_db_security_group": resourceAwsDbSecurityGroup(), + "aws_db_snapshot": resourceAwsDbSnapshot(), + "aws_db_subnet_group": resourceAwsDbSubnetGroup(), + "aws_devicefarm_project": resourceAwsDevicefarmProject(), + "aws_directory_service_directory": resourceAwsDirectoryServiceDirectory(), + "aws_directory_service_conditional_forwarder": resourceAwsDirectoryServiceConditionalForwarder(), + "aws_directory_service_log_subscription": resourceAwsDirectoryServiceLogSubscription(), + "aws_dlm_lifecycle_policy": resourceAwsDlmLifecyclePolicy(), + "aws_dms_certificate": resourceAwsDmsCertificate(), + "aws_dms_endpoint": resourceAwsDmsEndpoint(), + "aws_dms_event_subscription": resourceAwsDmsEventSubscription(), + "aws_dms_replication_instance": resourceAwsDmsReplicationInstance(), + "aws_dms_replication_subnet_group": resourceAwsDmsReplicationSubnetGroup(), + "aws_dms_replication_task": resourceAwsDmsReplicationTask(), + "aws_docdb_cluster": resourceAwsDocDBCluster(), + "aws_docdb_cluster_instance": resourceAwsDocDBClusterInstance(), + "aws_docdb_cluster_parameter_group": resourceAwsDocDBClusterParameterGroup(), + "aws_docdb_cluster_snapshot": resourceAwsDocDBClusterSnapshot(), + "aws_docdb_subnet_group": resourceAwsDocDBSubnetGroup(), + "aws_dx_bgp_peer": resourceAwsDxBgpPeer(), + "aws_dx_connection": resourceAwsDxConnection(), + "aws_dx_connection_association": resourceAwsDxConnectionAssociation(), + "aws_dx_gateway": resourceAwsDxGateway(), + "aws_dx_gateway_association": resourceAwsDxGatewayAssociation(), + "aws_dx_gateway_association_proposal": resourceAwsDxGatewayAssociationProposal(), + "aws_dx_hosted_private_virtual_interface": resourceAwsDxHostedPrivateVirtualInterface(), + "aws_dx_hosted_private_virtual_interface_accepter": resourceAwsDxHostedPrivateVirtualInterfaceAccepter(), + "aws_dx_hosted_public_virtual_interface": resourceAwsDxHostedPublicVirtualInterface(), + "aws_dx_hosted_public_virtual_interface_accepter": resourceAwsDxHostedPublicVirtualInterfaceAccepter(), + "aws_dx_hosted_transit_virtual_interface": resourceAwsDxHostedTransitVirtualInterface(), + "aws_dx_hosted_transit_virtual_interface_accepter": resourceAwsDxHostedTransitVirtualInterfaceAccepter(), + "aws_dx_lag": resourceAwsDxLag(), + "aws_dx_private_virtual_interface": resourceAwsDxPrivateVirtualInterface(), + "aws_dx_public_virtual_interface": resourceAwsDxPublicVirtualInterface(), + "aws_dx_transit_virtual_interface": resourceAwsDxTransitVirtualInterface(), + "aws_dynamodb_table": resourceAwsDynamoDbTable(), + "aws_dynamodb_table_item": resourceAwsDynamoDbTableItem(), + "aws_dynamodb_tag": resourceAwsDynamodbTag(), + "aws_dynamodb_global_table": resourceAwsDynamoDbGlobalTable(), + "aws_dynamodb_kinesis_streaming_destination": resourceAwsDynamoDbKinesisStreamingDestination(), + "aws_ebs_default_kms_key": resourceAwsEbsDefaultKmsKey(), + "aws_ebs_encryption_by_default": resourceAwsEbsEncryptionByDefault(), + "aws_ebs_snapshot": resourceAwsEbsSnapshot(), + "aws_ebs_snapshot_copy": resourceAwsEbsSnapshotCopy(), + "aws_ebs_snapshot_import": resourceAwsEbsSnapshotImport(), + "aws_ebs_volume": resourceAwsEbsVolume(), + "aws_ec2_availability_zone_group": resourceAwsEc2AvailabilityZoneGroup(), + "aws_ec2_capacity_reservation": resourceAwsEc2CapacityReservation(), + "aws_ec2_carrier_gateway": resourceAwsEc2CarrierGateway(), + "aws_ec2_client_vpn_authorization_rule": resourceAwsEc2ClientVpnAuthorizationRule(), + "aws_ec2_client_vpn_endpoint": resourceAwsEc2ClientVpnEndpoint(), + "aws_ec2_client_vpn_network_association": resourceAwsEc2ClientVpnNetworkAssociation(), + "aws_ec2_client_vpn_route": resourceAwsEc2ClientVpnRoute(), + "aws_ec2_fleet": resourceAwsEc2Fleet(), + "aws_ec2_local_gateway_route": resourceAwsEc2LocalGatewayRoute(), + "aws_ec2_local_gateway_route_table_vpc_association": resourceAwsEc2LocalGatewayRouteTableVpcAssociation(), + "aws_ec2_managed_prefix_list": resourceAwsEc2ManagedPrefixList(), + "aws_ec2_managed_prefix_list_entry": resourceAwsEc2ManagedPrefixListEntry(), + "aws_ec2_tag": resourceAwsEc2Tag(), + "aws_ec2_traffic_mirror_filter": resourceAwsEc2TrafficMirrorFilter(), + "aws_ec2_traffic_mirror_filter_rule": resourceAwsEc2TrafficMirrorFilterRule(), + "aws_ec2_traffic_mirror_target": resourceAwsEc2TrafficMirrorTarget(), + "aws_ec2_traffic_mirror_session": resourceAwsEc2TrafficMirrorSession(), + "aws_ec2_transit_gateway": resourceAwsEc2TransitGateway(), + "aws_ec2_transit_gateway_peering_attachment": resourceAwsEc2TransitGatewayPeeringAttachment(), + "aws_ec2_transit_gateway_peering_attachment_accepter": resourceAwsEc2TransitGatewayPeeringAttachmentAccepter(), + "aws_ec2_transit_gateway_prefix_list_reference": resourceAwsEc2TransitGatewayPrefixListReference(), + "aws_ec2_transit_gateway_route": resourceAwsEc2TransitGatewayRoute(), + "aws_ec2_transit_gateway_route_table": resourceAwsEc2TransitGatewayRouteTable(), + "aws_ec2_transit_gateway_route_table_association": resourceAwsEc2TransitGatewayRouteTableAssociation(), + "aws_ec2_transit_gateway_route_table_propagation": resourceAwsEc2TransitGatewayRouteTablePropagation(), + "aws_ec2_transit_gateway_vpc_attachment": resourceAwsEc2TransitGatewayVpcAttachment(), + "aws_ec2_transit_gateway_vpc_attachment_accepter": resourceAwsEc2TransitGatewayVpcAttachmentAccepter(), + "aws_ecr_lifecycle_policy": resourceAwsEcrLifecyclePolicy(), + "aws_ecrpublic_repository": resourceAwsEcrPublicRepository(), + "aws_ecr_registry_policy": resourceAwsEcrRegistryPolicy(), + "aws_ecr_replication_configuration": resourceAwsEcrReplicationConfiguration(), + "aws_ecr_repository": resourceAwsEcrRepository(), + "aws_ecr_repository_policy": resourceAwsEcrRepositoryPolicy(), + "aws_ecs_capacity_provider": resourceAwsEcsCapacityProvider(), + "aws_ecs_cluster": resourceAwsEcsCluster(), + "aws_ecs_service": resourceAwsEcsService(), + "aws_ecs_tag": resourceAwsEcsTag(), + "aws_ecs_task_definition": resourceAwsEcsTaskDefinition(), + "aws_efs_access_point": resourceAwsEfsAccessPoint(), + "aws_efs_backup_policy": resourceAwsEfsBackupPolicy(), + "aws_efs_file_system": resourceAwsEfsFileSystem(), + "aws_efs_file_system_policy": resourceAwsEfsFileSystemPolicy(), + "aws_efs_mount_target": resourceAwsEfsMountTarget(), + "aws_egress_only_internet_gateway": resourceAwsEgressOnlyInternetGateway(), + "aws_eip": resourceAwsEip(), + "aws_eip_association": resourceAwsEipAssociation(), + "aws_eks_cluster": resourceAwsEksCluster(), + "aws_eks_addon": resourceAwsEksAddon(), + "aws_eks_fargate_profile": resourceAwsEksFargateProfile(), + "aws_eks_identity_provider_config": resourceAwsEksIdentityProviderConfig(), + "aws_eks_node_group": resourceAwsEksNodeGroup(), + "aws_elasticache_cluster": resourceAwsElasticacheCluster(), + "aws_elasticache_global_replication_group": resourceAwsElasticacheGlobalReplicationGroup(), + "aws_elasticache_parameter_group": resourceAwsElasticacheParameterGroup(), + "aws_elasticache_replication_group": resourceAwsElasticacheReplicationGroup(), + "aws_elasticache_security_group": resourceAwsElasticacheSecurityGroup(), + "aws_elasticache_subnet_group": resourceAwsElasticacheSubnetGroup(), + "aws_elasticache_user": resourceAwsElasticacheUser(), + "aws_elasticache_user_group": resourceAwsElasticacheUserGroup(), + "aws_elastic_beanstalk_application": resourceAwsElasticBeanstalkApplication(), + "aws_elastic_beanstalk_application_version": resourceAwsElasticBeanstalkApplicationVersion(), + "aws_elastic_beanstalk_configuration_template": resourceAwsElasticBeanstalkConfigurationTemplate(), + "aws_elastic_beanstalk_environment": resourceAwsElasticBeanstalkEnvironment(), + "aws_elasticsearch_domain": resourceAwsElasticSearchDomain(), + "aws_elasticsearch_domain_policy": resourceAwsElasticSearchDomainPolicy(), + "aws_elasticsearch_domain_saml_options": resourceAwsElasticSearchDomainSAMLOptions(), + "aws_elastictranscoder_pipeline": resourceAwsElasticTranscoderPipeline(), + "aws_elastictranscoder_preset": resourceAwsElasticTranscoderPreset(), + "aws_elb": resourceAwsElb(), + "aws_elb_attachment": resourceAwsElbAttachment(), + "aws_emr_cluster": resourceAwsEMRCluster(), + "aws_emr_instance_group": resourceAwsEMRInstanceGroup(), + "aws_emr_instance_fleet": resourceAwsEMRInstanceFleet(), + "aws_emr_managed_scaling_policy": resourceAwsEMRManagedScalingPolicy(), + "aws_emr_security_configuration": resourceAwsEMRSecurityConfiguration(), + "aws_flow_log": resourceAwsFlowLog(), + "aws_fsx_backup": resourceAwsFsxBackup(), + "aws_fsx_lustre_file_system": resourceAwsFsxLustreFileSystem(), + "aws_fsx_ontap_file_system": resourceAwsFsxOntapFileSystem(), + "aws_fsx_windows_file_system": resourceAwsFsxWindowsFileSystem(), + "aws_fms_admin_account": resourceAwsFmsAdminAccount(), + "aws_fms_policy": resourceAwsFmsPolicy(), + "aws_gamelift_alias": resourceAwsGameliftAlias(), + "aws_gamelift_build": resourceAwsGameliftBuild(), + "aws_gamelift_fleet": resourceAwsGameliftFleet(), + "aws_gamelift_game_session_queue": resourceAwsGameliftGameSessionQueue(), + "aws_glacier_vault": resourceAwsGlacierVault(), + "aws_glacier_vault_lock": resourceAwsGlacierVaultLock(), + "aws_globalaccelerator_accelerator": resourceAwsGlobalAcceleratorAccelerator(), + "aws_globalaccelerator_endpoint_group": resourceAwsGlobalAcceleratorEndpointGroup(), + "aws_globalaccelerator_listener": resourceAwsGlobalAcceleratorListener(), + "aws_glue_catalog_database": resourceAwsGlueCatalogDatabase(), + "aws_glue_catalog_table": resourceAwsGlueCatalogTable(), + "aws_glue_classifier": resourceAwsGlueClassifier(), + "aws_glue_connection": resourceAwsGlueConnection(), + "aws_glue_dev_endpoint": resourceAwsGlueDevEndpoint(), + "aws_glue_crawler": resourceAwsGlueCrawler(), + "aws_glue_data_catalog_encryption_settings": resourceAwsGlueDataCatalogEncryptionSettings(), + "aws_glue_job": resourceAwsGlueJob(), + "aws_glue_ml_transform": resourceAwsGlueMLTransform(), + "aws_glue_partition": resourceAwsGluePartition(), + "aws_glue_registry": resourceAwsGlueRegistry(), + "aws_glue_resource_policy": resourceAwsGlueResourcePolicy(), + "aws_glue_schema": resourceAwsGlueSchema(), + "aws_glue_security_configuration": resourceAwsGlueSecurityConfiguration(), + "aws_glue_trigger": resourceAwsGlueTrigger(), + "aws_glue_user_defined_function": resourceAwsGlueUserDefinedFunction(), + "aws_glue_workflow": resourceAwsGlueWorkflow(), + "aws_guardduty_detector": resourceAwsGuardDutyDetector(), + "aws_guardduty_filter": resourceAwsGuardDutyFilter(), + "aws_guardduty_invite_accepter": resourceAwsGuardDutyInviteAccepter(), + "aws_guardduty_ipset": resourceAwsGuardDutyIpset(), + "aws_guardduty_member": resourceAwsGuardDutyMember(), + "aws_guardduty_organization_admin_account": resourceAwsGuardDutyOrganizationAdminAccount(), + "aws_guardduty_organization_configuration": resourceAwsGuardDutyOrganizationConfiguration(), + "aws_guardduty_publishing_destination": resourceAwsGuardDutyPublishingDestination(), + "aws_guardduty_threatintelset": resourceAwsGuardDutyThreatintelset(), + "aws_iam_access_key": resourceAwsIamAccessKey(), + "aws_iam_account_alias": resourceAwsIamAccountAlias(), + "aws_iam_account_password_policy": resourceAwsIamAccountPasswordPolicy(), + "aws_iam_group_policy": resourceAwsIamGroupPolicy(), + "aws_iam_group": resourceAwsIamGroup(), + "aws_iam_group_membership": resourceAwsIamGroupMembership(), + "aws_iam_group_policy_attachment": resourceAwsIamGroupPolicyAttachment(), + "aws_iam_instance_profile": resourceAwsIamInstanceProfile(), + "aws_iam_openid_connect_provider": resourceAwsIamOpenIDConnectProvider(), + "aws_iam_policy": resourceAwsIamPolicy(), + "aws_iam_policy_attachment": resourceAwsIamPolicyAttachment(), + "aws_iam_role_policy_attachment": resourceAwsIamRolePolicyAttachment(), + "aws_iam_role_policy": resourceAwsIamRolePolicy(), + "aws_iam_role": resourceAwsIamRole(), + "aws_iam_saml_provider": resourceAwsIamSamlProvider(), + "aws_iam_server_certificate": resourceAwsIAMServerCertificate(), + "aws_iam_service_linked_role": resourceAwsIamServiceLinkedRole(), + "aws_iam_user_group_membership": resourceAwsIamUserGroupMembership(), + "aws_iam_user_policy_attachment": resourceAwsIamUserPolicyAttachment(), + "aws_iam_user_policy": resourceAwsIamUserPolicy(), + "aws_iam_user_ssh_key": resourceAwsIamUserSshKey(), + "aws_iam_user": resourceAwsIamUser(), + "aws_iam_user_login_profile": resourceAwsIamUserLoginProfile(), + "aws_imagebuilder_component": resourceAwsImageBuilderComponent(), + "aws_imagebuilder_distribution_configuration": resourceAwsImageBuilderDistributionConfiguration(), + "aws_imagebuilder_image": resourceAwsImageBuilderImage(), + "aws_imagebuilder_image_pipeline": resourceAwsImageBuilderImagePipeline(), + "aws_imagebuilder_image_recipe": resourceAwsImageBuilderImageRecipe(), + "aws_imagebuilder_infrastructure_configuration": resourceAwsImageBuilderInfrastructureConfiguration(), + "aws_inspector_assessment_target": resourceAWSInspectorAssessmentTarget(), + "aws_inspector_assessment_template": resourceAWSInspectorAssessmentTemplate(), + "aws_inspector_resource_group": resourceAWSInspectorResourceGroup(), + "aws_instance": resourceAwsInstance(), + "aws_internet_gateway": resourceAwsInternetGateway(), + "aws_iot_certificate": resourceAwsIotCertificate(), + "aws_iot_policy": resourceAwsIotPolicy(), + "aws_iot_policy_attachment": resourceAwsIotPolicyAttachment(), + "aws_iot_thing": resourceAwsIotThing(), + "aws_iot_thing_principal_attachment": resourceAwsIotThingPrincipalAttachment(), + "aws_iot_thing_type": resourceAwsIotThingType(), + "aws_iot_topic_rule": resourceAwsIotTopicRule(), + "aws_iot_role_alias": resourceAwsIotRoleAlias(), + "aws_key_pair": resourceAwsKeyPair(), + "aws_kinesis_analytics_application": resourceAwsKinesisAnalyticsApplication(), + "aws_kinesisanalyticsv2_application": resourceAwsKinesisAnalyticsV2Application(), + "aws_kinesisanalyticsv2_application_snapshot": resourceAwsKinesisAnalyticsV2ApplicationSnapshot(), + "aws_kinesis_firehose_delivery_stream": resourceAwsKinesisFirehoseDeliveryStream(), + "aws_kinesis_stream": resourceAwsKinesisStream(), + "aws_kinesis_stream_consumer": resourceAwsKinesisStreamConsumer(), + "aws_kinesis_video_stream": resourceAwsKinesisVideoStream(), + "aws_kms_alias": resourceAwsKmsAlias(), + "aws_kms_external_key": resourceAwsKmsExternalKey(), + "aws_kms_grant": resourceAwsKmsGrant(), + "aws_kms_key": resourceAwsKmsKey(), + "aws_kms_ciphertext": resourceAwsKmsCiphertext(), + "aws_lakeformation_data_lake_settings": resourceAwsLakeFormationDataLakeSettings(), + "aws_lakeformation_permissions": resourceAwsLakeFormationPermissions(), + "aws_lakeformation_resource": resourceAwsLakeFormationResource(), + "aws_lambda_alias": resourceAwsLambdaAlias(), + "aws_lambda_code_signing_config": resourceAwsLambdaCodeSigningConfig(), + "aws_lambda_event_source_mapping": resourceAwsLambdaEventSourceMapping(), + "aws_lambda_function_event_invoke_config": resourceAwsLambdaFunctionEventInvokeConfig(), + "aws_lambda_function": resourceAwsLambdaFunction(), + "aws_lambda_layer_version": resourceAwsLambdaLayerVersion(), + "aws_lambda_permission": resourceAwsLambdaPermission(), + "aws_lambda_provisioned_concurrency_config": resourceAwsLambdaProvisionedConcurrencyConfig(), + "aws_launch_configuration": resourceAwsLaunchConfiguration(), + "aws_launch_template": resourceAwsLaunchTemplate(), + "aws_lex_bot": resourceAwsLexBot(), + "aws_lex_bot_alias": resourceAwsLexBotAlias(), + "aws_lex_intent": resourceAwsLexIntent(), + "aws_lex_slot_type": resourceAwsLexSlotType(), + "aws_licensemanager_association": resourceAwsLicenseManagerAssociation(), + "aws_licensemanager_license_configuration": resourceAwsLicenseManagerLicenseConfiguration(), + "aws_lightsail_domain": resourceAwsLightsailDomain(), + "aws_lightsail_instance": resourceAwsLightsailInstance(), + "aws_lightsail_instance_public_ports": resourceAwsLightsailInstancePublicPorts(), + "aws_lightsail_key_pair": resourceAwsLightsailKeyPair(), + "aws_lightsail_static_ip": resourceAwsLightsailStaticIp(), + "aws_lightsail_static_ip_attachment": resourceAwsLightsailStaticIpAttachment(), + "aws_lb_cookie_stickiness_policy": resourceAwsLBCookieStickinessPolicy(), + "aws_load_balancer_policy": resourceAwsLoadBalancerPolicy(), + "aws_load_balancer_backend_server_policy": resourceAwsLoadBalancerBackendServerPolicies(), + "aws_load_balancer_listener_policy": resourceAwsLoadBalancerListenerPolicies(), + "aws_lb_ssl_negotiation_policy": resourceAwsLBSSLNegotiationPolicy(), + "aws_macie2_account": resourceAwsMacie2Account(), + "aws_macie2_classification_job": resourceAwsMacie2ClassificationJob(), + "aws_macie2_custom_data_identifier": resourceAwsMacie2CustomDataIdentifier(), + "aws_macie2_findings_filter": resourceAwsMacie2FindingsFilter(), + "aws_macie2_invitation_accepter": resourceAwsMacie2InvitationAccepter(), + "aws_macie2_member": resourceAwsMacie2Member(), + "aws_macie2_organization_admin_account": resourceAwsMacie2OrganizationAdminAccount(), + "aws_macie_member_account_association": resourceAwsMacieMemberAccountAssociation(), + "aws_macie_s3_bucket_association": resourceAwsMacieS3BucketAssociation(), + "aws_main_route_table_association": resourceAwsMainRouteTableAssociation(), + "aws_mq_broker": resourceAwsMqBroker(), + "aws_mq_configuration": resourceAwsMqConfiguration(), + "aws_media_convert_queue": resourceAwsMediaConvertQueue(), + "aws_media_package_channel": resourceAwsMediaPackageChannel(), + "aws_media_store_container": resourceAwsMediaStoreContainer(), + "aws_media_store_container_policy": resourceAwsMediaStoreContainerPolicy(), + "aws_msk_cluster": resourceAwsMskCluster(), + "aws_msk_configuration": resourceAwsMskConfiguration(), + "aws_msk_scram_secret_association": resourceAwsMskScramSecretAssociation(), + "aws_mwaa_environment": resourceAwsMwaaEnvironment(), + "aws_nat_gateway": resourceAwsNatGateway(), + "aws_network_acl": resourceAwsNetworkAcl(), + "aws_default_network_acl": resourceAwsDefaultNetworkAcl(), + "aws_neptune_cluster": resourceAwsNeptuneCluster(), + "aws_neptune_cluster_endpoint": resourceAwsNeptuneClusterEndpoint(), + "aws_neptune_cluster_instance": resourceAwsNeptuneClusterInstance(), + "aws_neptune_cluster_parameter_group": resourceAwsNeptuneClusterParameterGroup(), + "aws_neptune_cluster_snapshot": resourceAwsNeptuneClusterSnapshot(), + "aws_neptune_event_subscription": resourceAwsNeptuneEventSubscription(), + "aws_neptune_parameter_group": resourceAwsNeptuneParameterGroup(), + "aws_neptune_subnet_group": resourceAwsNeptuneSubnetGroup(), + "aws_network_acl_rule": resourceAwsNetworkAclRule(), + "aws_network_interface": resourceAwsNetworkInterface(), + "aws_network_interface_attachment": resourceAwsNetworkInterfaceAttachment(), + "aws_networkfirewall_firewall": resourceAwsNetworkFirewallFirewall(), + "aws_networkfirewall_firewall_policy": resourceAwsNetworkFirewallFirewallPolicy(), + "aws_networkfirewall_logging_configuration": resourceAwsNetworkFirewallLoggingConfiguration(), + "aws_networkfirewall_resource_policy": resourceAwsNetworkFirewallResourcePolicy(), + "aws_networkfirewall_rule_group": resourceAwsNetworkFirewallRuleGroup(), + "aws_opsworks_application": resourceAwsOpsworksApplication(), + "aws_opsworks_stack": resourceAwsOpsworksStack(), + "aws_opsworks_java_app_layer": resourceAwsOpsworksJavaAppLayer(), + "aws_opsworks_haproxy_layer": resourceAwsOpsworksHaproxyLayer(), + "aws_opsworks_static_web_layer": resourceAwsOpsworksStaticWebLayer(), + "aws_opsworks_php_app_layer": resourceAwsOpsworksPhpAppLayer(), + "aws_opsworks_rails_app_layer": resourceAwsOpsworksRailsAppLayer(), + "aws_opsworks_nodejs_app_layer": resourceAwsOpsworksNodejsAppLayer(), + "aws_opsworks_memcached_layer": resourceAwsOpsworksMemcachedLayer(), + "aws_opsworks_mysql_layer": resourceAwsOpsworksMysqlLayer(), + "aws_opsworks_ganglia_layer": resourceAwsOpsworksGangliaLayer(), + "aws_opsworks_custom_layer": resourceAwsOpsworksCustomLayer(), + "aws_opsworks_instance": resourceAwsOpsworksInstance(), + "aws_opsworks_user_profile": resourceAwsOpsworksUserProfile(), + "aws_opsworks_permission": resourceAwsOpsworksPermission(), + "aws_opsworks_rds_db_instance": resourceAwsOpsworksRdsDbInstance(), + "aws_organizations_organization": resourceAwsOrganizationsOrganization(), + "aws_organizations_account": resourceAwsOrganizationsAccount(), + "aws_organizations_delegated_administrator": resourceAwsOrganizationsDelegatedAdministrator(), + "aws_organizations_policy": resourceAwsOrganizationsPolicy(), + "aws_organizations_policy_attachment": resourceAwsOrganizationsPolicyAttachment(), + "aws_organizations_organizational_unit": resourceAwsOrganizationsOrganizationalUnit(), + "aws_placement_group": resourceAwsPlacementGroup(), + "aws_prometheus_workspace": resourceAwsPrometheusWorkspace(), + "aws_proxy_protocol_policy": resourceAwsProxyProtocolPolicy(), + "aws_qldb_ledger": resourceAwsQLDBLedger(), + "aws_quicksight_group": resourceAwsQuickSightGroup(), + "aws_quicksight_group_membership": resourceAwsQuickSightGroupMembership(), + "aws_quicksight_user": resourceAwsQuickSightUser(), + "aws_ram_principal_association": resourceAwsRamPrincipalAssociation(), + "aws_ram_resource_association": resourceAwsRamResourceAssociation(), + "aws_ram_resource_share": resourceAwsRamResourceShare(), + "aws_ram_resource_share_accepter": resourceAwsRamResourceShareAccepter(), + "aws_rds_cluster": resourceAwsRDSCluster(), + "aws_rds_cluster_endpoint": resourceAwsRDSClusterEndpoint(), + "aws_rds_cluster_instance": resourceAwsRDSClusterInstance(), + "aws_rds_cluster_parameter_group": resourceAwsRDSClusterParameterGroup(), + "aws_rds_cluster_role_association": resourceAwsRDSClusterRoleAssociation(), + "aws_rds_global_cluster": resourceAwsRDSGlobalCluster(), + "aws_redshift_cluster": resourceAwsRedshiftCluster(), + "aws_redshift_security_group": resourceAwsRedshiftSecurityGroup(), + "aws_redshift_parameter_group": resourceAwsRedshiftParameterGroup(), + "aws_redshift_subnet_group": resourceAwsRedshiftSubnetGroup(), + "aws_redshift_snapshot_copy_grant": resourceAwsRedshiftSnapshotCopyGrant(), + "aws_redshift_snapshot_schedule": resourceAwsRedshiftSnapshotSchedule(), + "aws_redshift_snapshot_schedule_association": resourceAwsRedshiftSnapshotScheduleAssociation(), + "aws_redshift_event_subscription": resourceAwsRedshiftEventSubscription(), + "aws_resourcegroups_group": resourceAwsResourceGroupsGroup(), + "aws_route53_delegation_set": resourceAwsRoute53DelegationSet(), + "aws_route53_hosted_zone_dnssec": resourceAwsRoute53HostedZoneDnssec(), + "aws_route53_key_signing_key": resourceAwsRoute53KeySigningKey(), + "aws_route53_query_log": resourceAwsRoute53QueryLog(), + "aws_route53_record": resourceAwsRoute53Record(), + "aws_route53_zone_association": resourceAwsRoute53ZoneAssociation(), + "aws_route53_vpc_association_authorization": resourceAwsRoute53VPCAssociationAuthorization(), + "aws_route53_zone": resourceAwsRoute53Zone(), + "aws_route53_health_check": resourceAwsRoute53HealthCheck(), + "aws_route53_resolver_dnssec_config": resourceAwsRoute53ResolverDnssecConfig(), + "aws_route53_resolver_endpoint": resourceAwsRoute53ResolverEndpoint(), + "aws_route53_resolver_firewall_config": resourceAwsRoute53ResolverFirewallConfig(), + "aws_route53_resolver_firewall_domain_list": resourceAwsRoute53ResolverFirewallDomainList(), + "aws_route53_resolver_firewall_rule": resourceAwsRoute53ResolverFirewallRule(), + "aws_route53_resolver_firewall_rule_group": resourceAwsRoute53ResolverFirewallRuleGroup(), + "aws_route53_resolver_firewall_rule_group_association": resourceAwsRoute53ResolverFirewallRuleGroupAssociation(), + "aws_route53_resolver_query_log_config": resourceAwsRoute53ResolverQueryLogConfig(), + "aws_route53_resolver_query_log_config_association": resourceAwsRoute53ResolverQueryLogConfigAssociation(), + "aws_route53_resolver_rule_association": resourceAwsRoute53ResolverRuleAssociation(), + "aws_route53_resolver_rule": resourceAwsRoute53ResolverRule(), + "aws_route53recoverycontrolconfig_cluster": resourceAwsRoute53RecoveryControlConfigCluster(), + "aws_route53recoverycontrolconfig_control_panel": resourceAwsRoute53RecoveryControlConfigControlPanel(), + "aws_route53recoverycontrolconfig_routing_control": resourceAwsRoute53RecoveryControlConfigRoutingControl(), + "aws_route53recoverycontrolconfig_safety_rule": resourceAwsRoute53RecoveryControlConfigSafetyRule(), + "aws_route53recoveryreadiness_cell": resourceAwsRoute53RecoveryReadinessCell(), + "aws_route53recoveryreadiness_readiness_check": resourceAwsRoute53RecoveryReadinessReadinessCheck(), + "aws_route53recoveryreadiness_recovery_group": resourceAwsRoute53RecoveryReadinessRecoveryGroup(), + "aws_route53recoveryreadiness_resource_set": resourceAwsRoute53RecoveryReadinessResourceSet(), "aws_route": resourceAwsRoute(), "aws_route_table": resourceAwsRouteTable(), "aws_default_route_table": resourceAwsDefaultRouteTable(), diff --git a/aws/resource_aws_ec2_managed_prefix_list.go b/aws/resource_aws_ec2_managed_prefix_list.go index 6c7a5a65312d..0911f33a642b 100644 --- a/aws/resource_aws_ec2_managed_prefix_list.go +++ b/aws/resource_aws_ec2_managed_prefix_list.go @@ -51,6 +51,7 @@ func resourceAwsEc2ManagedPrefixList() *schema.Resource { "entry": { Type: schema.TypeSet, Optional: true, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "cidr": { diff --git a/aws/resource_aws_ec2_managed_prefix_list_entry.go b/aws/resource_aws_ec2_managed_prefix_list_entry.go new file mode 100644 index 000000000000..a8b40194ae75 --- /dev/null +++ b/aws/resource_aws_ec2_managed_prefix_list_entry.go @@ -0,0 +1,278 @@ +package aws + +import ( + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/finder" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/waiter" +) + +func resourceAwsEc2ManagedPrefixListEntry() *schema.Resource { + //lintignore:R011 + return &schema.Resource{ + Create: resourceAwsEc2ManagedPrefixListEntryCreate, + Read: resourceAwsEc2ManagedPrefixListEntryRead, + Delete: resourceAwsEc2ManagedPrefixListEntryDelete, + Importer: &schema.ResourceImporter{ + State: resourceAwsEc2ManagedPrefixListEntryImport, + }, + + Schema: map[string]*schema.Schema{ + "cidr": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.IsCIDR, + }, + "description": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringLenBetween(0, 255), + }, + "prefix_list_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "version": { + Type: schema.TypeInt, + Computed: true, + }, + }, + } +} + +func resourceAwsEc2ManagedPrefixListEntryCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + pl_id := d.Get("prefix_list_id").(string) + cidrBlock := d.Get("cidr").(string) + description := d.Get("description").(string) + + pl, err := finder.ManagedPrefixListByID(conn, pl_id) + if err != nil { + return err + } + + entry, err := expandPrefixEntry(pl, cidrBlock, description) + if err != nil { + return err + } + input := &ec2.ModifyManagedPrefixListInput{ + PrefixListId: aws.String(pl_id), + CurrentVersion: pl.Version, + } + + input.AddEntries = []*ec2.AddPrefixListEntry{(*ec2.AddPrefixListEntry)(entry)} + + _, err = conn.ModifyManagedPrefixList(input) + if err != nil { + return fmt.Errorf("error adding EC2 Managed Prefix List entry (%s): %w", d.Id(), err) + } + if _, err := waiter.ManagedPrefixListModified(conn, pl_id); err != nil { + return fmt.Errorf("error waiting for EC2 Managed Prefix List (%s) update: %w", pl_id, err) + } + + getEntriesInput := &ec2.GetManagedPrefixListEntriesInput{ + PrefixListId: pl.PrefixListId, + } + var entries []*ec2.PrefixListEntry + id := tfec2.ManagedPrefixListEntryCreateID(pl_id, cidrBlock) + log.Printf("[DEBUG] Computed EC2 Managed Prefix List entry ID %s", id) + + err = resource.Retry(waiter.ManagedPrefixListEntryCreateTimeout, func() *resource.RetryError { + + entries, err = getEc2ManagedPrefixListEntries(conn, getEntriesInput) + + if err != nil { + return resource.NonRetryableError(fmt.Errorf("error listing EC2 Managed Prefix List (%s) entries: %s", d.Id(), err)) + } + + cidr := findEntryMatch(entry, entries) + if cidr == nil { + log.Printf("[DEBUG] Unable to find matching entry (%s) for EC2 Managed Prefix List %s", + id, pl_id) + return resource.RetryableError(fmt.Errorf("No match found")) + } + + log.Printf("[DEBUG] Found entry for EC2 Managed Prefix List entry (%s): %s", id, cidr) + return nil + }) + if isResourceTimeoutError(err) { + entries, err = getEc2ManagedPrefixListEntries(conn, getEntriesInput) + + cidr := findEntryMatch(entry, entries) + if cidr == nil { + return fmt.Errorf("Error finding matching EC2 Managed Prefix List entry: %s", err) + } + } + if err != nil { + return fmt.Errorf("Error finding matching entry (%s) for EC2 Managed Prefix List %s", id, pl_id) + } + + d.SetId(id) + return resourceAwsEc2ManagedPrefixListEntryRead(d, meta) +} + +func resourceAwsEc2ManagedPrefixListEntryRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + pl_id := d.Get("prefix_list_id").(string) + cidrBlock := d.Get("cidr").(string) + description := d.Get("description").(string) + pl, err := finder.ManagedPrefixListByID(conn, pl_id) + if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidPrefixListIDNotFound) { + // The EC2 Managed Prefix List containing this entry no longer exists. + d.SetId("") + return nil + } + if err != nil { + return fmt.Errorf("Error finding EC2 Managed Prefix List (%s) for entry (%s): %s", pl_id, d.Id(), err) + } + + input := &ec2.GetManagedPrefixListEntriesInput{ + PrefixListId: pl.PrefixListId, + } + var entry *ec2.PrefixListEntry + var entries []*ec2.PrefixListEntry + entries, err = getEc2ManagedPrefixListEntries(conn, input) + + if err != nil { + return fmt.Errorf("error listing entries of EC2 Managed Prefix List (%s): %w", d.Id(), err) + } + + log.Printf("[DEBUG] Entries %v", entries) + + p, err := expandPrefixEntry(pl, cidrBlock, description) + if err != nil { + return err + } + + if len(entries) == 0 { + log.Printf("[WARN] No entries were found for EC2 Managed Prefix List (%s) looking for entry (%s)", + *pl.PrefixListName, d.Id()) + d.SetId("") + return nil + } + + entry = findEntryMatch(p, entries) + + if entry == nil { + log.Printf("[DEBUG] Unable to find matching entry (%s) for EC2 Managed Prefix List %s", + d.Id(), pl_id) + d.SetId("") + return nil + } + + log.Printf("[DEBUG] Found entry for EC2 Managed Prefix List (%s): %s", pl_id, entry) + + d.Set("cidr", entry.Cidr) + d.Set("description", entry.Description) + d.Set("version", pl.Version) + + return nil +} + +func resourceAwsEc2ManagedPrefixListEntryDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).ec2conn + pl_id := d.Get("prefix_list_id").(string) + cidrBlock := d.Get("cidr").(string) + description := d.Get("description").(string) + + pl, err := finder.ManagedPrefixListByID(conn, pl_id) + if err != nil { + return err + } + + entry, err := expandPrefixEntry(pl, cidrBlock, description) + if err != nil { + return err + } + input := &ec2.ModifyManagedPrefixListInput{ + CurrentVersion: pl.Version, + PrefixListId: pl.PrefixListId, + RemoveEntries: []*ec2.RemovePrefixListEntry{{Cidr: entry.Cidr}}, + } + + _, err = conn.ModifyManagedPrefixList(input) + + if err != nil { + return fmt.Errorf("error deleting EC2 Managed Prefix List entry (%s): %w", d.Id(), err) + } + + _, err = waiter.ManagedPrefixListModified(conn, pl_id) + + if err != nil { + return fmt.Errorf("error waiting for EC2 Managed Prefix List entry (%s) deletion: %w", d.Id(), err) + } + + return nil +} + +func findEntryMatch(e *ec2.PrefixListEntry, entries []*ec2.PrefixListEntry) *ec2.PrefixListEntry { + var entry *ec2.PrefixListEntry + for _, r := range entries { + if e.Cidr != nil && r.Cidr != nil && *e.Cidr != *r.Cidr { + continue + } + + entry = r + } + return entry +} + +func expandPrefixEntry(pl *ec2.ManagedPrefixList, cidrBlock string, description string) (*ec2.PrefixListEntry, error) { + var apiObject ec2.PrefixListEntry + + if description != "" { + apiObject.Description = aws.String(description) + } + + var err error + switch *pl.AddressFamily { + case "IPv4": + err = validateIpv4CIDRBlock(cidrBlock) + case "IPv6": + err = validateIpv6CIDRBlock(cidrBlock) + } + if err != nil { + return nil, err + } + apiObject.Cidr = aws.String(cidrBlock) + + return &apiObject, nil +} + +func resourceAwsEc2ManagedPrefixListEntryImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + prefixListID, cidrBlock, err := tfec2.ManagedPrefixListEntryParseID(d.Id()) + if err != nil { + return nil, err + } + + d.Set("prefix_list_id", prefixListID) + d.Set("cidr", cidrBlock) + d.SetId(tfec2.ManagedPrefixListEntryCreateID(prefixListID, cidrBlock)) + + return []*schema.ResourceData{d}, nil +} + +func getEc2ManagedPrefixListEntries(conn *ec2.EC2, input *ec2.GetManagedPrefixListEntriesInput) ([]*ec2.PrefixListEntry, error) { + var entries []*ec2.PrefixListEntry + err := conn.GetManagedPrefixListEntriesPages(input, func(page *ec2.GetManagedPrefixListEntriesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + entries = append(entries, page.Entries...) + + return !lastPage + }) + return entries, err +} diff --git a/aws/resource_aws_ec2_managed_prefix_list_entry_test.go b/aws/resource_aws_ec2_managed_prefix_list_entry_test.go new file mode 100644 index 000000000000..ada486694d3d --- /dev/null +++ b/aws/resource_aws_ec2_managed_prefix_list_entry_test.go @@ -0,0 +1,431 @@ +package aws + +import ( + "fmt" + "log" + "regexp" + "strings" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/awserr" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" +) + +func TestAccAwsEc2ManagedPrefixListEntry_ipv4(t *testing.T) { + var managedPrefixList ec2.ManagedPrefixList + var managedPrefixListEntries []*ec2.PrefixListEntry + entry := &ec2.PrefixListEntry{ + Cidr: aws.String("10.0.0.0/8"), + } + rName := acctest.RandomWithPrefix("tf-acc-test") + + testEntryCount := func(*terraform.State) error { + if len(managedPrefixListEntries) != 1 { + return fmt.Errorf("Wrong EC2 Managed Prefix List Entry count, expected %d, got %d", + 1, len(managedPrefixListEntries)) + } + + entry := managedPrefixListEntries[0] + if *entry.Cidr != "10.0.0.0/8" { + return fmt.Errorf("Wrong EC2 Managed Prefix List Entry, expected %v, got %v", + "10.0.0.0/8", *entry.Cidr) + } + + return nil + } + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsEc2ManagedPrefixListEntryIpv4Config(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &managedPrefixList, &managedPrefixListEntries), + testAccCheckAWSEc2ManagedPrefixListEntryAttributes("aws_ec2_managed_prefix_list_entry.entry_1", &managedPrefixListEntries, entry), + resource.TestCheckResourceAttrPair( + "aws_ec2_managed_prefix_list_entry.entry_1", "prefix_list_id", "aws_ec2_managed_prefix_list.web", "id"), + resource.TestCheckResourceAttr( + "aws_ec2_managed_prefix_list_entry.entry_1", "cidr", "10.0.0.0/8"), + testEntryCount, + ), + }, + { + ResourceName: "aws_ec2_managed_prefix_list_entry.entry_1", + ImportState: true, + ImportStateIdFunc: testAccAwsEc2ManagedPrefixListEntryImportStateIdFunc("aws_ec2_managed_prefix_list_entry.entry_1"), + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAwsEc2ManagedPrefixListEntry_ipv6(t *testing.T) { + var managedPrefixList ec2.ManagedPrefixList + var managedPrefixListEntries []*ec2.PrefixListEntry + entry := &ec2.PrefixListEntry{ + Cidr: aws.String("::/0"), + } + + rName := acctest.RandomWithPrefix("tf-acc-test") + entryName := "aws_ec2_managed_prefix_list_entry.entry_1" + + testEntryCount := func(*terraform.State) error { + if len(managedPrefixListEntries) != 1 { + return fmt.Errorf("Wrong EC2 Managed Prefix List Entry count, expected %d, got %d", + 1, len(managedPrefixListEntries)) + } + + entry := managedPrefixListEntries[0] + if *entry.Cidr != "::/0" { + return fmt.Errorf("Wrong EC2 Managed Prefix List Entry, expected %v, got %v", + "::/0", *entry.Cidr) + } + + return nil + } + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsEc2ManagedPrefixListEntryIpv6Config(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &managedPrefixList, &managedPrefixListEntries), + testAccCheckAWSEc2ManagedPrefixListEntryAttributes("aws_ec2_managed_prefix_list_entry.entry_1", &managedPrefixListEntries, entry), + resource.TestCheckResourceAttrPair( + entryName, "prefix_list_id", "aws_ec2_managed_prefix_list.web", "id"), + resource.TestCheckResourceAttr("aws_ec2_managed_prefix_list_entry.entry_1", "cidr", "::/0"), + testEntryCount, + ), + }, + }, + }) +} + +func TestAccAwsEc2ManagedPrefixListEntry_expectInvalidTypeError(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsEc2ManagedPrefixListEntryExpectInvalidType(rName), + ExpectError: regexp.MustCompile(`invalid CIDR address: ::/244`), + }, + }, + }) +} + +func TestAccAwsEc2ManagedPrefixListEntry_expectInvalidCIDR(t *testing.T) { + rName := acctest.RandomWithPrefix("tf-acc-test") + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsEc2ManagedPrefixListEntryInvalidIPv4CIDR(rName), + ExpectError: regexp.MustCompile("invalid CIDR address: 1.2.3.4/33"), + }, + { + Config: testAccAwsEc2ManagedPrefixListEntryInvalidIPv6CIDR(rName), + ExpectError: regexp.MustCompile("invalid CIDR address: ::/244"), + }, + }, + }) +} + +func TestAccAwsEc2ManagedPrefixListEntry_description(t *testing.T) { + var managedPrefixList ec2.ManagedPrefixList + var managedPrefixListEntries []*ec2.PrefixListEntry + var entry ec2.PrefixListEntry + + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsEc2ManagedPrefixListEntryDescriptionConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &managedPrefixList, &managedPrefixListEntries), + testAccCheckAWSEc2ManagedPrefixListEntryAttributes("aws_ec2_managed_prefix_list_entry.entry_1", &managedPrefixListEntries, &entry), + resource.TestCheckResourceAttr("aws_ec2_managed_prefix_list_entry.entry_1", "description", "TF acceptance test ec2 managed prefix list entry"), + ), + }, + }, + }) +} + +func TestAccAwsEc2ManagedPrefixListEntry_disappears(t *testing.T) { + var managedPrefixList ec2.ManagedPrefixList + var managedPrefixListEntries []*ec2.PrefixListEntry + resourceName := "aws_ec2_managed_prefix_list_entry.entry_1" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckEc2ManagedPrefixList(t) }, + ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsEc2ManagedPrefixListDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAwsEc2ManagedPrefixListEntryIpv4Config(rName), + Check: resource.ComposeAggregateTestCheckFunc( + testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &managedPrefixList, &managedPrefixListEntries), + testAccCheckResourceDisappears(testAccProvider, resourceAwsEc2ManagedPrefixListEntry(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func testAccCheckAWSEc2ManagedPrefixListEntryDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).ec2conn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_ec2_managed_prefix_list" { + continue + } + + // Retrieve our list + req := &ec2.DescribePrefixListsInput{ + PrefixListIds: []*string{aws.String(rs.Primary.ID)}, + } + resp, err := conn.DescribePrefixLists(req) + if err == nil { + if len(resp.PrefixLists) > 0 && *resp.PrefixLists[0].PrefixListId == rs.Primary.ID { + return fmt.Errorf("EC2 Managed Prefix List (%s) still exists.", rs.Primary.ID) + } + + return nil + } + + ec2err, ok := err.(awserr.Error) + if !ok { + return err + } + // Confirm error code is what we want + if ec2err.Code() != "InvalidPrefixListId.NotFound" { + return err + } + } + + return nil +} + +func testAccCheckAWSEc2ManagedPrefixListExists(n string, prefixList *ec2.ManagedPrefixList, entries *[]*ec2.PrefixListEntry) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No EC2 Managed Prefix List is set") + } + + conn := testAccProvider.Meta().(*AWSClient).ec2conn + req := &ec2.DescribeManagedPrefixListsInput{ + PrefixListIds: []*string{aws.String(rs.Primary.ID)}, + } + resp, err := conn.DescribeManagedPrefixLists(req) + if err != nil { + return err + } + + if len(resp.PrefixLists) > 0 && *resp.PrefixLists[0].PrefixListId == rs.Primary.ID { + *prefixList = *resp.PrefixLists[0] + input := &ec2.GetManagedPrefixListEntriesInput{ + PrefixListId: prefixList.PrefixListId, + } + remoteEntries, err := getEc2ManagedPrefixListEntries(conn, input) + if err != nil { + return err + } + *entries = remoteEntries + log.Printf("[DEBUG] [within-tests] Entries are : %v", entries) + return nil + } + + return fmt.Errorf("EC2 Managed Prefix List Entry not found") + } +} + +func testAccCheckAWSEc2ManagedPrefixListEntryAttributes(n string, entries *[]*ec2.PrefixListEntry, entry *ec2.PrefixListEntry) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("EC2 Managed Prefix List Entry Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No EC2 Managed Prefix List Entry is set") + } + + if entry == nil { + entry = &ec2.PrefixListEntry{ + Cidr: aws.String("10.0.0.0/8"), + } + } + + var matchingEntry *ec2.PrefixListEntry + log.Printf("[DEBUG] [within-tests] Entries are : %v", entries) + if len(*entries) == 0 { + return fmt.Errorf("No Entries") + } + + for _, r := range *entries { + if entry.Cidr != nil && r.Cidr != nil && *entry.Cidr != *r.Cidr { + continue + } + + matchingEntry = r + } + + if matchingEntry != nil { + log.Printf("[DEBUG] Matching entry found : %s", matchingEntry) + return nil + } + + return fmt.Errorf("Error here\n\tlooking for %s, wasn't found in %s", entry, entries) + } +} + +func testAccAwsEc2ManagedPrefixListEntryImportStateIdFunc(resourceName string) resource.ImportStateIdFunc { + return func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("not found: %s", resourceName) + } + + plID := rs.Primary.Attributes["prefix_list_id"] + cidrBlock := rs.Primary.Attributes["cidr"] + + var parts []string + parts = append(parts, plID) + parts = append(parts, cidrBlock) + + return strings.Join(parts, ","), nil + } +} + +func testAccAwsEc2ManagedPrefixListEntryIpv4Config(rName string) string { + return fmt.Sprintf(` +resource "aws_ec2_managed_prefix_list" "web" { + name = %[1]q + address_family = "IPv4" + max_entries = 5 + + tags = { + Name = %[1]q + } +} + +resource "aws_ec2_managed_prefix_list_entry" "entry_1" { + cidr = "10.0.0.0/8" + prefix_list_id = aws_ec2_managed_prefix_list.web.id +} +`, rName) +} + +func testAccAwsEc2ManagedPrefixListEntryIpv6Config(rName string) string { + return fmt.Sprintf(` +resource "aws_ec2_managed_prefix_list" "web" { + name = %[1]q + address_family = "IPv6" + max_entries = 5 + + tags = { + Name = %[1]q + } +} + +resource "aws_ec2_managed_prefix_list_entry" "entry_1" { + cidr = "::/0" + prefix_list_id = aws_ec2_managed_prefix_list.web.id +} +`, rName) +} + +func testAccAwsEc2ManagedPrefixListEntryDescriptionConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_ec2_managed_prefix_list" "web" { + name = %[1]q + address_family = "IPv4" + max_entries = 5 + + tags = { + Name = %[1]q + } +} + +resource "aws_ec2_managed_prefix_list_entry" "entry_1" { + cidr = "10.0.0.0/8" + description = "TF acceptance test ec2 managed prefix list entry" + prefix_list_id = aws_ec2_managed_prefix_list.web.id +} +`, rName) +} + +func testAccAwsEc2ManagedPrefixListEntryExpectInvalidType(rName string) string { + return fmt.Sprintf(` +resource "aws_ec2_managed_prefix_list" "web" { + name = %[1]q + address_family = "IPv4" + max_entries = 5 +} + +resource "aws_ec2_managed_prefix_list_entry" "ipv6" { + cidr = "::/244" + prefix_list_id = aws_ec2_managed_prefix_list.web.id +} +`, rName) +} + +func testAccAwsEc2ManagedPrefixListEntryInvalidIPv4CIDR(rName string) string { + return fmt.Sprintf(` +resource "aws_ec2_managed_prefix_list" "foo" { + name = %[1]q + address_family = "IPv4" + max_entries = 5 +} + +resource "aws_ec2_managed_prefix_list_entry" "ipv4" { + cidr = "1.2.3.4/33" + prefix_list_id = aws_ec2_managed_prefix_list.foo.id +} +`, rName) +} + +func testAccAwsEc2ManagedPrefixListEntryInvalidIPv6CIDR(rName string) string { + return fmt.Sprintf(` +resource "aws_ec2_managed_prefix_list" "foo" { + name = %[1]q + address_family = "IPv6" + max_entries = 5 +} + +resource "aws_ec2_managed_prefix_list_entry" "ipv6" { + cidr = "::/244" + prefix_list_id = aws_ec2_managed_prefix_list.foo.id +} +`, rName) +} diff --git a/website/docs/r/ec2_managed_prefix_list.html.markdown b/website/docs/r/ec2_managed_prefix_list.html.markdown index 777c5cc817f5..7a795a3e62fb 100644 --- a/website/docs/r/ec2_managed_prefix_list.html.markdown +++ b/website/docs/r/ec2_managed_prefix_list.html.markdown @@ -10,6 +10,12 @@ description: |- Provides a managed prefix list resource. +~> **NOTE on Managed Prefix Lists and Managed Prefix List Entries:** Terraform +currently provides both a standalone [Managed Prefix List Entry resource](ec2_managed_prefix_list_entry.html) (a single entry), +and a Managed Prefix List resource with entries defined in-line. At this time you +cannot use a Managed Prefix List with in-line rules in conjunction with any Managed +Prefix List Entry resources. Doing so will cause a conflict of entries and will overwrite entries. + ~> **NOTE on `max_entries`:** When you reference a Prefix List in a resource, the maximum number of entries for the prefix lists counts as the same number of rules or entries for the resource. For example, if you create a prefix list with a maximum diff --git a/website/docs/r/ec2_managed_prefix_list_entry.html.markdown b/website/docs/r/ec2_managed_prefix_list_entry.html.markdown new file mode 100644 index 000000000000..fd27dd8bf208 --- /dev/null +++ b/website/docs/r/ec2_managed_prefix_list_entry.html.markdown @@ -0,0 +1,63 @@ +--- +subcategory: "VPC" +layout: "aws" +page_title: "AWS: aws_ec2_managed_prefix_list_entry" +description: |- + Provides a managed prefix list entry resource. +--- + +# Resource: aws_ec2_managed_prefix_list_entry + +Provides a managed prefix list entry resource. + +~> **NOTE on Managed Prefix Lists and Managed Prefix List Entries:** Terraform +currently provides both a standalone Managed Prefix List Entry resource (a single entry), +and a [Managed Prefix List resource](ec2_managed_prefix_list.html) with entries defined +in-line. At this time you cannot use a Managed Prefix List with in-line rules in +conjunction with any Managed Prefix List Entry resources. Doing so will cause a conflict +of entries and will overwrite entries. + +## Example Usage + +Basic usage + +```terraform +resource "aws_ec2_managed_prefix_list" "example" { + name = "All VPC CIDR-s" + address_family = "IPv4" + max_entries = 5 + + tags = { + Env = "live" + } +} + +resource "aws_ec2_managed_prefix_list_entry" "entry_1" { + cidr = aws_vpc.example.cidr_block + description = "Primary" + prefix_list_id = aws_ec2_managed_prefix_list.entry.id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `cidr` - (Required) CIDR block of this entry. +* `description` - (Optional) Description of this entry. Due to API limitations, updating only the description of an existing entry requires temporarily removing and re-adding the entry. +* `prefix_list_id` - (Required) CIDR block of this entry. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `id` - ID of the managed prefix list entry. +* `version` - Latest version of this prefix list entry. + +## Import + +Prefix Lists can be imported using the `prefix_list_id` and `cidr` separated by a `,`, e.g. + +``` +$ terraform import aws_ec2_managed_prefix_list_entry.default pl-0570a1d2d725c16be,10.0.3.0/24 +``` From 43a8f1938e026880a1eb8a923dddbfb8248df8c8 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 22 Sep 2021 15:20:55 -0400 Subject: [PATCH 2/6] Add CHANGELOG entry. --- .changelog/19394.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/19394.txt diff --git a/.changelog/19394.txt b/.changelog/19394.txt new file mode 100644 index 000000000000..6804cefb3ccd --- /dev/null +++ b/.changelog/19394.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_ec2_managed_prefix_list_entry +``` \ No newline at end of file From 883d0462f5724f86927de1912b44ca490fca9123 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 22 Sep 2021 15:22:13 -0400 Subject: [PATCH 3/6] Tweak documentation. --- website/docs/r/ec2_managed_prefix_list_entry.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/ec2_managed_prefix_list_entry.html.markdown b/website/docs/r/ec2_managed_prefix_list_entry.html.markdown index fd27dd8bf208..d37dfe19f64a 100644 --- a/website/docs/r/ec2_managed_prefix_list_entry.html.markdown +++ b/website/docs/r/ec2_managed_prefix_list_entry.html.markdown @@ -56,7 +56,7 @@ In addition to all arguments above, the following attributes are exported: ## Import -Prefix Lists can be imported using the `prefix_list_id` and `cidr` separated by a `,`, e.g. +Prefix List Entriess can be imported using the `prefix_list_id` and `cidr` separated by a `,`, e.g. ``` $ terraform import aws_ec2_managed_prefix_list_entry.default pl-0570a1d2d725c16be,10.0.3.0/24 From bd4dd547812b55bee5b10882e266af8352e04570 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Wed, 22 Sep 2021 18:02:47 -0400 Subject: [PATCH 4/6] r/aws_ec2_managed_prefix_list_entry: Use internal finder package. --- aws/internal/service/ec2/finder/finder.go | 80 ++++++- aws/internal/service/ec2/waiter/status.go | 21 +- aws/internal/service/ec2/waiter/waiter.go | 36 ++-- aws/resource_aws_ec2_managed_prefix_list.go | 41 +--- ...ource_aws_ec2_managed_prefix_list_entry.go | 201 ++++-------------- ..._aws_ec2_managed_prefix_list_entry_test.go | 184 ++++------------ ...source_aws_ec2_managed_prefix_list_test.go | 26 +-- 7 files changed, 215 insertions(+), 374 deletions(-) diff --git a/aws/internal/service/ec2/finder/finder.go b/aws/internal/service/ec2/finder/finder.go index 684fd83e6d29..6e27d49010f5 100644 --- a/aws/internal/service/ec2/finder/finder.go +++ b/aws/internal/service/ec2/finder/finder.go @@ -814,13 +814,87 @@ func ManagedPrefixListByID(conn *ec2.EC2, id string) (*ec2.ManagedPrefixList, er } output, err := conn.DescribeManagedPrefixLists(input) + + if tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidPrefixListIDNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } + } + if err != nil { return nil, err } - if output == nil || len(output.PrefixLists) == 0 { - return nil, nil + if output == nil || len(output.PrefixLists) == 0 || output.PrefixLists[0] == nil { + return nil, tfresource.NewEmptyResultError(input) + } + + if count := len(output.PrefixLists); count > 1 { + return nil, tfresource.NewTooManyResultsError(count, input) + } + + prefixList := output.PrefixLists[0] + + if state := aws.StringValue(prefixList.State); state == ec2.PrefixListStateDeleteComplete { + return nil, &resource.NotFoundError{ + Message: state, + LastRequest: input, + } + } + + return prefixList, nil +} + +func ManagedPrefixListEntriesByID(conn *ec2.EC2, id string) ([]*ec2.PrefixListEntry, error) { + input := &ec2.GetManagedPrefixListEntriesInput{ + PrefixListId: aws.String(id), + } + + var prefixListEntries []*ec2.PrefixListEntry + + err := conn.GetManagedPrefixListEntriesPages(input, func(page *ec2.GetManagedPrefixListEntriesOutput, lastPage bool) bool { + if page == nil { + return !lastPage + } + + for _, entry := range page.Entries { + if entry == nil { + continue + } + + prefixListEntries = append(prefixListEntries, entry) + } + + return !lastPage + }) + + if tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidPrefixListIDNotFound) { + return nil, &resource.NotFoundError{ + LastError: err, + LastRequest: input, + } } - return output.PrefixLists[0], nil + if err != nil { + return nil, err + } + + return prefixListEntries, nil +} + +func ManagedPrefixListEntryByIDAndCIDR(conn *ec2.EC2, id, cidr string) (*ec2.PrefixListEntry, error) { + prefixListEntries, err := ManagedPrefixListEntriesByID(conn, id) + + if err != nil { + return nil, err + } + + for _, entry := range prefixListEntries { + if aws.StringValue(entry.Cidr) == cidr { + return entry, nil + } + } + + return nil, &resource.NotFoundError{} } diff --git a/aws/internal/service/ec2/waiter/status.go b/aws/internal/service/ec2/waiter/status.go index 6547d450c0ad..d8300e160851 100644 --- a/aws/internal/service/ec2/waiter/status.go +++ b/aws/internal/service/ec2/waiter/status.go @@ -481,22 +481,19 @@ func VpnGatewayVpcAttachmentState(conn *ec2.EC2, vpnGatewayID, vpcID string) res } } -const ( - managedPrefixListStateNotFound = "NotFound" - managedPrefixListStateUnknown = "Unknown" -) - -func ManagedPrefixListState(conn *ec2.EC2, prefixListId string) resource.StateRefreshFunc { +func ManagedPrefixListState(conn *ec2.EC2, id string) resource.StateRefreshFunc { return func() (interface{}, string, error) { - managedPrefixList, err := finder.ManagedPrefixListByID(conn, prefixListId) - if err != nil { - return nil, managedPrefixListStateUnknown, err + output, err := finder.ManagedPrefixListByID(conn, id) + + if tfresource.NotFound(err) { + return nil, "", nil } - if managedPrefixList == nil { - return nil, managedPrefixListStateNotFound, nil + + if err != nil { + return nil, "", err } - return managedPrefixList, aws.StringValue(managedPrefixList.State), nil + return output, aws.StringValue(output.State), nil } } diff --git a/aws/internal/service/ec2/waiter/waiter.go b/aws/internal/service/ec2/waiter/waiter.go index e96442eda81e..04bc48f130c6 100644 --- a/aws/internal/service/ec2/waiter/waiter.go +++ b/aws/internal/service/ec2/waiter/waiter.go @@ -638,59 +638,67 @@ const ( ManagedPrefixListTimeout = 15 * time.Minute ) -func ManagedPrefixListCreated(conn *ec2.EC2, prefixListId string) (*ec2.ManagedPrefixList, error) { +func ManagedPrefixListCreated(conn *ec2.EC2, id string) (*ec2.ManagedPrefixList, error) { stateConf := &resource.StateChangeConf{ Pending: []string{ec2.PrefixListStateCreateInProgress}, Target: []string{ec2.PrefixListStateCreateComplete}, Timeout: ManagedPrefixListTimeout, - Refresh: ManagedPrefixListState(conn, prefixListId), + Refresh: ManagedPrefixListState(conn, id), } outputRaw, err := stateConf.WaitForState() if output, ok := outputRaw.(*ec2.ManagedPrefixList); ok { + if state := aws.StringValue(output.State); state == ec2.PrefixListStateCreateFailed { + tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateMessage))) + } + return output, err } return nil, err } -func ManagedPrefixListModified(conn *ec2.EC2, prefixListId string) (*ec2.ManagedPrefixList, error) { +func ManagedPrefixListModified(conn *ec2.EC2, id string) (*ec2.ManagedPrefixList, error) { stateConf := &resource.StateChangeConf{ Pending: []string{ec2.PrefixListStateModifyInProgress}, Target: []string{ec2.PrefixListStateModifyComplete}, Timeout: ManagedPrefixListTimeout, - Refresh: ManagedPrefixListState(conn, prefixListId), + Refresh: ManagedPrefixListState(conn, id), } outputRaw, err := stateConf.WaitForState() if output, ok := outputRaw.(*ec2.ManagedPrefixList); ok { + if state := aws.StringValue(output.State); state == ec2.PrefixListStateModifyFailed { + tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateMessage))) + } + return output, err } return nil, err } -func ManagedPrefixListDeleted(conn *ec2.EC2, prefixListId string) error { +func ManagedPrefixListDeleted(conn *ec2.EC2, id string) (*ec2.ManagedPrefixList, error) { stateConf := &resource.StateChangeConf{ Pending: []string{ec2.PrefixListStateDeleteInProgress}, - Target: []string{ec2.PrefixListStateDeleteComplete}, + Target: []string{}, Timeout: ManagedPrefixListTimeout, - Refresh: ManagedPrefixListState(conn, prefixListId), + Refresh: ManagedPrefixListState(conn, id), } - _, err := stateConf.WaitForState() + outputRaw, err := stateConf.WaitForState() - if tfawserr.ErrCodeEquals(err, "InvalidPrefixListID.NotFound") { - return nil - } + if output, ok := outputRaw.(*ec2.ManagedPrefixList); ok { + if state := aws.StringValue(output.State); state == ec2.PrefixListStateDeleteFailed { + tfresource.SetLastError(err, errors.New(aws.StringValue(output.StateMessage))) + } - if err != nil { - return err + return output, err } - return nil + return nil, err } func VpcEndpointAccepted(conn *ec2.EC2, vpcEndpointID string, timeout time.Duration) (*ec2.VpcEndpoint, error) { diff --git a/aws/resource_aws_ec2_managed_prefix_list.go b/aws/resource_aws_ec2_managed_prefix_list.go index 0911f33a642b..7539fe4e8372 100644 --- a/aws/resource_aws_ec2_managed_prefix_list.go +++ b/aws/resource_aws_ec2_managed_prefix_list.go @@ -15,6 +15,7 @@ import ( tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/finder" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/waiter" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) func resourceAwsEc2ManagedPrefixList() *schema.Resource { @@ -115,9 +116,10 @@ func resourceAwsEc2ManagedPrefixListCreate(d *schema.ResourceData, meta interfac } if len(tags) > 0 { - input.TagSpecifications = ec2TagSpecificationsFromKeyValueTags(tags, "prefix-list") + input.TagSpecifications = ec2TagSpecificationsFromKeyValueTags(tags, ec2.ResourceTypePrefixList) } + log.Printf("[DEBUG] Creating EC2 Managed Prefix List: %s", input) output, err := conn.CreateManagedPrefixList(input) if err != nil { @@ -127,7 +129,7 @@ func resourceAwsEc2ManagedPrefixListCreate(d *schema.ResourceData, meta interfac d.SetId(aws.StringValue(output.PrefixList.PrefixListId)) if _, err := waiter.ManagedPrefixListCreated(conn, d.Id()); err != nil { - return fmt.Errorf("error waiting for EC2 Managed Prefix List (%s) creation: %w", d.Id(), err) + return fmt.Errorf("error waiting for EC2 Managed Prefix List (%s) create: %w", d.Id(), err) } return resourceAwsEc2ManagedPrefixListRead(d, meta) @@ -140,7 +142,7 @@ func resourceAwsEc2ManagedPrefixListRead(d *schema.ResourceData, meta interface{ pl, err := finder.ManagedPrefixListByID(conn, d.Id()) - if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidPrefixListIDNotFound) { + if !d.IsNewResource() && tfresource.NotFound(err) { log.Printf("[WARN] EC2 Managed Prefix List %s not found, removing from state", d.Id()) d.SetId("") return nil @@ -150,40 +152,17 @@ func resourceAwsEc2ManagedPrefixListRead(d *schema.ResourceData, meta interface{ return fmt.Errorf("error reading EC2 Managed Prefix List (%s): %w", d.Id(), err) } - if pl == nil { - if d.IsNewResource() { - return fmt.Errorf("error reading EC2 Managed Prefix List (%s): not found", d.Id()) - } - - log.Printf("[WARN] EC2 Managed Prefix List %s not found, removing from state", d.Id()) - d.SetId("") - return nil - } - - input := &ec2.GetManagedPrefixListEntriesInput{ - PrefixListId: pl.PrefixListId, - } - var prefixListEntries []*ec2.PrefixListEntry - - err = conn.GetManagedPrefixListEntriesPages(input, func(page *ec2.GetManagedPrefixListEntriesOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } - - prefixListEntries = append(prefixListEntries, page.Entries...) - - return !lastPage - }) + prefixListEntries, err := finder.ManagedPrefixListEntriesByID(conn, d.Id()) if err != nil { - return fmt.Errorf("error listing entries of EC2 Managed Prefix List (%s): %w", d.Id(), err) + return fmt.Errorf("error reading EC2 Managed Prefix List (%s) Entries: %w", d.Id(), err) } d.Set("address_family", pl.AddressFamily) d.Set("arn", pl.PrefixListArn) if err := d.Set("entry", flattenEc2PrefixListEntries(prefixListEntries)); err != nil { - return fmt.Errorf("error setting attribute entry of managed prefix list %s: %w", d.Id(), err) + return fmt.Errorf("error setting entry: %w", err) } d.Set("max_entries", pl.MaxEntries) @@ -340,8 +319,8 @@ func resourceAwsEc2ManagedPrefixListDelete(d *schema.ResourceData, meta interfac return fmt.Errorf("error deleting EC2 Managed Prefix List (%s): %w", d.Id(), err) } - if err := waiter.ManagedPrefixListDeleted(conn, d.Id()); err != nil { - return fmt.Errorf("error waiting for EC2 Managed Prefix List (%s) deletion: %w", d.Id(), err) + if _, err := waiter.ManagedPrefixListDeleted(conn, d.Id()); err != nil { + return fmt.Errorf("error waiting for EC2 Managed Prefix List (%s) delete: %w", d.Id(), err) } return nil diff --git a/aws/resource_aws_ec2_managed_prefix_list_entry.go b/aws/resource_aws_ec2_managed_prefix_list_entry.go index a8b40194ae75..a1477a661bc8 100644 --- a/aws/resource_aws_ec2_managed_prefix_list_entry.go +++ b/aws/resource_aws_ec2_managed_prefix_list_entry.go @@ -6,13 +6,12 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/finder" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/waiter" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) func resourceAwsEc2ManagedPrefixListEntry() *schema.Resource { @@ -53,125 +52,73 @@ func resourceAwsEc2ManagedPrefixListEntry() *schema.Resource { func resourceAwsEc2ManagedPrefixListEntryCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - pl_id := d.Get("prefix_list_id").(string) - cidrBlock := d.Get("cidr").(string) - description := d.Get("description").(string) - pl, err := finder.ManagedPrefixListByID(conn, pl_id) + cidr := d.Get("cidr").(string) + plID := d.Get("prefix_list_id").(string) + id := tfec2.ManagedPrefixListEntryCreateID(plID, cidr) + pl, err := finder.ManagedPrefixListByID(conn, plID) + if err != nil { - return err + return fmt.Errorf("error reading EC2 Managed Prefix List (%s): %w", plID, err) } - entry, err := expandPrefixEntry(pl, cidrBlock, description) - if err != nil { - return err + addPrefixListEntry := &ec2.AddPrefixListEntry{Cidr: aws.String(cidr)} + + if v, ok := d.GetOk("description"); ok { + addPrefixListEntry.Description = aws.String(v.(string)) } + input := &ec2.ModifyManagedPrefixListInput{ - PrefixListId: aws.String(pl_id), + AddEntries: []*ec2.AddPrefixListEntry{addPrefixListEntry}, CurrentVersion: pl.Version, + PrefixListId: aws.String(plID), } - input.AddEntries = []*ec2.AddPrefixListEntry{(*ec2.AddPrefixListEntry)(entry)} - _, err = conn.ModifyManagedPrefixList(input) - if err != nil { - return fmt.Errorf("error adding EC2 Managed Prefix List entry (%s): %w", d.Id(), err) - } - if _, err := waiter.ManagedPrefixListModified(conn, pl_id); err != nil { - return fmt.Errorf("error waiting for EC2 Managed Prefix List (%s) update: %w", pl_id, err) - } - getEntriesInput := &ec2.GetManagedPrefixListEntriesInput{ - PrefixListId: pl.PrefixListId, + if err != nil { + return fmt.Errorf("error creating EC2 Managed Prefix List Entry (%s): %w", id, err) } - var entries []*ec2.PrefixListEntry - id := tfec2.ManagedPrefixListEntryCreateID(pl_id, cidrBlock) - log.Printf("[DEBUG] Computed EC2 Managed Prefix List entry ID %s", id) - - err = resource.Retry(waiter.ManagedPrefixListEntryCreateTimeout, func() *resource.RetryError { - entries, err = getEc2ManagedPrefixListEntries(conn, getEntriesInput) - - if err != nil { - return resource.NonRetryableError(fmt.Errorf("error listing EC2 Managed Prefix List (%s) entries: %s", d.Id(), err)) - } - - cidr := findEntryMatch(entry, entries) - if cidr == nil { - log.Printf("[DEBUG] Unable to find matching entry (%s) for EC2 Managed Prefix List %s", - id, pl_id) - return resource.RetryableError(fmt.Errorf("No match found")) - } + d.SetId(id) - log.Printf("[DEBUG] Found entry for EC2 Managed Prefix List entry (%s): %s", id, cidr) - return nil - }) - if isResourceTimeoutError(err) { - entries, err = getEc2ManagedPrefixListEntries(conn, getEntriesInput) - - cidr := findEntryMatch(entry, entries) - if cidr == nil { - return fmt.Errorf("Error finding matching EC2 Managed Prefix List entry: %s", err) - } - } - if err != nil { - return fmt.Errorf("Error finding matching entry (%s) for EC2 Managed Prefix List %s", id, pl_id) + if _, err := waiter.ManagedPrefixListModified(conn, plID); err != nil { + return fmt.Errorf("error waiting for EC2 Managed Prefix List Entry (%s) create: %w", d.Id(), err) } - d.SetId(id) return resourceAwsEc2ManagedPrefixListEntryRead(d, meta) } func resourceAwsEc2ManagedPrefixListEntryRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - pl_id := d.Get("prefix_list_id").(string) - cidrBlock := d.Get("cidr").(string) - description := d.Get("description").(string) - pl, err := finder.ManagedPrefixListByID(conn, pl_id) - if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidPrefixListIDNotFound) { - // The EC2 Managed Prefix List containing this entry no longer exists. - d.SetId("") - return nil - } - if err != nil { - return fmt.Errorf("Error finding EC2 Managed Prefix List (%s) for entry (%s): %s", pl_id, d.Id(), err) - } - input := &ec2.GetManagedPrefixListEntriesInput{ - PrefixListId: pl.PrefixListId, - } - var entry *ec2.PrefixListEntry - var entries []*ec2.PrefixListEntry - entries, err = getEc2ManagedPrefixListEntries(conn, input) + plID, cidr, err := tfec2.ManagedPrefixListEntryParseID(d.Id()) - if err != nil { - return fmt.Errorf("error listing entries of EC2 Managed Prefix List (%s): %w", d.Id(), err) - } - - log.Printf("[DEBUG] Entries %v", entries) - - p, err := expandPrefixEntry(pl, cidrBlock, description) if err != nil { return err } - if len(entries) == 0 { - log.Printf("[WARN] No entries were found for EC2 Managed Prefix List (%s) looking for entry (%s)", - *pl.PrefixListName, d.Id()) + outputRaw, err := tfresource.RetryWhenNewResourceNotFound(waiter.ManagedPrefixListEntryCreateTimeout, func() (interface{}, error) { + return finder.ManagedPrefixListEntryByIDAndCIDR(conn, plID, cidr) + }, d.IsNewResource()) + + if !d.IsNewResource() && tfresource.NotFound(err) { + log.Printf("[WARN] EC2 Managed Prefix List Entry (%s) not found, removing from state", d.Id()) d.SetId("") return nil } - entry = findEntryMatch(p, entries) - - if entry == nil { - log.Printf("[DEBUG] Unable to find matching entry (%s) for EC2 Managed Prefix List %s", - d.Id(), pl_id) - d.SetId("") - return nil + if err != nil { + return fmt.Errorf("error reading EC2 Managed Prefix List Entry (%s): %w", d.Id(), err) } - log.Printf("[DEBUG] Found entry for EC2 Managed Prefix List (%s): %s", pl_id, entry) + entry := outputRaw.(*ec2.PrefixListEntry) + + pl, err := finder.ManagedPrefixListByID(conn, plID) + + if err != nil { + return fmt.Errorf("error reading EC2 Managed Prefix List (%s): %w", plID, err) + } d.Set("cidr", entry.Cidr) d.Set("description", entry.Description) @@ -182,97 +129,43 @@ func resourceAwsEc2ManagedPrefixListEntryRead(d *schema.ResourceData, meta inter func resourceAwsEc2ManagedPrefixListEntryDelete(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).ec2conn - pl_id := d.Get("prefix_list_id").(string) - cidrBlock := d.Get("cidr").(string) - description := d.Get("description").(string) - pl, err := finder.ManagedPrefixListByID(conn, pl_id) - if err != nil { - return err - } + plID, cidr, err := tfec2.ManagedPrefixListEntryParseID(d.Id()) - entry, err := expandPrefixEntry(pl, cidrBlock, description) if err != nil { return err } + input := &ec2.ModifyManagedPrefixListInput{ - CurrentVersion: pl.Version, - PrefixListId: pl.PrefixListId, - RemoveEntries: []*ec2.RemovePrefixListEntry{{Cidr: entry.Cidr}}, + CurrentVersion: aws.Int64(int64(d.Get("version").(int))), + PrefixListId: aws.String(plID), + RemoveEntries: []*ec2.RemovePrefixListEntry{{Cidr: aws.String(cidr)}}, } _, err = conn.ModifyManagedPrefixList(input) if err != nil { - return fmt.Errorf("error deleting EC2 Managed Prefix List entry (%s): %w", d.Id(), err) + return fmt.Errorf("error deleting EC2 Managed Prefix List Entry (%s): %w", d.Id(), err) } - _, err = waiter.ManagedPrefixListModified(conn, pl_id) + _, err = waiter.ManagedPrefixListModified(conn, plID) if err != nil { - return fmt.Errorf("error waiting for EC2 Managed Prefix List entry (%s) deletion: %w", d.Id(), err) + return fmt.Errorf("error waiting for EC2 Managed Prefix List Entry (%s) delete: %w", d.Id(), err) } return nil } -func findEntryMatch(e *ec2.PrefixListEntry, entries []*ec2.PrefixListEntry) *ec2.PrefixListEntry { - var entry *ec2.PrefixListEntry - for _, r := range entries { - if e.Cidr != nil && r.Cidr != nil && *e.Cidr != *r.Cidr { - continue - } - - entry = r - } - return entry -} - -func expandPrefixEntry(pl *ec2.ManagedPrefixList, cidrBlock string, description string) (*ec2.PrefixListEntry, error) { - var apiObject ec2.PrefixListEntry - - if description != "" { - apiObject.Description = aws.String(description) - } - - var err error - switch *pl.AddressFamily { - case "IPv4": - err = validateIpv4CIDRBlock(cidrBlock) - case "IPv6": - err = validateIpv6CIDRBlock(cidrBlock) - } - if err != nil { - return nil, err - } - apiObject.Cidr = aws.String(cidrBlock) - - return &apiObject, nil -} - func resourceAwsEc2ManagedPrefixListEntryImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - prefixListID, cidrBlock, err := tfec2.ManagedPrefixListEntryParseID(d.Id()) + plID, cidr, err := tfec2.ManagedPrefixListEntryParseID(d.Id()) + if err != nil { return nil, err } - d.Set("prefix_list_id", prefixListID) - d.Set("cidr", cidrBlock) - d.SetId(tfec2.ManagedPrefixListEntryCreateID(prefixListID, cidrBlock)) + d.Set("cidr", cidr) + d.Set("prefix_list_id", plID) return []*schema.ResourceData{d}, nil } - -func getEc2ManagedPrefixListEntries(conn *ec2.EC2, input *ec2.GetManagedPrefixListEntriesInput) ([]*ec2.PrefixListEntry, error) { - var entries []*ec2.PrefixListEntry - err := conn.GetManagedPrefixListEntriesPages(input, func(page *ec2.GetManagedPrefixListEntriesOutput, lastPage bool) bool { - if page == nil { - return !lastPage - } - - entries = append(entries, page.Entries...) - - return !lastPage - }) - return entries, err -} diff --git a/aws/resource_aws_ec2_managed_prefix_list_entry_test.go b/aws/resource_aws_ec2_managed_prefix_list_entry_test.go index ada486694d3d..33abeea2d736 100644 --- a/aws/resource_aws_ec2_managed_prefix_list_entry_test.go +++ b/aws/resource_aws_ec2_managed_prefix_list_entry_test.go @@ -2,44 +2,24 @@ package aws import ( "fmt" - "log" "regexp" - "strings" "testing" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/ec2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/finder" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) func TestAccAwsEc2ManagedPrefixListEntry_ipv4(t *testing.T) { - var managedPrefixList ec2.ManagedPrefixList - var managedPrefixListEntries []*ec2.PrefixListEntry - entry := &ec2.PrefixListEntry{ - Cidr: aws.String("10.0.0.0/8"), - } + var entry ec2.PrefixListEntry rName := acctest.RandomWithPrefix("tf-acc-test") - testEntryCount := func(*terraform.State) error { - if len(managedPrefixListEntries) != 1 { - return fmt.Errorf("Wrong EC2 Managed Prefix List Entry count, expected %d, got %d", - 1, len(managedPrefixListEntries)) - } - - entry := managedPrefixListEntries[0] - if *entry.Cidr != "10.0.0.0/8" { - return fmt.Errorf("Wrong EC2 Managed Prefix List Entry, expected %v, got %v", - "10.0.0.0/8", *entry.Cidr) - } - - return nil - } - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { testAccPreCheck(t); testAccPreCheckEc2ManagedPrefixList(t) }, ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, @@ -47,13 +27,11 @@ func TestAccAwsEc2ManagedPrefixListEntry_ipv4(t *testing.T) { { Config: testAccAwsEc2ManagedPrefixListEntryIpv4Config(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &managedPrefixList, &managedPrefixListEntries), - testAccCheckAWSEc2ManagedPrefixListEntryAttributes("aws_ec2_managed_prefix_list_entry.entry_1", &managedPrefixListEntries, entry), + testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &entry), resource.TestCheckResourceAttrPair( "aws_ec2_managed_prefix_list_entry.entry_1", "prefix_list_id", "aws_ec2_managed_prefix_list.web", "id"), resource.TestCheckResourceAttr( "aws_ec2_managed_prefix_list_entry.entry_1", "cidr", "10.0.0.0/8"), - testEntryCount, ), }, { @@ -67,32 +45,12 @@ func TestAccAwsEc2ManagedPrefixListEntry_ipv4(t *testing.T) { } func TestAccAwsEc2ManagedPrefixListEntry_ipv6(t *testing.T) { - var managedPrefixList ec2.ManagedPrefixList - var managedPrefixListEntries []*ec2.PrefixListEntry - entry := &ec2.PrefixListEntry{ - Cidr: aws.String("::/0"), - } - + var entry ec2.PrefixListEntry rName := acctest.RandomWithPrefix("tf-acc-test") entryName := "aws_ec2_managed_prefix_list_entry.entry_1" - testEntryCount := func(*terraform.State) error { - if len(managedPrefixListEntries) != 1 { - return fmt.Errorf("Wrong EC2 Managed Prefix List Entry count, expected %d, got %d", - 1, len(managedPrefixListEntries)) - } - - entry := managedPrefixListEntries[0] - if *entry.Cidr != "::/0" { - return fmt.Errorf("Wrong EC2 Managed Prefix List Entry, expected %v, got %v", - "::/0", *entry.Cidr) - } - - return nil - } - resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { testAccPreCheck(t); testAccPreCheckEc2ManagedPrefixList(t) }, ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, @@ -100,12 +58,10 @@ func TestAccAwsEc2ManagedPrefixListEntry_ipv6(t *testing.T) { { Config: testAccAwsEc2ManagedPrefixListEntryIpv6Config(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &managedPrefixList, &managedPrefixListEntries), - testAccCheckAWSEc2ManagedPrefixListEntryAttributes("aws_ec2_managed_prefix_list_entry.entry_1", &managedPrefixListEntries, entry), + testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &entry), resource.TestCheckResourceAttrPair( entryName, "prefix_list_id", "aws_ec2_managed_prefix_list.web", "id"), resource.TestCheckResourceAttr("aws_ec2_managed_prefix_list_entry.entry_1", "cidr", "::/0"), - testEntryCount, ), }, }, @@ -114,8 +70,9 @@ func TestAccAwsEc2ManagedPrefixListEntry_ipv6(t *testing.T) { func TestAccAwsEc2ManagedPrefixListEntry_expectInvalidTypeError(t *testing.T) { rName := acctest.RandomWithPrefix("tf-acc-test") + resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { testAccPreCheck(t); testAccPreCheckEc2ManagedPrefixList(t) }, ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, @@ -130,8 +87,9 @@ func TestAccAwsEc2ManagedPrefixListEntry_expectInvalidTypeError(t *testing.T) { func TestAccAwsEc2ManagedPrefixListEntry_expectInvalidCIDR(t *testing.T) { rName := acctest.RandomWithPrefix("tf-acc-test") + resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { testAccPreCheck(t); testAccPreCheckEc2ManagedPrefixList(t) }, ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, @@ -149,14 +107,11 @@ func TestAccAwsEc2ManagedPrefixListEntry_expectInvalidCIDR(t *testing.T) { } func TestAccAwsEc2ManagedPrefixListEntry_description(t *testing.T) { - var managedPrefixList ec2.ManagedPrefixList - var managedPrefixListEntries []*ec2.PrefixListEntry var entry ec2.PrefixListEntry - rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, + PreCheck: func() { testAccPreCheck(t); testAccPreCheckEc2ManagedPrefixList(t) }, ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, @@ -164,8 +119,7 @@ func TestAccAwsEc2ManagedPrefixListEntry_description(t *testing.T) { { Config: testAccAwsEc2ManagedPrefixListEntryDescriptionConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &managedPrefixList, &managedPrefixListEntries), - testAccCheckAWSEc2ManagedPrefixListEntryAttributes("aws_ec2_managed_prefix_list_entry.entry_1", &managedPrefixListEntries, &entry), + testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &entry), resource.TestCheckResourceAttr("aws_ec2_managed_prefix_list_entry.entry_1", "description", "TF acceptance test ec2 managed prefix list entry"), ), }, @@ -174,8 +128,7 @@ func TestAccAwsEc2ManagedPrefixListEntry_description(t *testing.T) { } func TestAccAwsEc2ManagedPrefixListEntry_disappears(t *testing.T) { - var managedPrefixList ec2.ManagedPrefixList - var managedPrefixListEntries []*ec2.PrefixListEntry + var entry ec2.PrefixListEntry resourceName := "aws_ec2_managed_prefix_list_entry.entry_1" rName := acctest.RandomWithPrefix("tf-acc-test") @@ -188,7 +141,7 @@ func TestAccAwsEc2ManagedPrefixListEntry_disappears(t *testing.T) { { Config: testAccAwsEc2ManagedPrefixListEntryIpv4Config(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &managedPrefixList, &managedPrefixListEntries), + testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &entry), testAccCheckResourceDisappears(testAccProvider, resourceAwsEc2ManagedPrefixListEntry(), resourceName), ), ExpectNonEmptyPlan: true, @@ -201,111 +154,60 @@ func testAccCheckAWSEc2ManagedPrefixListEntryDestroy(s *terraform.State) error { conn := testAccProvider.Meta().(*AWSClient).ec2conn for _, rs := range s.RootModule().Resources { - if rs.Type != "aws_ec2_managed_prefix_list" { + if rs.Type != "aws_ec2_managed_prefix_list_entry" { continue } - // Retrieve our list - req := &ec2.DescribePrefixListsInput{ - PrefixListIds: []*string{aws.String(rs.Primary.ID)}, - } - resp, err := conn.DescribePrefixLists(req) - if err == nil { - if len(resp.PrefixLists) > 0 && *resp.PrefixLists[0].PrefixListId == rs.Primary.ID { - return fmt.Errorf("EC2 Managed Prefix List (%s) still exists.", rs.Primary.ID) - } - - return nil - } + plID, cidr, err := tfec2.ManagedPrefixListEntryParseID(rs.Primary.ID) - ec2err, ok := err.(awserr.Error) - if !ok { - return err - } - // Confirm error code is what we want - if ec2err.Code() != "InvalidPrefixListId.NotFound" { + if err != nil { return err } - } - return nil -} - -func testAccCheckAWSEc2ManagedPrefixListExists(n string, prefixList *ec2.ManagedPrefixList, entries *[]*ec2.PrefixListEntry) resource.TestCheckFunc { - return func(s *terraform.State) error { - rs, ok := s.RootModule().Resources[n] - if !ok { - return fmt.Errorf("Not found: %s", n) - } + _, err = finder.ManagedPrefixListEntryByIDAndCIDR(conn, plID, cidr) - if rs.Primary.ID == "" { - return fmt.Errorf("No EC2 Managed Prefix List is set") + if tfresource.NotFound(err) { + continue } - conn := testAccProvider.Meta().(*AWSClient).ec2conn - req := &ec2.DescribeManagedPrefixListsInput{ - PrefixListIds: []*string{aws.String(rs.Primary.ID)}, - } - resp, err := conn.DescribeManagedPrefixLists(req) if err != nil { return err } - if len(resp.PrefixLists) > 0 && *resp.PrefixLists[0].PrefixListId == rs.Primary.ID { - *prefixList = *resp.PrefixLists[0] - input := &ec2.GetManagedPrefixListEntriesInput{ - PrefixListId: prefixList.PrefixListId, - } - remoteEntries, err := getEc2ManagedPrefixListEntries(conn, input) - if err != nil { - return err - } - *entries = remoteEntries - log.Printf("[DEBUG] [within-tests] Entries are : %v", entries) - return nil - } - - return fmt.Errorf("EC2 Managed Prefix List Entry not found") + return fmt.Errorf("EC2 Managed Prefix List Entry %s still exists", rs.Primary.ID) } + + return nil } -func testAccCheckAWSEc2ManagedPrefixListEntryAttributes(n string, entries *[]*ec2.PrefixListEntry, entry *ec2.PrefixListEntry) resource.TestCheckFunc { +func testAccCheckAWSEc2ManagedPrefixListExists(n string, v *ec2.PrefixListEntry) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { - return fmt.Errorf("EC2 Managed Prefix List Entry Not found: %s", n) + return fmt.Errorf("Not found: %s", n) } if rs.Primary.ID == "" { - return fmt.Errorf("No EC2 Managed Prefix List Entry is set") + return fmt.Errorf("No EC2 Managed Prefix List Entry ID is set") } - if entry == nil { - entry = &ec2.PrefixListEntry{ - Cidr: aws.String("10.0.0.0/8"), - } - } + conn := testAccProvider.Meta().(*AWSClient).ec2conn + + plID, cidr, err := tfec2.ManagedPrefixListEntryParseID(rs.Primary.ID) - var matchingEntry *ec2.PrefixListEntry - log.Printf("[DEBUG] [within-tests] Entries are : %v", entries) - if len(*entries) == 0 { - return fmt.Errorf("No Entries") + if err != nil { + return err } - for _, r := range *entries { - if entry.Cidr != nil && r.Cidr != nil && *entry.Cidr != *r.Cidr { - continue - } + output, err := finder.ManagedPrefixListEntryByIDAndCIDR(conn, plID, cidr) - matchingEntry = r + if err != nil { + return err } - if matchingEntry != nil { - log.Printf("[DEBUG] Matching entry found : %s", matchingEntry) - return nil - } + *v = *output - return fmt.Errorf("Error here\n\tlooking for %s, wasn't found in %s", entry, entries) + return nil } } @@ -317,13 +219,9 @@ func testAccAwsEc2ManagedPrefixListEntryImportStateIdFunc(resourceName string) r } plID := rs.Primary.Attributes["prefix_list_id"] - cidrBlock := rs.Primary.Attributes["cidr"] - - var parts []string - parts = append(parts, plID) - parts = append(parts, cidrBlock) + cidr := rs.Primary.Attributes["cidr"] - return strings.Join(parts, ","), nil + return tfec2.ManagedPrefixListEntryCreateID(plID, cidr), nil } } diff --git a/aws/resource_aws_ec2_managed_prefix_list_test.go b/aws/resource_aws_ec2_managed_prefix_list_test.go index 619811928c21..5dd9a409b80a 100644 --- a/aws/resource_aws_ec2_managed_prefix_list_test.go +++ b/aws/resource_aws_ec2_managed_prefix_list_test.go @@ -6,12 +6,11 @@ import ( "testing" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - tfec2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2" "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/ec2/finder" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource" ) func TestAccAwsEc2ManagedPrefixList_basic(t *testing.T) { @@ -309,19 +308,17 @@ func testAccCheckAwsEc2ManagedPrefixListDestroy(s *terraform.State) error { continue } - pl, err := finder.ManagedPrefixListByID(conn, rs.Primary.ID) + _, err := finder.ManagedPrefixListByID(conn, rs.Primary.ID) - if tfawserr.ErrCodeEquals(err, tfec2.ErrCodeInvalidPrefixListIDNotFound) { + if tfresource.NotFound(err) { continue } if err != nil { - return fmt.Errorf("error reading EC2 Managed Prefix List (%s): %w", rs.Primary.ID, err) + return err } - if pl != nil { - return fmt.Errorf("EC2 Managed Prefix List (%s) still exists", rs.Primary.ID) - } + return fmt.Errorf("EC2 Managed Prefix List %s still exists", rs.Primary.ID) } return nil @@ -330,25 +327,20 @@ func testAccCheckAwsEc2ManagedPrefixListDestroy(s *terraform.State) error { func testAccAwsEc2ManagedPrefixListExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return fmt.Errorf("resource %s not found", resourceName) + return fmt.Errorf("Not found: %s", resourceName) } if rs.Primary.ID == "" { - return fmt.Errorf("resource %s has not set its id", resourceName) + return fmt.Errorf("No EC2 Managed Prefix List ID is set") } conn := testAccProvider.Meta().(*AWSClient).ec2conn - pl, err := finder.ManagedPrefixListByID(conn, rs.Primary.ID) + _, err := finder.ManagedPrefixListByID(conn, rs.Primary.ID) if err != nil { - return fmt.Errorf("error reading EC2 Managed Prefix List (%s): %w", rs.Primary.ID, err) - } - - if pl == nil { - return fmt.Errorf("EC2 Managed Prefix List (%s) not found", rs.Primary.ID) + return err } return nil From 3b4e718462ff53e3a0d28fa8ed8ab1af30b9f2cd Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 23 Sep 2021 08:48:07 -0400 Subject: [PATCH 5/6] r/aws_ec2_managed_prefix_list_entry: Get acceptance tests working Acceptance test output: % make testacc TESTARGS='-run=TestAccAwsEc2ManagedPrefixListEntry_' ==> Checking that code complies with gofmt requirements... TF_ACC=1 go test ./aws -v -count 1 -parallel 20 -run=TestAccAwsEc2ManagedPrefixListEntry_ -timeout 180m === RUN TestAccAwsEc2ManagedPrefixListEntry_ipv4 === PAUSE TestAccAwsEc2ManagedPrefixListEntry_ipv4 === RUN TestAccAwsEc2ManagedPrefixListEntry_ipv6 === PAUSE TestAccAwsEc2ManagedPrefixListEntry_ipv6 === RUN TestAccAwsEc2ManagedPrefixListEntry_expectInvalidTypeError === PAUSE TestAccAwsEc2ManagedPrefixListEntry_expectInvalidTypeError === RUN TestAccAwsEc2ManagedPrefixListEntry_expectInvalidCIDR === PAUSE TestAccAwsEc2ManagedPrefixListEntry_expectInvalidCIDR === RUN TestAccAwsEc2ManagedPrefixListEntry_description === PAUSE TestAccAwsEc2ManagedPrefixListEntry_description === RUN TestAccAwsEc2ManagedPrefixListEntry_disappears === PAUSE TestAccAwsEc2ManagedPrefixListEntry_disappears === CONT TestAccAwsEc2ManagedPrefixListEntry_ipv4 === CONT TestAccAwsEc2ManagedPrefixListEntry_description === CONT TestAccAwsEc2ManagedPrefixListEntry_expectInvalidCIDR === CONT TestAccAwsEc2ManagedPrefixListEntry_expectInvalidTypeError === CONT TestAccAwsEc2ManagedPrefixListEntry_ipv6 === CONT TestAccAwsEc2ManagedPrefixListEntry_disappears --- PASS: TestAccAwsEc2ManagedPrefixListEntry_expectInvalidTypeError (3.42s) --- PASS: TestAccAwsEc2ManagedPrefixListEntry_expectInvalidCIDR (3.82s) --- PASS: TestAccAwsEc2ManagedPrefixListEntry_disappears (29.57s) --- PASS: TestAccAwsEc2ManagedPrefixListEntry_description (33.29s) --- PASS: TestAccAwsEc2ManagedPrefixListEntry_ipv4 (33.90s) --- PASS: TestAccAwsEc2ManagedPrefixListEntry_ipv6 (57.92s) PASS ok github.com/terraform-providers/terraform-provider-aws/aws 61.445s --- ..._aws_ec2_managed_prefix_list_entry_test.go | 104 +++++++++--------- 1 file changed, 55 insertions(+), 49 deletions(-) diff --git a/aws/resource_aws_ec2_managed_prefix_list_entry_test.go b/aws/resource_aws_ec2_managed_prefix_list_entry_test.go index 33abeea2d736..f59cce57a493 100644 --- a/aws/resource_aws_ec2_managed_prefix_list_entry_test.go +++ b/aws/resource_aws_ec2_managed_prefix_list_entry_test.go @@ -16,6 +16,8 @@ import ( func TestAccAwsEc2ManagedPrefixListEntry_ipv4(t *testing.T) { var entry ec2.PrefixListEntry + resourceName := "aws_ec2_managed_prefix_list_entry.test" + plResourceName := "aws_ec2_managed_prefix_list.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -27,17 +29,16 @@ func TestAccAwsEc2ManagedPrefixListEntry_ipv4(t *testing.T) { { Config: testAccAwsEc2ManagedPrefixListEntryIpv4Config(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &entry), - resource.TestCheckResourceAttrPair( - "aws_ec2_managed_prefix_list_entry.entry_1", "prefix_list_id", "aws_ec2_managed_prefix_list.web", "id"), - resource.TestCheckResourceAttr( - "aws_ec2_managed_prefix_list_entry.entry_1", "cidr", "10.0.0.0/8"), + testAccCheckAWSEc2ManagedPrefixListEntryExists(resourceName, &entry), + resource.TestCheckResourceAttrPair(resourceName, "prefix_list_id", plResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "cidr", "10.0.0.0/8"), + resource.TestCheckResourceAttr(resourceName, "description", ""), ), }, { - ResourceName: "aws_ec2_managed_prefix_list_entry.entry_1", + ResourceName: resourceName, ImportState: true, - ImportStateIdFunc: testAccAwsEc2ManagedPrefixListEntryImportStateIdFunc("aws_ec2_managed_prefix_list_entry.entry_1"), + ImportStateIdFunc: testAccAwsEc2ManagedPrefixListEntryImportStateIdFunc(resourceName), ImportStateVerify: true, }, }, @@ -46,8 +47,9 @@ func TestAccAwsEc2ManagedPrefixListEntry_ipv4(t *testing.T) { func TestAccAwsEc2ManagedPrefixListEntry_ipv6(t *testing.T) { var entry ec2.PrefixListEntry + resourceName := "aws_ec2_managed_prefix_list_entry.test" + plResourceName := "aws_ec2_managed_prefix_list.test" rName := acctest.RandomWithPrefix("tf-acc-test") - entryName := "aws_ec2_managed_prefix_list_entry.entry_1" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckEc2ManagedPrefixList(t) }, @@ -58,12 +60,18 @@ func TestAccAwsEc2ManagedPrefixListEntry_ipv6(t *testing.T) { { Config: testAccAwsEc2ManagedPrefixListEntryIpv6Config(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &entry), - resource.TestCheckResourceAttrPair( - entryName, "prefix_list_id", "aws_ec2_managed_prefix_list.web", "id"), - resource.TestCheckResourceAttr("aws_ec2_managed_prefix_list_entry.entry_1", "cidr", "::/0"), + testAccCheckAWSEc2ManagedPrefixListEntryExists(resourceName, &entry), + resource.TestCheckResourceAttrPair(resourceName, "prefix_list_id", plResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "cidr", "::/0"), + resource.TestCheckResourceAttr(resourceName, "description", ""), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccAwsEc2ManagedPrefixListEntryImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, }, }) } @@ -108,6 +116,8 @@ func TestAccAwsEc2ManagedPrefixListEntry_expectInvalidCIDR(t *testing.T) { func TestAccAwsEc2ManagedPrefixListEntry_description(t *testing.T) { var entry ec2.PrefixListEntry + resourceName := "aws_ec2_managed_prefix_list_entry.test" + plResourceName := "aws_ec2_managed_prefix_list.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ @@ -119,29 +129,37 @@ func TestAccAwsEc2ManagedPrefixListEntry_description(t *testing.T) { { Config: testAccAwsEc2ManagedPrefixListEntryDescriptionConfig(rName), Check: resource.ComposeTestCheckFunc( - testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &entry), - resource.TestCheckResourceAttr("aws_ec2_managed_prefix_list_entry.entry_1", "description", "TF acceptance test ec2 managed prefix list entry"), + testAccCheckAWSEc2ManagedPrefixListEntryExists(resourceName, &entry), + resource.TestCheckResourceAttrPair(resourceName, "prefix_list_id", plResourceName, "id"), + resource.TestCheckResourceAttr(resourceName, "cidr", "10.0.0.0/8"), + resource.TestCheckResourceAttr(resourceName, "description", rName), ), }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: testAccAwsEc2ManagedPrefixListEntryImportStateIdFunc(resourceName), + ImportStateVerify: true, + }, }, }) } func TestAccAwsEc2ManagedPrefixListEntry_disappears(t *testing.T) { var entry ec2.PrefixListEntry - resourceName := "aws_ec2_managed_prefix_list_entry.entry_1" + resourceName := "aws_ec2_managed_prefix_list_entry.test" rName := acctest.RandomWithPrefix("tf-acc-test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPreCheckEc2ManagedPrefixList(t) }, ErrorCheck: testAccErrorCheck(t, ec2.EndpointsID), Providers: testAccProviders, - CheckDestroy: testAccCheckAwsEc2ManagedPrefixListDestroy, + CheckDestroy: testAccCheckAWSEc2ManagedPrefixListEntryDestroy, Steps: []resource.TestStep{ { Config: testAccAwsEc2ManagedPrefixListEntryIpv4Config(rName), Check: resource.ComposeAggregateTestCheckFunc( - testAccCheckAWSEc2ManagedPrefixListExists("aws_ec2_managed_prefix_list.web", &entry), + testAccCheckAWSEc2ManagedPrefixListEntryExists(resourceName, &entry), testAccCheckResourceDisappears(testAccProvider, resourceAwsEc2ManagedPrefixListEntry(), resourceName), ), ExpectNonEmptyPlan: true, @@ -180,7 +198,7 @@ func testAccCheckAWSEc2ManagedPrefixListEntryDestroy(s *terraform.State) error { return nil } -func testAccCheckAWSEc2ManagedPrefixListExists(n string, v *ec2.PrefixListEntry) resource.TestCheckFunc { +func testAccCheckAWSEc2ManagedPrefixListEntryExists(n string, v *ec2.PrefixListEntry) resource.TestCheckFunc { return func(s *terraform.State) error { rs, ok := s.RootModule().Resources[n] if !ok { @@ -227,103 +245,91 @@ func testAccAwsEc2ManagedPrefixListEntryImportStateIdFunc(resourceName string) r func testAccAwsEc2ManagedPrefixListEntryIpv4Config(rName string) string { return fmt.Sprintf(` -resource "aws_ec2_managed_prefix_list" "web" { +resource "aws_ec2_managed_prefix_list" "test" { name = %[1]q address_family = "IPv4" max_entries = 5 - - tags = { - Name = %[1]q - } } -resource "aws_ec2_managed_prefix_list_entry" "entry_1" { +resource "aws_ec2_managed_prefix_list_entry" "test" { cidr = "10.0.0.0/8" - prefix_list_id = aws_ec2_managed_prefix_list.web.id + prefix_list_id = aws_ec2_managed_prefix_list.test.id } `, rName) } func testAccAwsEc2ManagedPrefixListEntryIpv6Config(rName string) string { return fmt.Sprintf(` -resource "aws_ec2_managed_prefix_list" "web" { +resource "aws_ec2_managed_prefix_list" "test" { name = %[1]q address_family = "IPv6" max_entries = 5 - - tags = { - Name = %[1]q - } } -resource "aws_ec2_managed_prefix_list_entry" "entry_1" { +resource "aws_ec2_managed_prefix_list_entry" "test" { cidr = "::/0" - prefix_list_id = aws_ec2_managed_prefix_list.web.id + prefix_list_id = aws_ec2_managed_prefix_list.test.id } `, rName) } func testAccAwsEc2ManagedPrefixListEntryDescriptionConfig(rName string) string { return fmt.Sprintf(` -resource "aws_ec2_managed_prefix_list" "web" { +resource "aws_ec2_managed_prefix_list" "test" { name = %[1]q address_family = "IPv4" max_entries = 5 - - tags = { - Name = %[1]q - } } -resource "aws_ec2_managed_prefix_list_entry" "entry_1" { +resource "aws_ec2_managed_prefix_list_entry" "test" { cidr = "10.0.0.0/8" - description = "TF acceptance test ec2 managed prefix list entry" - prefix_list_id = aws_ec2_managed_prefix_list.web.id + description = %[1]q + prefix_list_id = aws_ec2_managed_prefix_list.test.id } `, rName) } func testAccAwsEc2ManagedPrefixListEntryExpectInvalidType(rName string) string { return fmt.Sprintf(` -resource "aws_ec2_managed_prefix_list" "web" { +resource "aws_ec2_managed_prefix_list" "test" { name = %[1]q address_family = "IPv4" max_entries = 5 } -resource "aws_ec2_managed_prefix_list_entry" "ipv6" { +resource "aws_ec2_managed_prefix_list_entry" "test" { cidr = "::/244" - prefix_list_id = aws_ec2_managed_prefix_list.web.id + prefix_list_id = aws_ec2_managed_prefix_list.test.id } `, rName) } func testAccAwsEc2ManagedPrefixListEntryInvalidIPv4CIDR(rName string) string { return fmt.Sprintf(` -resource "aws_ec2_managed_prefix_list" "foo" { +resource "aws_ec2_managed_prefix_list" "test" { name = %[1]q address_family = "IPv4" max_entries = 5 } -resource "aws_ec2_managed_prefix_list_entry" "ipv4" { +resource "aws_ec2_managed_prefix_list_entry" "test" { cidr = "1.2.3.4/33" - prefix_list_id = aws_ec2_managed_prefix_list.foo.id + prefix_list_id = aws_ec2_managed_prefix_list.test.id } `, rName) } func testAccAwsEc2ManagedPrefixListEntryInvalidIPv6CIDR(rName string) string { return fmt.Sprintf(` -resource "aws_ec2_managed_prefix_list" "foo" { +resource "aws_ec2_managed_prefix_list" "test" { name = %[1]q address_family = "IPv6" max_entries = 5 } -resource "aws_ec2_managed_prefix_list_entry" "ipv6" { +resource "aws_ec2_managed_prefix_list_entry" "test" { cidr = "::/244" - prefix_list_id = aws_ec2_managed_prefix_list.foo.id + prefix_list_id = aws_ec2_managed_prefix_list.test.id } `, rName) } From 58b7d129a06b4362282b97314cba97ee1c7a1af5 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 23 Sep 2021 08:58:15 -0400 Subject: [PATCH 6/6] r/aws_ec2_managed_prefix_list_entry: Remove 'version' attribute. --- ...ource_aws_ec2_managed_prefix_list_entry.go | 20 ++++++++----------- ...c2_managed_prefix_list_entry.html.markdown | 5 ++--- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/aws/resource_aws_ec2_managed_prefix_list_entry.go b/aws/resource_aws_ec2_managed_prefix_list_entry.go index a1477a661bc8..89284b042bf2 100644 --- a/aws/resource_aws_ec2_managed_prefix_list_entry.go +++ b/aws/resource_aws_ec2_managed_prefix_list_entry.go @@ -42,10 +42,6 @@ func resourceAwsEc2ManagedPrefixListEntry() *schema.Resource { Required: true, ForceNew: true, }, - "version": { - Type: schema.TypeInt, - Computed: true, - }, }, } } @@ -56,6 +52,7 @@ func resourceAwsEc2ManagedPrefixListEntryCreate(d *schema.ResourceData, meta int cidr := d.Get("cidr").(string) plID := d.Get("prefix_list_id").(string) id := tfec2.ManagedPrefixListEntryCreateID(plID, cidr) + pl, err := finder.ManagedPrefixListByID(conn, plID) if err != nil { @@ -114,15 +111,8 @@ func resourceAwsEc2ManagedPrefixListEntryRead(d *schema.ResourceData, meta inter entry := outputRaw.(*ec2.PrefixListEntry) - pl, err := finder.ManagedPrefixListByID(conn, plID) - - if err != nil { - return fmt.Errorf("error reading EC2 Managed Prefix List (%s): %w", plID, err) - } - d.Set("cidr", entry.Cidr) d.Set("description", entry.Description) - d.Set("version", pl.Version) return nil } @@ -136,8 +126,14 @@ func resourceAwsEc2ManagedPrefixListEntryDelete(d *schema.ResourceData, meta int return err } + pl, err := finder.ManagedPrefixListByID(conn, plID) + + if err != nil { + return fmt.Errorf("error reading EC2 Managed Prefix List (%s): %w", plID, err) + } + input := &ec2.ModifyManagedPrefixListInput{ - CurrentVersion: aws.Int64(int64(d.Get("version").(int))), + CurrentVersion: pl.Version, PrefixListId: aws.String(plID), RemoveEntries: []*ec2.RemovePrefixListEntry{{Cidr: aws.String(cidr)}}, } diff --git a/website/docs/r/ec2_managed_prefix_list_entry.html.markdown b/website/docs/r/ec2_managed_prefix_list_entry.html.markdown index d37dfe19f64a..e18d9f67f4ec 100644 --- a/website/docs/r/ec2_managed_prefix_list_entry.html.markdown +++ b/website/docs/r/ec2_managed_prefix_list_entry.html.markdown @@ -44,7 +44,7 @@ resource "aws_ec2_managed_prefix_list_entry" "entry_1" { The following arguments are supported: * `cidr` - (Required) CIDR block of this entry. -* `description` - (Optional) Description of this entry. Due to API limitations, updating only the description of an existing entry requires temporarily removing and re-adding the entry. +* `description` - (Optional) Description of this entry. Due to API limitations, updating only the description of an entry requires recreating the entry. * `prefix_list_id` - (Required) CIDR block of this entry. ## Attributes Reference @@ -52,11 +52,10 @@ The following arguments are supported: In addition to all arguments above, the following attributes are exported: * `id` - ID of the managed prefix list entry. -* `version` - Latest version of this prefix list entry. ## Import -Prefix List Entriess can be imported using the `prefix_list_id` and `cidr` separated by a `,`, e.g. +Prefix List Entries can be imported using the `prefix_list_id` and `cidr` separated by a `,`, e.g. ``` $ terraform import aws_ec2_managed_prefix_list_entry.default pl-0570a1d2d725c16be,10.0.3.0/24