lamby 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2da2381e04438228fa63901ffd863bc2d1f97bf84e834cb57d40fc8d2353fc4e
4
- data.tar.gz: 8bd9e4a546114e937fc3da4efa0fddd1e5d0800e5b757145662ac0d7e3c603e1
3
+ metadata.gz: 954664823a70a5343c9d06f9a790130dbbd979e93109434a529b122bb1bd5bf2
4
+ data.tar.gz: f3e99fbb29575ac288c9a52ea075d93935973b1623ad343fe996abf291b6978a
5
5
  SHA512:
6
- metadata.gz: ff7c934023c0237523b96cf5ebb374d3866c4eecadc3790615fc783e8f93db32ebf99b7c3c96b309debab0eaff54f8e5e1680d8e58bdbc67c3a96d954fe9fdb5
7
- data.tar.gz: c9ea5922cd3e329b0b4665d0a7a45c2d0f8155a7cb25928ba35ea719d81511465263b94ee195b8b378761460c2fdba84d03fc42444f2ed92a573b04b8387a81f
6
+ metadata.gz: 297e899dc3ce51257cdc33ac49513a889dd1660e7e3c66747974d40a239339162c29308111389a4a399f95f07c0e7a3b87c69a76c040219f378c61700aacff92
7
+ data.tar.gz: db9294acefd8e0879993059fe86dc62bee20ea1f73e40ded8bcb0db7cfd76d768545ffb13dccfe43940a2d26c8ad065af7e9c17b2c808415d1a893258a859740
@@ -0,0 +1 @@
1
+ 3.6.6
@@ -0,0 +1 @@
1
+ 2.5.3
@@ -1,7 +1,11 @@
1
1
  ---
2
- sudo: false
2
+ if: branch = master OR type = pull_request
3
3
  language: ruby
4
4
  cache: bundler
5
5
  rvm:
6
6
  - 2.5.3
7
- before_install: gem install bundler -v 1.17.3
7
+ before_install:
8
+ - sudo gem install bundler -v 1.17.3
9
+ - bin/setup
10
+ script:
11
+ - bin/test
@@ -0,0 +1,6 @@
1
+ # Add homebrew-based depencencies here
2
+ tap "aws/tap"
3
+ tap "customink/bootstrap-python"
4
+ tap "github/bootstrap"
5
+ brew "aws-sam-cli"
6
+ cask "docker"
@@ -2,34 +2,145 @@ PATH
2
2
  remote: .
3
3
  specs:
4
4
  lamby (0.2.0)
5
- activesupport
6
5
  rack
6
+ rails
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- activesupport (5.2.2)
11
+ actioncable (5.2.2.1)
12
+ actionpack (= 5.2.2.1)
13
+ nio4r (~> 2.0)
14
+ websocket-driver (>= 0.6.1)
15
+ actionmailer (5.2.2.1)
16
+ actionpack (= 5.2.2.1)
17
+ actionview (= 5.2.2.1)
18
+ activejob (= 5.2.2.1)
19
+ mail (~> 2.5, >= 2.5.4)
20
+ rails-dom-testing (~> 2.0)
21
+ actionpack (5.2.2.1)
22
+ actionview (= 5.2.2.1)
23
+ activesupport (= 5.2.2.1)
24
+ rack (~> 2.0)
25
+ rack-test (>= 0.6.3)
26
+ rails-dom-testing (~> 2.0)
27
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
28
+ actionview (5.2.2.1)
29
+ activesupport (= 5.2.2.1)
30
+ builder (~> 3.1)
31
+ erubi (~> 1.4)
32
+ rails-dom-testing (~> 2.0)
33
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
34
+ activejob (5.2.2.1)
35
+ activesupport (= 5.2.2.1)
36
+ globalid (>= 0.3.6)
37
+ activemodel (5.2.2.1)
38
+ activesupport (= 5.2.2.1)
39
+ activerecord (5.2.2.1)
40
+ activemodel (= 5.2.2.1)
41
+ activesupport (= 5.2.2.1)
42
+ arel (>= 9.0)
43
+ activestorage (5.2.2.1)
44
+ actionpack (= 5.2.2.1)
45
+ activerecord (= 5.2.2.1)
46
+ marcel (~> 0.3.1)
47
+ activesupport (5.2.2.1)
12
48
  concurrent-ruby (~> 1.0, >= 1.0.2)
13
49
  i18n (>= 0.7, < 2)
14
50
  minitest (~> 5.1)
15
51
  tzinfo (~> 1.1)
16
- concurrent-ruby (1.1.4)
52
+ arel (9.0.0)
53
+ aws-eventstream (1.0.2)
54
+ aws-partitions (1.146.0)
55
+ aws-sdk-core (3.48.2)
56
+ aws-eventstream (~> 1.0, >= 1.0.2)
57
+ aws-partitions (~> 1.0)
58
+ aws-sigv4 (~> 1.1)
59
+ jmespath (~> 1.0)
60
+ aws-sdk-ssm (1.41.0)
61
+ aws-sdk-core (~> 3, >= 3.48.2)
62
+ aws-sigv4 (~> 1.1)
63
+ aws-sigv4 (1.1.0)
64
+ aws-eventstream (~> 1.0, >= 1.0.2)
65
+ builder (3.2.3)
66
+ concurrent-ruby (1.1.5)
67
+ crass (1.0.4)
68
+ erubi (1.8.0)
69
+ globalid (0.4.2)
70
+ activesupport (>= 4.2.0)
17
71
  i18n (1.6.0)
18
72
  concurrent-ruby (~> 1.0)
73
+ jmespath (1.4.0)
74
+ loofah (2.2.3)
75
+ crass (~> 1.0.2)
76
+ nokogiri (>= 1.5.9)
77
+ mail (2.7.1)
78
+ mini_mime (>= 0.1.1)
79
+ marcel (0.3.3)
80
+ mimemagic (~> 0.3.2)
81
+ metaclass (0.0.4)
82
+ method_source (0.9.2)
83
+ mimemagic (0.3.3)
84
+ mini_mime (1.0.1)
85
+ mini_portile2 (2.4.0)
19
86
  minitest (5.11.3)
87
+ mocha (1.8.0)
88
+ metaclass (~> 0.0.1)
89
+ nio4r (2.3.1)
90
+ nokogiri (1.10.2)
91
+ mini_portile2 (~> 2.4.0)
20
92
  rack (2.0.6)
93
+ rack-test (1.1.0)
94
+ rack (>= 1.0, < 3)
95
+ rails (5.2.2.1)
96
+ actioncable (= 5.2.2.1)
97
+ actionmailer (= 5.2.2.1)
98
+ actionpack (= 5.2.2.1)
99
+ actionview (= 5.2.2.1)
100
+ activejob (= 5.2.2.1)
101
+ activemodel (= 5.2.2.1)
102
+ activerecord (= 5.2.2.1)
103
+ activestorage (= 5.2.2.1)
104
+ activesupport (= 5.2.2.1)
105
+ bundler (>= 1.3.0)
106
+ railties (= 5.2.2.1)
107
+ sprockets-rails (>= 2.0.0)
108
+ rails-dom-testing (2.0.3)
109
+ activesupport (>= 4.2.0)
110
+ nokogiri (>= 1.6)
111
+ rails-html-sanitizer (1.0.4)
112
+ loofah (~> 2.2, >= 2.2.2)
113
+ railties (5.2.2.1)
114
+ actionpack (= 5.2.2.1)
115
+ activesupport (= 5.2.2.1)
116
+ method_source
117
+ rake (>= 0.8.7)
118
+ thor (>= 0.19.0, < 2.0)
21
119
  rake (12.3.2)
120
+ sprockets (3.7.2)
121
+ concurrent-ruby (~> 1.0)
122
+ rack (> 1, < 3)
123
+ sprockets-rails (3.2.1)
124
+ actionpack (>= 4.0)
125
+ activesupport (>= 4.0)
126
+ sprockets (>= 3.0.0)
127
+ thor (0.20.3)
22
128
  thread_safe (0.3.6)
23
129
  tzinfo (1.2.5)
24
130
  thread_safe (~> 0.1)
131
+ websocket-driver (0.7.0)
132
+ websocket-extensions (>= 0.1.0)
133
+ websocket-extensions (0.1.3)
25
134
 
26
135
  PLATFORMS
27
136
  ruby
28
137
 
29
138
  DEPENDENCIES
139
+ aws-sdk-ssm
30
140
  bundler
31
141
  lamby!
32
142
  minitest
143
+ mocha
33
144
  rake
34
145
 
35
146
  BUNDLED WITH
data/Pipfile ADDED
@@ -0,0 +1,12 @@
1
+ [[source]]
2
+ url = "https://pypi.org/simple"
3
+ verify_ssl = true
4
+ name = "pypi"
5
+
6
+ [packages]
7
+
8
+ [dev-packages]
9
+
10
+ [requires]
11
+ python_version = "3.7"
12
+ awscli = "*"
@@ -0,0 +1,21 @@
1
+ {
2
+ "_meta": {
3
+ "hash": {
4
+ "sha256": "e90ffb3268e39f48a61a46d3b09fe56bb9447190af124f7e6ec4947a6b87873e"
5
+ },
6
+ "pipfile-spec": 6,
7
+ "requires": {
8
+ "awscli": "*",
9
+ "python_version": "3.7"
10
+ },
11
+ "sources": [
12
+ {
13
+ "name": "pypi",
14
+ "url": "https://pypi.org/simple",
15
+ "verify_ssl": true
16
+ }
17
+ ]
18
+ },
19
+ "default": {},
20
+ "develop": {}
21
+ }
data/README.md CHANGED
@@ -1,83 +1,19 @@
1
1
 
2
- # Lamby
2
+ # Lamby [![Build Status](https://travis-ci.org/customink/lamby.svg?branch=master)](https://travis-ci.org/customink/lamby)
3
3
 
