diff --git a/samtranslator/plugins/application/serverless_app_plugin.py b/samtranslator/plugins/application/serverless_app_plugin.py index 3b6e6246c..5b1131e3b 100644 --- a/samtranslator/plugins/application/serverless_app_plugin.py +++ b/samtranslator/plugins/application/serverless_app_plugin.py @@ -111,7 +111,7 @@ def on_before_transform_template(self, template_dict): if key not in self._applications: try: - if not RegionConfiguration.is_sar_supported(): + if not RegionConfiguration.is_service_supported("serverlessrepo"): raise InvalidResourceException( logical_id, "Serverless Application Repository is not available in this region." ) diff --git a/samtranslator/region_configuration.py b/samtranslator/region_configuration.py index 73f802e1c..8656549f0 100644 --- a/samtranslator/region_configuration.py +++ b/samtranslator/region_configuration.py @@ -26,31 +26,32 @@ def is_apigw_edge_configuration_supported(cls): ] @classmethod - def is_sar_supported(cls): + def is_service_supported(cls, service, region=None): """ - SAR is not supported in some regions. + Not all services are supported in all regions. This method returns whether a given + service is supported in a given region. If no region is specified, the current region + (as identified by boto3) is used. https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/ - https://docs.aws.amazon.com/general/latest/gr/serverlessrepo.html - :return: True, if SAR is supported in current region. + :param service: service code (string used to obtain a boto3 client for the service) + :param region: region identifier (e.g., us-east-1) + :return: True, if the service is supported in the region """ session = boto3.Session() - # get the current region - region = session.region_name + if not region: + # get the current region + region = session.region_name - # need to handle when region is None so that it won't break - if region is None: - if ArnGenerator.BOTO_SESSION_REGION_NAME is not None: - region = ArnGenerator.BOTO_SESSION_REGION_NAME - else: - raise NoRegionFound("AWS Region cannot be found") + # need to handle when region is None so that it won't break + if region is None: + if ArnGenerator.BOTO_SESSION_REGION_NAME is not None: + region = ArnGenerator.BOTO_SESSION_REGION_NAME + else: + raise NoRegionFound("AWS Region cannot be found") - # boto3 get_available_regions call won't return us-gov and cn regions even if SAR is available - if region.startswith("cn") or region.startswith("us-gov"): - return True - - # get all regions where SAR are available - available_regions = session.get_available_regions("serverlessrepo") + # check if the service is available in region + partition = session.get_partition_for_region(region) + available_regions = session.get_available_regions(service, partition_name=partition) return region in available_regions diff --git a/tests/unit/test_region_configuration.py b/tests/unit/test_region_configuration.py index ac45832f4..699596e37 100644 --- a/tests/unit/test_region_configuration.py +++ b/tests/unit/test_region_configuration.py @@ -36,3 +36,27 @@ def test_when_apigw_edge_configuration_is_not_supported(self, partition): get_partition_name_patch.return_value = partition self.assertFalse(RegionConfiguration.is_apigw_edge_configuration_supported()) + + @parameterized.expand( + [ + # use ec2 as it's just about everywhere + ["ec2", "cn-north-1"], + ["ec2", "us-west-2"], + ["ec2", "us-gov-east-1"], + ["ec2", "us-isob-east-1"], + ["ec2", None], + # test SAR since SAM uses that + ["serverlessrepo", "us-east-1"], + ["serverlessrepo", "ap-southeast-2"], + ] + ) + def test_is_service_supported_positive(self, service, region): + self.assertTrue(RegionConfiguration.is_service_supported(service, region)) + + def test_is_service_supported_negative(self): + # use an unknown service name + self.assertFalse(RegionConfiguration.is_service_supported("ec1", "us-east-1")) + # use a region that does not exist + self.assertFalse(RegionConfiguration.is_service_supported("ec2", "us-east-0")) + # hard to test with a real service, since the test may start failing once that + # service is rolled out to more regions...