Skip to content

Latest commit

 

History

History
1863 lines (1488 loc) · 107 KB

CHANGES.md

File metadata and controls

1863 lines (1488 loc) · 107 KB

Change Notes

🚨 v3.0.0 - The Paydown Edition 🚨

This is a BREAKING RELEASE with significant breaking changes noted below.

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • Added NewTaskState to aws/step namespace to enable the new AWS Step Functions Task integrations. See the blog post for more information and aws/step/task_test.go for an example.

🚨 v2.0.0 - The Breaking Edition 🚨

This is a BREAKING RELEASE with many breaking changes noted below.

  • ⚠️ BREAKING
    • Replaced all logrus.Logger usage by rs.zerolog
      • This was a widescale change that impacted most of the codebase. There were two reasons why this was done: (1) logrus.Logger is officially in maintenance mode. (2) zerolog has a larger backing community which I can only hope means longer term support.
    • Changed SpartaOptions to ExtendedOptions to eliminate golint warnings
    • Changed cloudformation.CloudFormationResourceName to cloudformation.ResourceName to eliminate golint warnings
    • Removed HandleAWSLambda legacy function in favor of NewAWSLambda
    • WorkflowHook function signatures were changed for more idiomatic go usage. They now return (context.Context, error) values to allow for mutating the context.Context objected supplied to each invocation.
  • 🏁 CHANGES
    • Decoupled build from provision step to decouple building from packaging and deployment. Run go run main.go -h for the new application actions.
      • CloudFormation stack parameters are now expressed as explicit StackParameters rather than inline literals. The previously inlined values are represented as Template Metadata values. The precomputed template can be deployed using AWS CLI.
    • Added dockerFile argument to support OCI image creation. Dockerfiles may be used in liue of ZIP files for packaging.
    • Enabled new positional arguments with mage in the public Sparta magefile actions.
    • Added step.APIGatewayTaskState to support calling API Gateway
    • Added autogenerated code for all Step function choice states.
    • Added cloudtest package to bootstrap writing Lambda asynchronous event-based integration tests that are confirmed by log statements or invocation metrics.
    • Eliminated WorkflowHook single instance members in favor of slices.
    • Updated all AWS Architecture images to the versions in the Asset package
  • 🐛 FIXED

v1.15.0 - The Daylight Savings Edition 🕑

v1.14.0 - The post:Invent Edition 🎰

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Added step.NewExpressStateMachine to support creating AWS Step Functions Express Workflows functions that support the new step function type

    • Added archetype.NewEventBridgeScheduledReactor and archetype.NewEventBridgeEventReactor

      • These convenience functions provide convenience constructors for EventBridge Lambda Subscribers.

      • Sample usage:

        func echoEventBridgeEvent(ctx context.Context, msg json.RawMessage) (interface{}, error) {
          logger, _ := ctx.Value(sparta.ContextKeyLogger).(*logrus.Logger)
          var eventData map[string]interface{}
          err := json.Unmarshal(msg, &eventData)
          logger.WithFields(logrus.Fields{
            "error":   err,
            "message": eventData,
          }).Info("EventBridge event")
          return nil, err
        }
        
        func main() {
          //...
          eventBridgeReactorFunc := spartaArchetype.EventBridgeReactorFunc(echoEventBridgeEvent)
          lambdaFn, _ := spartaArchetype.NewEventBridgeScheduledReactor(eventBridgeReactorFunc,
                          "rate(1 minute)",
                          nil)
          // Register lambdaFn
        }
    • Updated describe output to use latest AWS Architecture Icons.

  • 🐛 FIXED

v1.13.0 - The pre:Invent Edition 🗓

v1.12.0 - The Mapping Edition 🗺

  • ⚠️ BREAKING
  • 🏁 CHANGES
  • 🐛 FIXED
    • Fixed latent issue in step.ParallelState that prevented Branches field from being properly marshaled.

v1.11.0 - The Firehose Edition 🚒

v1.10.0 - The Load Balancer Edition ⚖️

v1.9.4 - The Sockets Edition 🔌

  • ⚠️ BREAKING
    • Update sparta.Main and sparta.MainEx to accept new APIGateway interface type rather than concrete API type. This should be backward compatible for most usage and was done to support the new APIV2 Gateway type.
  • 🏁 CHANGES
    • Added [API V2] type to provision WebSocket APIs
    • Update to go modules
  • 🐛 FIXED

v1.9.3 - The Discovery Edition ☁️🔍

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Added Cloud Map discovery publisher
    • Added panic recover handler to more gracefully handle exceptions
    • Include AWS Session in context with key sparta.ContextKeyAWSSession
  • 🐛 FIXED

v1.9.2 - The Names Edition 📛

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Added API.EndpointConfiguration field to API.

    • Added decorator.APIGatewayDomainDecorator to associate a custom domain with an API Gateway instance

      • Usage:

          hooks := &sparta.WorkflowHooks{}
          serviceDecorator := spartaDecorators.APIGatewayDomainDecorator(apiGateway,
            gocf.String(acmCertARNLiteral),
            "", // Optional base path value
            "subdomain.mydomain.net")
          hooks.ServiceDecorators = []sparta.ServiceDecoratorHookHandler{
            serviceDecorator,
          }
      • See apigateway_domain_test for a complete example.

      • See the AWS Documentation for more information.

  • 🐛 FIXED

v1.9.1 - The CodeCommitment Edition 💕

v1.9.0 - The LayerCake Edition 🍰

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Added LambdaAWSInfo.Layers field to support Lambda Layers

      • Usage:

        lambdaRole := sparta.IAMRoleDefinition{
          Privileges: []sparta.IAMRolePrivilege{
            iamBuilder.Allow("lambda:GetLayerVersion").
              ForResource().
              Literal("*").
              ToPrivilege(),
          },
        }
        lambdaFn, lambdaFnErr := sparta.NewAWSLambda("Hello World",
          helloWorld,
          lambdaRole)
        lambdaFn.Layers = []gocf.Stringable{
          gocf.String("arn:aws:lambda:us-west-2:123412341234:layer:ffmpeg:1"),
        }
    • Added WithCondition to IAM Builder

    • Added s3Site.UserManifestData map property to allow for custom user data to be included in MANIFEST.json content that is deployed to an S3 Site bucket.

      • Userdata is scoped to a userdata keyname in MANIFEST.json
      • See the SpartaAmplify sample app for a complete example.
    • Added github.com/mweagle/Sparta/system.RunAndCaptureOSCommand

      • This is convenience function to support alternative io.Writer sinks for stdout and stderr.
    • Minor usability improvements to --status report output

  • 🐛 FIXED

