step

command module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2020 License: Apache-2.0 Imports: 10 Imported by: 0

README

Step (Beta)

One Small Step for Go

Step is a opinionated implementation of the AWS State Machine language in Go used to build and test AWS Step Functions and Lambdas. Step combines the Structure of a state machine with the Code of a lambda so that the two can be developed, tested and maintained together.

The three core components of Step are:

  1. Library: tools for building and deploying Step Functions in Go.
  2. Implementation: of the AWS State Machine specification to test with the code together (README).
  3. Deployer: to deploy Lambda's and Step Functions securely (README)
Getting Started

A Step function has two parts:

  1. A State Machine description in JSON, which outlines the flow of execution.
  2. The Lambda Function which executes the TaskFn states of the step function.

Create a State Machine like this:

func StateMachine(lambdaArn string) (machine.StateMachine, error) {
  state_machine, err := machine.FromJSON([]byte(`{
    "Comment": "Hello World",
    "StartAt": "HelloFn",
    "States": {
      "Hello": {
        "Type": "TaskFn",
        "Comment": "Deploy Step Function",
        "End": true
      }
    }
  }`))

  if err != nil {
      return nil, err
  }

  // Set the Handlers
  state_machine.SetTaskFnHandlers(CreateTaskHandlers())

  // Set Lambda Arn to call with Task States
  state_machine.SetResource(&lambdaArn)

  return state_machine, nil
}

TaskFn is a custom state type that injects Parameters to execute the correct handler.

Each TaskFn must have a handler that implements func(context.Context, <input_type>) (interface{}, error). These are defined like:

func CreateTaskFunctions() *handler.TaskHandlers {
  tm := handler.TaskHandlers{}
  // Assign Hello state the HelloHandler
	tm["Hello"] = HelloHandler
	return &tm
}

type Hello struct {
  Greeting *string
}

// HelloHandler takes a Hello struct alters its greeting and returns it
func HelloHandler(_ context.Context, hello *Hello) (*Hello, error) {
  if hello.Greeting == "" {
    hello.Greeting = "Hello World"
  }
  return hello, nil
}

To build a Step Function we then need an executable that can:

  1. Be executed in a Lambda
  2. Build the State Machine
func main() {
  var arg, command string
  switch len(os.Args) {
  case 1:
    fmt.Println("Starting Lambda")
    run.LambdaTasks(StateMachine("lambda"))
  case 2:
    command = os.Args[1]
    arg = ""
  case 3:
    command = os.Args[1]
    arg = os.Args[2]
  default:
    printUsage() // Print how to use and exit
  }

  switch command {
  case "json":
    run.JSON(StateMachine(arg))
  case "exec":
    run.Exec(StateMachine(""))(&arg)
  default:
    printUsage() // Print how to use and exit
  }

}
  1. ./step-hello-world will run as a Lambda Function
  2. ./step-hello-world json will print out the state machine
Testing

A core benefit when using Step and joining the State Machine and Lambda together is that it makes it possible to test your Step Functions execution.

For example, a basic test that ensures the correct output and execution path through the Hello World step function looks like:

func Test_HelloWorld_StateMachine(t *testing.T) {
  state_machine, err := StateMachine("")
  assert.NoError(t, err)

  exec, err := state_machine.Execute(&Hello{})
  assert.NoError(t, err)
  assert.Equal(t, "Hello World", exec.Output["Greeting"])

  assert.Equal(t, state_machine.Path(), []string{
    "Hello",
  })
}
Deploying

There are two ways to get a State Machine into the cloud:

  1. Bootstrap: Directly upload the Lambda and Step Function to AWS
  2. Deploy: Using the Step Deployer which is a Step Function included in this library.

The Step executable can perform both of these functions.

Step does not create the Lambda or Step Function in AWS, it only modifies them. So before either bootstrapping or deploying the resources must already be created.

First build and install step with:

go build && go install

Bootstrap (directly upload to the Step Function and Lambda):

# Use AWS credentials or assume-role into AWS
# Build linux zip for lambda
GOOS=linux go build -o lambda
zip lambda.zip lambda

# Tell step to bootstrap this lambda
step bootstrap                        \
  -lambda "coinbase-step-hello-world" \
  -step "coinbase-step-hello-world"   \
  -states "$(./step-hello-world json)"

Deploy (via the step-deployer step function):

GOOS=linux go build -o lambda
zip lambda.zip lambda

# Tell step-deployer to deploy this lambda
step deploy                           \
  -lambda "coinbase-step-hello-world" \
  -step "coinbase-step-hello-world"   \
  -states "$(./step-hello-world json)"
Development State

Step is still Beta and its API might change quickly.

  1. AWS Step Functions, State Machines, Bifrost, and Building Deployers
  2. Open Sourcing Coinbase’s Secure Deployment Pipeline
  3. https://docs.aws.amazon.com/step-functions/latest/dg/step-functions-dg.pdf
  4. https://github.com/vkkis93/serverless-step-functions-offline
  5. https://github.com/totherik/step

CC Renee French for the logo, borrowed from GopherCon 2017

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
aws
s3
s3 tools
s3 tools
The deployer package contains the Step Deployer service that is a Step Function that Deploys Step Functions.
The deployer package contains the Step Deployer service that is a Step Function that Deploys Step Functions.
errors has a list of common errors and error functions
errors has a list of common errors and error functions
Lambda Handler Data Structures and types
Lambda Handler Data Structures and types
Simple Implementation of JSON Path for state machine
Simple Implementation of JSON Path for state machine
State Machine implementation State Machine Parser
State Machine implementation State Machine Parser
utils
is
run
run takes arguments
run takes arguments
to
to is a list of Functions use to convert things to things
to is a list of Functions use to convert things to things

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL