Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step function creation errors when using specific IAM roles within steps #7826

Open
mik3h0 opened this issue Jul 5, 2024 · 0 comments
Open
Labels

Comments

@mik3h0
Copy link

mik3h0 commented Jul 5, 2024

Recreating the issue

import boto3
from moto import mock_aws

STATE_MACHINE_DEFINITION = """
{
  "StartAt": "ListTables",
  "States": {
    "ListTables": {
      "Type": "Task",
      "Parameters": {},
      "Resource": "arn:aws:states:::aws-sdk:dynamodb:listTables",
      "End": true,
      "Credentials": {
        "RoleArn": "arn:aws:iam::123456789012:role/role/role"
      }
    }
  }
}
"""


def test_recreate_credentials_issue():
    with mock_aws(config={"stepfunctions": {"execute_state_machine": True}}):
        client = boto3.client("stepfunctions", region_name="us-east-1")
        response = client.create_state_machine(
            name="test",
            definition=STATE_MACHINE_DEFINITION,
            roleArn="arn:aws:iam::123456789012:role/service-role/StatesExecutionRole-us-east-1",
        )

AWS added support for individual steps to assume an IAM role earlier this year. The syntax for this is in the example above. this functionality enables, for example, cross-account DynamoDB queries etc.

Expected behaviour

The step function should be created

Actual behaviour

An exception is raised. The key line is:

moto.stepfunctions.parser.asl.parse.asl_parser.ASLParserException: ASLParserException ['line 10:6, at "Credentials", mismatched input \'"Credentials"\' expecting {\'"Comment"\', \'"Type"\', \'"Choices"\', \'"Default"\', \'"Branches"\', \'"SecondsPath"\', \'"Seconds"\', \'"TimestampPath"\', \'"Timestamp"\', \'"TimeoutSeconds"\', \'"TimeoutSecondsPath"\', \'"HeartbeatSeconds"\', \'"HeartbeatSecondsPath"\', \'"ItemProcessor"\', \'"Iterator"\', \'"ItemSelector"\', \'"MaxConcurrency"\', \'"Resource"\', \'"InputPath"\', \'"OutputPath"\', \'"ItemsPath"\', \'"ResultPath"\', \'"Result"\', \'"Parameters"\', \'"ResultSelector"\', \'"ItemReader"\', \'"Next"\', \'"End"\', \'"Cause"\', \'"CausePath"\', \'"Error"\', \'"ErrorPath"\', \'"Retry"\', \'"Catch"\'}', "line 15:0, at }, extraneous input '}' expecting <EOF>"]

Full stack trace below

Moto Version

5.0.10

Stack trace

tests/test_recreate_credentials_issue.py:21 (test_recreate_zero_issue)
definition = '\n{\n  "StartAt": "ListTables",\n  "States": {\n    "ListTables": {\n      "Type": "Task",\n      "Parameters": {},\n...true,\n      "Credentials": {\n        "RoleArn": "arn:aws:iam::123456789012:role/role/role"\n      }\n    }\n  }\n}\n'

    @staticmethod
    def _validate_definition(definition: str):
        # Validate
        # TODO: pass through static analyser.
        try:
>           AmazonStateLanguageParser.parse(definition)

../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/moto/stepfunctions/parser/models.py:68: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

src = '\n{\n  "StartAt": "ListTables",\n  "States": {\n    "ListTables": {\n      "Type": "Task",\n      "Parameters": {},\n...true,\n      "Credentials": {\n        "RoleArn": "arn:aws:iam::123456789012:role/role/role"\n      }\n    }\n  }\n}\n'

    @staticmethod
    def parse(src: str) -> Program:
        # Attempt to build the AST and look out for syntax errors.
        syntax_error_listener = SyntaxErrorListener()
    
        input_stream = InputStream(src)
        lexer = ASLLexer(input_stream)
        stream = CommonTokenStream(lexer)
        parser = ASLParser(stream)
        parser.removeErrorListeners()
        parser.addErrorListener(syntax_error_listener)
        tree = parser.state_machine()
    
        errors = syntax_error_listener.errors
        if errors:
>           raise ASLParserException(errors=errors)
E           moto.stepfunctions.parser.asl.parse.asl_parser.ASLParserException: ASLParserException ['line 10:6, at "Credentials", mismatched input \'"Credentials"\' expecting {\'"Comment"\', \'"Type"\', \'"Choices"\', \'"Default"\', \'"Branches"\', \'"SecondsPath"\', \'"Seconds"\', \'"TimestampPath"\', \'"Timestamp"\', \'"TimeoutSeconds"\', \'"TimeoutSecondsPath"\', \'"HeartbeatSeconds"\', \'"HeartbeatSecondsPath"\', \'"ItemProcessor"\', \'"Iterator"\', \'"ItemSelector"\', \'"MaxConcurrency"\', \'"Resource"\', \'"InputPath"\', \'"OutputPath"\', \'"ItemsPath"\', \'"ResultPath"\', \'"Result"\', \'"Parameters"\', \'"ResultSelector"\', \'"ItemReader"\', \'"Next"\', \'"End"\', \'"Cause"\', \'"CausePath"\', \'"Error"\', \'"ErrorPath"\', \'"Retry"\', \'"Catch"\'}', "line 15:0, at }, extraneous input '}' expecting <EOF>"]

../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/moto/stepfunctions/parser/asl/parse/asl_parser.py:65: ASLParserException

During handling of the above exception, another exception occurred:

    def test_recreate_zero_issue():
        with mock_aws(config={"stepfunctions": {"execute_state_machine": True}}):
            client = boto3.client("stepfunctions", region_name="us-east-1")
>           response = client.create_state_machine(
                name="test",
                definition=STATE_MACHINE_DEFINITION,
                roleArn="arn:aws:iam::123456789012:role/service-role/StatesExecutionRole-us-east-1",
            )

test_recreate_credentials_issue.py:25: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/client.py:565: in _api_call
    return self._make_api_call(operation_name, kwargs)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/client.py:1001: in _make_api_call
    http, parsed_response = self._make_request(
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/client.py:1027: in _make_request
    return self._endpoint.make_request(operation_model, request_dict)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/endpoint.py:119: in make_request
    return self._send_request(request_dict, operation_model)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/endpoint.py:202: in _send_request
    while self._needs_retry(
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/endpoint.py:354: in _needs_retry
    responses = self._event_emitter.emit(
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/hooks.py:412: in emit
    return self._emitter.emit(aliased_event_name, **kwargs)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/hooks.py:256: in emit
    return self._emit(event_name, kwargs)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/hooks.py:239: in _emit
    response = handler(**kwargs)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/retryhandler.py:207: in __call__
    if self._checker(**checker_kwargs):
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/retryhandler.py:284: in __call__
    should_retry = self._should_retry(
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/retryhandler.py:307: in _should_retry
    return self._checker(
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/retryhandler.py:363: in __call__
    checker_response = checker(
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/retryhandler.py:247: in __call__
    return self._check_caught_exception(
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/retryhandler.py:416: in _check_caught_exception
    raise caught_exception
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/endpoint.py:278: in _do_get_response
    responses = self._event_emitter.emit(event_name, request=request)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/hooks.py:412: in emit
    return self._emitter.emit(aliased_event_name, **kwargs)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/hooks.py:256: in emit
    return self._emit(event_name, kwargs)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/botocore/hooks.py:239: in _emit
    response = handler(**kwargs)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/moto/core/botocore_stubber.py:37: in __call__
    response = self.process_request(request)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/moto/core/botocore_stubber.py:84: in process_request
    status, headers, body = method_to_execute(
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/moto/core/responses.py:290: in dispatch
    return cls()._dispatch(*args, **kwargs)
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/moto/core/responses.py:501: in _dispatch
    return self.call_action()
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/moto/core/responses.py:587: in call_action
    response = method()
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/moto/stepfunctions/responses.py:31: in create_state_machine
    state_machine = self.stepfunction_backend.create_state_machine(
../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/moto/stepfunctions/parser/models.py:87: in create_state_machine
    StepFunctionsParserBackend._validate_definition(definition=definition)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

definition = '\n{\n  "StartAt": "ListTables",\n  "States": {\n    "ListTables": {\n      "Type": "Task",\n      "Parameters": {},\n...true,\n      "Credentials": {\n        "RoleArn": "arn:aws:iam::123456789012:role/role/role"\n      }\n    }\n  }\n}\n'

    @staticmethod
    def _validate_definition(definition: str):
        # Validate
        # TODO: pass through static analyser.
        try:
            AmazonStateLanguageParser.parse(definition)
        except ASLParserException as asl_parser_exception:
>           invalid_definition = InvalidDefinition()
E           TypeError: AWSError.__init__() missing 1 required positional argument: 'message'

../../../../../../Library/Caches/pypoetry/virtualenvs/centralised-lock-Q7F2D_P9-py3.11/lib/python3.11/site-packages/moto/stepfunctions/parser/models.py:70: TypeError
@bblommers bblommers added the bug label Aug 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants