Repository: PrefectHQ/prefect

Issue:
Trigger AWS Step Function Workflow
We should add a Task to our Task Library (in `src/prefect/tasks/aws`) for triggering the execution of AWS Step Function workflows.  Presumably this can be done from the Step Function API (e.g., https://docs.aws.amazon.com/step-functions/latest/apireference/API_StartExecution.html) with some authentication parameters that can be stored as Prefect Secrets.


Discussion:

Resolving patch:
diff --git a/src/prefect/tasks/aws/__init__.py b/src/prefect/tasks/aws/__init__.py
--- a/src/prefect/tasks/aws/__init__.py
+++ b/src/prefect/tasks/aws/__init__.py
@@ -12,6 +12,7 @@
         LambdaInvoke,
         LambdaList,
     )
+    from prefect.tasks.aws.step_function import StepActivate
 except ImportError:
     raise ImportError(
         'Using `prefect.tasks.aws` requires Prefect to be installed with the "aws" extra.'
diff --git a/src/prefect/tasks/aws/step_function.py b/src/prefect/tasks/aws/step_function.py
new file mode 100644
--- /dev/null
+++ b/src/prefect/tasks/aws/step_function.py
@@ -0,0 +1,70 @@
+import boto3
+
+from prefect import Task
+from prefect.client import Secret
+from prefect.utilities.tasks import defaults_from_attrs
+
+
+class StepActivate(Task):
+    """
+    Task for activating an AWS Step Function.
+
+    Args:
+        - state_machine_arn (str): the Amazon Resource Name (ARN) of the state machine
+            to execute
+        - execution_name (str): the name of the execution, this name must be unique for
+            your AWS account, region, and state machine for 90 days
+        - execution_input (str, optional): string that contains the JSON input data for
+            the execution
+        - aws_credentials_secret (str, optional): the name of the Prefect Secret
+            which stores your AWS credentials; this Secret must be a JSON string
+            with two keys: `ACCESS_KEY` and `SECRET_ACCESS_KEY`
+        - **kwargs (dict, optional): additional keyword arguments to pass to the
+            Task constructor
+    """
+
+    def __init__(
+        self,
+        state_machine_arn: str,
+        execution_name: str,
+        execution_input: str = "{}",
+        aws_credentials_secret: str = "AWS_CREDENTIALS",
+        **kwargs
+    ):
+        self.state_machine_arn = state_machine_arn
+        self.execution_name = execution_name
+        self.execution_input = execution_input
+        self.aws_credentials_secret = aws_credentials_secret
+        super().__init__(**kwargs)
+
+    @defaults_from_attrs("aws_credentials_secret")
+    def run(self, aws_credentials_secret: str = "AWS_CREDENTIALS"):
+        """
+        Task run method. Activates AWS Step function.
+
+        Args:
+            - aws_credentials_secret (str, optional): the name of the Prefect Secret
+                which stores your AWS credentials; this Secret must be a JSON string
+                with two keys: `ACCESS_KEY` and `SECRET_ACCESS_KEY`
+
+        Returns:
+            - dict: response from AWS StartExecution endpoint
+        """
+
+        ## get AWS credentials
+        aws_credentials = Secret(aws_credentials_secret).get()
+        aws_access_key = aws_credentials["ACCESS_KEY"]
+        aws_secret_access_key = aws_credentials["SECRET_ACCESS_KEY"]
+        step_client = boto3.client(
+            "stepfunctions",
+            aws_access_key_id=aws_access_key,
+            aws_secret_access_key=aws_secret_access_key,
+        )
+
+        response = step_client.start_execution(
+            stateMachineArn=self.state_machine_arn,
+            name=self.execution_name,
+            input=self.execution_input,
+        )
+
+        return response


Test patch:
diff --git a/tests/tasks/aws/test_step_function.py b/tests/tasks/aws/test_step_function.py
new file mode 100644
--- /dev/null
+++ b/tests/tasks/aws/test_step_function.py
@@ -0,0 +1,35 @@
+from unittest.mock import MagicMock
+
+import pytest
+
+import prefect
+from prefect.tasks.aws import StepActivate
+from prefect.utilities.configuration import set_temporary_config
+
+
+class TestStepActivate:
+    def test_initialization(self):
+        task = StepActivate(state_machine_arn="arn", execution_name="name")
+        assert task.aws_credentials_secret == "AWS_CREDENTIALS"
+
+    def test_initialization_passes_to_task_constructor(self):
+        task = StepActivate(
+            state_machine_arn="arn", execution_name="name", name="test", tags=["AWS"]
+        )
+        assert task.name == "test"
+        assert task.tags == {"AWS"}
+
+    def test_creds_are_pulled_from_secret(self, monkeypatch):
+        task = StepActivate(state_machine_arn="arn", execution_name="name")
+        client = MagicMock()
+        boto3 = MagicMock(client=client)
+        monkeypatch.setattr("prefect.tasks.aws.step_function.boto3", boto3)
+        with set_temporary_config({"cloud.use_local_secrets": True}):
+            with prefect.context(
+                secrets=dict(
+                    AWS_CREDENTIALS={"ACCESS_KEY": "42", "SECRET_ACCESS_KEY": "99"}
+                )
+            ):
+                task.run()
+        kwargs = client.call_args[1]
+        assert kwargs == {"aws_access_key_id": "42", "aws_secret_access_key": "99"}