This is a BREAKING RELEASE with significant breaking changes noted below.
⚠️ BREAKING- All CloudFormation moved to go-formation
- All AWS API access moved to AWS SDK V2
- Changed all AWS Session references to AWS V2 Config references.
- Pulled
gocontext variable through async operations.
- 🏁 CHANGES
- Added
NewTaskStateto 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.
- Added
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
SpartaOptionstoExtendedOptionsto eliminate golint warnings - Changed
cloudformation.CloudFormationResourceNametocloudformation.ResourceNameto eliminate golint warnings - Removed
HandleAWSLambdalegacy function in favor ofNewAWSLambda - WorkflowHook function signatures were changed for more idiomatic
gousage. They now return(context.Context, error)values to allow for mutating thecontext.Contextobjected supplied to each invocation.
- Replaced all logrus.Logger usage by rs.zerolog
- 🏁 CHANGES
- Decoupled build from provision step to decouple building from packaging and deployment. Run
go run main.go -hfor 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
dockerFileargument 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.APIGatewayTaskStateto 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
WorkflowHooksingle instance members in favor of slices. - Updated all AWS Architecture images to the versions in the Asset package
- Decoupled build from provision step to decouple building from packaging and deployment. Run
- 🐛 FIXED
⚠️ BREAKING- 🏁 CHANGES
- Added sparta.AWSLambdaProvider to encapsulate an AWS Lambda compatible instance.
- Existing
*sparta.LambdaAWSInfoobjects can be constructed from aAWSLambdaProvidervia sparta.NewAWSLambdaFromProvider.
- Existing
- Added
--inputExtensionscommand line argument to the Explore command to support filtering eligible assets for interactive testing. - Updated
describeoutput format and layout- See the SpartaCast example
- Added
sparta.Describableinterface to allow for user-supplied decorators to provide nodes and edges to the layout.- ServiceDecoratorHookHandler instances that implement Describable are eligible to be included in the layout.
- Added a
Completelog statement to the end of log output.- Example:
INFO[0044] Complete Time (Local)="02 May 20 05:38 PDT" Time (UTC)="2020-05-02T12:38:54Z"
- Example:
- Add
step.NewDynamicWaitDurationStateto allow for input-dependent wait functions.
- Added sparta.AWSLambdaProvider to encapsulate an AWS Lambda compatible instance.
- 🐛 FIXED
- Avoid creating default state machine role when an external role is set
- Moved to PNG AWS Architecture icons for
describeoutput to elimniate data-uri SVG rendering issues.
-
⚠️ 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
describeoutput to use latest AWS Architecture Icons.
-
-
🐛 FIXED
-
⚠️ BREAKING -
🏁 CHANGES
-
Updated go-cloudformation dependency to expose:
- LambdaEventInvokeConfig for success/failure handlers
- See the blog post for more information
- Destinations can be connected via TemplateDecorators or ServiceDecoratorHook
- LambdaEventSourceMapping for updated stream controls
- See the blog post for more information
- LambdaEventInvokeConfig for success/failure handlers
-
Added cloudwatch.EmbeddedMetric to support publishing CloudWatch Embedded Metrics via logs
-
See the blog post for more information
-
Usage:
metricDirective := emMetric.NewMetricDirective("SpecialNamespace", // Initialize with metric dimensions map[string]string{"functionVersion": os.Getenv("AWS_LAMBDA_FUNCTION_VERSION")}) // Record a metric value metricDirective.Metrics["invocations"] = cloudwatch.MetricValue{ Unit: cloudwatch.UnitCount, Value: 1, } // Publish optionally accepts additional high-cardinality KV properties emMetric.Publish(nil)
-
-
-
🐛 FIXED
⚠️ BREAKING- 🏁 CHANGES
- Added step.MapState to support creating AWS Step functions that support the new Map State
- See the blog post for more details
- Also the corresponding sample application in the Sparta Step project.
- Added step.MapState to support creating AWS Step functions that support the new Map State
- 🐛 FIXED
- Fixed latent issue in step.ParallelState that prevented
Branchesfield from being properly marshaled.
- Fixed latent issue in step.ParallelState that prevented
⚠️ BREAKING- 🏁 CHANGES
- Added archetype.NewKinesisFirehoseTransformer and archetype.NewKinesisFirehoseLambdaTransformer to support Kinesis Firehose Lambda Transforms
- See the documentation for more details
- Also the corresponding sample application at the SpartaXForm repo.
- Added archetype.NewKinesisFirehoseTransformer and archetype.NewKinesisFirehoseLambdaTransformer to support Kinesis Firehose Lambda Transforms
- 🐛 FIXED
⚠️ BREAKING- 🏁 CHANGES
- Added ApplicationLoadBalancerDecorator type to support Lambda functions as load balancer targets.
- See the documentation for more details
- Also the corresponding sample application at the SpartaALB repo.
- Added ApplicationLoadBalancerDecorator type to support Lambda functions as load balancer targets.
- 🐛 FIXED
⚠️ BREAKING- Update
sparta.Mainandsparta.MainExto 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.
- Update
- 🏁 CHANGES
- Added [API V2] type to provision WebSocket APIs
- See the documentation for more details
- Update to
gomodules
- Added [API V2] type to provision WebSocket APIs
- 🐛 FIXED
-
⚠️ BREAKING -
🏁 CHANGES
- Added Cloud Map discovery publisher
- See the documentation
- Added
panicrecover handler to more gracefully handle exceptions - Include AWS Session in context with key
sparta.ContextKeyAWSSession
- Added Cloud Map discovery publisher
-
🐛 FIXED
- Update to support new Amazon Linux AMI
- Fixed latent issue where
envspecified log level wasn't respected at lambda execution time
-
⚠️ BREAKING -
🏁 CHANGES
-
Added
API.EndpointConfigurationfield to API.- This field exposes the EndpointConfiguration property to specify either EDGE or REGIONAL API types.
-
Added
decorator.APIGatewayDomainDecoratorto 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
-
⚠️ BREAKING -
🏁 CHANGES
-
Added
CodeCommitPermissiontype to support CodeCommit notifications -
There is an archetype constructor that encapsulates this type of Lambda reactor.
-
Usage:
func echoCodeCommit(ctx context.Context, event awsLambdaEvents.CodeCommitEvent) (interface{}, error) { // ... return &event, nil } func main() { // ... reactor, reactorErr := spartaArchetype.NewCodeCommitReactor(spartaArchetype.CodeCommitReactorFunc(echoCodeCommit), gocf.String("TestCodeCommitRepo"), nil, nil, nil) ... }
-
-
Updated to staticcheck.io
-
-
🐛 FIXED
-
⚠️ BREAKING -
🏁 CHANGES
-
Added
LambdaAWSInfo.Layersfield 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
WithConditionto IAM Builder -
Added
s3Site.UserManifestDatamap 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.Writersinks for stdout and stderr.
- This is convenience function to support alternative
-
Minor usability improvements to
--statusreport output
-
-
🐛 FIXED
-
⚠️ BREAKING- Renamed
archetype.CloudWatchLogsReactortoarchetype.CloudWatchReactor- Also changed
OnLogMessagetoOnCloudWatchMessage- I consistently forget the fact that CloudWatch is more than logs
- Moved the internal
cloudwatchlogspackage to thecloudwatch/logsimport path
- Also changed
- Renamed fluent typenames in github.com/mweagle/Sparta/aws/iam/builder to support Principal-based builders
- Renamed
step.NewTaskStatetostep.NewLambdaTaskStateto 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
ContextKeyLambdaVersionsconstant
- This also obsoleted the
- Renamed
-
🏁 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:
- See the SpartaStepServicefull project for an example of a service that:
-
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-stdinfor local authentication. Previously useddocker 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]- See the Docker docs
-
Include
docker -voutput 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 resourceRefandAttvalues to the Stack Outputs- The set of
Attvalues is extracted from the CloudFormation Resource Specification via the go-cloudformation project.
- The set of
-
-
🐛 FIXED
- API Gateway custom headers were not being properly returned
- RegisterLambdaUtilizationMetricPublisher Name ref obsolete
⚠️ BREAKING- Renamed
archetype.NewCloudWatchLogsReactortoarchetype.NewCloudWatchReactor
- Renamed
- 🏁 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.NewCloudWatchScheduledReactorandarchetype.NewCloudWatchEventedReactor
- Moved all documentation into the master branch to make it a bit easier to update docs together with code.
- 🐛 FIXED
-
⚠️ BREAKING -
🏁 CHANGES
-
Moved
decorator.DriftDetectortovalidator.DriftDetectorand 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
LambdaFuncNameto 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
-
⚠️ BREAKING -
🏁 CHANGES
-
Added
decorator.DriftDetectorto 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
-
⚠️ BREAKING -
🏁 CHANGES
-
Added
LambdaAWSInfo.Interceptorssupport-
Interceptorsare 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 toWorkflowHooks. -
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
contextvalue - AfterSetup: Called after Sparta creates your lambda's
contextvalue - 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.ProperNameas framework name literal -
Add lightweight Key-Value interface and S3 and DynamoDB implementations to support SpartaTodoBackend
- The DynamoDB provider uses dynamodbattribute to map
gostructs to attributes. - See the aws.accessor docs
- The DynamoDB provider uses dynamodbattribute to map
-
-
🐛 FIXED
-
⚠️ 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.NewResponseto produce a newResponsetype 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.
- See the response for an example
- API Gateway lambda functions should use
- Eliminate pre 1.0 GM Sparta function signature:
-
🏁 CHANGES
-
Add more go idiomatic
sparta.NewAWSLambda(...) (*sparta.LambdaAWSInfo, error)constructor- The existing
sparta.HandleAWSLambdafunction is deprecated and will be removed in a subsequent release
- The existing
-
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.S3Accessortype to enable utility methods for:PutGetGetAllDeleteDeleteAll
- Embed a
-
Added prealloc check to ensure that slices are preallocated when possible
-
-
🐛 FIXED
- Fix latent issue where CloudWatch Log ARN was malformed commit
-
⚠️ BREAKING -
🏁 CHANGES
-
Expose
sparta.InstanceID()that returns a random instance identifier for a single Lambda container instance- The instanceID field is also included in the ContextLogger
-
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]stringparameter is the custom Name-Value pairs to use as a CloudWatch Dimension
-
-
Add
WorkflowHooks.Validatorsto 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.
-
⚠️ BREAKING- Moved
sparta.LambdaVersioningDecoratortodecorator.LambdaVersioningDecorator - Updated cloudformation.ConvergeStackState to accept a timeout parameter
- Updated ServiceDecorator.DecorateService to accept the S3Key parameter
- This allows
ServiceDecoratorsto add their own Lambda-backed CloudFormation custom resources and have them instantiated at AWS Lambda runtime. (eg: CloudFormation Lambda-backed custom resources ). See next section for more information.
- This allows
- Moved
-
🏁 CHANGES
-
Simplified CustomResource creation and dispatch logic
-
The benefit of this is that users can define new
CustomResourceCommandimplementing 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:
-
Create a resource that embeds gocf.CloudFormationCustomResource and your custom event properties:
type HelloWorldResourceRequest struct { Message *gocf.StringExpr } type HelloWorldResource struct { gocf.CloudFormationCustomResource HelloWorldResourceRequest }
-
Register the custom resource provider with RegisterCustomResourceProvider
-
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.ResourcePropertiesmap into your command handler instance and perform the requested operation.
- Unmarshal the
-
-
Added a set of
archetype.*convenience functions to createsparta.LambdaAWSInfofor 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
--nocolorcommand line option to suppress colorized output. Default value:false. -
When a service
provisionfails, 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.NewLogAggregatorDecoratorwhich 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
WorkflowHooksstruct toMainExto annotate your service with an example CloudFront distribution. Note that CF distributions introduce a significant provisioning delay. -
See SpartaHTML for more
-
-
Added
decorator.S3ArtifactPublisherDecoratorto publish an arbitrary JSON file to an S3 location- This is implemented as Sparta-backed CustomResource
-
Added
statuscommand 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 testto catch misspellings
-
-
🐛 FIXED
⚠️ BREAKING- 🏁 CHANGES
- Update branchname and release tag to support Go 1.11 modules.
- 🐛 FIXED
- Fixed
panicwhen extracting lambda function name.
- Fixed
⚠️ BREAKING- 🏁 CHANGES
- Added
decorator.LogAggregatorDecorator- This is a decorator that:
- Creates a CloudWatchLogs Subscription Filter for the Lambda functions
- Creates a Kinesis sink with the user defined shard count to receive the log events.
- Subscribes the relay lambda function to the Kinesis stream
- See SpartaPProf for an example that relays log entries to Google StackDriver.
- This is a decorator that:
- Added
decorator.PublishAttOutputDecoratoranddecorator.PublishRefOutputDecoratoras convenience functions to update the Stack Outputs section. - Added
RuntimeLoggerHookto WorkflowHooks to support logrus logger hooks. - Added
IsExecutingInLambda () boolto return execution environment
- Added
- 🐛 FIXED
-
⚠️ 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
sqsResourceNameis the name of a CloudFormation resource provisioned by the stack - Use the aws.SQSEvent value type as the incoming message
- Where
-
See the SpartaSQS project for a complete example
-
-
Migrated
describecommand to use Cytoscape.JS library- Cytoscape supports several layout algorithms and per-service node icons.
-
Added
APIGatewayEnvelopetype to allow struct embedding and overriding of theBodyfield. 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:generatecould 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.
⚠️ BREAKING- 🏁 CHANGES
- Re-implemented the
explorecommand.- The
explorecommand 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:
- The
- Eliminate redundant
Statemententries in AssumeRolePolicyDocument - Add
sparta.StampedBuildIDglobal variable to access the BuildID value (either user defined or automatically generated) - Added
-z/--timestampscommand line flag to optionally include UTC timestamp prefix on every log line. - Prefer
git rev-parse HEADvalue for fallback BuildID value iff--buildIDisn't provided as a provision command line argument. If an error is detected callinggit, the previous randomly initialized buffer behavior is used.
- Re-implemented the
- 🐛 FIXED
-
⚠️ BREAKING- Removed
lambdabinarybuild tags from BuildDockerImage- AWS native support for Go in AWS caused a significant difference in standard vs
lambdabinarybuild targets executed which prevented custom application options from being respected.
- AWS native support for Go in AWS caused a significant difference in standard vs
- Removed
-
🏁 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
describeoutput 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.IAMRolePrivilegefluent 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
-sand-wlink flags- See Shrink your Go Binaries with this One Weird Trick for more information
-
Added
github.com/mweagle/Sparta/aws/cloudformation.UserAccountScopedStackNameto produce CloudFormation Stack names that are namespaced by AWS account username -
Ensure
PreandPostdeploy hooks are granted proper permissions- See SpartaSafeDeploy for more information.
-
Added Sparta/aws/apigateway.Error to support returning custom API Gateway errors
- See SpartaHTML for example usage
-
API Gateway
errorresponses are now converted to JSON objects via a Body Mapping template:"application/json": "$input.path('$.errorMessage')",
- See the AWS docs for more information
-
Added check for Linux only package sysinfo. This Linux-only package is ignored by
go getbecause 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
NewAuthorizedMethoddidn't properly preserve the AuthorizerID when serializing to CloudFormation. This also forced a change to the function signature to accept agocf.Stringablesatisfying type for the authorizerID.
⚠️ BREAKING- 🏁 CHANGES
- Added events package for Sparta specific event types.
- Initial top level event is
APIGatewayRequesttype for responding to API-Gateway mediated requests.
- Initial top level event is
- Prefer stamping
buildIDinto binary rather than providing as environment variable. Previously the stamped buildID was theenv.SPARTA_BUILD_IDmutable variable. - Remove dependency on go-validator
- Added events package for Sparta specific event types.
- 🐛 FIXED
- Fixed latent bug where Discovery wasn't properly initialized in AWS Lambda execution context
- Fixed latent bug where CommandLineOptions weren't properly defined in AWS build target
- Affected SpartaCodePipeline project
-
Sparta Go function signature has been changed to ONLY support the official AWS Lambda Go signatures
func ()func () errorfunc (TIn) errorfunc () (TOut, error)func (context.Context) errorfunc (context.Context, TIn) errorfunc (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.HandleAWSLambdacreation function, a function pointer that satisfies one of the supported signatures. -
Providing an invalid signature such as
func() stringwill produce aprovisiontime error as in:Error: Invalid lambda returns: Hello World. Error: handler returns a single value, but it does not implement error -
⚠️ BREAKING- Removed
sparta.NewLambdaconstructor - Removed
sparta.NewServeMuxLambdaproxying function - Removed
sparta.LambdaFunctiontype ContextKeyLambdaContextis no longer published into the context. Prefer the official AWS FromContext() function to access the AWS Go Lambda context.- Moved DashboardDecorator to
decoratorsnamespace - Removed
explorecommand line option as proxying tier is no longer supported - Changed all
logrusimports to proper lowercase format
- Removed
-
🏁 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
*Handlerinterface versions:TemplateDecoratorHookFuncWorkflowHookFuncArchiveHookFuncServiceDecoratorHookFuncRollbackHookFunc
-
Added
CodeDeployServiceUpdateDecoratorto support safe AWS Lambda deploys- Safe lambda deploys are implemented via ServiceDecoratorHooks
- See SpartaSafeDeploy for a complete example
-
Added requestID and lambdaARN request-scoped *logrus.Entry to
contextargument.- This can be accessed as in:
contextLogger, contextLoggerOk := ctx.Value(sparta.ContextKeyRequestLogger).(*logrus.Entry) if contextLoggerOk { contextLogger.Info("Request scoped log") }
- The existing
*logrus.Loggerentry is also available in thecontextvia:
logger, loggerOk := ctx.Value(sparta.ContextKeyLogger).(*logrus.Logger)
-
NewMethod now accepts variadic parameters to limit how many API Gateway integration mappings are defined
-
Added
SupportedRequestContentTypesto NewMethod to limit API Gateway generated content. -
Added
apiGateway.CORSOptionsfield 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
provisionwould not consistently create new API Gateway Stage events.
- Fix latent bug where
-
⚠️ BREAKING- 🏁 CHANGES
- Improved API-Gateway CORS support. The following customizations are opt-in:
- Parameterize CORS headers returned by OPTIONS via API.CORSOptions
- Add
SupportedRequestContentTypesto 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
possibleHTTPStatusCodeResponsesvalues 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
- Improved API-Gateway CORS support. The following customizations are opt-in:
- 🐛 FIXED
- Re-enable
cloudformation:DescribeStacksandcloudformation:DescribeStackResourceprivileges to support HTML based deployments
- Re-enable
⚠️ BREAKINGTagsfor 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_IDenvironment variable.
- 🐛 FIXED
- Correct CLI typo
-
⚠️ BREAKING- Changed
step.NewStateMachinesignature to include StateMachineName as first argument per Nov 15th, 2017 release
- Changed
-
🏁 CHANGES
-
Add
profilecommand- 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
profileSparta command.- For more information, please see The new pprof user interface - ⭐️, Profiling Go programs with pprof, or the Go blog
- See the SpartaPProf sample for a service that installs profiling hooks.
- Ensure you have the latest
pprofUI 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.Durationsupplied as the third parameter toScheduleProfileLoop.
-
Eliminate unnecessary logging in AWS lambda environment
-
Log NodeJS process.uptime()
-
-
🐛 FIXED
- Added more constructive message when working directory for
go builddoesn't containmainpackage.
- Added more constructive message when working directory for
⚠️ BREAKING- 🏁 CHANGES
- 🐛 FIXED
- Fixed
exploreinteractive debugging instructions
- Fixed
-
⚠️ BREAKING -
🏁 CHANGES
-
Added support for Step functions.
- Step functions are expressed via a combination of: states,
NewStateMachine, and adding aStateMachineDecoratoras a service hook. - See the SpartaStep sample for a service that provisions a simple roll die state machine.
- Step functions are expressed via a combination of: states,
-
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
⚠️ BREAKING- 🏁 CHANGES
- Add
sparta.LambdaNameto return the reflection-discovered name of anhttp.HandleFuncinstance.
- Add
- 🐛 FIXED
- Fixed issue with
--describenot rendering CloudFormation template properly - Better handle failures when posting body - thanks @nylar
- Fixed issue with
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
NewLambdaHTTPHandlertoNewServeMuxLambda - Remove obsolete
InvokeIDfrom LambdaContext - Changed
codePipelineTriggerCLI arg name tocodePipelinePackage
- Changed
-
🏁 CHANGES
-
Eliminated NodeJS cold start
cp & chmodpenalty! 🔥- 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 debugwill log everything atlogger.Debuglevel and higher including all AWS API calls made both atprovisionand Lambda execution time. - Help resolve "Works on My Stack" syndrome.
- Provisioning a service with
-
HTTP handler
panicevents are now recovered and the traceback logged for both NodeJS andcgodeployments -
Introduced
sparta.HandleAWSLambda-
sparta.HandleAWSLambdaaccepts standardhttp.RequestFuncsignatures 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.Loggersparta.ContextKeyLambdaContext=>*sparta.LambdaContext
-
Example:
loggerVal, loggerValOK := r.Context().Value(sparta.ContextKeyLogger).(*logrus.Logger)
-
-
Added support for CodePipeline
- See the SpartaCodePipeline project for a complete example and the related post.
-
Upgraded NodeJS to nodejs6.10 runtime
-
Parity between NodeJS and Python/
cgostartup output -
Both NodeJS and
cgobased 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
⚠️ 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
⚠️ 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
-
⚠️ BREAKING- Removed
sparta.NewNamedLambda. Stable, user-defined function names can be supplied via the SpartaOptions.Name field.
- Removed
-
🏁 CHANGES
-
- You can provision a CloudWatch dashboard that provides a single overview and link portal for your Lambda-based service. Use the new
sparta.DashboardDecoratorfunction 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
60value 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"-
Example:
-
For more info, see the AWS Blog Post
-
The SpartaXRay sample application has additional code samples.
- You can provision a CloudWatch dashboard that provides a single overview and link portal for your Lambda-based service. Use the new
-
XRay support added
- added
LambdaFunctionOptions.TracingConfigfield to LambdaFunctionOptions - added XRay IAM privileges to default IAM role settings:
- xray:PutTraceSegments
- xray:PutTelemetryRecords
- See AWS blog for more information
- added
-
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.Namefield wasn't consistently used for function names.
- Fixed latent issue where
⚠️ BREAKING- 🏁 CHANGES
- added Sparta/aws/cloudformation.UserScopedStackName() to generate username-suffixed CloudFormation StackNames
- 🐛 FIXED
⚠️ BREAKING- Replaced all https://github.com/crewjam/go-cloudformation references with https://github.com/mweagle/go-cloudformation references
- This is mostly internal facing, but impacts advanced usage via ServiceDecoratorHook users. Clients may need to update the types used to create alternative topologies.
- Replaced all https://github.com/crewjam/go-cloudformation references with https://github.com/mweagle/go-cloudformation references
- 🏁 CHANGES
- 🐛 FIXED
- Fixed latent issue where CGO-enabled services that reference
cgo.NewSession()would not build properly - Fixed latent issue where S3 backed sites (eg: SpartaHugo) would not refresh on update.
- 55
- Fixed latent issue where CGO-enabled services that reference
-
⚠️ BREAKING -
🏁 CHANGES
-
Added
--inplace/-ccommand 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/-fcommand line flag[text, txt, json]to specify logfile output format. Default istext.
-
-
🐛 FIXED
-
⚠️ BREAKING -
🏁 CHANGES
- Support Go 1.8 newly optional GOPATH environment variable
- Python proxied
cgobuilds 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::Roledefinitions to minimize CloudFormation resource update churn
-
🐛 FIXED
- Fixed latent bug where S3 bucket version check didn't respect
--noopmode. - Fixed latent
cgobug where command line arguments weren't properly parsed
- Fixed latent bug where S3 bucket version check didn't respect
⚠️ 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
- 🎉 Python CGO support added. See the https://github.com/mweagle/SpartaPython project for example usage!
- 🐛 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
VersionIDin the AWS Lambda Code value.
-
⚠️ BREAKINGdescribeoption now requires-b/--s3Bucketargument- Changed signature of
aws/s3/CreateS3RollbackFuncto accept full S3 URL, includingversionIdquery param - Signatures for
sparta.Provisionandsparta.Discoverupdated with new arguments
-
🏁 CHANGES
- Add
-p/--codePipelineTriggercommand line option to generate CodePipeline deployment package - Add
sparta.RegisterCodePipelineEnvironmentto 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
EnvironmentandKmsKeyArnproperties to LambdaFunctionOptions. See AWS for more information. - Move all build artifacts to ./sparta directory
-n/--noopargument 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
- Add
-
🐛 FIXED
-
⚠️ 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
--ldflagssupport to support lightweight dynamic string variables- Usage:
go run main.go provision --level info --s3Bucket $(S3_BUCKET) --ldflags "-X main.dynamicValue=SampleValue"
- Usage:
- Added LambdaFunctionOptions.SpartaOptions struct
-
🐛 FIXED
⚠️ 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
describeoutput sparta.CloudFormationResourceNameproxies togithub.com/mweagle/Sparta/aws/cloudformation.CloudFormationResourceName. Thespartapackage function is deprecated and will be removed in a subsequent release.
- 🐛 FIXED
- Fixed latent bug in
github.com/mweagle/Sparta/zip.AddToZipwhere 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.
- Fixed latent bug in
⚠️ BREAKING- 🏁 CHANGES
- Improved
describeoutput. Includes APIGateway resources and more consistent UI. - Additive changes to WorkflowHooks
Contextproperty 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
- Improved
- 🐛 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.
-
⚠️ BREAKING-
NewMethodandNewAuthorizedMethodfor 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.StatusOKfor all non-POST requests, andhttp.StatusCreatedfor 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"
- Prior to this change, Sparta would automatically use
-
-
🏁 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
dependenciesfrom ./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
-
⚠️ BREAKINGTemplateDecoratorsignature changed to includecontext map[string]interface{}to support sharing state acrossWorkflowHooks(below).
-
🏁 CHANGES
- Add
SpartaBuildIDstack 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/--buildIDparameter forprovision.- 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.MainExfor non-breaking signature extension
- Add
-
🐛 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.VALUErather thanTYPE.
-
⚠️ BREAKING- 🏁 CHANGES
- Upgrade to latest go-cloudformation that required internal refactoring.
- 🐛 FIXED
- N/A
⚠️ BREAKINGTemplateDecoratorsignature changed to includeserviceName,S3Bucket, andS3Keyto allow for decorating CloudFormation with UserData to support alternative topology deployments.CommonIAMStatementschanged frommap[string][]iamPolicyStatementto struct with named fields.PushSourceConfigurationActionschanged frommap[string][]stringto struct with named fields.- Eliminated goptions
- 🏁 CHANGES
- Moved CLI parsing to Cobra
- Applications can extend the set of flags for existing Sparta commands (eg,
provisioncan include--subnetIDs) as well as add their own top level commands to theCommandLineOptionsexported values. See SpartaCICD for an example.
- Applications can extend the set of flags for existing Sparta commands (eg,
- Added Sparta/aws/cloudformation
ConvertToTemplateExpressionto convert string value into Fn::Join compatible representation. Parses inline AWS references and supports user-defined template properties. - Added
sparta/aws/iamPolicyStatement type - Upgraded
describeoutput to use Mermaid 6.0.0 - All goreportcard issues fixed.
- Moved CLI parsing to Cobra
- 🐛 FIXED
- Fixed latent VPC provisioning bug where VPC/Subnet IDs couldn't be provided to template serialization.
⚠️ BREAKINGTemplateDecoratorsignature changed to includemap[string]stringto allow for decorating CloudFormation resource metadata
- 🏁 CHANGES
- All NodeJS CustomResources moved to go
- Add support for user-defined CloudFormation CustomResources via
LambdaAWSInfo.RequireCustomResource DiscoveryInfostruct now includesTagLogicalResourceIDfield with CloudFormation Resource ID of calling lambda function
- 🐛 FIXED
- N/A
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
- VPC support! Added LambdaFunctionVPCConfig to LambdaFunctionsOptions struct.
- Updated NodeJS runtime to nodejs4.3
- CloudFormation updates are now done via Change Sets, rather than UpdateStack.
- APIGateway and CloudWatchEvents are now configured using CloudFormation. They were previously implemented using NodeJS CustomResources.
- 🐛 FIXED
- Fixed latent issue where
IAM::Roleresources didn't use stable CloudFormation resource names - Fixed latent issue where names & descriptions of Lambda functions weren't consistent
- 1
- Fixed latent issue where
⚠️ BREAKING- N/A
- 🏁 CHANGES
- Run
go generateas part of the provision step
- Run
- 🐛 FIXED
- N/A
⚠️ BREAKING- N/A
- 🏁 CHANGES
- N/A
- 🐛 FIXED
⚠️ BREAKING- N/A
- 🏁 CHANGES
- Added cloudwatchlogs.Event to support unmarshaling CloudWatchLogs data
⚠️ BREAKING- N/A
- 🏁 CHANGES
- Added LambdaAWSInfo.URLPath to enable localhost testing
- See explore_test.go for example
- Added LambdaAWSInfo.URLPath to enable localhost testing
- 🐛 FIXED
⚠️ 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=1environment 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 debuglog level includes AWS SDK status- Also include
debuglevel message listing AWS SDK version for diagnostic info
- Also include
- Log output includes lambda deployment package size
⚠️ BREAKING- Change
sparta.Discovery()return type frommap[string]interface{}tosparta.DiscoveryInfo.- This type provides first class access to service-scoped and
DependsOn-related resource information
- This type provides first class access to service-scoped and
- Change
- 🏁 CHANGES
- N/A
⚠️ BREAKING- Enforce that a single Go function cannot be associated with more than 1
sparta.LamddaAWSInfostruct.- This was done so that
sparta.Discoverycan reliably use the enclosing Go function name for discovery.
- This was done so that
- Enforce that a non-nil
*sparta.APIvalue provided tosparta.Main()includes a non-empty set of resources and methods
- Enforce that a single Go function cannot be associated with more than 1
- 🏁 CHANGES
type
- This type can be used to enable CloudWatch Events
- See the SpartaApplication example app for a sample usage.
sparta.Discoverynow returns the following CloudFormation Pseudo Parameters:- StackName
- StackID
- Region
- Upgrade to Mermaid 0.5.7 to fix
describerendering failure on Chrome.
- This type can be used to enable CloudWatch Events
-
⚠️ BREAKING- Changed
NewRequesttoNewLambdaRequestto support mock API gateway requests being made inexploremode TemplateDecoratorsignature changed to support go-cloudformation representation of the CloudFormation JSON template.- /ht @crewjam for go-cloudformation
- Use
sparta.EventSourceMappingrather than aws.CreateEventSourceMappingInput type forLambdaAWSInfo.EventSourceMappingsslice - 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.
- Changed
-
🏁 CHANGES
-
💥 Add
LambdaAWSInfo.DependsOnslice- Lambda functions can now declare explicit dependencies on resources added via a
TemplateDecoratorfunction - The
DependsOnvalue should be the dependency's logical resource name. Eg, the value returned fromCloudFormationResourceName(...).
- Lambda functions can now declare explicit dependencies on resources added via a
-
💥 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 explicitDependsOnof 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
lambdaBinarybuild tag scope to support Windows builds. -
Add
SESPermissiontype 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
MessageBodyStoragefield.
-
Add
NewAPIGatewayRequestto support localhost API Gateway mock requests
-
⚠️ BREAKING- N/A
- 🏁 CHANGES
- Add S3 Object Expiration warning message if the target bucket doesn't specify one.
- Replace internal CloudFormation polling loop with WaitUntilStackCreateComplete and WaitUntilStackUpdateComplete
⚠️ BREAKING- N/A
- 🏁 CHANGES
- Reduce deployed binary size by excluding Sparta embedded resources from deployed binary via build tags.
-
⚠️ 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.
- API Gateway responses are only transformed into a standard format in the case of a go lambda function returning an HTTP status code >= 400
-
🏁 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
stringor ajson.RawMessagetype.
-
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 } }
-
⚠️ BREAKING- N/A
- 🏁 CHANGES
- Added
explore.NewRequestto support localhost testing of lambda functions.- Clients can supply optional event data similar to the AWS Console feature.
- See explore_test for an example.
- Added
-
⚠️ BREAKINGsparta.Main()signature changed to accept optionalS3Sitepointer
-
🏁 CHANGES
-
Updated
describeCSS 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.
-
⚠️ BREAKINGsparta.Main()signature changed to accept optionalS3Sitepointer
- 🏁 CHANGES
- Added
S3Sitetype and optional static resource provisioning as part ofprovision- See the SpartaHTML application for a complete example
- Added
API.CORSEnabledoption (defaults to false).- If defined, all APIGateway methods will have CORS Enabled.
- Update logging to use structured fields rather than variadic, concatenation
- Reimplement
explorecommand line option.- The
explorecommand line option creates a localhost server to which requests can be sent for testing. The POST request body MUST be application/json, with top leveleventandcontextkeys for proper unmarshaling.
- The
- Expose NewLambdaHTTPHandler() which can be used to generate an httptest
- Added
⚠️ BREAKING- N/A
- 🏁 CHANGES
- Documentation moved to gosparta.io
compliant value for
go testintegration.- 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
IAMRoleDefinitionCloudFormation names would collide if they had the same Permission set. - Remove API Gateway view from
describeif none is defined.
- Documentation moved to gosparta.io
compliant value for
⚠️ 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?.
- Changed:
- Add .travis.yml for CI support.
- 🏁 CHANGES
- Added LambdaAWSInfo.Decorator field (type TemplateDecorator ). If defined, the template decorator will be called during CloudFormation template creation and enables a Sparta lambda function to annotate the CloudFormation template with additional Resources or Output entries.
- See TestDecorateProvision for an example.
- Improved API Gateway
describeoutput. - Added method response support.
- The DefaultMethodResponses map is used if Method.Responses is empty (
len(Responses) <= 0) at provision time. - The default response map defines
201for POST methods, and200for all other methods. An API Gateway method may only support a single 2XX status code.
- The DefaultMethodResponses map is used if Method.Responses is empty (
- Added integration response support for to support HTTP status codes defined in status.go.
- The DefaultIntegrationResponses map is used if Integration.Responses is empty (
len(Responses) <= 0) at provision time. - The mapping uses regular expressions based on the standard golang HTTP StatusText values.
- The DefaultIntegrationResponses map is used if Integration.Responses is empty (
- Added
SpartaHomeandSpartaVersiontemplate outputs.
- Added LambdaAWSInfo.Decorator field (type TemplateDecorator ). If defined, the template decorator will be called during CloudFormation template creation and enables a Sparta lambda function to annotate the CloudFormation template with additional Resources or Output entries.
⚠️ BREAKING- Changed
Sparta.Main()signature to accept API pointer as fourth argument. Parameter is optional.
- Changed
- 🏁 CHANGES
- Preliminary support for API Gateway provisioning
- See API type for more information.
describeoutput includes:- Dynamically generated CloudFormation Template
- API Gateway json
- Lambda implementation of
CustomResourcesfor 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.
- Preliminary support for API Gateway provisioning
⚠️ BREAKING- Changed
LambdaEventtype tojson.RawMessage - Changed AddPermissionInput type to sparta types:
LambdaPermissionS3PermissionSNSPermission
- Changed
- 🏁 CHANGES
sparta.NewLambda(...)supports eitherstringorsparta.IAMRoleDefinitiontypes for the IAM role execution valuesparta.IAMRoleDefinitiontypes implicitly create an IAM::Role resource as part of the stackstringvalues refer to pre-existing IAM rolenames
S3PermissiontypeS3Permissiontypes denotes an S3 event source that should be automatically configured as part of the service definition.- S3's LambdaConfiguration is managed by a Lambda custom resource dynamically generated as part of in the CloudFormation template.
- The subscription management resource is inline NodeJS code and leverages the cfn-response module.
SNSPermissiontypeSNSPermissiontypes denote an SNS topic that should should send events to the target Lambda function- An SNS Topic's subscriber list is managed by a Lambda custom resource dynamically generated as part of in the CloudFormation template.
- The subscription management resource is inline NodeJS code and leverages the cfn-response module.
LambdaPermissiontype- These denote Lambda Permissions whose event source subscriptions should NOT be managed by the service definition.
- Improved
describeoutput CSS and layout- Describe now includes push/pull Lambda event sources
- Fixed latent bug where Lambda functions didn't have CloudFormation::Log privileges
- Initial release