4
- <img src="https://git.io/fhjSv" alt="Lamby: Simple Rails & AWS Lambda Integration using Rack." align="right" /><h3>Simple Rails & AWS Lambda Integration using Rack</h3>
4
+ <img src="https://user-images.githubusercontent.com/2381/54278425-af365680-4568-11e9-972a-6b73e0a44bb5.jpg" alt="Lamby: Simple Rails & AWS Lambda Integration using Rack." align="right" /><h3>Simple Rails & AWS Lambda Integration using Rack</h3>
5
5
 
6
- The goal of this project is to provide minimal code along with comprehensive documentation to get your Rails application running under AWS Lambda.
6
+ The goal of this project is to provide minimal code to convert API Gateway `event` and `context` objects into Rack events for your Rails application in a Lambda handler. Most everything else is [documentation](https://github.com/customink/lamby/issues?q=is%3Aissue+is%3Aopen+label%3Adocs+sort%3Acreated-asc).
7
7
 
8
- This gem's code will focus mainly on converting API Gateway `event` and `context` objects into a Rack `env` to send to your Rails application. Most everything else is documentation. Please use the table of contents below to quickly navigate to any guides that interests you the most.
9
-
10
- ### Table of Contents
11
-
12
- * [How Does Lamby Work?](#how-does-lamby-work)
13
- * [Getting Started](#getting-started)
14
- * [Installing AWS CLI and AWS SAM](#installing-aws-cli-and-aws-sam)
15
- * [Bin Script Conventions](#bin-script-conventions)
16
- * [SAM Bugs and Patches](#sam-bugs-and-patches)
17
- * [About AWS SAM and CloudFormation](#about-aws-sam-and-cloudformation)
18
- * [Performance](#performance)
19
- * [Database Connections](#database-connections)
20
- * [Basic Ruby and Lambda](#basic-ruby-and-lambda)
21
- * [Contributing](#contributing)
22
- * [Code of Conduct](#code-of-conduct)
23
-
24
- The following are code and/or documentation items we are currently working on. Please open an issue and suggest a new one if you do not see it here. Thanks!
25
-
26
- * [ ] Ensure Rack integration is solid and high quality.
27
- - Cookies, Sessions, Query Params, Forms, etc.
28
- * [ ] Encrypted Session Secret via AWS System Manager Parameter Store.
29
- * [ ] Better Gemfile usage for development and/or test groups.
30
- * [ ] Hooking up Rails asset precompile to a S3 bucket and using an asset host.
31
- * [ ] Ensure Rails tagged UUID logging matches APIGateway/Lambda IDs in CloudWatch.
32
- * [ ] Documentation around using ImageMagick and Lambda Layers.
33
- - https://twitter.com/clare_liguori/status/1087861037712400385
34
- - https://github.com/mthenw/awesome-layers
35
- * [ ] Explore how New Relic could be used if at all.
36
- * [ ] Add `isBase64Encoded` to response as needed.
37
- * [ ] Better Railtie hooks, and gem structure. Tests.
38
-
39
-
40
- ## How Does Lamby Work?
41
-
42
- Since [Rails is on Rack](https://guides.rubyonrails.org/rails_on_rack.html), the Lamby gem relies on converting API Gateway events sent to your `handler` and converting them to a [Rack](https://rack.github.io) `env` object. We then send that object to your application and pass the result back to the Lambda handler which expects a simple object/hash containing the `statusCode`, `body`, and `headers`. It is that simple.
43
-
44
- Thanks to the projects and people below which inspired our code and implementation strategies.
45
-
46
- * [AWS Sinatra Example](https://github.com/aws-samples/serverless-sinatra-sample)
47
- * [Rack Lambda Handler Pull Request](https://github.com/rack/rack/pull/1337)
48
- * [Serverless Rack Plugin](https://github.com/logandk/serverless-rack)
49
- * [Jets' Rack Implementation](https://github.com/tongueroo/jets/blob/master/lib/jets/controller/rack/env.rb)
50
-
51
- Other small details which Lamby helps with.
52
-
53
- * Ensure all `Logger` objects use `STDOUT`.
54
- * Sets the `RAILS_LOG_TO_STDOUT` environment variable.
55
- * Provides a debug response in development (or when `LAMBY_DEBUG` env set) using `?debug=1` query param.
8
+ ```ruby
9
+ def handler(event:, context:)
10
+ Lamby.handler $app, event, context
11
+ end
12
+ ```
56
13
 
57
14
 
58
15
  ## Getting Started
59
16
 
60
- ℹ️ Some of these steps may be automated once we learn they are worth automating.
61
-
62
- #### New Basic Rails Application Example
63
-
64
- Assuming you have a basic Rails application, or maybe you want to make a new one from scratch.
65
-
66
- ```shell
67
- $ gem install rails
68
- $ rails new my_app \
69
- --skip-active-record \
70
- --skip-action-mailer \
71
- --skip-active-storage \
72
- --skip-action-cable \
73
- --skip-spring \
74
- --skip-coffee \
75
- --skip-turbolinks \
76
- --skip-bootsnap
77
- $ cd my_app
78
- $ rbenv local 2.5.3
79
- ```
80
-
81
17
  #### Add The Gem
82
18
 
83
19
  Add the Lamby gem to your Rails project's `Gemfile`.
@@ -91,7 +27,7 @@ gem 'lamby'
91
27
  Create an `app.rb` file that will be the source for the Lambda's handler. Example:
92
28
 
93
29
  ```ruby
94
- ENV['SECRET_KEY_BASE'] = '...' # Temporary hack, see TODO list above.
30
+ ENV['SECRET_KEY_BASE'] = '...' # Temporary hack, see TODO list in projects tab.
95
31
  require_relative 'config/boot'
96
32
  require 'lamby'
97
33
  require_relative 'config/application'
@@ -130,243 +66,41 @@ $ echo '/vendor/bundle' >> .gitignore
130
66
 
131
67
  #### Get Running
132
68
 
133
- To run your Lambda locally or deploy it, please read the following sections:
134
-
135
- * [Installing AWS CLI and AWS SAM](#installing-aws-cli-and-aws-sam)
136
- * [Bin Script Conventions](#bin-script-conventions)
137
-
69
+ To run your Lambda locally or deploy it, please read the following docs.
138
70
 
139
- ## Installing AWS CLI and AWS SAM
71
+ * [Installing AWS CLI and AWS SAM](https://github.com/customink/lamby/issues/18)
72
+ * [Bin Scripts - Setup, Build, Server, & Deploy](https://github.com/customink/lamby/issues/17)
140
73
 
141
- You will need both of these tools to run SAM locally and/or deploy your Lambda application to AWS. SAM also requires the usage of Docker.
74
+ ## Additional Documentation
142
75
 
143
- * [Install SAM CLI](https://aws.amazon.com/serverless/sam/)
144
- * [Installing the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)
145
- * [Install Docker](https://docs.docker.com/install/)
76
+ In order to provide minimal code and ultimate flexibility for any type of Rails application on Lambda, optional or advanced features require that you write additional CloudFormation code or perform AWS Console actions to get the desired results.
146
77
 
78
+ To that end, we are using our GitHub issues along with the `[docs]` label as a project-focused Stack Overflow where we encourage you to participate in and ask questions. Here are a few high level docs now that may interests most users. Also, [browse all docs](https://github.com/customink/lamby/issues?q=is%3Aissue+is%3Aopen+label%3Adocs) or open a new `[question]` issue and we would be glad to help!
147
79
 
148
- ## Bin Script Conventions
149
-
150
- Below is a list of bin scripts we recommend creating for your AWS SAM & Rails projects. Each section contains a short description on what the script does. Remember, think of these scripts as starting points! You should add to or adjust each to meet your needs while following [Strap](https://github.com/MikeMcQuaid/strap) and [Scripts to Rule Them All](https://githubengineering.com/scripts-to-rule-them-all/) conventions.
151
-
152
- #### bin/bootstrap
153
-
154
- The current Docker image for Lambda's Ruby runtime is only compatible with Bundler prior to version 2.0.0. So this bootstrap makes sure the latest 1.x bundler is installed and used.
155
-
156
- ```shell
157
- #!/bin/bash
158
- set -e
159
-
160
- gem uninstall -aIx bundler
161
- gem install bundler -v 1.17.3
162
- ```
163
-
164
- #### bin/setup
165
-
166
- Nothing fancy here, just calling build where most of the work is done.
167
-
168
- ```shell
169
- #!/bin/bash
170
- set -e
171
-
172
- ./bin/build
173
- ```
174
-
175
- #### bin/build
176
-
177
- This makes use of the [sam build](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-build.html) command along with the `--use-container` option to ensure gems with native extensions are built for both the AWS' Linux platform and your native host platform. It also:
178
-
179
- * Sets up a pristine build environment.
180
- * Removes unnecessary project files copied over during the build.
181
- * Cleans build directory's vendor gems of unwanted cache files. Saves ~40% [package size](https://docs.aws.amazon.com/lambda/latest/dg/limits.html).
182
- * Builds local platform gems on top of copied Linux platform gems.
183
-
184
- ```shell
185
- #!/bin/bash
186
- set -e
187
-
188
- # Clean any previous bundle dir.
189
- rm -rf ./.bundle \
190
- ./vendor/bundle \
191
- ./.aws-sam/build \
192
- node_modules
193
-
194
- # Clean up Rails
195
- ./bin/rails log:clear tmp:clear
196
-
197
- # Ensure native extensions built for platform.
198
- sam build --use-container
199
-
200
- # Clean build dir of unneeded artifacts.
201
- pushd ./.aws-sam/build/RailsFunction/
202
- rm -rf .aws-sam \
203
- .git \
204
- node_modules \
205
- test \
206
- template.yaml \
207
- package.json \
208
- yarn.lock \
209
- tmp
210
- rm -rf vendor/bundle/ruby/2.5.0/cache
211
- popd
212
-
213
- # Avoid doing local bundle work if building for deploy.
214
- if [ -z ${SKIP_LOCAL_BUNDLE+x} ]; then
215
- # Copy the build bundle to allow server native extensions to work.
216
- cp -R ./.aws-sam/build/RailsFunction/vendor/bundle ./vendor/bundle
217
- # Make a comingled bundle dir for build and this platform.
218
- rm -rf ./.bundle
219
- bundle install --path vendor/bundle
220
- fi
221
- ```
222
-
223
- #### bin/deploy
224
-
225
- Uses both the [sam package](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-package.html) and [sam deploy](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-deploy.html) commands to ship your Lambda stack to AWS. It also:
226
-
227
- * Uses or sets the `RAILS_ENV` variable. Defaults to `development`.
228
- * Uses or sets the `CF_BUCKET_NAME` variable. This is the name of the S3 bucket that holds your deploy artifacts.
229
- * Sets the `SKIP_LOCAL_BUNDLE` environment variable used by build.
230
-
231
- ```shell
232
- #!/bin/bash
233
- set -e
234
-
235
- export RAILS_ENV=${RAILS_ENV:="development"}
236
- export CF_BUCKET_NAME=${CF_BUCKET_NAME:="mycloudformationbucket.example.org"}
237
- export SKIP_LOCAL_BUNDLE="1"
238
-
239
- ./bin/build
240
-
241
- sam package \
242
- --template-file ./.aws-sam/build/template.yaml \
243
- --output-template-file ./.aws-sam/build/packaged.yaml \
244
- --s3-bucket $CF_BUCKET_NAME \
245
- --s3-prefix "my-app-${RAILS_ENV}"
246
-
247
- sam deploy \
248
- --template-file ./.aws-sam/build/packaged.yaml \
249
- --stack-name "my-app-${RAILS_ENV}" \
250
- --capabilities "CAPABILITY_IAM" \
251
- --parameter-overrides \
252
- RailsEnv=${RAILS_ENV}
253
- ```
254
-
255
- So an example `bin/deploy-production` script would look like this.
256
-
257
- ```shell
258
- #!/bin/bash
259
- set -e
260
-
261
- export RAILS_ENV="production"
262
-
263
- ./bin/deploy
264
- ```
265
-
266
- #### bin/server
267
-
268
- Start the normal Rails development server. Make sure to run setup/build prior.
269
-
270
- ```shell
271
- #!/bin/bash
272
- set -e
273
-
274
- ./bin/rails server
275
- ```
276
-
277
- #### bin/server-sam
278
-
279
- Uses the [sam local start-api](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-start-api.html) command to
280
-
281
- ```shell
282
- #!/bin/bash
283
- set -e
284
-
285
- # Delete the static build to avoid local server using it.
286
- rm -rf ./.aws-sam/build
287
- sam local start-api
288
- ```
289
-
290
-
291
- ## SAM Bugs and Patches
292
-
293
- Unfortunately, the SAM CLI project has a few needed enhancements and if you decide to do any local development via the [sam local start-api](#binserver-sam) command, it will need to be patched on your local machine. I used the commands below to find the two files needing patching.
294
-
295
- ```shell
296
- $ which sam # Use directory info below in find command.
297
- $ find /usr/local -name container.py | grep samcli
298
- $ find /usr/local -name local_apigw_service.py | grep samcli
299
- ```
300
-
301
- Here are the issues we have created on the SAM CLI project. Details on the patches below.
302
-
303
- * [Add Docker Delegated Consistency to Volume](https://github.com/awslabs/aws-sam-cli/pull/1046)
304
- * [Missing Authentication Token for root path '/'](https://github.com/awslabs/aws-sam-cli/issues/437)
305
-
306
- #### Docker Volume Mount Performance on Mac
307
-
308
- If you are on a Mac, Docker has a [known performance issue](https://forums.docker.com/t/file-access-in-mounted-volumes-extremely-slow-cpu-bound/8076) when sharing volumes due to the overhead of keeping files in sync. This performance issue means your Rails application could take ~60 seconds to load in development. Thankfully, Docker has [tooling in place](https://docs.docker.com/docker-for-mac/osxfs-caching/) to help.
309
-
310
- Once you found the correct `container.py` file, make this change below to tell the Docker SDK to mount the volume with both the `ro` (read-only) option and `delegated` consistency mode.
311
-
312
- ```diff
313
- @@ -95,7 +95,7 @@
314
- # https://docs.docker.com/storage/bind-mounts
315
- # Mount the host directory as "read only" inside container
316
- "bind": self._working_dir,
317
- - "mode": "ro"
318
- + "mode": "ro,delegated"
319
- }
320
- },
321
- # We are not running an interactive shell here.
322
- ```
323
-
324
- #### Fixing Root SAM Local Proxy Paths
325
-
326
- We need our API Gateway to use both a root path and a greedy proxy path to forward to Rails in development. SAM has a feature compatibility bug where it forces static file hosting on the root path. Once you found the correct `local_apigw_service.py` file, make the change below to disable static `public` directory assets on the root path. Don't worry, Rails & Rack will serve your static files automatically instead.
327
-
328
- ```diff
329
- @@ -71,7 +71,7 @@
330
- """
331
-
332
- self._app = Flask(__name__,
333
- - static_url_path="", # Mount static files at root '/'
334
- + static_url_path=None, # Mount static files at root '/'
335
- static_folder=self.static_dir # Serve static files from this directory
336
- )
337
- ```
80
+ * [Installing AWS CLI and AWS SAM](https://github.com/customink/lamby/issues/18)
81
+ * [Bin Scripts - Setup, Build, Server, & Deploy](https://github.com/customink/lamby/issues/17)
82
+ * [Custom Domain Name, Edge/Regional, & CloudFront](https://github.com/customink/lamby/issues/10)
83
+ * [API Gateway Permissions & CloudWatch Logs](https://github.com/customink/lamby/issues/6)
84
+ * [How Does Lamby Work?](https://github.com/customink/lamby/issues/12)
85
+ * [Performance & Real World Usage](https://github.com/customink/lamby/issues/16)
86
+ * [Database Connections](https://github.com/customink/lamby/issues/13)
87
+ * [Basic Ruby with Lambda & AWS SAM](https://github.com/customink/lamby/issues/14)
88
+ * [Docker Perf on Mac & Root Proxy SAM Bugs](https://github.com/customink/lamby/issues/15)
338
89
 
339
90
 
340
91
  ## About AWS SAM and CloudFormation
341
92
 
342
- AWS SAM is shorthand for the [Serverless Application Model](https://github.com/awslabs/serverless-application-model) and it is a superset of CloudFormation - a language that describes and provisions your infrastructure using code. As your application grows and requires additional AWS resources, learning how to express this in your `template.yml` is critical. We recommend the following links when needing to learn both SAM and CloudFormation.
93
+ AWS SAM is shorthand for the [Serverless Application Model](https://github.com/awslabs/serverless-application-model) and it is a superset of CloudFormation - a language that describes and provisions your infrastructure using code. As your application grows and requires additional AWS resources, learning how to express this in your `template.yaml` is critical. We recommend the following links when needing to learn both SAM and CloudFormation.
343
94
 
344
95
  * [AWS Serverless Application Model (SAM)](https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md)
345
96
  * [AWS CloudFormation User Guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)
346
97
 
347
98
 
348
- ## Performance
349
-
350
- Because your Rails app is initialized outside the `handler` it should be loaded into memory and respond to requests in a very timely manner. Make sure to set the `MemorySize` as needed in your `template.yml` and you should get comparable performance to EC2. Initial tests show that basic view rendering only takes a few milliseconds. Please do share your performance results if you have any!
351
-
352
-
353
- ## Database Connections
354
-
355
- If you want to use a database with Rails and Lambda, I would highly suggest using DynamoDB with the excellent [AWS Record](https://github.com/aws/aws-sdk-ruby-record) gem. However, if you want to explore and share how you might use Lamby with PG or MySQL, I'd love to hear about it.
356
-
357
-
358
- ## Basic Ruby and Lambda
359
-
360
- Curious about using AWS SAM with Ruby and no Rails? Please see this 757rb (Norfolk Ruby User's Group) repository for an overview on how to kick-start your next Ruby project.
361
-
362
- * [Using Ruby with AWS Lambda & SAM](https://github.com/757rb/hello-757rb-lambda)
363
-
364
-
365
99
  ## Contributing
366
100
 
367
101
  After checking out the repo, run `./bin/setup` to install dependencies. Then, run `./bin/test` to run the tests. **NOTE: There are no tests now but adding them is on our TODO list.**
368
102
 
369
- Bug reports and pull requests are welcome on GitHub at https://github.com/metaskills/lamby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
103
+ Bug reports and pull requests are welcome on GitHub at https://github.com/customink/lamby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
370
104
 
371
105
 
372
106
  ## Code of Conduct
data/Rakefile CHANGED
@@ -5,6 +5,8 @@ Rake::TestTask.new(:test) do |t|
5
5
  t.libs << "test"
6
6
  t.libs << "lib"
7
7
  t.test_files = FileList["test/**/*_test.rb"]
8
+ t.verbose = false
9
+ t.warning = false
8
10
  end
9
11
 
10
12
  task :default => :test
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -e
4
+
5
+ cd "$(dirname "$0")/.."
6
+
7
+ if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ]; then
8
+ brew bundle check || {
9
+ echo "==> Installing Homebrew dependencies..."
10
+ brew bundle --verbose
11
+ }
12
+ else
13
+ echo "Skipping because bootstrap is currently macOS depentant."
14
+ exit 1
15
+ fi
16
+
17
+ echo "==> Setting up python..."
18
+ if [ "$(which pyenv)" != "" ] && [ "$(which pipenv)" != "" ]; then
19
+ brew bootstrap-pyenv-python
20
+ else
21
+ echo "Skipping because pyenv/pipenv were not found."
22
+ exit 1;
23
+ fi
24
+
25
+ echo "==> Setting up ruby..."
26
+ if [ "$(which rbenv)" != "" ] && [ "$(which ruby-build)" != "" ]; then
27
+ brew bootstrap-rbenv-ruby
28
+ else
29
+ echo "Skipping because rbenv/ruby-build were not found."
30
+ exit 1;
31
+ fi
data/bin/setup CHANGED
@@ -5,3 +5,9 @@ IFS=$'\n\t'
5
5
  set -vx
6
6
 
7
7
  bundle install
8
+
9
+ if [ "$(pipenv --version)" != "" ]; then
10
+ pipenv install
11
+ else
12
+ echo "WARNING: pipenv not found in \$PATH. Skipping pipenv install"
13
+ fi
@@ -19,7 +19,7 @@ Resources:
19
19
  Type: AWS::Serverless::Api
20
20
  Properties:
21
21
  StageName: !Ref RailsEnv
22
- EndpointConfiguration: EDGE
22
+ EndpointConfiguration: REGIONAL
23
23
  DefinitionBody:
24
24
  swagger: 2.0
25
25
  info: { title: !Ref 'AWS::StackName' }
@@ -27,7 +27,7 @@ Resources:
27
27
  schemes: [ 'https' ]
28
28
  paths:
29
29
  /:
30
- get:
30
+ x-amazon-apigateway-any-method:
31
31
  x-amazon-apigateway-integration:
32
32
  uri:
33
33
  Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${RailsFunction.Arn}:live/invocations
@@ -59,12 +59,13 @@ Resources:
59
59
  Environment:
60
60
  Variables:
61
61
  RAILS_ENV: !Ref RailsEnv
62
+ FunctionName: !Join [ '', [ 'hello-rails-', !Ref RailsEnv, '-', !Ref 'AWS::Region' ] ]
62
63
  Events:
63
64
  Root:
64
65
  Type: Api
65
66
  Properties:
66
67
  Path: /
67
- Method: GET
68
+ Method: ANY
68
69
  RestApiId: !Ref RailsApi
69
70
  RailsAppAll:
70
71
  Type: Api
@@ -19,8 +19,10 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
  spec.add_dependency 'rack'
22
- spec.add_dependency 'activesupport'
22
+ spec.add_dependency 'rails'
23
+ spec.add_development_dependency 'aws-sdk-ssm'
23
24
  spec.add_development_dependency 'bundler'
24
25
  spec.add_development_dependency 'rake'
25
26
  spec.add_development_dependency 'minitest'
27
+ spec.add_development_dependency 'mocha'
26
28
  end
@@ -7,6 +7,8 @@ require 'lamby/sam_helpers'
7
7
  require 'lamby/rack'
8
8
  require 'lamby/debug'
9
9
  require 'lamby/handler'
10
+ require 'rails/railtie'
11
+ require 'lamby/railtie'
10
12
 
11
13
  module Lamby
12
14
 
@@ -16,4 +18,6 @@ module Lamby
16
18
  Handler.call(app, event, context)
17
19
  end
18
20
 
21
+ autoload :SsmParameterStore, 'lamby/ssm_parameter_store'
22
+
19
23
  end
@@ -0,0 +1,11 @@
1
+ module Lamby
2
+ class Railtie < ::Rails::Railtie
3
+
4
+ config.lamby = ActiveSupport::OrderedOptions.new
5
+
6
+ rake_tasks do
7
+ load 'lamby/tasks.rake'
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,145 @@
1
+ require 'aws-sdk-ssm'
2
+
3
+ module Lamby
4
+ class SsmParameterStore
5
+
6
+ MAX_RESULTS = 10
7
+
8
+ Param = Struct.new :name, :env, :value
9
+
10
+ attr_reader :path, :params
11
+
12
+ class << self
13
+
14
+ def dotenv(path)
15
+ new(path).get!.to_dotenv
16
+ end
17
+
18
+ end
19
+
20
+ def initialize(path, options = {})
21
+ @path = path
22
+ @params = []
23
+ @options = options
24
+ end
25
+
26
+ def to_env
27
+ params.each do |param|
28
+ ENV[param.env] = param.value
29
+ end
30
+ end
31
+
32
+ def to_dotenv
33
+ File.open(dotenv_file, 'w') { |f| f.write(dotenv_contents) }
34
+ end
35
+
36
+ def get!
37
+ get_all!
38
+ get_history! if label.present?
39
+ self
40
+ end
41
+
42
+ def label
43
+ ENV['LAMBY_SSM_PARAMS_LABEL'] || @options[:label]
44
+ end
45
+
46
+ def client
47
+ @client ||= begin
48
+ options = @options[:client_options] || {}
49
+ Aws::SSM::Client.new(options)
50
+ end
51
+ end
52
+
53
+
54
+ private
55
+
56
+ def dotenv_file
57
+ @options[:dotenv_file] || ENV['LAMBY_SSM_PARAMS_FILE'] || Rails.root.join(".env.#{Rails.env}")
58
+ end
59
+
60
+ def dotenv_contents
61
+ params.each_with_object('') do |param, contents|
62
+ line = "export #{param.env}=#{param.value}\n"
63
+ contents << line
64
+ end
65
+ end
66
+
67
+ # Path
68
+
69
+ def get_all!
70
+ return params if @got_all
71
+ get_parse_all
72
+ while @all_response.next_token do get_parse_all end
73
+ @got_all = true
74
+ params
75
+ end
76
+
77
+ def get_parse_all
78
+ get_all
79
+ parse_all
80
+ end
81
+
82
+ def get_all
83
+ @all_response = client.get_parameters_by_path(get_all_options)
84
+ end
85
+
86
+ def get_all_options
87
+ { path: path,
88
+ recursive: true,
89
+ with_decryption: true,
90
+ max_results: MAX_RESULTS
91
+ }.tap { |options|
92
+ token = @all_response.try(:next_token)
93
+ options[:next_token] = token if token
94
+ }
95
+ end
96
+
97
+ def parse_all
98
+ @all_response.parameters.each do |p|
99
+ env = p.name.split('/').last
100
+ params << Param.new(p.name, env, p.value)
101
+ end
102
+ end
103
+
104
+ # History
105
+
106
+ def get_history!
107
+ return params if @got_history
108
+ params.each do |param|
109
+ name = param.name
110
+ get_parse_history(name)
111
+ while @hist_response.next_token do get_parse_history(name) end
112
+ end
113
+ @got_history = true
114
+ params
115
+ end
116
+
117
+ def get_parse_history(name)
118
+ get_history(name)
119
+ parse_history(name)
120
+ end
121
+
122
+ def get_history(name)
123
+ @hist_response = client.get_parameter_history(get_history_options(name))
124
+ end
125
+
126
+ def get_history_options(name)
127
+ { name: name,
128
+ with_decryption: true,
129
+ max_results: MAX_RESULTS
130
+ }.tap { |options|
131
+ token = @hist_response.try(:next_token)
132
+ options[:next_token] = token if token
133
+ }
134
+ end
135
+
136
+ def parse_history(name)
137
+ @hist_response.parameters.each do |p|
138
+ next unless p.labels.include? label
139
+ param = params.detect { |param| param.name == name }
140
+ param.value = p.value
141
+ end
142
+ end
143
+
144
+ end
145
+ end
@@ -0,0 +1,14 @@
1
+ namespace :lamby do
2
+
3
+ namespace :ssm do
4
+
5
+ desc 'Create a Dotenv file '
6
+ task :dotenv => :environment do
7
+ path = ENV['LAMBY_SSM_PARAMS_PATH']
8
+ raise ArgumentError, 'The LAMBY_SSM_PARAMS_PATH env is required.' unless path
9
+ Lamby::SsmParameterStore.dotenv(path)
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -1,3 +1,3 @@
1
1
  module Lamby
2
- VERSION = '0.2.0'
2
+ VERSION = '0.3.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lamby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ken Collins
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-13 00:00:00.000000000 Z
11
+ date: 2019-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: activesupport
28
+ name: rails
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: aws-sdk-ssm
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,20 @@ dependencies:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: mocha
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  description: Simple Rails & AWS Lambda Integration using Rack and various utilities.
84
112
  email:
85
113
  - kcollins@customink.com
@@ -88,25 +116,34 @@ extensions: []
88
116
  extra_rdoc_files: []
89
117
  files:
90
118
  - ".gitignore"
119
+ - ".python-version"
120
+ - ".ruby-version"
91
121
  - ".travis.yml"
122
+ - Brewfile
92
123
  - CHANGELOG.md
93
124
  - CODE_OF_CONDUCT.md
94
125
  - Gemfile
95
126
  - Gemfile.lock
96
127
  - LICENSE.txt
128
+ - Pipfile
129
+ - Pipfile.lock
97
130
  - README.md
98
131
  - Rakefile
132
+ - bin/bootstrap
99
133
  - bin/console
100
134
  - bin/setup
101
135
  - bin/test
102
- - doc/template.yml
136
+ - doc/template.yaml
103
137
  - lamby.gemspec
104
138
  - lib/lamby.rb
105
139
  - lib/lamby/debug.rb
106
140
  - lib/lamby/handler.rb
107
141
  - lib/lamby/logger.rb
108
142
  - lib/lamby/rack.rb
143
+ - lib/lamby/railtie.rb
109
144
  - lib/lamby/sam_helpers.rb
145
+ - lib/lamby/ssm_parameter_store.rb
146
+ - lib/lamby/tasks.rake
110
147
  - lib/lamby/version.rb
111
148
  homepage: https://github.com/customink/lamby
112
149
  licenses: