Overview

This is a brief overview of Sparta’s core concepts. Additional information regarding specific features is available from the menu.

Terms and Concepts

At a high level, Sparta transforms a go binary’s registered lambda functions into a set of independently addressable AWS Lambda functions . Additionally, Sparta provides microservice authors an opportunity to satisfy other requirements such as defining the IAM Roles under which their function will execute in AWS, additional infrastructure requirements, and telemetry and alerting information (via CloudWatch).

The table below summarizes some of the primary Sparta terminology.

Service Name

Sparta applications are deployed as a single unit, using the ServiceName as a stable logical identifier. The ServiceName is used as your application's CloudFormation StackName
    stackName := "MyUniqueServiceName"
    sparta.Main(stackName,
      "Simple Sparta application",
      myLambdaFunctions,
      nil,
      nil)
        

Sparta Lambda Function

A Sparta-compatible lambda is a standard http.HandlerFunc instance. Sparta translates the results of the http.ResponseWriter (both status and body) to determine the AWS Lambda response.
func mySpartaHandler(w http.ResponseWriter,
                      r *http.Request) {
  // Lambda code
}

Privileges

To support accessing other AWS resources in your Go function, Sparta users may define IAM Roles with tightly defined sparta.IAMRolePrivilege values. This allows you to define the minimal set of privileges under which your Go function will execute. The Privilege.Resource field value may also be a StringExpression referencing a CloudFormation dynamically provisioned entity.
lambdaFn.RoleDefinition.Privileges = append(lambdaFn.RoleDefinition.Privileges,
  sparta.IAMRolePrivilege{
    Actions:  []string{"s3:GetObject", "s3:HeadObject"},
    Resource: "arn:aws:s3:::MyS3Bucket",
})

Permissions

To configure AWS Lambda Event Sources, Sparta provides both sparta.LambdaPermission and service-specific Permission types; eg: sparta.CloudWatchEventsPermission. The service-specific Permission types automatically register your lambda function with the remote AWS service, using each service's specific API.
cloudWatchEventsPermission := sparta.CloudWatchEventsPermission{}
cloudWatchEventsPermission.Rules = make(map[string]sparta.CloudWatchEventsRule, 0)
cloudWatchEventsPermission.Rules["Rate5Mins"] = sparta.CloudWatchEventsRule{
  ScheduleExpression: "rate(5 minutes)",
}
lambdaFn.Permissions = append(lambdaFn.Permissions, cloudWatchEventsPermission)

Dynamic Resources

Sparta applications can specify other AWS Resources (eg, SNS Topics) as part of their application. The dynamic resource outputs can be referenced by Sparta lambda functions via gocf.Ref and gocf.GetAtt functions.
snsTopicName := sparta.CloudFormationResourceName("SNSDynamicTopic")
snsTopic := &gocf.SNSTopic{
  DisplayName: gocf.String("Sparta Application SNS topic"),
})
lambdaFn := sparta.HandleAWSLambda(
  sparta.LambdaName(echoDynamicSNSEvent),
  http.HandlerFunc(echoDynamicSNSEvent),
  sparta.IAMRoleDefinition{})
lambdaFn.Permissions = append(lambdaFn.Permissions, sparta.SNSPermission{
	BasePermission: sparta.BasePermission{
		SourceArn: gocf.Ref(snsTopicName),
	},
})

Discovery

To support Sparta lambda functions discovering dynamically assigned AWS values (eg, S3 Bucket Names), Sparta provides sparta.Discover.
func echoS3DynamicBucketEvent(event *json.RawMessage,
  context *sparta.LambdaContext,
  w http.ResponseWriter,
  logger *logrus.Logger) {

  config, _ := sparta.Discover()
  // Use config to determine the bucket name to which RawMessage should be stored
}

Given a set of registered Sparta lambda function, a typical provision build to create a new service follows this workflow. Items with dashed borders are opt-in user behaviors.

graph TD classDef stdOp fill:#FFF,stroke:#A00,stroke-width:2px; classDef userHook fill:#B5B2A1,stroke:#A00,stroke-width:2px,stroke-dasharray: 5, 5; iam[Verify Static IAM Roles] class iam stdOp; preBuild[WorkflowHook - PreBuild] class preBuild userHook; compile[Cross Compile for AWS AMI] cgoCompile[CGO Docker Compile for AWS AMI] class compile,cgoCompile stdOp; postBuild[WorkflowHook - PostBuild] class postBuild userHook; nodeJSProxyShims[Create NodeJS-Go HTTP Proxies] pythonJSProxyShims[Create Python-CGO HTTP Proxies] package[ZIP archive] class nodeJSProxyShims,pythonJSProxyShims,package stdOp; userArchive[WorkflowHook - Archive] class userArchive userHook; upload[Upload Archive to S3] packageAssets[Conditionally ZIP S3 Site Assets] uploadAssets[Upload S3 Assets] class upload,packageAssets,uploadAssets stdOp; preMarshall[WorkflowHook - PreMarshall] class preMarshall userHook; generate[Marshal to CloudFormation] class generate stdOp; decorate[Call Lambda Decorators - Dynamic AWS Resources] class decorate stdOp; serviceDecorator[Service Decorator] class serviceDecorator userHook; postMarshall[WorkflowHook - PostMarshall] class postMarshall stdOp; uploadTemplate[Upload Template to S3] updateStack[Create/Update Stack] inplaceUpdates[In-place λ code updates] wait[Wait for Complete/Failure Result] class uploadTemplate,updateStack,inplaceUpdates,wait stdOp; iam-->preBuild preBuild-->|go|compile preBuild-->|cgo|cgoCompile compile-->postBuild cgoCompile-->postBuild postBuild-->|go|nodeJSProxyShims nodeJSProxyShims-->package nodeJSProxyShims-->packageAssets postBuild-->|cgo|pythonJSProxyShims pythonJSProxyShims-->package pythonJSProxyShims-->packageAssets package-->userArchive userArchive-->upload packageAssets-->uploadAssets uploadAssets-->generate upload-->generate generate-->preMarshall preMarshall-->decorate decorate-->serviceDecorator serviceDecorator-->postMarshall postMarshall-->uploadTemplate uploadTemplate-->|standard|updateStack uploadTemplate-->|inplace|inplaceUpdates updateStack-->wait
This diagram is rendered with Mermaid. Please open an issue if it doesn't render properly.

During provisioning, Sparta uses AWS Lambda-backed Custom Resources to support operations for which CloudFormation doesn’t yet support (eg, API Gateway creation).

At runtime, Sparta uses NodeJS shims to proxy the request to your go handler.

Next Steps

Writing a simple Sparta Application.