diff --git a/moto/apigateway/models.py b/moto/apigateway/models.py index 06637205d..1390db1a3 100644 --- a/moto/apigateway/models.py +++ b/moto/apigateway/models.py @@ -92,7 +92,7 @@ class Deployment(CloudFormationModel, dict): ): properties = cloudformation_json["Properties"] rest_api_id = properties["RestApiId"] - name = properties["StageName"] + name = properties.get("StageName") desc = properties.get("Description", "") backend = apigateway_backends[account_id][region_name] return backend.create_deployment( @@ -220,7 +220,7 @@ class Method(CloudFormationModel, dict): resource_id = properties["ResourceId"] method_type = properties["HttpMethod"] auth_type = properties["AuthorizationType"] - key_req = properties["ApiKeyRequired"] + key_req = properties.get("ApiKeyRequired") backend = apigateway_backends[account_id][region_name] m = backend.put_method( function_id=rest_api_id, diff --git a/moto/cloudformation/parsing.py b/moto/cloudformation/parsing.py index b38aa7e1b..a303b6861 100644 --- a/moto/cloudformation/parsing.py +++ b/moto/cloudformation/parsing.py @@ -185,7 +185,11 @@ def clean_json(resource_json, resources_map): {"Ref": re.findall(r'(?<=\${)[^"]*?(?=})', sub)[0]}, resources_map, ) - fn_sub_value = fn_sub_value.replace(sub, cleaned_ref) + if cleaned_ref is not None: + fn_sub_value = fn_sub_value.replace(sub, cleaned_ref) + else: + # The ref was not found in the template - either it didn't exist, or we couldn't parse it + pass for literal in literals: fn_sub_value = fn_sub_value.replace( literal, literal.replace("!", "") diff --git a/tests/test_apigateway/test_apigateway_cloudformation.py b/tests/test_apigateway/test_apigateway_cloudformation.py index d6cdea3ba..b1d72fa39 100644 --- a/tests/test_apigateway/test_apigateway_cloudformation.py +++ b/tests/test_apigateway/test_apigateway_cloudformation.py @@ -290,6 +290,28 @@ template = """{ } }""" +template_with_missing_sub = """{ + "AWSTemplateFormatVersion": "2010-09-09", + "Description": "AWS CloudFormation template", + "Resources": { + "UnknownResource": {"Type": "AWS::Cloud9::EnvironmentEC2", "Properties": {}}, + "ApiGatewayRestApi": { + "Type": "AWS::ApiGateway::RestApi", + "Properties": { + "Name": "test-api", + "Description": {"Fn::Sub": "${UnknownResource}"}, + "EndpointConfiguration": { + "Types": [ + "EDGE" + ] + } + } + } + }, + "Outputs": { + } +}""" + @mock_cloudformation @mock_lambda @@ -347,3 +369,15 @@ def test_simple_apigateway_with_lambda_proxy(): statement["Condition"]["ArnLike"]["AWS:SourceArn"].should.equal( "arn:aws:execute-api:us-east-1:123456789012:{}/*/*".format(api_id) ) + + +@mock_apigateway +@mock_cloudformation +def test_apigateway_with_unknown_description(): + region = "us-east-1" + apigw = boto3.client("apigateway", region_name=region) + cf = boto3.client("cloudformation", region_name=region) + cf.create_stack(StackName="teststack", TemplateBody=template_with_missing_sub) + + api = apigw.get_rest_apis()["items"][0] + api.should.have.key("description").equals("${UnknownResource}")