v1.8.0 - The #postReInvent Edition ⌛️

  • ⚠️ BREAKING

    • Renamed archetype.CloudWatchLogsReactor to archetype.CloudWatchReactor
      • Also changed OnLogMessage to OnCloudWatchMessage
        • I consistently forget the fact that CloudWatch is more than logs
      • Moved the internal cloudwatchlogs package to the cloudwatch/logs import path
    • Renamed fluent typenames in github.com/mweagle/Sparta/aws/iam/builder to support Principal-based builders
    • Renamed step.NewTaskState to step.NewLambdaTaskState to enable type specific Step function services.
    • Simplified versioning Lambda resource so that the Lambda::Version resource is orphaned (via DeletionPolicy) rather than the prior implementation, which fetched all versions from the provisioned template and accumulated them over time.
      • This also obsoleted the ContextKeyLambdaVersions constant
  • 🏁 CHANGES

    • More documentation

    • Added Step function service integrations

      • See the SpartaStepServicefull project for an example of a service that:
        • Provisions no Lambda functions
        • Dockerizes itself
        • Pushes that image to ECR
        • Uses the resulting ECR Image URL as a Fargate Task in a Step function:
    • Added github.com/mweagle/Sparta/aws/iam/builder.IAMBuilder::ForPrincipals fluent builder. Example usage:

        "Statement": []spartaIAM.PolicyStatement{
          iamBuilder.Allow("sts:AssumeRole").
            ForPrincipals("states.amazonaws.com").
            ToPolicyStatement(),
    • Upgraded to docker login --password-stdin for local authentication. Previously used docker login --password. Example:

      INFO[0005] df64d3292fd6: Preparing
      INFO[0006] denied: Your Authorization Token has expired. Please run 'aws ecr get-login --no-include-email' to fetch a new one.
      INFO[0006] ECR push failed - reauthorizing               Error="exit status 1"
      INFO[0006] Login Succeeded
      INFO[0006] The push refers to repository [123412341234.dkr.ecr.us-west-2.amazonaws.com/argh]
      
    • Include docker -v output in log when calling BuildDockerImage

    • Added StateMachineNamedDecorator(stepFunctionResourceName) to supply the name of the Step function

    • Migrated all API-Gateway integration mappings to use the mapping override support in VTL.

      • This reduces the number of API-Gateway RegExp-based integration mappings and relies on a Lambda function returning a shape that matches the default application/json expectations:

        {
          "code" : int,
          "body" : ...,
          "headers": {
            "x-lowercase-header" : "foo",
          }
        }
      • The default shape can be customized by providing custom mapping templates to the IntegrationResponses

    • rest.MethodHandler:Headers has been deprecated.

      • Moving all header management to VTL eliminated the need to explicitly declare headers.
    • Added spartaDecorators.PublishAllResourceOutputs(cfResourceName, gocf.ResourceProperties) which adds all the associated resource Ref and Att values to the Stack Outputs

  • 🐛 FIXED

v1.7.3 - The Documentation Edition 📚

  • ⚠️ BREAKING
    • Renamed archetype.NewCloudWatchLogsReactor to archetype.NewCloudWatchReactor
  • 🏁 CHANGES
    • Moved all documentation into the master branch to make it a bit easier to update docs together with code.
      • See /docs_source/content/meta/_index.md for how to edit, preview, and submit.
    • Added archetype.NewCloudWatchScheduledReactor and archetype.NewCloudWatchEventedReactor
  • 🐛 FIXED

v1.7.2 - The Cloud Drift Edition v2 🌬☁️

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Moved decorator.DriftDetector to validator.DriftDetector and changed signature to ServiceValidationHookHandler

      • Clearly I was too focused on enabling drift detection than enabling it in an appropriate place.

      • Updated usage:

          import (
            "github.com/mweagle/Sparta/v3/validator"
          )
          workflowHooks := &sparta.WorkflowHooks{
            Validators: []sparta.ServiceValidationHookHandler{
              validator.DriftDetector(true),
            },
          }
    • Added LambdaFuncName to output when stack drift detected.

      • Example:

        WARN[0013] Stack drift detected                          Actual=debug Expected=info LambdaFuncName="Hello World" PropertyPath=/Environment/Variables/SPARTA_LOG_LEVEL Relation=NOT_EQUAL Resource=HelloWorldLambda80576f7b21690b0cb485a6b69c927aac972cd693
        
  • 🐛 FIXED

v1.7.1 - The Cloud Drift Edition 🌬☁️

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Added decorator.DriftDetector to optionally prevent operations in the presence of CloudFormation Drift.

      • Usage:

        workflowHooks := &sparta.WorkflowHooks{
          PreBuilds: []sparta.WorkflowHookHandler{
            decorator.DriftDetector(false),
          },
        }
      • Sample output:

        INFO[0001] Calling WorkflowHook                          Phase=PreBuild WorkflowHookContext="map[]"
        INFO[0001] Waiting for drift detection to complete       Status=DETECTION_IN_PROGRESS
        ERRO[0012] Stack drift detected                          Actual=debug Expected=info PropertyPath=/Environment/Variables/SPARTA_LOG_LEVEL Relation=NOT_EQUAL Resource=HelloWorldLambda80576f7b21690b0cb485a6b69c927aac972cd693
        INFO[0012] Invoking rollback functions
        ERRO[0012] Failed to provision service: DecorateWorkflow returned an error: stack MyHelloWorldStack-mweagle prevented update due to drift being detected
        
    • Usability improvements when errors produced. Previously the usage instructions were output on every failed command. Now they are only displayed if there are CLI argument validation errors.

    • Usability improvement to log individual validation errors if the CLI arguments are invalid.

  • 🐛 FIXED

    • Fixed latent issue where Sparta misreported its internal version

v1.7.0 - The Time Machine Edition 🕰

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Added LambdaAWSInfo.Interceptors support

      • Interceptors are functions (func(context.Context, json.RawMessage) context.Context) called in the normal event handling lifecycle to support cross cutting concerns. They are the runtime analog to WorkflowHooks.

      • The following stages are supported:

        • Begin: Called as soon as Sparta determines which user-function to invoke
        • BeforeSetup: Called before Sparta creates your lambda's context value
        • AfterSetup: Called after Sparta creates your lambda's context value
        • BeforeDispatch: Called before Sparta invokes your lambda function
        • AfterDispatch: Called after Sparta invokes your lambda function
        • Complete: Called immediately before Sparta returns your function return value(s) to AWS
      • The first interceptor is interceptor.RegisterXRayInterceptor(ctx, options) which creates a custom XRay Segment spanning your lambda's execution and supports:

        • Including the service BuildID in the Trace Annotation
        • Optionally including the incoming event, all log statements (trace and higher), and AWS request-id as Trace Metadata ONLY in the case when your lambda function returns an error.
          • Log messages are stored in a ring buffer and limited to 1024 entries.
      • This data is associated with XRay Traces in the console. Example:

      • See the SpartaXRayInterceptor repo for a complete sample

      • Go back in time to when you wish you had enabled debug-level logging before the error ever occurred.

    • Expose sparta.ProperName as framework name literal

    • Add lightweight Key-Value interface and S3 and DynamoDB implementations to support SpartaTodoBackend

  • 🐛 FIXED

v1.6.0 - The REST Edition 😴

  • ⚠️ BREAKING

    • Eliminate pre 1.0 GM Sparta function signature: type LambdaFunction func(*json.RawMessage, *LambdaContext, http.ResponseWriter, *logrus.Logger) 🎉
      • See the AWS Docs for officially supported signatures
    • Changed API Gateway response mapping to support body and header return values.
      • API Gateway lambda functions should use aws/apigateway.NewResponse to produce a new Response type with struct fields that are properly interpreted by the new $input.json('$.body') mapping expression.
      • The change was driven by the SpartaTodoBackend service's need to return both a body and HTTP location header.
  • 🏁 CHANGES

    • Add more go idiomatic sparta.NewAWSLambda(...) (*sparta.LambdaAWSInfo, error) constructor

      • The existing sparta.HandleAWSLambda function is deprecated and will be removed in a subsequent release
    • Added Sparta/archetype/rest package to streamline REST-based Sparta services.

      • This package includes a fluent builder (MethodHandler) and constructor function (RegisterResource) that transforms a rest.Resource implementing struct into an API Gateway resource.

      • Usage:

        // File: resource.go
        // TodoItemResource is the /todo/{id} resource
        type TodoItemResource struct {
        }
        // ResourceDefinition returns the Sparta REST definition for the Todo item
        func (svc *TodoItemResource) ResourceDefinition() (spartaREST.ResourceDefinition, error) {
        
          return spartaREST.ResourceDefinition{
            URL: todoItemURL,
            MethodHandlers: spartaREST.MethodHandlerMap{
              ...
            }
          }, nil
        }
        
        // File: main.go
        func() {
          myResource := &TodoItemResource{}
          resourceMap, resourcesErr := spartaREST.RegisterResource(apiGatewayInstance, myResource)
        }
      • Sample fluent method builder:

          // GET
          http.MethodGet: spartaREST.NewMethodHandler(svc.Get, http.StatusOK).
            StatusCodes(http.StatusInternalServerError).
            Privileges(svc.S3Accessor.KeysPrivilege("s3:GetObject"),
                        svc.S3Accessor.BucketPrivilege("s3:ListBucket")),
      • See SpartaTodoBackend for a complete example

        • The SpartaTodoBackend is a self-deploying CORS-accessible service that satisfies the TodoBackend online tests
    • Added Sparta/aws/accessor package to streamline S3-backed service creation.

      • Embed a services.S3Accessor type to enable utility methods for:
        • Put
        • Get
        • GetAll
        • Delete
        • DeleteAll
    • Added prealloc check to ensure that slices are preallocated when possible

  • 🐛 FIXED

    • Fix latent issue where CloudWatch Log ARN was malformed commit

v1.5.0 - The Observability Edition 🔭

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Expose sparta.InstanceID() that returns a random instance identifier for a single Lambda container instance

    • Add a self-monitoring function that publishes container-level metrics to CloudWatch.

      • Usage:

          import spartaCloudWatch "github.com/mweagle/Sparta/v3/aws/cloudwatch"
          func main() {
            ...
            spartaCloudWatch.RegisterLambdaUtilizationMetricPublisher(map[string]string{
              "BuildId":    sparta.StampedBuildID,
            })
            ...
          }
      • The optional map[string]string parameter is the custom Name-Value pairs to use as a CloudWatch Dimension

    • Add WorkflowHooks.Validators to support policy-based validation of the materialized template.

      • Each validator receives a complete read-only copy of the template
    • Add magefile actions in github.com/mweagle/Sparta/magefile to support cross platform scripting.

      • A Sparta service can use a standard magefile.go as in:

        // +build mage
        
        package main
        
        import (
          spartaMage "github.com/mweagle/Sparta/v3/magefile"
        )
        
        // Provision the service
        func Provision() error {
          return spartaMage.Provision()
        }
        
        // Describe the stack by producing an HTML representation of the CloudFormation
        // template
        func Describe() error {
          return spartaMage.Describe()
        }
        
        // Delete the service, iff it exists
        func Delete() error {
          return spartaMage.Delete()
        }
        
        // Status report if the stack has been provisioned
        func Status() error {
          return spartaMage.Status()
        }
        
        // Version information
        func Version() error {
          return spartaMage.Version()
        }

      which exposes the most common Sparta command line options.

      • Usage: mage status:

        $ mage status
        INFO[0000] ════════════════════════════════════════════════
        INFO[0000] ╔═╗╔═╗╔═╗╦═╗╔╦╗╔═╗   Version : 1.5.0
        INFO[0000] ╚═╗╠═╝╠═╣╠╦╝ ║ ╠═╣   SHA     : 8f199e1
        INFO[0000] ╚═╝╩  ╩ ╩╩╚═ ╩ ╩ ╩   Go      : go1.11.1
        INFO[0000] ════════════════════════════════════════════════
        INFO[0000] Service: MyHelloWorldStack-mweagle            LinkFlags= Option=status UTC="2018-10-20T04:46:57Z"
        INFO[0000] ════════════════════════════════════════════════
        INFO[0001] StackId                                       Id="arn:aws:cloudformation:us-west-2:************:stack/MyHelloWorldStack-mweagle/5817dff0-c5f1-11e8-b43a-503ac9841a99"
        INFO[0001] Stack status                                  State=UPDATE_COMPLETE
        INFO[0001] Created                                       Time="2018-10-02 03:14:59.127 +0000 UTC"
        INFO[0001] Last Update                                   Time="2018-10-19 03:23:00.048 +0000 UTC"
        INFO[0001] Tag                                           io:gosparta:buildId=7ee3e1bc52f15c4a636e05061eaec7b748db22a9
        
  • 🐛 FIXED

    • Fix latent issue where multiple archetype handlers of the same type would collide.

v1.4.0

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Simplified CustomResource creation and dispatch logic

      • The benefit of this is that users can define new CustomResourceCommand implementing CustomResources and have them roundtripped and instantiated at AWS Lambda execution time. 🎉

      • I'll write up more documentation, but the steps to defining your own Lambda-backed custom resource:

        1. Create a resource that embeds gocf.CloudFormationCustomResource and your custom event properties:

            type HelloWorldResourceRequest struct {
              Message *gocf.StringExpr
            }
            type HelloWorldResource struct {
              gocf.CloudFormationCustomResource
              HelloWorldResourceRequest
            }
        2. Register the custom resource provider with RegisterCustomResourceProvider

        3. Implement CustomResourceCommand

      • At provisioning time, an instance of your CustomResource will be created and the appropriate functions will be called with the incoming CloudFormationLambdaEvent.

        • Unmarshal the event.ResourceProperties map into your command handler instance and perform the requested operation.
    • Added a set of archetype.* convenience functions to create sparta.LambdaAWSInfo for specific event types.

      • The archetype.* package exposes creation functions to simplify common lambda types. Sample S3 Reactor handler:

          func echoS3Event(ctx context.Context, s3Event awsLambdaEvents.S3Event) (interface{}, error) {
            // Respond to s3:ObjectCreated:*", "s3:ObjectRemoved:*" S3 events
          }
          func main() {
            lambdaFn, _ := spartaArchetype.NewS3Reactor(spartaArchetype.S3ReactorFunc(echoS3Event),
              gocf.String("MY_S3_BUCKET"),
              nil)
              // ...
          }
    • Added --nocolor command line option to suppress colorized output. Default value: false.

    • When a service provision fails, only report resources that failed to succeed.

      • Previously, resources that were cancelled due to other resource failures were also logged as ERROR statements.
    • Added decorator.CloudWatchErrorAlarmDecorator(...) to create per-Lambda CloudWatch Alarms.

      • Sample usage:

          lambdaFn.Decorators = []sparta.TemplateDecoratorHandler{
            spartaDecorators.CloudWatchErrorAlarmDecorator(1, // Number of periods
              1, // Number of minutes per period
              1, // GreaterThanOrEqualToThreshold value
              gocf.String("SNS_TOPIC_ARN_OR_RESOURCE_REF")),
          }
    • Added decorator.NewLogAggregatorDecorator which forwards all CloudWatch log messages to a Kinesis stream.

      • See SpartaPProf for an example of forwarding CloudWatch log messages to Google StackDriver
    • Added decorator.CloudFrontSiteDistributionDecorator to provision a CloudFront distribution with a custom Route53 name and optional SSL support.

      • Sample usage:

        func distroHooks(s3Site *sparta.S3Site) *sparta.WorkflowHooks {
          hooks := &sparta.WorkflowHooks{}
          siteHookDecorator := spartaDecorators.CloudFrontSiteDistributionDecorator(s3Site,
            "subdomainNameHere",
            "myAWSHostedZone.com",
            "arn:aws:acm:us-east-1:OPTIONAL-ACM-CERTIFICATE-FOR-SSL")
          hooks.ServiceDecorators = []sparta.ServiceDecoratorHookHandler{
            siteHookDecorator,
          }
          return hooks
        }
      • Supply the WorkflowHooks struct to MainEx to annotate your service with an example CloudFront distribution. Note that CF distributions introduce a significant provisioning delay.

      • See SpartaHTML for more

    • Added decorator.S3ArtifactPublisherDecorator to publish an arbitrary JSON file to an S3 location

      • This is implemented as Sparta-backed CustomResource
    • Added status command to produce a report of a provisioned service. Sample usage:

      $ go run main.go status --redact
      INFO[0000] ════════════════════════════════════════════════
      INFO[0000] ╔═╗╔═╗╔═╗╦═╗╔╦╗╔═╗   Version : 1.4.0
      INFO[0000] ╚═╗╠═╝╠═╣╠╦╝ ║ ╠═╣   SHA     : 3681d28
      INFO[0000] ╚═╝╩  ╩ ╩╩╚═ ╩ ╩ ╩   Go      : go1.11.1
      INFO[0000] ════════════════════════════════════════════════
      INFO[0000] Service: SpartaPProf-mweagle                  LinkFlags= Option=status UTC="2018-10-05T12:24:57Z"
      INFO[0000] ════════════════════════════════════════════════
      INFO[0000] StackId                                       Id="arn:aws:cloudformation:us-west-2:************:stack/SpartaPProf-mweagle/da781540-c764-11e8-9bf1-0aceeffcea3c"
      INFO[0000] Stack status                                  State=CREATE_COMPLETE
      INFO[0000] Created                                       Time="2018-10-03 23:34:21.142 +0000 UTC"
      INFO[0000] Tag                                           io:gosparta:buildTags=googlepprof
      INFO[0000] Tag                                           io:gosparta:buildId=c3fbe8c289c3184efec842dca56b9bf541f39d21
      INFO[0000] Output                                        HelloWorldFunctionARN="arn:aws:lambda:us-west-2:************:function:SpartaPProf-mweagle_Hello_World"
      INFO[0000] Output                                        KinesisLogConsumerFunctionARN="arn:aws:lambda:us-west-2:************:function:SpartaPProf-mweagle_KinesisLogConsumer"
    • Replaced Makefile with magefile to better support cross platform builds.

      • This is an internal only change and does not impact users

      • For CONTRIBUTORS, to use the new mage targets:

        $> go get -u github.com/magefile/mage
        $> mage -l
        
        Targets:
          build                           the application
          clean                           the working directory
          describe                        runs the `TestDescribe` test to generate a describe HTML output file at graph.html
          ensureAllPreconditions          ensures that the source passes *ALL* static `ensure*` precondition steps
          ensureFormatted                 ensures that the source code is formatted with goimports
          ensureLint                      ensures that the source is `golint`ed
          ensureSpelling                  ensures that there are no misspellings in the source
          ensureStaticChecks              ensures that the source code passes static code checks
          ensureTravisBuildEnvironment    is the command that sets up the Travis environment to run the build.
          ensureVet                       ensures that the source has been `go vet`ted
          generateBuildInfo               creates the automatic buildinfo.go file so that we can stamp the SHA into the binaries we build...
          generateConstants               runs the set of commands that update the embedded CONSTANTS for both local and AWS Lambda execution
          installBuildRequirements        installs or updates the dependent packages that aren't referenced by the source, but are needed to build the Sparta source
          publish                         the latest source
          test                            runs the Sparta tests
          testCover                       runs the test and opens up the resulting report
          travisBuild                     is the task to build in the context of a Travis CI pipeline
        
    • Added misspell static check as part of mage test to catch misspellings

  • 🐛 FIXED

v1.3.0

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • Update branchname and release tag to support Go 1.11 modules.
  • 🐛 FIXED

v1.2.1

v1.2

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Added support for SQS event triggers.

      • SQS event sources use the same EventSourceMappings entry that is used by DynamoDB and Kinesis. For example:

        lambdaFn.EventSourceMappings = append(lambdaFn.EventSourceMappings,
            &sparta.EventSourceMapping{
              EventSourceArn: gocf.GetAtt(sqsResourceName, "Arn"),
              BatchSize:      2,
            })
        • Where sqsResourceName is the name of a CloudFormation resource provisioned by the stack
        • Use the aws.SQSEvent value type as the incoming message
      • See the SpartaSQS project for a complete example

    • Migrated describe command to use Cytoscape.JS library

      • Cytoscape supports several layout algorithms and per-service node icons.
    • Added APIGatewayEnvelope type to allow struct embedding and overriding of the Body field. Example:

      // FeedbackBody is the typed body submitted in a FeedbackRequest
      type FeedbackBody struct {
        Language string `json:"lang"`
        Comment  string `json:"comment"`
      }
      
      // FeedbackRequest is the typed input to the
      // onFeedbackDetectSentiment
      type FeedbackRequest struct {
        spartaEvents.APIGatewayEnvelope
        Body FeedbackBody `json:"body"`
      }
    • The previous APIGatewayRequest remains unchanged:

      type APIGatewayRequest struct {
        APIGatewayEnvelope
        Body interface{} `json:"body"`
      }
  • 🐛 FIXED

    • Fixed latent bug where dynamically created DynamoDB and Kinesis Event Source mappings had insufficient IAM privileges
    • Fixed latent bug where the S3Site source directory was validated before go:generate could have been executed. This resulted in cases where fresh-cloned repositories would not self-deploy.
      • The filepath existence requirement was moved further into the provision workflow to support inline JS build operations.

v1.1.1

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • Re-implemented the explore command.
      • The explore command provides a terminal-based UI to interactively submit events to provisioned Lambda functions.
      • The set of JSON files are determined by walking the working directory for all *.json files
      • Example:
    • Eliminate redundant Statement entries in AssumeRolePolicyDocument
    • Add sparta.StampedBuildID global variable to access the BuildID value (either user defined or automatically generated)
    • Added -z/--timestamps command line flag to optionally include UTC timestamp prefix on every log line.
    • Prefer git rev-parse HEAD value for fallback BuildID value iff --buildID isn't provided as a provision command line argument. If an error is detected calling git, the previous randomly initialized buffer behavior is used.
  • 🐛 FIXED

v1.1.0

  • ⚠️ BREAKING

    • Removed lambdabinary build tags from BuildDockerImage
      • AWS native support for Go in AWS caused a significant difference in standard vs lambdabinary build targets executed which prevented custom application options from being respected.
  • 🏁 CHANGES

    • Change EventSourceMapping.EventSourceArn from string to interface{} type.

      • This change was to allow for provisioning of Pull-based event sources being provisioned in the same Sparta application as the lambda definition.
      • For example, to reference a DynamoDB Stream created by in a ServiceDecoratorHook for the myDynamoDBResourceName resource you can now use:
      lambdaFn.EventSourceMappings = append(lambdaFn.EventSourceMappings,
        &sparta.EventSourceMapping{
          EventSourceArn:   gocf.GetAtt(myDynamoDBResourceName, "StreamArn"),
          StartingPosition: "TRIM_HORIZON",
          BatchSize:        10,
        })
    • Updated describe output format and upgraded to latest versions of static HTML assets.

      • Example:
    • Delegate CloudFormation template aggregation to go-cloudcondenser

    • Exposed ReservedConcurrentExecutions option for Lambda functions.

    • Exposed DeadLetterConfigArn property to support custom DLQ destinations.

    • Added IAM sparta.IAMRolePrivilege fluent builder type in the github.com/mweagle/Sparta/aws/iam/builder. Sample usage:

      iambuilder.Allow("ssm:GetParameter").ForResource().
        Literal("arn:aws:ssm:").
        Region(":").
        AccountID(":").
        Literal("parameter/MyReservedParameter").
        ToPrivilege()
    • Remove io:gosparta:home and io:gosparta:sha Tags from Lambda functions

    • Standardize on Lambda function naming in AWS Console

    • Reduced AWS Go binary size by 20% or more by including the -s and -w link flags

    • Added github.com/mweagle/Sparta/aws/cloudformation.UserAccountScopedStackName to produce CloudFormation Stack names that are namespaced by AWS account username

    • Ensure Pre and Post deploy hooks are granted proper permissions

    • Added Sparta/aws/apigateway.Error to support returning custom API Gateway errors

    • API Gateway error responses are now converted to JSON objects via a Body Mapping template:

      "application/json": "$input.path('$.errorMessage')",
    • Added check for Linux only package sysinfo. This Linux-only package is ignored by go get because of build tags and cannot be safely imported. An error will be shown if the package cannot be found:

      ERRO[0000] Failed to validate preconditions: Please run
      `go get -v github.com/zcalusic/sysinfo` to install this Linux-only package.
      This package is used when cross-compiling your AWS Lambda binary and cannot
      be safely imported across platforms. When you `go get` the package, you may
      see errors as in `undefined: syscall.Utsname`. These are expected and can be
      ignored
      
    • Added additional build-time static analysis check for suspicious coding practices with gas

  • 🐛 FIXED

    • 101
    • Fixed latent bug where NewAuthorizedMethod didn't properly preserve the AuthorizerID when serializing to CloudFormation. This also forced a change to the function signature to accept a gocf.Stringable satisfying type for the authorizerID.

v1.0.1

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • Added events package for Sparta specific event types.
      • Initial top level event is APIGatewayRequest type for responding to API-Gateway mediated requests.
    • Prefer stamping buildID into binary rather than providing as environment variable. Previously the stamped buildID was the env.SPARTA_BUILD_ID mutable variable.
    • Remove dependency on go-validator
  • 🐛 FIXED

v1.0.0

🎉 AWS Lambda for Go Support 🎉

  • Sparta Go function signature has been changed to ONLY support the official AWS Lambda Go signatures

    • func ()
    • func () error
    • func (TIn) error
    • func () (TOut, error)
    • func (context.Context) error
    • func (context.Context, TIn) error
    • func (context.Context) (TOut, error)
    • func (context.Context, TIn) (TOut, error)
  • See the lambda.Start docs or the related AWS Blog Post for more information.

  • ALL Sparta Go Lambda function targets MUST now use the sparta.HandleAWSLambda creation function, a function pointer that satisfies one of the supported signatures.

  • Providing an invalid signature such as func() string will produce a provision time error as in:

    Error: Invalid lambda returns: Hello World. Error: handler returns a single value, but it does not implement error
    
  • ⚠️ BREAKING

    • Removed sparta.NewLambda constructor
    • Removed sparta.NewServeMuxLambda proxying function
    • Removed sparta.LambdaFunction type
    • ContextKeyLambdaContext is no longer published into the context. Prefer the official AWS FromContext() function to access the AWS Go Lambda context.
    • Moved DashboardDecorator to decorators namespace
    • Removed explore command line option as proxying tier is no longer supported
    • Changed all logrus imports to proper lowercase format
  • 🏁 CHANGES

    • All decorators are now implemented as slices.

      • Existing single-valued fields remain supported, but deprecated
      • There are convenience types to adapt free functions to their *Handler interface versions:
        • TemplateDecoratorHookFunc
        • WorkflowHookFunc
        • ArchiveHookFunc
        • ServiceDecoratorHookFunc
        • RollbackHookFunc
    • Added CodeDeployServiceUpdateDecorator to support safe AWS Lambda deploys

    • Added requestID and lambdaARN request-scoped *logrus.Entry to context argument.

      • This can be accessed as in:
        contextLogger, contextLoggerOk := ctx.Value(sparta.ContextKeyRequestLogger).(*logrus.Entry)
        if contextLoggerOk {
          contextLogger.Info("Request scoped log")
        }
      • The existing *logrus.Logger entry is also available in the context via:
        logger, loggerOk := ctx.Value(sparta.ContextKeyLogger).(*logrus.Logger)
    • NewMethod now accepts variadic parameters to limit how many API Gateway integration mappings are defined

    • Added SupportedRequestContentTypes to NewMethod to limit API Gateway generated content.

    • Added apiGateway.CORSOptions field to configure CORS settings

    • Added Add S3Site.CloudFormationS3ResourceName()

      • This value can be used to scope CORS access to a dynamoc S3 website as in:
      apiGateway.CORSOptions = &sparta.CORSOptions{
        Headers: map[string]interface{}{
          "Access-Control-Allow-Origin":  gocf.GetAtt(s3Site.CloudFormationS3ResourceName(),
          "WebsiteURL"),
        }
      }
      • Improved CLI usability in consistency of named outputs, formatting.
    • 🐛 FIXED

      • Fix latent bug where provision would not consistently create new API Gateway Stage events.

v0.30.1

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • Improved API-Gateway CORS support. The following customizations are opt-in:
      • Parameterize CORS headers returned by OPTIONS via API.CORSOptions
      • Add SupportedRequestContentTypes to Method struct. This is a slice of supported content types that define what API-Gateway Content-Type values are supported. Limiting the set of supported content types reduces CloudFormation template size.
      • Add variadic possibleHTTPStatusCodeResponses values to NewMethod. If defined, Sparta will ONLY generate IntegrationResponse entries for the possible codes (including the default HTTP status code). The previous, and default behavior, is to generate IntegrationResponse entries for ALL valid HTTP status codes.
    • Include per-resource CloudFormation provisioning times in output log
    • Humanize magnitude output values and times with go-humanize
    • Replace CloudFormation polling log output with spinner
      • This feedback is only available in normal CLI output. JSON formatted output remains unchanged.
    • Usability improvements for Windows based builds
  • 🐛 FIXED
    • Re-enable cloudformation:DescribeStacks and cloudformation:DescribeStackResource privileges to support HTML based deployments

v0.30.0

  • ⚠️ BREAKING
    • Tags for dependent resources no longer available via sparta.Discover
    • Remove public sparta Tag* constants that were previously reserved for Discover support.
  • 🏁 CHANGES
    • Change sparta.Discover to use Environment data rather than CloudFormation API calls.
    • See SpartaDynamoDB for sample usage of multiple lambda functions depending on a single, dynamically provisioned Dynamo table.
    • Include BuildID in Lambda environment via SPARTA_BUILD_ID environment variable.
  • 🐛 FIXED
    • Correct CLI typo

v0.20.4

  • ⚠️ BREAKING

    • Changed step.NewStateMachine signature to include StateMachineName as first argument per Nov 15th, 2017 release
  • 🏁 CHANGES

    • Add profile command

      • Profile snapshots are enabled via:
      sparta.ScheduleProfileLoop(nil, 5*time.Second, 30*time.Second, "heap")
      • Profile snapshots are published to S3 and are locally aggregated across all lambda instance publishers. To view the ui, run the profile Sparta command.
      • See the SpartaPProf sample for a service that installs profiling hooks.
      • Ensure you have the latest pprof UI via go get -u -v github.com/google/pprof
      • The standard profile names are available, as well as a cpu type implied by a non-zero time.Duration supplied as the third parameter to ScheduleProfileLoop.
    • Eliminate unnecessary logging in AWS lambda environment

    • Log NodeJS process.uptime()

  • 🐛 FIXED

    • Added more constructive message when working directory for go build doesn't contain main package.

v0.20.3

  • ⚠️ BREAKING
  • 🏁 CHANGES
  • 🐛 FIXED
    • Fixed explore interactive debugging instructions

v0.20.2

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Added support for Step functions.

      • Step functions are expressed via a combination of: states, NewStateMachine, and adding a StateMachineDecorator as a service hook.
      • See the SpartaStep sample for a service that provisions a simple roll die state machine.
    • Usability improvements & enhancements for CLI log output. Text-formatted output now includes cleaner header as in:

      INFO[0000] ══════════════════════════════════════════════════════════════
      INFO[0000]    _______  ___   ___  _________
      INFO[0000]   / __/ _ \/ _ | / _ \/_  __/ _ |     Version : 0.20.2
      INFO[0000]  _\ \/ ___/ __ |/ , _/ / / / __ |     SHA     : 740028b
      INFO[0000] /___/_/  /_/ |_/_/|_| /_/ /_/ |_|     Go      : go1.9.1
      INFO[0000]
      INFO[0000] ══════════════════════════════════════════════════════════════
      INFO[0000] Service: SpartaStep-mweagle                   LinkFlags= Option=provision UTC="2017-11-01T01:14:31Z"
      INFO[0000] ══════════════════════════════════════════════════════════════
      
    • Added megacheck to compile pipeline. Fixed issues.

    • Corrected inline Go examples to use proper function references & signatures.

  • 🐛 FIXED

    • Handle case where multipart forms with empty values weren't handled #74

v0.20.1

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • Add sparta.LambdaName to return the reflection-discovered name of an http.HandleFunc instance.
  • 🐛 FIXED
    • Fixed issue with --describe not rendering CloudFormation template properly
    • Better handle failures when posting body - thanks @nylar

v0.20.0

⭐ Deprecation Notice

The sparta.LambdaFunc signature is officially deprecated in favor of http.HandlerFunc and will be removed in an upcoming release. See below for more information

  • ⚠️ BREAKING

    • Changed NewLambdaHTTPHandler to NewServeMuxLambda
    • Remove obsolete InvokeID from LambdaContext
    • Changed codePipelineTrigger CLI arg name to codePipelinePackage
  • 🏁 CHANGES

    • Eliminated NodeJS cold start cp & chmod penalty! 🔥

      • Prior to this release, the NodeJS proxying code would copy the embedded binary to /tmp and add the executable flag prior to actually launching the binary. This had a noticeable performance penalty for startup.
      • This release embeds the application or library in a ./bin directory with the file permissions set so that there is no additional filesystem overhead on cold-start. h/t to StackOverflow for the tips.
    • Migrated all IPC calls to protocolBuffers.

      • Message definitions are in the proxy directory.
    • The client-side log level (eg: --level debug) is carried into the AWS Lambda Code package.

      • Provisioning a service with --level debug will log everything at logger.Debug level and higher including all AWS API calls made both at provision and Lambda execution time.
      • Help resolve "Works on My Stack" syndrome.
    • HTTP handler panic events are now recovered and the traceback logged for both NodeJS and cgo deployments

    • Introduced sparta.HandleAWSLambda

      • sparta.HandleAWSLambda accepts standard http.RequestFunc signatures as in:

        func helloWorld(w http.ResponseWriter, r *http.Request) {
          ...
        }
        
        lambdaFn := sparta.HandleAWSLambda("Hello HTTP World",
          http.HandlerFunc(helloWorld),
          sparta.IAMRoleDefinition{})
      • This allows you to chain middleware for a lambda function as if it were a standard HTTP handler. Say, for instance: X-Ray.

      • The legacy sparta.LambdaFunction is still supported, but marked for deprecation. You will see a log warning as in:

        WARN[0045] DEPRECATED: sparta.LambdaFunc() signature provided. Please migrate to http.HandlerFunc()
        
      • LambdaContext and *logrus.Logger are now available in the requext.Context() via:

        • sparta.ContextKeyLogger => *logrus.Logger
        • sparta.ContextKeyLambdaContext => *sparta.LambdaContext
      • Example:

        • loggerVal, loggerValOK := r.Context().Value(sparta.ContextKeyLogger).(*logrus.Logger)
    • Added support for CodePipeline

    • Upgraded NodeJS to nodejs6.10 runtime

    • Parity between NodeJS and Python/cgo startup output

    • Both NodeJS and cgo based Sparta applications now log equivalent system information.

      • Example:

        {
          "level": "info",
          "msg": "SystemInfo",
          "systemInfo": {
            "sysinfo": {
              "version": "0.9.1",
              "timestamp": "2017-09-16T17:07:34.491807588Z"
            },
            "node": {
              "hostname": "ip-10-25-51-97",
              "machineid": "0046d1358d2346adbf8851e664b30d25",
              "hypervisor": "xenhvm",
              "timezone": "UTC"
            },
            "os": {
              "name": "Amazon Linux AMI 2017.03",
              "vendor": "amzn",
              "version": "2017.03",
              "architecture": "amd64"
            },
            "kernel": {
              "release": "4.9.43-17.38.amzn1.x86_64",
              "version": "#1 SMP Thu Aug 17 00:20:39 UTC 2017",
              "architecture": "x86_64"
            },
            "product": {},
            "board": {},
            "chassis": {},
            "bios": {},
            "cpu": {
              "vendor": "GenuineIntel",
              "model": "Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz",
              "cache": 25600,
              "threads": 2
            },
            "memory": {}
          },
          "time": "2017-09-16T17:07:34Z"
        }
  • 🐛 FIXED

    • There were more than a few

v0.13.2

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • Changed how Lambda FunctionName values are defined so that function name uniqueness is preserved for free, imported free, and struct-defined functions
  • 🐛 FIXED

v0.13.1

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • Changed how Lambda FunctionName values are defined so that same-named functions provisioned across multiple stacks remain unique. This is done by prefixing the function name with the CloudFormation StackName.
    • Cleaned up S3 upload log statements to prefer relative paths iff applicable
  • 🐛 FIXED

v0.13.0

  • ⚠️ BREAKING

    • Removed sparta.NewNamedLambda. Stable, user-defined function names can be supplied via the SpartaOptions.Name field.
  • 🏁 CHANGES

    • CloudWatch Dashboard Support!

      • You can provision a CloudWatch dashboard that provides a single overview and link portal for your Lambda-based service. Use the new sparta.DashboardDecorator function to automatically create a dashboard. This leverages the existing WorkflowHooks functionality.
      • Example:
      // Setup the DashboardDecorator lambda hook
      workflowHooks := &sparta.WorkflowHooks{
        ServiceDecorator: sparta.DashboardDecorator(lambdaFunctions, 60),
      }
      • Where the 60 value is the CloudWatch time series period.
      • The CloudWatch Dashboard URL will be included in your stack's Outputs as in:
      INFO[0064] Stack output                                  Description="CloudWatch Dashboard URL" Key=CloudWatchDashboardURL Value="https://us-west-2.console.aws.amazon.com/cloudwatch/home?region=us-west-2#dashboards:name=SpartaXRay-mweagle"
      
    • XRay support added

      • added LambdaFunctionOptions.TracingConfig field to LambdaFunctionOptions
      • added XRay IAM privileges to default IAM role settings:
        • xray:PutTraceSegments
        • xray:PutTelemetryRecords
      • See AWS blog for more information
    • added LambdaFunctionOptions.Tags to support tagging AWS Lambda functions

    • added SpartaGitHash output to both CLI and CloudWatch Dashboard output. This is in addition to the SpartaVersion value (which I occasionally have failed to update).

  • 🐛 FIXED

    • Fixed latent issue where SpartaOptions.Name field wasn't consistently used for function names.

v0.12.1

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • added Sparta/aws/cloudformation.UserScopedStackName() to generate username-suffixed CloudFormation StackNames
  • 🐛 FIXED

v0.12.0

v0.11.2

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Added --inplace/-c command line option to support safe, concurrent updating of Lambda code packages

      • If enabled AND the stack update changeset reports only modifications to Lambda functions, then Sparta will use the AWS Lambda API to update the function code.
      • If enabled AND additional mutations are reported, you'll see an error as in:
      ERRO[0022] Unsupported in-place operations detected:
        Add for IAMRole9fd267df3a3d0a144ae11a64c7fb9b7ffff3fb6c (ResourceType: AWS::IAM::Role),
        Add for mainhelloWorld2Lambda32fcf388f6b20e86feb93e990fa8decc5b3f9095 (ResourceType: AWS::Lambda::Function)
      
    • Prefer NewRecorder to internal type for CGO marshalling

    • Added --format/-f command line flag [text, txt, json] to specify logfile output format. Default is text.

  • 🐛 FIXED

v0.11.1

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Support Go 1.8 newly optional GOPATH environment variable
    • Python proxied cgo builds now preserve the transformed source in the ./sparta scratch space directory.
    • Sparta assigned AWS Lambda function names now strip the leading SCM prefix. Example:
    github.com/mweagle/SpartaPython.HelloWorld

    becomes:

    mweagle/SpartaPython.HelloWorld
    • Upgrade to Mermaid 7.0.0
    • Use stable PolicyName in IAM::Role definitions to minimize CloudFormation resource update churn
  • 🐛 FIXED

    • Fixed latent bug where S3 bucket version check didn't respect --noop mode.
    • Fixed latent cgo bug where command line arguments weren't properly parsed

v0.11.0

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • 🎉 Python CGO support added. See the https://github.com/mweagle/SpartaPython project for example usage!
      • In preliminary testing, the Python CGO package provides significant cold start and hot-execution performance benefits.
    • Migrated dependency management to dep
  • 🐛 FIXED
    • Fixed latent bug where DynamoDB EventSource mappings ResourceARNs weren't properly serialized.
    • Fixed latent bug where code pushed to S3 version-enabled buckets didn't use the latest VersionID in the AWS Lambda Code value.

v0.10.0

  • ⚠️ BREAKING

    • describe option now requires -b/--s3Bucket argument
    • Changed signature of aws/s3/CreateS3RollbackFunc to accept full S3 URL, including versionId query param
    • Signatures for sparta.Provision and sparta.Discover updated with new arguments
  • 🏁 CHANGES

    • Add -p/--codePipelineTrigger command line option to generate CodePipeline deployment package
    • Add sparta.RegisterCodePipelineEnvironment to define environment variables in support of CloudFormation Deployments. Example:
    func init() {
      sparta.RegisterCodePipelineEnvironment("test", map[string]string{
        "MESSAGE": "Hello Test!",
      })
      sparta.RegisterCodePipelineEnvironment("production", map[string]string{
        "MESSAGE": "Hello Production!",
      })
    }
    • Add support for Environment and KmsKeyArn properties to LambdaFunctionOptions. See AWS for more information.
    • Move all build artifacts to ./sparta directory
    • -n/--noop argument orphans S3 artifacts in ./sparta directory
    • Add support for S3 version policy enabled buckets
      • Artifacts pushed to S3 version-enabled buckets now use stable object keys. Rollback functions target specific versions if available.
    • Cleanup log statements
    • Add sparta/aws/session.NewSessionWithLevel() to support AWS LogLevel parameter
  • 🐛 FIXED

v0.9.3

  • ⚠️ BREAKING

  • 🏁 CHANGES

    • Added LambdaFunctionOptions.SpartaOptions struct
      • The primary use case is to support programmatically generated lambda functions that must be disambiguated by their Sparta name. Sparta defaults to reflection based function name identification.
    • Added --ldflags support to support lightweight dynamic string variables
      • Usage: go run main.go provision --level info --s3Bucket $(S3_BUCKET) --ldflags "-X main.dynamicValue=SampleValue"
  • 🐛 FIXED

v0.9.2

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • Move Sparta-related provisioning values from stack Outputs to Tags.
    • Add support for go BuildTags to support environment settings.
    • Added Sparta/aws/cloudformation functions to support stack creation.
    • Added Sparta/aws/s3 functions to encapsulate common S3 operations.
    • Added Sparta/zip functions to expose common ZIP related functions.
    • Legibility enhancements for describe output
    • sparta.CloudFormationResourceName proxies to github.com/mweagle/Sparta/aws/cloudformation.CloudFormationResourceName. The sparta package function is deprecated and will be removed in a subsequent release.
  • 🐛 FIXED
    • Fixed latent bug in github.com/mweagle/Sparta/zip.AddToZip where the supplied ZipWriter was incorrectly closed on function exit.
    • Fixed latent parsing userdata input
    • Fixed latent issue where empty ChangeSets were applied rather than deleted.

v0.9.1

  • ⚠️ BREAKING
  • 🏁 CHANGES
    • Improved describe output. Includes APIGateway resources and more consistent UI.
    • Additive changes to WorkflowHooks
      • Context property to set the initial context for Workflow hook execution
      • ServiceDecorator type to define service-scoped AWS resources. Previously, template decoration was bound to specific Lambda functions.
    • Published related SpartaVault: use AWS KMS to encrypt secrets as Go variables. See the KMS Docs for information.
    • Add Godeps support
  • 🐛 FIXED
    • Fixed latent bug when adding custom resources to the ZIP archive via ArchiveHook. ArchiveHook is now called after core Sparta assets are injected into archive.

v0.9.0

  • ⚠️ BREAKING

    • NewMethod and NewAuthorizedMethod for APIGateway definitions have been changed to include new, final parameter that marks the default integration response code.

      • Prior to this change, Sparta would automatically use http.StatusOK for all non-POST requests, and http.StatusCreated for POST requests. The change allows you to control whitelisted headers to be returned through APIGateway as in:
      // API response struct
      type helloWorldResponse struct {
        Location string `json:"location"`
        Body     string `json:"body"`
      }
      //
      // Promote the location key value to an HTTP header
      //
      apiGWMethod, _ := apiGatewayResource.NewMethod("GET", http.StatusOK)
      apiGWMethod.Responses[http.StatusOK].Parameters = map[string]bool{
        "method.response.header.Location": true,
      }
      apiGWMethod.Integration.Responses[http.StatusOK].Parameters["method.response.header.Location"] = "integration.response.body.location"
  • 🏁 CHANGES

    • (@sdbeard) Added sparta.NewNamedLambda that allows you to set stable AWS Lambda FunctionNames

    • Added spartaCF.AddAutoIncrementingLambdaVersionResource to support Lambda function versions. Should be called from a TemplateDecorator. Usage:

      autoIncrementingInfo, autoIncrementingInfoErr := spartaCF.AddAutoIncrementingLambdaVersionResource(serviceName,
        lambdaResourceName,
        cfTemplate,
        logger)
      if nil != autoIncrementingInfoErr {
        return autoIncrementingInfoErr
      }
    • Added new CloudWatch Metrics for lambda execution

    • Removed all NodeJS shim dependencies from ./resources/provision/package.json

    • Added utility CloudFormation script ./aws/cloudformation/cli/describe.go which produces a JSON serialization of a DescribeStacksOutput struct for build-time discovery of cluster-scoped resources.

    • Relaxed constraint that an API GW resource is bound to single Sparta lambda function. You can now register per-HTTP method name lambda functions for the same API GW resource.

    • Added Contributors section to README

  • 🐛 FIXED

v0.8.0

  • ⚠️ BREAKING

    • TemplateDecorator signature changed to include context map[string]interface{} to support sharing state across WorkflowHooks (below).
  • 🏁 CHANGES

    • Add SpartaBuildID stack output with build ID
    • WorkflowHooks
      • WorkflowHooks enable an application to customize the ZIP archive used as the AWS Lambda target rather than needing to embed resources inside their Go binary
      • They may also be used for Docker-based mixed topologies. See
    • Add optional -i/--buildID parameter for provision.
      • The parameter will be added to the stack outputs
      • A random value will be used if non is provided on the command line
    • Artifacts posted to S3 are now scoped by serviceName
    • Add sparta.MainEx for non-breaking signature extension
  • 🐛 FIXED

    • (@sdbeard) Fixed latent bug in Kinesis event source subscriptions that caused ValidationErrors during provisioning:

      ERRO[0028] ValidationError: [/Resources/IAMRole3dbc1b4199ad659e6267d25cfd8cc63b4124530d/Type/Policies/0/PolicyDocument/Statement/5/Resource] 'null' values are not allowed in templates
          status code: 400, request id: ed5fae8e-7103-11e6-8d13-b943b498f5a2
    • Fixed latent bug in ConvertToTemplateExpression when parsing input with multiple AWS JSON fragments.

    • Fixed latent bug in sparta.Discover which prevented dependent resources from being discovered at Lambda execution time.

    • Fixed latent bug in explore.NewAPIGatewayRequest where whitelisted param keynames were unmarshalled to method.request.TYPE.VALUE rather than TYPE.

v0.7.1

v0.7.0

  • ⚠️ BREAKING
    • TemplateDecorator signature changed to include serviceName, S3Bucket, and S3Key to allow for decorating CloudFormation with UserData to support alternative topology deployments.
    • CommonIAMStatements changed from map[string][]iamPolicyStatement to struct with named fields.
    • PushSourceConfigurationActions changed from map[string][]string to struct with named fields.
    • Eliminated goptions
  • 🏁 CHANGES
    • Moved CLI parsing to Cobra
      • Applications can extend the set of flags for existing Sparta commands (eg, provision can include --subnetIDs) as well as add their own top level commands to the CommandLineOptions exported values. See SpartaCICD for an example.
    • Added Sparta/aws/cloudformation ConvertToTemplateExpression to convert string value into Fn::Join compatible representation. Parses inline AWS references and supports user-defined template properties.
    • Added sparta/aws/iam PolicyStatement type
    • Upgraded describe output to use Mermaid 6.0.0
    • All goreportcard issues fixed.
  • 🐛 FIXED
    • Fixed latent VPC provisioning bug where VPC/Subnet IDs couldn't be provided to template serialization.

v0.6.0

  • ⚠️ BREAKING
    • TemplateDecorator signature changed to include map[string]string to allow for decorating CloudFormation resource metadata
  • 🏁 CHANGES
    • All NodeJS CustomResources moved to go
    • Add support for user-defined CloudFormation CustomResources via LambdaAWSInfo.RequireCustomResource
    • DiscoveryInfo struct now includes TagLogicalResourceID field with CloudFormation Resource ID of calling lambda function
  • 🐛 FIXED
    • N/A

v0.5.5

This release includes a major internal refactoring to move the current set of NodeJS Lambda-backed CloudFormation CustomResources to Sparta Go functions. The two migrated CustomActions are:

  • The S3 event source configuration
  • Provisioning an S3-static site

Both are implemented using cloudformationresources. There are no changes to the calling code and no regressions are expected.

  • ⚠️ BREAKING
    • APIGateway provisioning now only creates a single discovery file: MANIFEST.json at the site root.
  • 🏁 CHANGES
  • 🐛 FIXED
    • Fixed latent issue where IAM::Role resources didn't use stable CloudFormation resource names
    • Fixed latent issue where names & descriptions of Lambda functions weren't consistent
    • 1

v0.5.4

  • ⚠️ BREAKING
    • N/A
  • 🏁 CHANGES
    • Run go generate as part of the provision step
  • 🐛 FIXED
    • N/A

v0.5.3

  • ⚠️ BREAKING
    • N/A
  • 🏁 CHANGES
    • N/A
  • 🐛 FIXED

v0.5.2

  • ⚠️ BREAKING
    • N/A
  • 🏁 CHANGES

v0.5.1

  • ⚠️ BREAKING
    • N/A
  • 🏁 CHANGES
  • 🐛 FIXED

v0.5.0

  • ⚠️ BREAKING
    • N/A
  • 🏁 CHANGES
    • Added sparta.CloudWatchLogsPermission type to support lambda invocation in response to log events.
    • Fixed latent bug on Windows where temporary archives weren't properly deleted
    • The GO15VENDOREXPERIMENT=1 environment variable for cross compilation is now inherited from the current session.
      • Sparta previously always added it to the environment variables during compilation.
    • Hooked AWS SDK logger so that Sparta --level debug log level includes AWS SDK status
      • Also include debug level message listing AWS SDK version for diagnostic info
    • Log output includes lambda deployment package size

v0.4.0

  • ⚠️ BREAKING
    • Change sparta.Discovery() return type from map[string]interface{} to sparta.DiscoveryInfo.
      • This type provides first class access to service-scoped and DependsOn-related resource information
  • 🏁 CHANGES
    • N/A

v0.3.0

  • ⚠️ BREAKING
    • Enforce that a single Go function cannot be associated with more than 1 sparta.LamddaAWSInfo struct.
      • This was done so that sparta.Discovery can reliably use the enclosing Go function name for discovery.
    • Enforce that a non-nil *sparta.API value provided to sparta.Main() includes a non-empty set of resources and methods
  • 🏁 CHANGES type
    • This type can be used to enable CloudWatch Events
    • sparta.Discovery now returns the following CloudFormation Pseudo Parameters:
      • StackName
      • StackID
      • Region
    • Upgrade to Mermaid 0.5.7 to fix describe rendering failure on Chrome.

v0.2.0

  • ⚠️ BREAKING

    • Changed NewRequest to NewLambdaRequest to support mock API gateway requests being made in explore mode
    • TemplateDecorator signature changed to support go-cloudformation representation of the CloudFormation JSON template.
    • Use sparta.EventSourceMapping rather than aws.CreateEventSourceMappingInput type for LambdaAWSInfo.EventSourceMappings slice
    • Add dependency on crewjam/go-cloudformation for CloudFormation template creation
      • /ht @crewjam for the great library
    • CloudWatch log output no longer automatically uppercases all first order child key names.
  • 🏁 CHANGES

    • 💥 Add LambdaAWSInfo.DependsOn slice

      • Lambda functions can now declare explicit dependencies on resources added via a TemplateDecorator function
      • The DependsOn value should be the dependency's logical resource name. Eg, the value returned from CloudFormationResourceName(...).
    • 💥 Add sparta.Discovery() function

      • To be called from a Go lambda function (Eg, func echoEvent(*json.RawMessage, *LambdaContext, http.ResponseWriter, *logrus.Logger)), it returns the Outputs (both Fn::Att and Ref ) values of dynamically generated CloudFormation resources that are declared as explicit DependsOn of the current function.

      • Sample output return value:

        {
          "SESMessageStoreBucketa622fdfda5789d596c08c79124f12b978b3da772": {
            "DomainName": "spartaapplication-sesmessagestorebucketa622fdfda5-1rhh9ckj38gt4.s3.amazonaws.com",
            "Ref": "spartaapplication-sesmessagestorebucketa622fdfda5-1rhh9ckj38gt4",
            "Tags": [
              {
                "Key": "sparta:logicalBucketName",
                "Value": "Special"
              }
            ],
            "Type": "AWS::S3::Bucket",
            "WebsiteURL": "http://spartaapplication-sesmessagestorebucketa622fdfda5-1rhh9ckj38gt4.s3-website-us-west-2.amazonaws.com"
          },
          "golangFunc": "main.echoSESEvent"
        }
      • See the SES EventSource docs for more information.

    • Added TS (UTC TimeStamp) field to startup message

    • Improved stack provisioning performance

    • Fixed latent issue where CloudFormation template wasn't deleted from S3 on stack provisioning failure.

    • Refactor AWS runtime requirements into lambdaBinary build tag scope to support Windows builds.

    • Add SESPermission type to support triggering Lambda functions in response to inbound email

      • See doc_sespermission_test.go for an example
      • Storing the message body to S3 is done by assigning the MessageBodyStorage field.
    • Add NewAPIGatewayRequest to support localhost API Gateway mock requests

v0.1.5

v0.1.4

  • ⚠️ BREAKING
    • N/A
  • 🏁 CHANGES
    • Reduce deployed binary size by excluding Sparta embedded resources from deployed binary via build tags.

v0.1.3

  • ⚠️ BREAKING

    • API Gateway responses are only transformed into a standard format in the case of a go lambda function returning an HTTP status code >= 400
      • Previously all responses were wrapped which prevented integration with other services.
  • 🏁 CHANGES

    • Default integration mappings now defined for:

      • application/json
      • text/plain
      • application/x-www-form-urlencoded
      • multipart/form-data
      • Depending on the content-type, the Body value of the incoming event will either be a string or a json.RawMessage type.
    • CloudWatch log files support spawned golang binary JSON formatted logfiles

    • CloudWatch log output includes environment. Sample:

        {
            "AWS_SDK": "2.2.25",
            "NODE_JS": "v0.10.36",
            "OS": {
                "PLATFORM": "linux",
                "RELEASE": "3.14.48-33.39.amzn1.x86_64",
                "TYPE": "Linux",
                "UPTIME": 4755.330878024
            }
        }

v0.1.2

  • ⚠️ BREAKING
    • N/A
  • 🏁 CHANGES
    • Added explore.NewRequest to support localhost testing of lambda functions.
      • Clients can supply optional event data similar to the AWS Console feature.
      • See explore_test for an example.

v0.1.1

  • ⚠️ BREAKING

    • sparta.Main() signature changed to accept optional S3Site pointer
  • 🏁 CHANGES

    • Updated describe CSS font styles to eliminate clipping

    • Support {Ref: 'MyDynamicResource'} for SourceArn values. Example:

      lambdaFn.Permissions = append(lambdaFn.Permissions, sparta.SNSPermission{
        BasePermission: sparta.BasePermission{
          SourceArn: sparta.ArbitraryJSONObject{"Ref": snsTopicName},
        },
      })
      • Where snsTopicName is a CloudFormation resource name representing a resource added to the template via a TemplateDecorator.
    • Add CloudWatch metrics to help track container reuse.

      • Metrics are published to Sparta/<SERVICE_NAME> namespace.
      • MetricNames: ProcessCreated, ProcessReused, ProcessTerminated.

v0.1.0

  • ⚠️ BREAKING
    • sparta.Main() signature changed to accept optional S3Site pointer
  • 🏁 CHANGES
    • Added S3Site type and optional static resource provisioning as part of provision
      • See the SpartaHTML application for a complete example
    • Added API.CORSEnabled option (defaults to false).
      • If defined, all APIGateway methods will have CORS Enabled.
    • Update logging to use structured fields rather than variadic, concatenation
    • Reimplement explore command line option.
      • The explore command line option creates a localhost server to which requests can be sent for testing. The POST request body MUST be application/json, with top level event and context keys for proper unmarshaling.
    • Expose NewLambdaHTTPHandler() which can be used to generate an httptest

v0.0.7

  • ⚠️ BREAKING
    • N/A
  • 🏁 CHANGES
    • Documentation moved to gosparta.io compliant value for go test integration.
      • Add context struct to APIGatewayLambdaJSONEvent
      • Default description based on Go function name for AWS Lambda if none provided
      • Added SNS Event types for unmarshaling
      • Added DynamoDB Event types for unmarshaling
      • Added Kinesis Event types for unmarshaling
      • Fixed latent issue where IAMRoleDefinition CloudFormation names would collide if they had the same Permission set.
      • Remove API Gateway view from describe if none is defined.

v0.0.6

  • ⚠️ BREAKING
    • Changed:
      • type LambdaFunction func(*json.RawMessage, *LambdaContext, *http.ResponseWriter, *logrus.Logger)
        • TO
      • type LambdaFunction func(*json.RawMessage, *LambdaContext, http.ResponseWriter, *logrus.Logger)
      • See also FAQ: When should I use a pointer to an interface?.
  • Add .travis.yml for CI support.
  • 🏁 CHANGES

v0.0.5

  • ⚠️ BREAKING
    • Changed Sparta.Main() signature to accept API pointer as fourth argument. Parameter is optional.
  • 🏁 CHANGES
    • Preliminary support for API Gateway provisioning
      • See API type for more information.
    • describe output includes:
      • Dynamically generated CloudFormation Template
      • API Gateway json
      • Lambda implementation of CustomResources for push source configuration promoted from inline ZipFile JS code to external JS files that are proxied via index.js exports.
      • Fixed latent bug where remote push source registrations were deleted during stack updates.

v0.0.3

  • ⚠️ BREAKING
    • Changed LambdaEvent type to json.RawMessage
    • Changed AddPermissionInput type to sparta types:
      • LambdaPermission
      • S3Permission
      • SNSPermission
  • 🏁 CHANGES
    • sparta.NewLambda(...) supports either string or sparta.IAMRoleDefinition types for the IAM role execution value
      • sparta.IAMRoleDefinition types implicitly create an IAM::Role resource as part of the stack
      • string values refer to pre-existing IAM rolenames
    • S3Permission type
    • SNSPermission type
    • The subscription management resource is inline NodeJS code and leverages the cfn-response module.
    • LambdaPermission type
      • These denote Lambda Permissions whose event source subscriptions should NOT be managed by the service definition.
    • Improved describe output CSS and layout
      • Describe now includes push/pull Lambda event sources
    • Fixed latent bug where Lambda functions didn't have CloudFormation::Log privileges

v0.0.2

  • Update describe command to use mermaid for resource dependency tree

v0.0.1

  • Initial release