Aegis - Serverless Golang deploy tool and framework for AWS Lambda

Aegis

License Apache 2 godoc aegis Build Status Go Report Card

Aegis Documentation

Aegis is both a simple deploy tool and framework. Its primary goal is to help you write microservices in the AWS cloud quickly and easily. They are mutually exclusive tools.

Aegis is not intended to be an infrastructure management tool. It will never be as feature rich as tools like Terraform. Its goal is to assist in the development of microservices - not the maintenance of infrastructure.

Likewise the framework is rather lightweight as well. It may never have helpers and features for every AWS product under the sun. It provides a conventional framework to help you build serverless microservices faster. It removes a lot of boilerplate.

Getting Started

You'll need an AWS account of course. You'll also want to have your credentials setup as you would for using AWS CLI. Note that you can also pass AWS credentials via the CLI or by setting environment variables.

Get Aegis of course. Use the normal go get github.com/tmaiaroto/aegis. Ensure the aegis binary is in your executable path. You can build a fresh copy from the code in this repository or download the binary from the releases section of the GitHub project site. If you want to use the framework though, you'll need to use go get anyway.

You can find some examples in the examples directory of this repo. Aegis also comes with a command to setup some boilerplate code in a clean directory using aegis init. Note that it will not overwrite any existing files.

Work with your code and check settings in aegis.yaml. When you're ready, you can deploy with aegis deploy to upload your Lambda and setup some resources.

Aegis' deploy command will set up the Lambda function, an optional API Gateway, IAM roles, CloudWatch event rules, and other various triggers and permissions for your Lambda function. You're able to choose a specific IAM role if you like too. Just set it in aegis.yaml.

If you're deploying an API, the CLI output will show you the URL for it along with other helpful information.

The Aegis framework works by handling events (how anything using AWS Lambda works). The way in which it does this though is via "routers." This means your Lambda is actually able to handle multiple types of events if you so choose.

Many people will want to write one handler for one Lambda, but that's not a mandate of Lambda. So feel free to architect your microservices how you like.

There are several types of routers. You can handle incoming HTTP requests via API Gateway using various HTTP methods and paths. You can handle incoming S3 events. You can handle scheduled Lambda invocations using CloudWatch rules. You can even handle invocations from other Lambdas ("RPCs").

Building

It's easiest to download a binary to use Aegis, though you may wish to build for your specific platform. In this case, Go Modules is used. Easiest thing to do after cloning is:

GO111MODULE=on go mod download

Then build:

GO111MODULE=on go build

Unfortunately you can't do a straight go build because of one of the packages used. You'll get errors. So using Go Modules is the way.

Contributing

Please feel free to contribute (see CONTRIBUTING.md). Though outside of actual pull requests with code, please file issues. If you notice something broken, speak up. If you have an idea for a feature, put it in an issue. Feedback is perhaps one of the best ways to contribute. So don't feel compelled to code.

Keep in mind that not all ideas can be implemented. There is a design direction for this project and only so much time. Though it's still good to share ideas.

Running Tests

Goconvey is used for testing, just be sure to exclude the docs directory. For example: goconvey -excludedDirs docs

Otherwise, tests will run and also include the docs folder which will likely have problems.

Alternatively, run tests from the framework directory.

Owner
Tom Maiaroto
馃 Full stack developer and whatever else is needed.
Tom Maiaroto
Comments
  • There was a problem creating a default IAM role for Lambda. Check your configuration.

    There was a problem creating a default IAM role for Lambda. Check your configuration.

    Running deploy from the examples/cognito directory I get the following error.

    MalformedPolicyDocument: Invalid principal in policy: "SERVICE":"cognito-identity.amazonaws.com" status code: 400, request id: a2de5b72-7fa6-11e8-b8c9-0f4f651e0f50

  • token contains an invalid number of segments

    token contains an invalid number of segments

    I'm hitting this error in the cognito callback function. Looks like it's coming from here https://github.com/tmaiaroto/aegis/blob/master/framework/cognito_client.go#L287

  • aegis deploy error

    aegis deploy error

    I created a blank project using aegis init but am getting an error when trying to deploy.

    $ aegis deploy There was a problem building the Go app for the Lambda function. exit status 1

    Is there anything I should change in order to deploy this project?

  • Method to read/write encrypted config values

    Method to read/write encrypted config values

    More and more there are needs to deal with sensitive credentials. Be it a Cognito secret key or database connection info. Not everything can be handled by IAM and SDK calls.

    I made a project a long while ago called discfg. That exposed an HTTP API interface and used DyanmoDB as well. I'm thinking something simpler.

    I'm thinking a new command for the Aegis CLI that lets one read and write key values to perhaps just S3. This would avoid the use of DynamoDB (just another thing to provision and such). The reason being that these config values won't often change. There's no concern with write speed. Read speed? Ehh, should be ok. Especially considering many of these variables will only be read at start time. Warm Lambda invocations won't be affected at all.

    The CLI would expose three commands: read, readFull, and write

    It would use KMS to encrypt the stored values in S3. A bucket would need to be configured (aegis.yaml). The file name will come from configuration too (or conventionally be the name of the Lambda, though the ability to change that without losing config path is preferable).

    So all the Lambda would need at build time is the bucket/path. The deploy command would have already set up permissions to use KMS. Then it's just a matter of a simple helper function in the Lambda function to get the values.

    These would be as simple as setting environment variables. Perhaps the helper even pulls the entire file and sets as environment variables. So the process can be the same both when testing/developing locally and running in AWS. Or so that environment variables can be optionally used instead. It keeps things a bit more standard and flexible. Think CI tools, etc. Things that might not have KMS access yet still need to run the app or run an integration test, etc.

    The read and readFull commands are nice too. The normal read would only show part of the stored value, with asterisks protecting the bulk of it. For example, DB_PASSWORD=a1kj******ak should be enough for someone to quickly see what was currently set and if it's correct (in most cases). While a readFull command would show the value completely unencrypted. This is just security convenience. If someone is in a position where they don't want everything to appear on their screen unencrypted, they have a choice now.

    What this whole thing does though is it makes it harder for developers to push sensitive credentials to online repositories. The aegis.yaml file should theoretically be able to contain nothing sensitive. The Lambda environment variables and API Gateway stage variables set there shouldn't be sensitive passwords or keys because it's so incredibly easy to commit that aegis.yaml file. Many people will want to commit that file too instead of sharing it among people because it contains the function name, memory allocation, API name, etc. It should be able to be pushed to a public repo without concern.

    I'm not keen on making some sort of dot file that magically sets variables because again we're in the position of accidental publishing. There's still the need to then share that file with team members.

    S3 is central. It's easier to provision than DynamoDB and there's no management of capacity units to consider. All team members should have an AWS account with access to S3 and KMS. The specific KMS key and S3 bucket needed in this case. It provides one central point to control access to the credentials. It leaves absolutely no way to accidentally publish sensitive information either.

  • There was a problem building the Go app for the Lambda function.

    There was a problem building the Go app for the Lambda function.

    I ran:

    aegis init aegis deploy There was a problem building the Go app for the Lambda function. exit status 1

    Is there something I'm supposed to do after init?

  • How could one change the default 3 second timeout for (Basic Settings)

    How could one change the default 3 second timeout for (Basic Settings)

    I see in one of the examples that you can set an api->resourceTimeoutMs, but this doesn't seem to change the Basic Setting timeout in Lambda:

    img

    Please let me know if there is a setting to change this.

    Thank you

  • Add binary support

    Add binary support

    API Gateway now has binary support. It just needs to know which content-type headers to treat the media type accordingly. This should be configurable.

  • Custom Zip

    Custom Zip

    Is it possible to create a custom zip and include non go files like templates and such?

    I saw in the config file that you can provide a custom zip file, which i created by generating the go binary and placing it in a zip with my template but no dice.

    Any suggestions?

  • Cognito handlers and helpers

    Cognito handlers and helpers

    This is a big one, but it's very common and important for most apps.

    There should be handlers for each trigger described here: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-lambda-trigger-examples.html

    There should be middleware that can be used with the router.

    We can return HTML pages with Aegis actually. So either work with JSON to allow a custom app to design sign up forms, etc. Or return a default simple HTML form/template. I imagine 80%+ of the time apps would make all the sign up forms, etc. However, using redirects or iframes even could be valuable, especially for speed. This raises an interesting concept -- what about HTML templates held in S3? Aegis could load those to render. So design can be customized to a good degree. Of course lengthy forms for profile updates, etc. would be something to work on later or just completely out of the equation. Aegis hosted HTML through API Gateway could simply be simple signup/login. No extra form fields about phone numbers, birthdate, etc. It's much better to use CloudFront for hosting and not S3 (assuming templates are hosted there and not bundled with the Lambda...but actually why not bundle with deploy?) through Lambda through API Gateway. Though for speed/convenience...Something to think about.

    Pools have to be created outside of deploy. They can't have their attributes updated once created - so having a list of attributes in the config would be weird because they'd be a one time use. Also, it's just a lot here. It's bloating deploy. API Gateway and roles and such made sense (especially given the usage of API Gateway was opinionated), but maybe even some of that could benefit from separate commands for certain things. The first pass of Cognito in aegis could certainly require all Cognito setup to occur outside of the too. Using the web console is easy enough. Though a comprehensive CLI tool (that is likely to be quite opinionated) is a long term goal.

  • SES trigger/handler

    SES trigger/handler

    Much like the other handlers, there should be a trigger from incoming e-mails. "Handler routing" perhaps based on e-mail address or even domain.

    This one is probably more involved with the configuration than other event sources.

    https://aws.amazon.com/blogs/aws/new-receive-and-process-incoming-email-with-amazon-ses/

  • How to install

    How to install

    Sorry if I missed anything but How to install this project. I 've search for go and npm package but there was no result. Do I have to clone and build this project to have a binary file for aegis CLI ?

  • Support HTTP API

    Support HTTP API

    AWS recently released a better option for API Gateway and Lambda. Cheaper too. Also parses JWT which could be a nice option as well.

    It better matches how Aegis works. Still need to double check a few things (like stages), but may be a much better fit. Also realizing that there's no rate limiting, it may just be an option.

    https://aws.amazon.com/blogs/compute/announcing-http-apis-for-amazon-api-gateway/

  • Set up integration tests

    Set up integration tests

    Changes in various things can create issues from time to time. Having an integration test to ensure basic build and deploy works would be great. Having it periodically run automatically would be better.

    Maybe run this from a Lambda? 馃榾

  • AppSync/GraphQL support

    AppSync/GraphQL support

    I'd really like to add AppSync support. Then have a router for resolvers.

    • handle resolvers with a new router
    • import/export/push/sync with AppSync

    The Amplify CLI toolchain is great and all but, it's very heavy and does a lot. It also uses CloudFormation and as such there's a lot of stateful issues and limitations. For example, there is no ability to import and existing GraphQL AppSync API into the toolchain. However, the SDK has everything needed: https://docs.aws.amazon.com/cli/latest/reference/appsync/index.html#cli-aws-appsync

    I see no tool out there that pulls down your AppSync API, allowing you to update the VTL and then push back changes. So if something was created via the web console for example...you're hosed. Amplify CLI wouldn't be able to deal with it. A sync (no pun intended) would really help.

    I'm using AppSync GraphQL more and more and will replace a lot of my API needs with it. Not all, but a lot. Auth checks using Cognito are great and you can make multiple queries in the VTL templates (transactions etc) so checking for authorization based on data in RDS or something is pretty easy too. This eliminates a tremendous amount of need for Lambda functions.

    Want to send an e-mail if a user invites another user to their group in your app? Sure, you're looking at Lambda. So there's no way to completely avoid it but, AppSync is a very powerful thing that people are missing out on and aren't connecting all the dots (and the examples don't really show the potential either really).

    So being able to manage this from aegis fits in pretty naturally. Funny enough, one could use aegis then to build an entire API and never write any Go code at all. Technically speaking. Practically, of course you'd have more going on and would write some Go functions.

  • 3rd Party Add-Ons

    3rd Party Add-Ons

    I'm going to keep a running list of 3rd party add-on ideas here. These will not be part of this repository because all 3rd party things will be separate packages. Aegis only deals with AWS. However, there is a sense of interop and a desire to use other services.

    Tracing

    • Opentracing: http://opentracing.io https://github.com/opentracing/opentracing-go

    This one may even make sense to include (since logrus is) in the core framework package. It's a vendor neutral bridge, however it does not include X-Ray. So on the fence about it. Also makes me think about moving logrus out on the other hand. Regardless, I think this is very important and I think it can use the existing TraceStrategy interface to adapt calls; perhaps some additional methods on top for it specifically.

    Auth

    • Auth0 https://github.com/auth0-community/go-auth0

    This is such a popular service it seems like there should be a 3rd party package to work with.

  • Custom Services and related work

    Custom Services and related work

    The idea of "Services" are really just handler dependencies that get injected, but also can be configured. This configuration happens with a closure that receives context and the event. So it allows for a great deal of flexibility with what gets injected into a handler.

    Currently only the Cognito service (which is a more involved "helper" of the sorts) is used. The ability to add custom services is sorta there -- there's a Custom field on the Services struct, but it's not fully implemented. That is, nothing will get configured.

    For example, look at what happens with the Cognito service:

    if sCfg, ok := a.Services.configurations["cognito"]; ok && a.Services.Cognito == nil {
        cognitoCfg := sCfg(ctx, evt).(*CognitoAppClientConfig)
        cognitoCfg.TraceContext = a.TraceContext
        cognitoCfg.AWSClientTracer = a.AWSClientTracer
    

    The current Lambda context and event are given to the configuration function (held on a configurations map). This allows the Cognito service to use that context and event to configure itself.

    Currently, users could write some sort of configuration "New()" function and run it in each of the handlers they wish to use context and event data from...But that's not so much dependency injection. That's taking the event and instantiating a new service after the fact. We can make it a little cleaner. Not saying it's the only way it should be done or could be done...But it provides another option that may become more important when it comes to use 3rd party packages.

    First off: Refactor the check for cognito service configuration. That should be in its own function that not only checks for that, but also other services.

    Second: Also take into account Custom user services.

    The following is how the Cognito service gets configured: AegisApp.ConfigureService("cognito", func(ctxcontext.Context, evt map[string]interface{}) { ... })

    That should already work well for every other service in the future as well. Custom services should be something like ConfigureService("custom.myservice", func...)

    That function adds to the configurations map which gets used in the base aegisHandler(). It just needs to work for more than just the Cognito service now.

    So the groundwork is all in place. There's a clear path on how to implement these things, it just needs to happen. It was never really added. Though the intent for custom services was always there.

    The priority? That really is hard to say, because there are ways to use and configure services for your handlers already. Just do it inside the handler. This is mostly an enhancement and quality of life improvement that allows you to write less code (or potentially share more code with others).

Prueba de concepto: Boletia, una aplicaci贸n para venta de boletos, basada en microservicios event-driven. Desarrollada sobre AWS Serverless: Api Gateway, Lambda, DynamoDB, DynamoDB Streams
Prueba de concepto: Boletia, una aplicaci贸n para venta de boletos, basada en microservicios event-driven. Desarrollada sobre AWS Serverless: Api Gateway, Lambda, DynamoDB, DynamoDB Streams

Prueba de concepto: Boletia, una aplicaci贸n para venta de boletos, basada en microservicios event-driven. Desarrollada sobre AWS Serverless: Api Gatew

May 7, 2022
Una prueba t茅cnica: Servicio Golang REST API local, sobre Docker, gRPC, AWS Serverless y sobre Kubernetes en AWS EC2

Una prueba t茅cnica: Servicio Golang REST API local, sobre Docker, gRPC, AWS Serverless y sobre Kubernetes en AWS EC2

May 7, 2022
A Lambda function built with SAM (Serverless Application Module)

AWS SAM Lambda Function 漏 Israel Pereira Tavares da Silva The AWS Serverless Application Model (SAM) is an open-source framework for building serverle

Dec 19, 2021
Go-serverless-eth-event-listener - Go serverless, ethereum contract event listener with a sample contract

go-serverless-eth-event-listener This repository is for showing how to listen sm

May 19, 2022
Golang AWS SAM Lambda example

Golang AWS SAM Lambda example This example project shows how to use AWS SAM with

Nov 18, 2022
Lambda stack to turn off and destroy all resources from your personal AWS Account to avoid billing surprises
Lambda stack to turn off and destroy all resources from your personal AWS Account to avoid billing surprises

AWS, Turn off my Account, please Lambda stack to turn off and destroy all resources from your personal AWS Account to avoid billing surprises Resource

Oct 25, 2022
Mrrobot - A simple greetings bot for Slack that uses events api and hosted on AWS Lambda

Mr. Robot a greeter bot for your slack community build_docker

Aug 21, 2022
Go-xrayprofile - Selective profiling of AWS Lambda functions

go-xrayprofile AWS X-Ray is handy for understanding the overall performance of y

May 18, 2022
Getting presigned urls for S3 with AWS SDK Go V2. Easy deploy with Velcel CLI.

S3-Presigned-Urls-Vercel-Serverless Setup yarn install && yarn setup Run(Local) yarn start You need to set environment variables with os.setenv for lo

Jan 14, 2022
A serverless sync server for Santa, built on AWS

Rudolph Rudolph is the control server counterpart of Santa, and is used to rapidly deploy configurations to Santa agents. Rudolph is built in Amazon W

Dec 5, 2022
Simple CRUD API written in Go, built using AWS SAM tool and using the AWS' infrastructure.
Simple CRUD API written in Go, built using AWS SAM tool and using the AWS' infrastructure.

tutor-pet API Simple CRUD API written in Go, built using AWS SAM tool and using the AWS' infrastructure. Macro architecture: Code architecture: Pre-Re

Aug 17, 2022
Serverless SOAR (Security Orchestration, Automation and Response) framework for automatic inspection and evaluation of security alert
Serverless SOAR (Security Orchestration, Automation and Response) framework for automatic inspection and evaluation of security alert

DeepAlert DeepAlert is a serverless framework for automatic response of security alert. Overview DeepAlert receives a security alert that is event of

Jan 3, 2023
AWS credential_process utility to assume AWS IAM Roles with Yubikey Touch and Authenticator App TOPT MFA to provide temporary session credentials; With encrypted caching and support for automatic credential refresh.
AWS credential_process utility to assume AWS IAM Roles with Yubikey Touch and Authenticator App TOPT MFA to provide temporary session credentials; With encrypted caching and support for automatic credential refresh.

AWS credential_process utility to assume AWS IAM Roles with Yubikey Touch and Authenticator App TOPT MFA to provide temporary session credentials; With encrypted caching and support for automatic credential refresh.

Dec 20, 2022
Simple no frills AWS S3 Golang Library using REST with V4 Signing (without AWS Go SDK)

simples3 : Simple no frills AWS S3 Library using REST with V4 Signing Overview SimpleS3 is a golang library for uploading and deleting objects on S3 b

Nov 4, 2022
A package for access aws service using AWS SDK for Golang

goaws ?? A package for access aws service using AWS SDK for Golang Advantage with goaws package Example for get user list IAM with AWS SDK for Golang

Nov 25, 2021
Aws-cdk-go-examples - Example projects using the AWS CDK by Golang

aws-cdk-go-examples Example projects using the AWS CDK by Golang Useful commands

Nov 24, 2022
Integrate AWS EKS Anywhere cluster with AWS Services
 Integrate AWS EKS Anywhere cluster with AWS Services

This article provides step-by-step instruction on integrating AWS EKS Anywhere with AWS Services so the applications running on customer data center can securely connect with these services.

Mar 6, 2022
Apis para la administracion de notifiaciones, utilizando servicios como AWS SNS y AWS SQS

notificacion_api Servicio para env铆o de notificaci贸nes por difusi贸n en AWS SNS Especificaciones T茅cnicas Tecnolog铆as Implementadas y Versiones Golang

Jan 7, 2022
Aws-parameter-bulk - Export AWS SSM Parameter Store values in bulk to .env files

aws-parameter-bulk Utility to read parameters from AWS Systems Manager (SSM) Par

Oct 18, 2022