Utility to create AWS Step Function (SFN) activities out of command line programs.
$ sfncli -h
Usage of sfncli:
-activityname string
The activity name to register with AWS Step Functions. $VAR and ${VAR} env variables are expanded.
-cmd string
The command to run to process activity tasks.
-region string
The AWS region to send Step Function API calls. Defaults to AWS_REGION.
-cloudwatchregion string
The AWS region to send metric data. Defaults to the value of region.
-version
Print the version and exit.
-workername string
The worker name to send to AWS Step Functions when processing a task. Environment variables are expanded. The magic string MAGIC_ECS_TASK_ARN will be expanded to the ECS task ARN via the metadata service.
-workdirectory string
A directory path that is passed to the `cmd` using an env var `WORK_DIR`. For each activity task a new directory is created in `workdirectory` and it is cleaned up after the activity task exits. Defaults to "", does not create directory or set `WORK_DIR`
Example:
sfncli -activityname sleep-100 -region us-west-2 --cloudwatchregion us-west-1 -workername sleep-worker -cmd sleep 100
- On startup, call
CreateActivityto register an Activity with Step Functions. - Begin polling
GetActivityTaskfor tasks. - Get a task. Take the JSON input for the task and
- if it's a JSON object, use this as the last arg to the
cmdpassed tosfncli. - if it's anything else (e.g. JSON array), an error is thrown.
- if
_EXECUTION_NAMEis missing from the payload, an error is thrown - the
_EXECUTION_NAMEpayload attribute value is added to the environment of thecmdas_EXECUTION_NAME. - if workdirectory is set, create a sub-directory and add it to the environment of the
cmdasWORK_DIR.
- if it's a JSON object, use this as the last arg to the
- Start
SendTaskHeartbeatloop. - When the command exits:
- Call
SendTaskFailureif it exited nonzero, was killed, orsfnclireceived SIGTERM. - Call
SendTaskSuccessotherwise. Parse the last line of thestdoutof the command as the output for the task (it must be JSON). - If
workdirectorywas set then cleanupWORK_DIR/sub-directory-for-task
- Call
Error names in SFN state machines are useful for debugging and setting up branching/retry logic in state machine definitions.
sfncli will report the following error names if it encounters errors it can identify:
sfncli.TaskInputNotJSON: input to the task was not JSONsfncli.TaskFailureTaskInputMissingExecutionName: input is missing_EXECUTION_NAMEattributesfncli.CommandNotFound: the command passed tosfncliwas not foundsfncli.CommandKilled: the command process received SIGKILLsfncli.CommandExitedNonzero: the command process exited with a nonzero exit codesfncli.TaskOutputNotJSON: the task output (last line of command'sstdout) was not JSONsfncli.CommandTerminated:sfnclior the command received SIGTERMsfncli.Unknown: unexpected / unclassified errors
The command should signal an error by exiting with a nonzero status code. In this case, the behavior is:
- If the last line of stdout was a JSON-formatted string with an
errorfield, report an error to Step Functions with that field as the name and the value of thecausefield in the output line as the cause. - Otherwise, report an error with name
sfncli.CommandExitedNonzerowith the last line of stderr as the cause.
Start up a test activity that runs echo on the work it receives.
go run ./cmd/sfncli -region us-west-2 -activityname test-activity -workername sfncli-test -cmd echo
Create a new state machine that uses this activity for one of its states (this requires you to create a role for use with Step Functions):
aws --region us-west-2 stepfunctions create-state-machine --name test-state-machine --role-arn arn:aws:iam::589690932525:role/raf-test-step-functions --definition '{
"Comment": "Testing out step functions",
"StartAt": "foo",
"Version": "1.0",
"TimeoutSeconds": 60,
"States": {
"foo": {
"Resource": "arn:aws:states:us-west-2:589690932525:activity:test-activity",
"Type": "Task",
"End": true
}
}
}'
Note that you will need to replace the Resource above to reflect the correct ARN with your AWS account ID.
Start an execution of the state machine (again replacing the ARN below with the correct account ID):
aws --region us-west-2 stepfunctions start-execution --state-machine-arn arn:aws:states:us-west-2:589690932525:stateMachine:test-state-machine --input '{"_EXECUTION_NAME":"en", "hello": "world"}'
You should see echo run with the argument {"hello": "world"}.