Serverless-application-model: Plugin 'ImplicitApiPlugin' raised an exception: unhashable type: 'dict' when setting RestApiId from the output of a child stack

Created on 2 May 2019  路  2Comments  路  Source: aws/serverless-application-model

Description:

setting the RestApiId from the output of a child stack containing the AWS::Serverless::Api is causing errors

Steps to reproduce the issue:

Stack_A:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  RestApi:
    Type: AWS::Serverless::Api
    Properties:
      Name: my-rest-api
      StageName: Prod
      DefinitionBody: ...

Outputs:
  RestApi:
    Description: ...
    Value: !Ref RestApi

Stack_B:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  RestApiStack:
    Type: AWS::CloudFormation::Stack
    Properties:
      TemplateURL: Stack_A.yaml
      Parameters:...

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: .
      Runtime: python3.6
      Handler: my_file.get_handler
      Events:
        Api:
          Type: Api
          Properties:
            Path: a/b/{c}/d
            Method: get
            RestApiId: !GetAtt RestApiStack.Outputs.RestApi #causes exception

Error:

sam build --template "C:\......\template.yaml" --build-dir "C:\......\.aws-sam\build" 

2019-05-02 14:51:37 Plugin 'ImplicitApiPlugin' raised an exception: unhashable type: 'dict'
Traceback (most recent call last):
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samtranslator\plugins\__init__.py", line 130, in act
    getattr(plugin, method_name)(*args, **kwargs)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samtranslator\plugins\api\implicit_api_plugin.py", line 78, in on_before_transform_template
    self._process_api_events(function, api_events, template, condition)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samtranslator\plugins\api\implicit_api_plugin.py", line 141, in _process_api_events
    api_dict = self.api_conditions.setdefault(api_id, {})
TypeError: unhashable type: 'dict'
Traceback (most recent call last):
  File "c:\users\ABC\appdata\local\programs\python\python36\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "c:\users\ABC\appdata\local\programs\python\python36\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\Scripts\sam.exe\__main__.py", line 9, in <module>
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\click\core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\click\core.py", line 697, in main
    rv = self.invoke(ctx)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\click\core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\click\core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\click\core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\click\decorators.py", line 64, in new_func
    return ctx.invoke(f, obj, *args[1:], **kwargs)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\click\core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samcli\commands\build\command.py", line 95, in cli
    skip_pull_image, parameter_overrides)  # pragma: no cover
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samcli\commands\build\command.py", line 124, in do_cli
    skip_pull_image=skip_pull_image) as ctx:
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samcli\commands\build\build_context.py", line 57, in __enter__
    self._function_provider = SamFunctionProvider(self._template_dict, self._parameter_overrides)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samcli\commands\local\lib\sam_function_provider.py", line 45, in __init__
    self.template_dict = SamBaseProvider.get_template(template_dict, parameter_overrides)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samcli\commands\local\lib\sam_base_provider.py", line 62, in get_template
    template_dict = SamTranslatorWrapper(template_dict).run_plugins()
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samcli\lib\samlib\wrapper.py", line 67, in run_plugins
    parser.parse(template_copy, all_plugins)  # parse() will run all configured plugins
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samcli\lib\samlib\wrapper.py", line 120, in parse
    sam_plugins.act(LifeCycleEvents.before_transform_template, sam_template)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samtranslator\plugins\__init__.py", line 136, in act
    raise ex
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samtranslator\plugins\__init__.py", line 130, in act
    getattr(plugin, method_name)(*args, **kwargs)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samtranslator\plugins\api\implicit_api_plugin.py", line 78, in on_before_transform_template
    self._process_api_events(function, api_events, template, condition)
  File "C:\Users\ABC\AppData\Roaming\Python\Python36\site-packages\samtranslator\plugins\api\implicit_api_plugin.py", line 141, in _process_api_events
    api_dict = self.api_conditions.setdefault(api_id, {})
TypeError: unhashable type: 'dict'
Exit code: 1

Most helpful comment

We really need SAM allows to reference API created in another template so that we can use multiple SAM templates for our microservices and one SAM for root API Gateway and shared resources

All 2 comments

It isn't yet possible to reference a Serverless::Api in a child stack, but there are active conversations about it. I agree that it would be a great feature to be able to reference a Serverless::Api in another stack.

See https://github.com/awslabs/serverless-application-model/issues/349#issuecomment-458652439 for more information on this issue, and add another +1 to that issue to help get it prioritized. #866 is another feature that we're discussing that would help alleviate this problem.

We really need SAM allows to reference API created in another template so that we can use multiple SAM templates for our microservices and one SAM for root API Gateway and shared resources

Was this page helpful?
0 / 5 - 0 ratings