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 +4 -4
- data/.python-version +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -2
- data/Brewfile +6 -0
- data/Gemfile.lock +114 -3
- data/Pipfile +12 -0
- data/Pipfile.lock +21 -0
- data/README.md +26 -292
- data/Rakefile +2 -0
- data/bin/bootstrap +31 -0
- data/bin/setup +6 -0
- data/doc/{template.yml → template.yaml} +4 -3
- data/lamby.gemspec +3 -1
- data/lib/lamby.rb +4 -0
- data/lib/lamby/railtie.rb +11 -0
- data/lib/lamby/ssm_parameter_store.rb +145 -0
- data/lib/lamby/tasks.rake +14 -0
- data/lib/lamby/version.rb +1 -1
- metadata +41 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 954664823a70a5343c9d06f9a790130dbbd979e93109434a529b122bb1bd5bf2
|
4
|
+
data.tar.gz: f3e99fbb29575ac288c9a52ea075d93935973b1623ad343fe996abf291b6978a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 297e899dc3ce51257cdc33ac49513a889dd1660e7e3c66747974d40a239339162c29308111389a4a399f95f07c0e7a3b87c69a76c040219f378c61700aacff92
|
7
|
+
data.tar.gz: db9294acefd8e0879993059fe86dc62bee20ea1f73e40ded8bcb0db7cfd76d768545ffb13dccfe43940a2d26c8ad065af7e9c17b2c808415d1a893258a859740
|
data/.python-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.6.6
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.3
|
data/.travis.yml
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
---
|
2
|
-
|
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:
|
7
|
+
before_install:
|
8
|
+
- sudo gem install bundler -v 1.17.3
|
9
|
+
- bin/setup
|
10
|
+
script:
|
11
|
+
- bin/test
|
data/Brewfile
ADDED
data/Gemfile.lock
CHANGED
@@ -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
|
-
|
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
|
-
|
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
data/Pipfile.lock
ADDED
@@ -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://
|
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
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
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
|
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
|
-
|
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
|
-
|
74
|
+
## Additional Documentation
|
142
75
|
|
143
|
-
|
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
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
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.
|
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/
|
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
data/bin/bootstrap
ADDED
@@ -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
@@ -19,7 +19,7 @@ Resources:
|
|
19
19
|
Type: AWS::Serverless::Api
|
20
20
|
Properties:
|
21
21
|
StageName: !Ref RailsEnv
|
22
|
-
EndpointConfiguration:
|
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
|
-
|
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:
|
68
|
+
Method: ANY
|
68
69
|
RestApiId: !Ref RailsApi
|
69
70
|
RailsAppAll:
|
70
71
|
Type: Api
|
data/lamby.gemspec
CHANGED
@@ -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 '
|
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
|
data/lib/lamby.rb
CHANGED
@@ -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,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
|
data/lib/lamby/version.rb
CHANGED
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.
|
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-
|
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:
|
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.
|
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:
|