{"id":13514165,"url":"https://github.com/nzoschke/gofaas","last_synced_at":"2025-04-05T00:09:35.670Z","repository":{"id":136713308,"uuid":"121763122","full_name":"nzoschke/gofaas","owner":"nzoschke","description":"A boilerplate Go and AWS Lambda app. Demonstrates an expert configuration of 10+ AWS services to support running Go functions-as-a-service (FaaS).","archived":false,"fork":false,"pushed_at":"2018-10-09T13:47:55.000Z","size":16432,"stargazers_count":803,"open_issues_count":21,"forks_count":42,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-03-28T23:08:48.560Z","etag":null,"topics":["aws-lambda","cloudformation","golang","sam","serverless"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nzoschke.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/security-cors-jwt.md","support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-02-16T14:58:31.000Z","updated_at":"2025-02-14T15:18:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"8cb9a1a1-4db0-4c47-a740-e72e9001b78a","html_url":"https://github.com/nzoschke/gofaas","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nzoschke%2Fgofaas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nzoschke%2Fgofaas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nzoschke%2Fgofaas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nzoschke%2Fgofaas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nzoschke","download_url":"https://codeload.github.com/nzoschke/gofaas/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247266564,"owners_count":20910836,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-lambda","cloudformation","golang","sam","serverless"],"created_at":"2024-08-01T05:00:48.349Z","updated_at":"2025-04-05T00:09:35.646Z","avatar_url":"https://github.com/nzoschke.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Go Functions-as-a-Service\n\nRunning a Go application on AWS Lambda is easier than ever, once you figure out how to configure Lambda, API Gateway and 10 or other \"serverless\" services to support the Go functions.\n\nThis is a boilerplate app with all the AWS pieces configured correctly and explained in depth. See [the docs folder](docs/) for detailed guides about functions, tracing, security, automation and more with AWS and Go.\n\nWith this foundation you can skip over all the undifferentiated setup, and focus entirely on your Go code.\n\n## Motivation\n\nFunctions-as-a-Service (FaaS) like AWS Lambda are one of the latest advances in cloud Infrastructure-as-a-Service (IaaS). Go is particularly well-suited to run in Lambda due to its speed, size and cross-compiler. Check out the [Intro to Go Functions-as-a-Service and Lambda](docs/intro-go-faas.md) doc for more explanation.\n\nFor a long time, Go in Lambda was only possible through hacks -- execution shims, 3rd party frameworks and middleware, and little dev/prod parity. But in January 2018, [AWS launched official Go support for Lambda](https://aws.amazon.com/blogs/compute/announcing-go-support-for-aws-lambda/) and [Go released v1.10](https://golang.org/doc/go1.10) paving the clearest path yet for us Gophers.\n\nThis project demonstrates a simple and clean foundation for Go in Lambda. You can clone and deploy it with a few commands to get a feel for the stack. Or you can fork and rework it to turn it into your own web app.\n\nIt demonstrates:\n\n| Component                                      | Via                                     | Config, Code            |\n| ---------------------------------------------- |-----------------------------------------|:-----------------------:|\n| [HTTP functions][1]                            | Lambda, API Gateway                     | [💾](dashboard.go)      |\n| [Worker functions (one-off and periodic)][2]   | Lambda, Invoke API, CloudWatch Events   | [💾](worker.go)         |\n| [Development, packaging and deployment][3]     | make, go, aws-sam-cli, CloudFormation   | [⚙️](Makefile)          |\n| [Per-function environment and policies][4]     | Lambda, IAM                             | [⚙️](template.yml)      |\n| [Custom domains][5]                            | CloudFront, ACM                         | [⚙️](template.yml)      |\n| [Static web content][6]                        | S3, CloudFront, ACM                     | [⚙️](template.yml)      |\n| [Static web security with Google OAuth 2.0][7] | CloudFront, Lambda@Edge, SSM Parameters | [💾](web-auth/index.js) |\n| [Function security with CORS and JWT][8]       | API Gateway, jwt-go                     | [💾](jwt.go)            |\n| [Function traces and logs][9]                  | CloudWatch Logs, X-Ray, AWS SDKs for Go | [💾](aws.go)            |\n| [Notifications][10]                            | SNS                                     | [💾](notify.go)         |\n| [Databases and encryption at rest][11]         | DynamoDB, KMS                           | [💾](user.go)           |\n| [Testing with mock AWS clients][12]            | Go interfaces, aws-sdk-go               | [💾](aws_test.go)       |\n\n[1]: docs/http-functions.md\n[2]: docs/worker-functions.md\n[3]: docs/dev-package-deploy.md\n[4]: docs/per-function-policies.md\n[5]: docs/custom-domains.md\n[6]: docs/static-sites.md\n[7]: docs/lambda-at-edge-oauth.md\n[8]: docs/security-cors-jwt.md\n[9]: docs/traces-logs.md\n[10]: docs/notifications.md\n[11]: docs/databases-encryption.md\n[12]: docs/mock-aws-client.md\n\nWhat's remarkable is how little work is required to get all functionality for our app. We don't need a framework, platform-as-a-service, or even any 3rd party software-as-a-service. And no, we don't need servers. By standing on the shoulders of Go and AWS, all the undifferentiated heavy lifting is managed for us.\n\nWe just need an expert [CloudFormation config file](template.yml) and a simple [Makefile](Makefile), then we can focus entirely on writing Go functions.\n\n## Quick Start\n\nThis project uses :\n\n- [AWS CLI](https://aws.amazon.com/cli/)\n- [AWS SAM CLI](https://github.com/awslabs/aws-sam-cli)\n- [Docker CE](https://www.docker.com/community-edition)\n- [Go 1.10](https://golang.org/)\n- [watchexec](https://github.com/mattgreen/watchexec)\n\nInstall the CLI tools and Docker CE\n\n```console\n$ brew install awscli go node python@2 watchexec\n$ pip2 install aws-sam-cli\n$ open https://store.docker.com/search?type=edition\u0026offering=community\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eWe may want to upgrade existing tools...\u003c/summary\u003e\n\u0026nbsp;\n\n```console\n$ brew upgrade awscli go node python@2 watchexec\n$ pip2 install --upgrade aws-sam-cli\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eWe may want to double check the installed versions...\u003c/summary\u003e\n\u0026nbsp;\n\n```console\n$ aws --version\naws-cli/1.16.20 Python/3.7.0 Darwin/17.7.0 botocore/1.12.10\n\n$ sam --version\nSAM CLI, version 0.6.0\n\n$ docker version\nClient:\n Version:           18.06.1-ce\n API version:       1.38\n Go version:        go1.10.3\n Git commit:        e68fc7a\n Built:             Tue Aug 21 17:21:31 2018\n OS/Arch:           darwin/amd64\n Experimental:      false\n\nServer:\n Engine:\n  Version:          18.06.1-ce\n  API version:      1.38 (minimum version 1.12)\n  Go version:       go1.10.3\n  Git commit:       e68fc7a\n  Built:            Tue Aug 21 17:29:02 2018\n  OS/Arch:          linux/amd64\n  Experimental:     true\n\n\n$ go version\ngo version go1.11.1 darwin/amd64\n\n$ watchexec --version\nwatchexec 1.9.2\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eWe may also want to configure the AWS CLI with IAM keys to develop and deploy our application...\u003c/summary\u003e\n\u0026nbsp;\n\nFollow the [Creating an IAM User in Your AWS Account](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html) doc to create a IAM user with programmatic access. Call the user `gofaas-admin` and attach the \"Administrator Access\" policy for now.\n\nThen configure the CLI. Here we are creating a new profile that we can switch to with `export AWS_PROFILE=gofaas`. This will help us isolate our experiments from other AWS work.\n\nConfigure an AWS profile with keys and switch to the profile:\n\n```console\n$ aws configure --profile gofaas\nAWS Access Key ID [None]: AKIA................\nAWS Secret Access Key [None]: PQN4CWZXXbJEgnrom2fP0Z+z................\nDefault region name [None]: us-east-1\nDefault output format [None]: json\n\n$ export AWS_PROFILE=gofaas\n$ aws iam get-user\n{\n    \"User\": {\n        \"Path\": \"/\",\n        \"UserName\": \"gofaas-admin\",\n        \"UserId\": \"AIDAJA44LJEOECDPZ3S5U\",\n        \"Arn\": \"arn:aws:iam::572007530218:user/gofaas-admin\",\n        \"CreateDate\": \"2018-02-16T16:17:24Z\"\n    }\n}\n```\n\u003c/details\u003e\n\n### Get the App\n\nWe start by getting and testing the `github.com/nzoschke/gofaas`.\n\n```console\n$ git clone https://github.com/nzoschke/gofaas.git ~/dev/gofaas\n$ cd ~/dev/gofaas\n\n$ make test\ngo test -v ./...\ngo: finding github.com/aws/aws-xray-sdk-go v1.0.0-rc.8\ngo: finding github.com/aws/aws-lambda-go v1.6.0\ngo: finding github.com/aws/aws-sdk-go v1.15.49\n...\n=== RUN   TestUserCreate\n--- PASS: TestUserCreate (0.00s)\n...\nok     github.com/nzoschke/gofaas      0.014s\nPASS\n```\n\nThis gives us confidence in our Go environment.\n\n### Develop the App\n\nWe can then build the app and start a development server:\n\n```console\n$ make dev\ncd ./handlers/dashboard \u0026\u0026 GOOS=linux go build...\n2018/02/25 08:03:12 Connected to Docker 1.35\n2018/02/16 07:40:32 Fetching lambci/lambda:go1.x image for go1.x runtime...\n\nMounting handler (go1.x) at http://127.0.0.1:3000/users/{id} [DELETE]\nMounting handler (go1.x) at http://127.0.0.1:3000/users/{id} [PUT]\nMounting handler (go1.x) at http://127.0.0.1:3000/users/{id} [GET]\nMounting handler (go1.x) at http://127.0.0.1:3000/ [GET]\nMounting handler (go1.x) at http://127.0.0.1:3000/users [POST]\n```\n\nNow we can access our HTTP functions on port 3000:\n\n```console\n$ curl http://localhost:3000\n\u003chtml\u003e\u003cbody\u003e\u003ch1\u003egofaas dashboard\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e\n```\n\nWe can also invoke a function directly:\n\n```\n$ echo '{}' | sam local invoke WorkerFunction\n...\nSTART RequestId: 36d6d40e-0d4b-168c-63d5-76b25f543d21 Version: $LATEST\n2018/02/25 16:05:21 Worker Event: {SourceIP: TimeEnd:0001-01-01 00:00:00 +0000 UTC TimeStart:0001-01-01 00:00:00 +0000 UTC}\nEND RequestId: 36d6d40e-0d4b-168c-63d5-76b25f543d21\nREPORT RequestId: 36d6d40e-0d4b-168c-63d5-76b25f543d21  Duration: 681.67 ms  Billed Duration: 700 ms  Memory Size: 128 MB  Max Memory Used: 14 MB\n```\n\nNote: if you see `No AWS credentials found. Missing credentials may lead to slow startup...`, review `aws configure list` and your `AWS_PROFILE` env var.\n\nThis gives us confidence in our development environment.\n\n### Deploy the App\n\nNow we can package and deploy the app:\n\n```console\n$ make deploy\nmake_bucket: pkgs-572007530218-us-east-1\nUploading to 59d2ea5b6bdf38fcbcf62236f4c26f21  3018471 / 3018471.0  (100.00%)\nWaiting for changeset to be created\nWaiting for stack create/update to complete\nSuccessfully created/updated stack - gofaas\n\nApiUrl\thttps://x19vpdk568.execute-api.us-east-1.amazonaws.com/Prod\n```\n\nNow we can access our HTTP functions on AWS:\n\n```console\n$ curl https://x19vpdk568.execute-api.us-east-1.amazonaws.com/Prod\n\u003chtml\u003e\u003cbody\u003e\u003ch1\u003egofaas dashboard\u003c/h1\u003e\u003c/body\u003e\u003c/html\u003e\n```\n\nWe can also invoke a function directly:\n\n```console\n$ aws lambda invoke --function-name gofaas-WorkerFunction --log-type Tail --output text --query 'LogResult' out.log | base64 -D\nSTART RequestId: 0bb47628-1718-11e8-ad73-c58e72b8826c Version: $LATEST\n2018/02/21 15:01:07 Worker Event: {SourceIP: TimeEnd:0001-01-01 00:00:00 +0000 UTC TimeStart:0001-01-01 00:00:00 +0000 UTC}\nEND RequestId: 0bb47628-1718-11e8-ad73-c58e72b8826c\nREPORT RequestId: 0bb47628-1718-11e8-ad73-c58e72b8826c  Duration: 11.11 ms  Billed Duration: 100 ms  Memory Size: 128 MB  Max Memory Used: 41 MB\n```\n\nLook at that speedy 11 ms duration! Go is faster than the minimum billing duration of 100 ms.\n\nThis gives us confidence in our production environment.\n\n### Development Environment\n\nIf we want to work on the [worker](docs/worker-functions.md) or [database](docs/databases.md) functions locally, we need to give the functions environment variables with pointers to DynamoDB, KMS and S3. Open up `env.json` and set `BUCKET`, etc. with the ids of the resources we just created on deploy:\n\n```console\n$ aws cloudformation describe-stack-resources --output text --stack-name gofaas \\\n  --query 'StackResources[*].{Name:LogicalResourceId,Id:PhysicalResourceId,Type:ResourceType}' | \\\n  grep 'Bucket\\|Key\\|UsersTable'\n\ngofaas-bucket-aykdokk6aek8            Bucket      AWS::S3::Bucket\n8eb8e209-51fb-41fa-adfe-1ec401667df4  Key         AWS::KMS::Key\ngofaas-UsersTable-1CYAQH3HHHRGW       UsersTable  AWS::DynamoDB::Table\n```\n\n### Integration Testing\n\nWe can verify the app functionality by creating an isolated testing stack, testing all the endpoints, then deleting the stack. The `ci.sh` script automates this:\n\n```console\n$ ./ci.sh\naws cloudformation package ...\naws cloudformation deploy ...\n...\n\u003ctitle\u003eMy first gofaas/Vue app\u003c/title\u003e\n\"username\": \"test\"\n{\"ExecutedVersion\":null,\"FunctionError\":null,\"LogResult\":null,\"Payload\":\"\",\"StatusCode\":202}\n...\n✅ SUCCESS!\n```\n\n## Docs\n\nCheck out [the docs folder](docs/) where each component is explained in more detail.\n\n## Contributing\n\nFind a bug or see a way to improve the project? [Open an issue](https://github.com/nzoschke/gofaas/issues).\n\n## License\n\nApache 2.0 © 2018 Noah Zoschke\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnzoschke%2Fgofaas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnzoschke%2Fgofaas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnzoschke%2Fgofaas/lists"}