Repository: localstack/localstack

Issue:
Support starting stepfunctions with a custom Lambda endpoint
<!-- Love localstack? Please consider supporting our collective:
👉  https://opencollective.com/localstack/donate -->

# Type of request: This is a ...

[ ] bug report
[x] feature request

# Detailed description

Until https://github.com/localstack/localstack/issues/1783 is resolved (which is blocked on upstream bug https://github.com/aws/aws-cli/issues/4727), it's not possible to use cloudformation to package and deploy a lambda to localstack.

One workaround for this is to manually upload a lambda to localstack's lambda service, but this requires manually zipping and uploading. If you need to add API Gateway to the lambdas then that's even more fiddly AWS CLI work.

In AWS' documentation for step functions local (https://docs.aws.amazon.com/step-functions/latest/dg/sfn-local-lambda.html#start-stepfunctions-local) they have a better workaround, pass a lambda endpoint (where you're running sam locally, outside of localstack): 

`java -jar StepFunctionsLocal.jar --lambda-endpoint http://localhost:3001`

Looking at localstack code, this `lambda-endpoint` doesn't seem to be configurable: https://github.com/localstack/localstack/blob/master/localstack/services/stepfunctions/stepfunctions_starter.py#L15

`lambda_endpoint = aws_stack.get_local_service_url('lambda')`

Would it be possible to expose this as a localstack environment variable, eg. `STEPFUNCTIONS_LAMBDA_ENDPOINT`?

That way we could use localstack with sam in the same way stepfunctions-local can be used with sam, to talk to a sam API running locally outside of localstack.

This would also allow running lambci Docker images locally and communicating with them from a step function, again this is often easier than uploading via CLI.


Discussion:

Resolving patch:
diff --git a/localstack/config.py b/localstack/config.py
--- a/localstack/config.py
+++ b/localstack/config.py
@@ -119,6 +119,9 @@
 # Whether to skip downloading additional infrastructure components (e.g., custom Elasticsearch versions)
 SKIP_INFRA_DOWNLOADS = os.environ.get('SKIP_INFRA_DOWNLOADS', '').strip()
 
+# Stepfunctions lambda endpoint override
+STEPFUNCTIONS_LAMBDA_ENDPOINT = os.environ.get('STEPFUNCTIONS_LAMBDA_ENDPOINT', '').strip()
+
 
 def has_docker():
     try:
@@ -159,7 +162,7 @@ def is_linux():
                    'USE_SSL', 'DEBUG', 'KINESIS_ERROR_PROBABILITY', 'DYNAMODB_ERROR_PROBABILITY', 'PORT_WEB_UI',
                    'START_WEB', 'DOCKER_BRIDGE_IP', 'DEFAULT_REGION', 'LAMBDA_JAVA_OPTS', 'LOCALSTACK_API_KEY',
                    'LAMBDA_CONTAINER_REGISTRY', 'TEST_AWS_ACCOUNT_ID', 'DISABLE_EVENTS', 'EDGE_PORT',
-                   'EDGE_PORT_HTTP', 'SKIP_INFRA_DOWNLOADS']
+                   'EDGE_PORT_HTTP', 'SKIP_INFRA_DOWNLOADS', 'STEPFUNCTIONS_LAMBDA_ENDPOINT']
 
 for key, value in six.iteritems(DEFAULT_SERVICE_PORTS):
     clean_key = key.upper().replace('-', '_')
diff --git a/localstack/services/stepfunctions/stepfunctions_starter.py b/localstack/services/stepfunctions/stepfunctions_starter.py
--- a/localstack/services/stepfunctions/stepfunctions_starter.py
+++ b/localstack/services/stepfunctions/stepfunctions_starter.py
@@ -12,7 +12,7 @@
 
 
 def get_command():
-    lambda_endpoint = aws_stack.get_local_service_url('lambda')
+    lambda_endpoint = config.STEPFUNCTIONS_LAMBDA_ENDPOINT or aws_stack.get_local_service_url('lambda')
     dynamodb_endpoint = aws_stack.get_local_service_url('dynamodb')
     sns_endpoint = aws_stack.get_local_service_url('sns')
     sqs_endpoint = aws_stack.get_local_service_url('sqs')


Test patch: