sparta

package module
v0.0.0-...-d7435ac Latest Latest
Warning

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

Go to latest
Published: Dec 1, 2015 License: MIT Imports: 37 Imported by: 0

README

Build Status

Sparta

Overview

Sparta takes a set of golang functions and automatically provisions them in AWS Lambda as a logical unit.

Functions must implement

type LambdaFunction func(*json.RawMessage,
                          *LambdaContext,
                          http.ResponseWriter,
                          *logrus.Logger)

where

  • json.RawMessage : The arbitrary json.RawMessage event data provided to the function.
  • LambdaContext : golang compatible representation of the AWS Lambda Context
  • http.ResponseWriter : Writer for response. The HTTP status code & response body is translated to a pass/fail result provided to the context.done() handler.
  • logrus.Logger : logrus logger with JSON output. See an example for including JSON fields.

Given a set of registered golang functions, Sparta will:

  • Either verify or provision the defined IAM roles
  • Build a deployable application via Provision()
  • Zip the contents and associated JS proxying logic
  • Dynamically create a CloudFormation template to either create or update the service state.
  • Optionally:
    • Register with S3 and SNS for push source configuration
    • Provision an API Gateway service to make your functions publicly available

Note that Lambda updates may be performed with no interruption in service.

Sample Lambda Application

  1. Create application.go :
```go
package main

import (
  "encoding/json"
  "fmt"
  "github.com/Sirupsen/logrus"
  sparta "github.com/mweagle/Sparta"
  "net/http"
)

func echoEvent(event *sparta.LambdaEvent,
               context *sparta.LambdaContext,
               w http.ResponseWriter,
               logger *logrus.Logger) {

  logger.WithFields(logrus.Fields{
    "RequestID": context.AWSRequestID,
  }).Info("Request received")

  eventData, err := json.Marshal(*event)
  if err != nil {
    logger.Error("Failed to marshal event data: ", err.Error())
    http.Error(*w, err.Error(), http.StatusInternalServerError)
  }
  logger.Info("Event data: ", string(eventData))
}

func main() {
  var lambdaFunctions []*sparta.LambdaAWSInfo

  lambdaEcho := sparta.NewLambda(sparta.IAMRoleDefinition{},
                                  echoEvent,
                                  nil)
  lambdaFunctions = append(lambdaFunctions, lambdaEcho)
  sparta.Main("SpartaEcho",
               "This is a sample Sparta application",
               lambdaFunctions)
}
```
  1. go get ./...
  2. go run application.go provision --s3Bucket MY_S3_BUCKET_NAME
    • You'll need to change MY_S3_BUCKET_NAME to an accessible S3 bucketname
  3. Visit the AWS Lambda console and confirm your Lambda function is accessible

See also the Sparta Application for an example.

Examples - Advanced

The []sparta.LambdaAWSInfo.Permissions slice allows Lambda functions to automatically manage remote event source subscriptions. Push-based event sources are updated via CustomResources that are injected into the CloudFormation template if appropriate.

Examples:

The per-service API logic is inline NodeJS ZipFile code. See the provision directory for more.

See also the Sparta Application for a standalone example.

Examples - API Gateway (Preliminary)

It's possible to expose to your golang functions over HTTPS by associating an API Gateway. To enable API Gateway support, you must:

  • Define a Stage
  • Define an API Gateway name and provide the previously defined stage.
  • Create one or more (resource, httpMethod) pairs that are bound to your lambda function.

Example:

package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/Sirupsen/logrus"
	sparta "github.com/mweagle/Sparta"
)

////////////////////////////////////////////////////////////////////////////////
// Echo handler
//
func echoEvent(event *json.RawMessage,
                context *sparta.LambdaContext,
                w http.ResponseWriter,
                logger *logrus.Logger) {
	logger.WithFields(logrus.Fields{
		"RequestID": context.AWSRequestID,
		"Event":     string(*event),
	}).Info("Request received")

	fmt.Fprintf(*w, "Hello World!")
}

func main() {
	stage := sparta.NewStage("test")
	apiGateway := sparta.NewAPIGateway("MySpartaAPI", stage)

	var lambdaFunctions []*sparta.LambdaAWSInfo
	lambdaFn := sparta.NewLambda(sparta.IAMRoleDefinition{}, echoEvent, nil)
	apiGatewayResource, _ := apiGateway.NewResource("/hello/echo", lambdaFn)
	apiGatewayResource.NewMethod("GET")

	lambdaFunctions = append(lambdaFunctions, lambdaFn)
	sparta.Main("SampleApplication",
		"Sample application with API Gateway support",
		lambdaFunctions,
		apiGateway)
}

This API can be deployed via:

go run api.go --level debug provision --s3Bucket $MY_S3_BUCKET_NAME

The provisioning log will output the AWS-assigned API Gateway URL as in:

...
Outputs: [{
    Description: "API Gateway URL",
    OutputKey: "URL",
    OutputValue: "https://vpv0e9nv83.execute-api.us-west-2.amazonaws.com/test"
  }],
...

You can then access a specific resource by appending the path component to the OutputValue of the URL value as in:

$ curl -vs https://jhn4bubx7h.execute-api.us-west-2.amazonaws.com/test/hello/echo

*   Trying 54.230.147.237...
* Connected to jhn4bubx7h.execute-api.us-west-2.amazonaws.com (54.230.147.237) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate: *.execute-api.us-west-2.amazonaws.com
* Server certificate: Symantec Class 3 Secure Server CA - G4
* Server certificate: VeriSign Class 3 Public Primary Certification Authority - G5
> GET /test/hello/echo HTTP/1.1
> Host: jhn4bubx7h.execute-api.us-west-2.amazonaws.com
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json
< Content-Length: 14
< Connection: keep-alive
< Date: Mon, 23 Nov 2015 17:02:01 GMT
< x-amzn-RequestId: e968e0f1-9203-11e5-9134-61048221e24a
< X-Cache: Miss from cloudfront
< Via: 1.1 5687015cb50d88319b87aae0ee898267.cloudfront.net (CloudFront)
< X-Amz-Cf-Id: lxP1CTKaV5ArYkfZCNJeWnUaF-63AwCM3-puXo315d_HwSvdhz7ibQ==
<
* Connection #0 to host jhn4bubx7h.execute-api.us-west-2.amazonaws.com left intact
"Hello World!"

NOTE: Providing nil as the Stage argument to sparta.NewAPIGateway() will provision an API instance, but will not deploy it.

Prerequisites
  1. Verify your golang SDK credentials are properly configured
  2. If referring to pre-existing IAM Roles, verify that the Lambda IAM Permissions are properly configured and that the correct IAM RoleName is provided to sparta.NewLambda()
    • More information on the Lambda permission model is available here

Lambda Flow Graph

It's also possible to generate a visual representation of your Lambda connections via the describe command line argument.

go run application.go describe --out ./graph.html && open ./graph.html

Description Sample Output

Additional documentation

View the latest versions at GoDoc or run make docs in the source directory & visit http://localhost:8090.

Caveats

  1. golang isn't officially supported by AWS (yet) - But, you can vote to make golang officially supported. - Because of this, there is a per-container initialization cost of:
    • Copying the embedded binary to /tmp
    • Changing the binary permissions
    • Launching it from the new location
    • See the AWS Forum for more background - Depending on container reuse, this initialization penalty (~700ms) may prove burdensome. - See the JAWS project for a pure NodeJS alternative. - See the PAWS project for a pure Python alternative.
  2. There are Lambda Limits that may affect your development

Outstanding

  • Eliminate NodeJS CustomResources
  • Support API Gateway updates
    • Currently API reprovisioning is done by delete => create
  • Optimize CONSTANTS.go for deployed binary
  • Implement APIGateway graph
  • Support APIGateway inline Model definition
  • Support custom domains

Documentation

Overview

Package sparta transforms a set of golang functions into an Amazon Lambda deployable unit.

The deployable archive includes

  1. NodeJS proxy logic
  2. A golang binary
  3. Dynamically generated CloudFormation template that supports create/update & delete operations.
  4. If specified, CloudFormation custom resources to automatically configure S3/SNS push registration
  5. If specified, API Gateway provisioning logic via custom resources to make the golang functions publicly accessible.

See the Main() docs for more information and examples

Index

Examples

Constants

View Source
const (
	// OutputSpartaHomeKey is the keyname used in the CloudFormation Output
	// that stores the Sparta home URL.
	OutputSpartaHomeKey = "SpartaHome"

	// OutputSpartaVersionKey is the keyname used in the CloudFormation Output
	// that stores the Sparta version used to provision/update the service.
	OutputSpartaVersionKey = "SpartaVersion"
)
View Source
const (
	// @enum APIGatewayPrincipal
	APIGatewayPrincipal = "apigateway.amazonaws.com"
	// @enum AWSPrincipal
	S3Principal = "s3.amazonaws.com"
	// @enum AWSPrincipal
	SNSPrincipal = "sns.amazonaws.com"
	// @enum AWSPrincipal
	EC2Principal = "ec2.amazonaws.com"
	// @enum AWSPrincipal
	LambdaPrincipal = "lambda.amazonaws.com"
)

AWS Principal ARNs from http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html

View Source
const SpartaVersion = "0.0.6"

SpartaVersion defines the current Sparta release

Variables

View Source
var AssumePolicyDocument = ArbitraryJSONObject{
	"Version": "2012-10-17",
	"Statement": []ArbitraryJSONObject{
		{
			"Effect": "Allow",
			"Principal": ArbitraryJSONObject{
				"Service": []string{LambdaPrincipal},
			},
			"Action": []string{"sts:AssumeRole"},
		},
		{
			"Effect": "Allow",
			"Principal": ArbitraryJSONObject{
				"Service": []string{EC2Principal},
			},
			"Action": []string{"sts:AssumeRole"},
		},
		{
			"Effect": "Allow",
			"Principal": ArbitraryJSONObject{
				"Service": []string{APIGatewayPrincipal},
			},
			"Action": []string{"sts:AssumeRole"},
		},
	},
}

AssumePolicyDocument defines common a IAM::Role PolicyDocument used as part of IAM::Role resource definitions

View Source
var CommonIAMStatements = map[string][]ArbitraryJSONObject{
	"core": []ArbitraryJSONObject{
		ArbitraryJSONObject{
			"Action": []string{"logs:CreateLogGroup",
				"logs:CreateLogStream",
				"logs:PutLogEvents"},
			"Effect":   "Allow",
			"Resource": "arn:aws:logs:*:*:*",
		},
		ArbitraryJSONObject{
			"Action":   []string{"cloudwatch:PutMetricData"},
			"Effect":   "Allow",
			"Resource": "*",
		},
		ArbitraryJSONObject{
			"Effect": "Allow",
			"Action": []string{"cloudformation:DescribeStacks"},
			"Resource": ArbitraryJSONObject{
				"Fn::Join": []interface{}{"", cfArn},
			},
		},
	},
	"dynamodb": []ArbitraryJSONObject{
		ArbitraryJSONObject{"Effect": "Allow",
			"Action": []string{"dynamodb:DescribeStream",
				"dynamodb:GetRecords",
				"dynamodb:GetShardIterator",
				"dynamodb:ListStreams",
			},
		}},
	"kinesis": []ArbitraryJSONObject{
		ArbitraryJSONObject{
			"Effect": "Allow",
			"Action": []string{"kinesis:GetRecords",
				"kinesis:GetShardIterator",
				"kinesis:DescribeStream",
				"kinesis:ListStreams",
			},
		},
	},
}

CommonIAMStatements defines common IAM::Role Policy Statement values for different AWS service types. See http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#genref-aws-service-namespaces for names. http://docs.aws.amazon.com/lambda/latest/dg/monitoring-functions.html for more information.

View Source
var PushSourceConfigurationActions = map[string][]string{
	"s3.amazonaws.com": {"s3:GetBucketLocation",
		"s3:GetBucketNotification",
		"s3:PutBucketNotification",
		"s3:GetBucketNotificationConfiguration",
		"s3:PutBucketNotificationConfiguration"},
	"sns.amazonaws.com": {"sns:ConfirmSubscription",
		"sns:GetTopicAttributes",
		"sns:Subscribe",
		"sns:Unsubscribe"},
	"apigateway.amazonaws.com": {"apigateway:*",
		"lambda:AddPermission",
		"lambda:RemovePermission",
		"lambda:GetPolicy"},
}

PushSourceConfigurationActions map stores common IAM Policy Actions for Lambda push-source configuration management. The configuration is handled by CustomResources inserted into the generated CloudFormation template.

Functions

func CloudFormationResourceName

func CloudFormationResourceName(prefix string, parts ...string) string

CloudFormationResourceName returns a name suitable as a logical CloudFormation resource value. See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html for more information. The `prefix` value should provide a hint as to the resource type (eg, `SNSConfigurator`, `ImageTranscoder`). Note that the returned name is not content-addressable.

func DefaultIntegrationResponses

func DefaultIntegrationResponses() map[int]IntegrationResponse

DefaultIntegrationResponses returns a map of HTTP status codes to integration response RegExps to return customized HTTP status codes to API Gateway clients. The regexp is triggered by the presence of a golang HTTP status string in the response body. https://golang.org/src/net/http/status.go

func DefaultMethodResponses

func DefaultMethodResponses(successfulHTTPStatusCode int) map[int]Response

DefaultMethodResponses returns the default set of Method HTTPStatus->Response pass through responses. The successfulHTTPStatusCode param is the single 2XX response code to use for the method.

func Delete

func Delete(serviceName string, logger *logrus.Logger) error

Delete the provided serviceName. Failing to delete a non-existent service is not considered an error. Note that the delete does

func Describe

func Describe(serviceName string, serviceDescription string, lambdaAWSInfos []*LambdaAWSInfo, api *API, outputWriter io.Writer, logger *logrus.Logger) error

Describe produces a graphical representation of a service's Lambda and data sources. Typically automatically called as part of a compiled golang binary via the `describe` command line option.

func Execute

func Execute(lambdaAWSInfos []*LambdaAWSInfo, port int, parentProcessPID int, logger *logrus.Logger) error

Execute creates an HTTP listener to dispatch execution. Typically called via Main() via command line arguments.

func Explore

func Explore(serviceName string, logger *logrus.Logger) error

Explore supports interactive command line invocation of the previously provisioned Sparta service

func Main

func Main(serviceName string, serviceDescription string, lambdaAWSInfos []*LambdaAWSInfo, api *API) error

Main defines the primary handler for transforming an application into a Sparta package. The serviceName is used to uniquely identify your service within a region and will be used for subsequent updates. For provisioning, ensure that you've properly configured AWS credentials for the golang SDK. See http://docs.aws.amazon.com/sdk-for-go/api/aws/defaults.html#DefaultChainCredentials-constant for more information.

Example (ApiGateway)

Should be main() in your application

package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/Sirupsen/logrus"
)

// NOTE: your application MUST use `package main` and define a `main()` function.  The
// example text is to make the documentation compatible with godoc.

func echoAPIGatewayEvent(event *json.RawMessage,
	context *LambdaContext,
	w http.ResponseWriter,
	logger *logrus.Logger) {
	logger.WithFields(logrus.Fields{
		"RequestID": context.AWSRequestID,
		"Event":     string(*event),
	}).Info("Request received")

	fmt.Fprintf(w, "Hello World!")
}

// Should be main() in your application
func main() {

	// Create the MyEchoAPI API Gateway, with stagename /test.  The associated
	// Stage reesource will cause the API to be deployed.
	stage := NewStage("test")
	apiGateway := NewAPIGateway("MyEchoAPI", stage)

	// Create a lambda function
	echoAPIGatewayLambdaFn := NewLambda(IAMRoleDefinition{}, echoAPIGatewayEvent, nil)

	// Associate a URL path component with the Lambda function
	apiGatewayResource, _ := apiGateway.NewResource("/echoHelloWorld", echoAPIGatewayLambdaFn)

	// Associate 1 or more HTTP methods with the Resource.
	apiGatewayResource.NewMethod("GET")

	// After the stack is deployed, the
	// echoAPIGatewayEvent lambda function will be available at:
	// https://{RestApiID}.execute-api.{AWSRegion}.amazonaws.com/test
	//
	// The dynamically generated URL will be written to STDOUT as part of stack provisioning as in:
	//
	//	Outputs: [{
	//      Description: "API Gateway URL",
	//      OutputKey: "URL",
	//      OutputValue: "https://zdjfwrcao7.execute-api.us-west-2.amazonaws.com/test"
	//    }]
	// eg:
	// 	curl -vs https://zdjfwrcao7.execute-api.us-west-2.amazonaws.com/test/echoHelloWorld

	// Start
	Main("HelloWorldLambdaService", "Description for Hello World Lambda", []*LambdaAWSInfo{echoAPIGatewayLambdaFn}, apiGateway)
}
Example (ApiGatewayHTTPSEvent)

Should be main() in your application

package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/Sirupsen/logrus"
)

// NOTE: your application MUST use `package main` and define a `main()` function.  The
// example text is to make the documentation compatible with godoc.

func echoAPIGatewayHTTPEvent(event *json.RawMessage,
	context *LambdaContext,
	w http.ResponseWriter,
	logger *logrus.Logger) {

	var lambdaEvent APIGatewayLambdaJSONEvent
	err := json.Unmarshal([]byte(*event), &lambdaEvent)
	if err != nil {
		logger.Error("Failed to unmarshal event data: ", err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	responseBody, err := json.Marshal(lambdaEvent)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	} else {
		fmt.Fprint(w, string(responseBody))
	}
}

// Should be main() in your application
func main() {

	// Create the MyEchoAPI API Gateway, with stagename /test.  The associated
	// Stage reesource will cause the API to be deployed.
	stage := NewStage("v1")
	apiGateway := NewAPIGateway("MyEchoHTTPAPI", stage)

	// Create a lambda function
	echoAPIGatewayLambdaFn := NewLambda(IAMRoleDefinition{}, echoAPIGatewayEvent, nil)

	// Associate a URL path component with the Lambda function
	apiGatewayResource, _ := apiGateway.NewResource("/echoHelloWorld", echoAPIGatewayLambdaFn)

	// Associate 1 or more HTTP methods with the Resource.
	method, err := apiGatewayResource.NewMethod("GET")
	if err != nil {
		panic("Failed to create NewMethod")
	}
	// Whitelist query parameters that should be passed to lambda function
	method.Parameters["method.request.querystring.myKey"] = true
	method.Parameters["method.request.querystring.myOtherKey"] = true

	// Start
	Main("HelloWorldLambdaHTTPSService", "Description for Hello World HTTPS Lambda", []*LambdaAWSInfo{echoAPIGatewayLambdaFn}, apiGateway)
}
Example (Basic)
package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/Sirupsen/logrus"
)

// NOTE: your application MUST use `package main` and define a `main()` function.  The
// example text is to make the documentation compatible with godoc.
// Should be main() in your application

func mainHelloWorld(event *json.RawMessage, context *LambdaContext, w http.ResponseWriter, logger *logrus.Logger) {
	fmt.Fprintf(w, "Hello World!")
}

func main() {
	var lambdaFunctions []*LambdaAWSInfo
	helloWorldLambda := NewLambda("PreexistingAWSLambdaRoleName", mainHelloWorld, nil)
	lambdaFunctions = append(lambdaFunctions, helloWorldLambda)
	Main("HelloWorldLambdaService", "Description for Hello World Lambda", lambdaFunctions, nil)
}

func NewLogger

func NewLogger(level string) (*logrus.Logger, error)

NewLogger returns a new logrus.Logger instance. It is the caller's responsibility to set the formatter if needed.

func Provision

func Provision(noop bool,
	serviceName string,
	serviceDescription string,
	lambdaAWSInfos []*LambdaAWSInfo,
	api *API,
	s3Bucket string,
	templateWriter io.Writer,
	logger *logrus.Logger) error

Provision compiles, packages, and provisions (either via create or update) a Sparta application. The serviceName is the service's logical identify and is used to determine create vs update operations. The compilation options/flags are:

TAGS:         -tags lambdabinary
ENVIRONMENT:  GOOS=linux GOARCH=amd64 GO15VENDOREXPERIMENT=1

The compiled binary is packaged with a NodeJS proxy shim to manage AWS Lambda setup & invocation per http://docs.aws.amazon.com/lambda/latest/dg/authoring-function-in-nodejs.html

The two files are ZIP'd, posted to S3 and used as an input to a dynamically generated CloudFormation template (http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) which creates or updates the service state.

More information on golang 1.5's support for vendor'd resources is documented at

https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo/edit
https://medium.com/@freeformz/go-1-5-s-vendor-experiment-fd3e830f52c3#.voiicue1j
type Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

Types

type API

type API struct {

	// Existing API to CloneFrom
	CloneFrom   string
	Description string
	// contains filtered or unexported fields
}

API represents the AWS API Gateway data associated with a given Sparta app. Proxies the AWS SDK's CreateRestApiInput data. See http://docs.aws.amazon.com/sdk-for-go/api/service/apigateway.html#type-CreateRestApiInput

func NewAPIGateway

func NewAPIGateway(name string, stage *Stage) *API

NewAPIGateway returns a new API Gateway structure. If stage is defined, the API Gateway will also be deployed as part of stack creation.

func (API) MarshalJSON

func (api API) MarshalJSON() ([]byte, error)

MarshalJSON customizes the JSON representation used when serializing to the CloudFormation template representation.

func (*API) NewResource

func (api *API) NewResource(pathPart string, parentLambda *LambdaAWSInfo) (*Resource, error)

NewResource associates a URL path value with the LambdaAWSInfo golang lambda. To make the Resource available, associate one or more Methods via NewMethod().

type APIGatewayLambdaJSONEvent

type APIGatewayLambdaJSONEvent struct {
	// HTTPMethod
	Method string `json:"method"`
	// Body, if available
	Body json.RawMessage `json:"body"`
	// Whitelisted HTTP headers
	Headers map[string]string `json:"headers"`
	// Whitelisted HTTP query params
	QueryParams map[string]string `json:"queryParams"`
	// Whitelisted path parameters
	PathParams map[string]string `json:"pathParams"`
}

APIGatewayLambdaJSONEvent provides a pass through mapping of all whitelisted Parameters. The transformation is defined by the resources/gateway/inputmapping_json.vtl template.

type ArbitraryJSONObject

type ArbitraryJSONObject map[string]interface{}

ArbitraryJSONObject represents an untyped key-value object. CloudFormation resource representations are aggregated as []ArbitraryJSONObject before being marsharled to JSON for API operations.

type BasePermission

type BasePermission struct {
	// The AWS account ID (without hyphens) of the source owner
	SourceAccount string `json:"SourceAccount,omitempty"`
	// The ARN of a resource that is invoking your function.
	SourceArn string `json:"SourceArn,omitempty"`
}

BasePermission (http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-permission.html) type for common AWS Lambda permission data.

type IAMRoleDefinition

type IAMRoleDefinition struct {
	// Slice of IAMRolePrivilege entries
	Privileges []IAMRolePrivilege
}

IAMRoleDefinition stores a slice of IAMRolePrivilege values to "Allow" for the given IAM::Role. Note that the CommonIAMStatements will be automatically included and do not need to be multiply specified.

type IAMRolePrivilege

type IAMRolePrivilege struct {
	// What actions you will allow.
	// Each AWS service has its own set of actions.
	// For example, you might allow a user to use the Amazon S3 ListBucket action,
	// which returns information about the items in a bucket.
	// Any actions that you don't explicitly allow are denied.
	Actions []string
	// Which resources you allow the action on. For example, what specific Amazon
	// S3 buckets will you allow the user to perform the ListBucket action on?
	// Users cannot access any resources that you have not explicitly granted
	// permissions to.
	Resource string
}

IAMRolePrivilege struct stores data necessary to create an IAM Policy Document as part of the inline IAM::Role resource definition. See http://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html for more information

type Integration

type Integration struct {
	Parameters         map[string]string
	RequestTemplates   map[string]string
	CacheKeyParameters []string
	CacheNamespace     string
	Credentials        string

	Responses map[int]IntegrationResponse
}

Integration proxies the AWS SDK's Integration data. See http://docs.aws.amazon.com/sdk-for-go/api/service/apigateway.html#type-Integration

func (Integration) MarshalJSON

func (integration Integration) MarshalJSON() ([]byte, error)

MarshalJSON customizes the JSON representation used when serializing to the CloudFormation template representation.

type IntegrationResponse

type IntegrationResponse struct {
	Parameters       map[string]string `json:",omitempty"`
	SelectionPattern string            `json:",omitempty"`
	Templates        map[string]string `json:",omitempty"`
}

IntegrationResponse proxies the AWS SDK's IntegrationResponse data. See http://docs.aws.amazon.com/sdk-for-go/api/service/apigateway.html#type-IntegrationResponse

type LambdaAWSInfo

type LambdaAWSInfo struct {

	// Role name (NOT ARN) to use during AWS Lambda Execution.  See
	// the FunctionConfiguration (http://docs.aws.amazon.com/lambda/latest/dg/API_FunctionConfiguration.html)
	// docs for more info.
	// Note that either `RoleName` or `RoleDefinition` must be supplied
	RoleName string
	// IAM Role Definition if the stack should implicitly create an IAM role for
	// lambda execution. Note that either `RoleName` or `RoleDefinition` must be supplied
	RoleDefinition *IAMRoleDefinition
	// Additional exeuction options
	Options *LambdaFunctionOptions
	// Permissions to enable push-based Lambda execution.  See the
	// Permission Model docs (http://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html)
	// for more information.
	Permissions []LambdaPermissionExporter
	// EventSource mappings to enable for pull-based Lambda execution.  See the
	// Event Source docs (http://docs.aws.amazon.com/lambda/latest/dg/intro-core-components.html)
	// for more information
	EventSourceMappings []*lambda.CreateEventSourceMappingInput
	// Template decorator. If defined, the decorator will be called to insert additional
	// resources on behalf of this lambda function
	Decorator TemplateDecorator
	// contains filtered or unexported fields
}

LambdaAWSInfo stores all data necessary to provision a golang-based AWS Lambda function.

func NewLambda

func NewLambda(roleNameOrIAMRoleDefinition interface{}, fn LambdaFunction, lambdaOptions *LambdaFunctionOptions) *LambdaAWSInfo

NewLambda returns a LambdaAWSInfo value that can be provisioned via CloudFormation. The roleNameOrIAMRoleDefinition must either be a `string` or `IAMRoleDefinition` type

Example (IAMRoleDefinition)
package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/Sirupsen/logrus"
)

func lambdaHelloWorld2(event *json.RawMessage, context *LambdaContext, w http.ResponseWriter, logger *logrus.Logger) {
	fmt.Fprintf(w, "Hello World!")
}

func main() {
	roleDefinition := IAMRoleDefinition{}
	roleDefinition.Privileges = append(roleDefinition.Privileges, IAMRolePrivilege{
		Actions: []string{"s3:GetObject",
			"s3:PutObject"},
		Resource: "arn:aws:s3:::*",
	})
	helloWorldLambda := NewLambda(IAMRoleDefinition{}, lambdaHelloWorld2, nil)
	if nil != helloWorldLambda {
		fmt.Printf("Failed to create new Lambda function")
	}
}
Example (PreexistingIAMRoleName)
package main

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/Sirupsen/logrus"
)

func lambdaHelloWorld(event *json.RawMessage, context *LambdaContext, w http.ResponseWriter, logger *logrus.Logger) {
	fmt.Fprintf(w, "Hello World!")
}

func main() {
	helloWorldLambda := NewLambda("PreexistingAWSLambdaRoleName", lambdaHelloWorld, nil)
	if nil != helloWorldLambda {
		fmt.Printf("Failed to create new Lambda function")
	}
}

type LambdaContext

type LambdaContext struct {
	AWSRequestID       string `json:"awsRequestId"`
	InvokeID           string `json:"invokeid"`
	LogGroupName       string `json:"logGroupName"`
	LogStreamName      string `json:"logStreamName"`
	FunctionName       string `json:"functionName"`
	MemoryLimitInMB    string `json:"memoryLimitInMB"`
	FunctionVersion    string `json:"functionVersion"`
	InvokedFunctionARN string `json:"invokedFunctionArn"`
}

LambdaContext defines the AWS Lambda Context object provided by the AWS Lambda runtime. See http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html for more information on field values. Note that the golang version doesn't functions defined on the Context object.

type LambdaFunction

type LambdaFunction func(*json.RawMessage, *LambdaContext, http.ResponseWriter, *logrus.Logger)

LambdaFunction is the golang function signature required to support AWS Lambda execution. Standard HTTP response codes are used to signal AWS Lambda success/failure on the proxied context() object. See http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html for more information.

200 - 299       : Success
<200 || >= 300  : Failure

Content written to the ResponseWriter will be used as the response/Error value provided to AWS Lambda.

type LambdaFunctionOptions

type LambdaFunctionOptions struct {
	// Additional function description
	Description string
	// Memory limit
	MemorySize int64
	// Timeout (seconds)
	Timeout int64
}

LambdaFunctionOptions defines additional AWS Lambda execution params. See the AWS Lambda FunctionConfiguration (http://docs.aws.amazon.com/lambda/latest/dg/API_FunctionConfiguration.html) docs for more information. Note that the "Runtime" field will be automatically set to "nodejs" (at least until golang is officially supported)

type LambdaPermission

type LambdaPermission struct {
	BasePermission
	// The entity for which you are granting permission to invoke the Lambda function
	Principal string
}

LambdaPermission type that creates a Lambda::Permission entry in the generated template, but does NOT automatically register the lambda with the BasePermission.SourceArn. Typically used to register lambdas with externally managed event producers

type LambdaPermissionExporter

type LambdaPermissionExporter interface {
	// contains filtered or unexported methods
}

LambdaPermissionExporter defines an interface for polymorphic collection of Permission entries that support specialization for additional resource generation.

type Method

type Method struct {
	APIKeyRequired bool

	// Request data
	Parameters map[string]bool
	Models     map[string]Model

	// Response map
	Responses map[int]Response

	// Integration response map
	Integration Integration
	// contains filtered or unexported fields
}

Method proxies the AWS SDK's Method data. See http://docs.aws.amazon.com/sdk-for-go/api/service/apigateway.html#type-Method

func (Method) MarshalJSON

func (method Method) MarshalJSON() ([]byte, error)

MarshalJSON customizes the JSON representation used when serializing to the CloudFormation template representation. If method.Responses is empty, the DefaultMethodResponses map will be used, where the HTTP Success code is 201 for POST methods and 200 for all other methodnames.

type Model

type Model struct {
	Description string `json:",omitempty"`
	Name        string `json:",omitempty"`
	Schema      string `json:",omitempty"`
}

Model proxies the AWS SDK's Model data. See http://docs.aws.amazon.com/sdk-for-go/api/service/apigateway.html#type-Model

NOTE: Dynamic Model creation is currently _NOT_ implemented.

type Resource

type Resource struct {
	Methods map[string]*Method
	// contains filtered or unexported fields
}

Resource proxies the AWS SDK's Resource data. See http://docs.aws.amazon.com/sdk-for-go/api/service/apigateway.html#type-Resource

func (Resource) MarshalJSON

func (resource Resource) MarshalJSON() ([]byte, error)

MarshalJSON customizes the JSON representation used when serializing to the CloudFormation template representation.

func (*Resource) NewAuthorizedMethod

func (resource *Resource) NewAuthorizedMethod(httpMethod string, authorizationType string) (*Method, error)

NewAuthorizedMethod associates the httpMethod name and authorizationType with the given Resource.

func (*Resource) NewMethod

func (resource *Resource) NewMethod(httpMethod string) (*Method, error)

NewMethod associates the httpMethod name with the given Resource. The returned Method has no authorization requirements.

type Response

type Response struct {
	Parameters map[string]bool  `json:",omitempty"`
	Models     map[string]Model `json:",omitempty"`
}

Response proxies the AWS SDK's PutMethodResponseInput data. See http://docs.aws.amazon.com/sdk-for-go/api/service/apigateway.html#type-PutMethodResponseInput

type S3Permission

type S3Permission struct {
	BasePermission
	// S3 events to register for (eg: `[]string{"s3:ObjectCreated:*", "s3:ObjectRemoved:*"}`).
	Events []string `json:"Events,omitempty"`
	// S3.NotificationConfigurationFilter
	// to scope event forwarding.  See
	// 		http://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html
	// for more information.
	Filter s3.NotificationConfigurationFilter `json:"Filter,omitempty"`
}

S3Permission struct that imples the S3 BasePermission.SourceArn should be updated (via PutBucketNotificationConfiguration) to automatically push events to the owning Lambda. See http://docs.aws.amazon.com/lambda/latest/dg/intro-core-components.html#intro-core-components-event-sources for more information.

Example
package main

import (
	"encoding/json"
	"net/http"

	"github.com/Sirupsen/logrus"
)

const s3Bucket = "arn:aws:sns:us-west-2:123412341234:myBucket"

func s3LambdaProcessor(event *json.RawMessage, context *LambdaContext, w http.ResponseWriter, logger *logrus.Logger) {
	logger.WithFields(logrus.Fields{
		"RequestID": context.AWSRequestID,
	}).Info("S3Event")

	logger.Info("Event data: ", string(*event))
}

func main() {
	var lambdaFunctions []*LambdaAWSInfo
	// Define the IAM role
	roleDefinition := IAMRoleDefinition{}
	roleDefinition.Privileges = append(roleDefinition.Privileges, IAMRolePrivilege{
		Actions: []string{"s3:GetObject",
			"s3:PutObject"},
		Resource: s3Bucket,
	})
	// Create the Lambda
	s3Lambda := NewLambda(IAMRoleDefinition{}, s3LambdaProcessor, nil)

	// Add a Permission s.t. the Lambda function automatically registers for S3 events
	s3Lambda.Permissions = append(s3Lambda.Permissions, S3Permission{
		BasePermission: BasePermission{
			SourceArn: s3Bucket,
		},
		Events: []string{"s3:ObjectCreated:*", "s3:ObjectRemoved:*"},
	})

	lambdaFunctions = append(lambdaFunctions, s3Lambda)
	Main("S3LambdaApp", "Registers for S3 events", lambdaFunctions, nil)
}

type SNSPermission

type SNSPermission struct {
	BasePermission
}

SNSPermission struct that imples the S3 BasePermission.SourceArn should be updated (via PutBucketNotificationConfiguration) to automatically push events to the parent Lambda. See http://docs.aws.amazon.com/lambda/latest/dg/intro-core-components.html#intro-core-components-event-sources for more information.

Example
package main

import (
	"encoding/json"
	"net/http"

	"github.com/Sirupsen/logrus"
)

const snsTopic = "arn:aws:sns:us-west-2:123412341234:mySNSTopic"

func snsProcessor(event *json.RawMessage, context *LambdaContext, w http.ResponseWriter, logger *logrus.Logger) {
	logger.WithFields(logrus.Fields{
		"RequestID": context.AWSRequestID,
	}).Info("SNSEvent")
	logger.Info("Event data: ", string(*event))
}

func main() {
	var lambdaFunctions []*LambdaAWSInfo

	snsLambda := NewLambda(IAMRoleDefinition{}, snsProcessor, nil)
	snsLambda.Permissions = append(snsLambda.Permissions, SNSPermission{
		BasePermission: BasePermission{
			SourceArn: snsTopic,
		},
	})
	lambdaFunctions = append(lambdaFunctions, snsLambda)
	Main("SNSLambdaApp", "Registers for SNS events", lambdaFunctions, nil)
}

type Stage

type Stage struct {
	CacheClusterEnabled bool
	CacheClusterSize    string
	Description         string
	Variables           map[string]string
	// contains filtered or unexported fields
}

Stage proxies the AWS SDK's Stage data. See http://docs.aws.amazon.com/sdk-for-go/api/service/apigateway.html#type-Stage

func NewStage

func NewStage(name string) *Stage

NewStage returns a Stage object with the given name. Providing a Stage value to NewAPIGateway implies that the API Gateway resources should be deployed (eg: made publicly accessible). See http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api.html

func (Stage) MarshalJSON

func (stage Stage) MarshalJSON() ([]byte, error)

MarshalJSON customizes the JSON representation used when serializing to the CloudFormation template representation.

type TemplateDecorator

type TemplateDecorator func(lambdaResourceName string,
	lambdaResourceDefinition ArbitraryJSONObject,
	resources ArbitraryJSONObject,
	outputs ArbitraryJSONObject,
	logger *logrus.Logger) error

TemplateDecorator if defined, allows Lambda functions to annotate the CloudFormation template definition. Both the resources and the outputs params are initialized to an empty ArbitraryJSONObject and should be populated with valid CloudFormation types. The CloudFormationResourceName() function can be used to generate logical resource names for insertion keys. See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html and http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html for more information.

Directories

Path Synopsis
aws
s3
Package s3 provides types to support unmarshalling generic `event *json.RawMessage` types into S3 specific event structures.
Package s3 provides types to support unmarshalling generic `event *json.RawMessage` types into S3 specific event structures.

Jump to

Keyboard shortcuts

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