@brunwig/mup-aws-beanstalk 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +6 -0
- package/.eslintignore +2 -0
- package/.eslintrc.yml +10 -0
- package/.github/FUNDING.yml +12 -0
- package/changelog.md +56 -0
- package/docs/getting-started.md +83 -0
- package/docs/index.md +333 -0
- package/index.js +1 -0
- package/lib/assets/env.sh +30 -0
- package/lib/assets/env.yaml +19 -0
- package/lib/assets/graceful_shutdown.sh +14 -0
- package/lib/assets/graceful_shutdown.yaml +7 -0
- package/lib/assets/health-check.js +54 -0
- package/lib/assets/health-check.js.map +1 -0
- package/lib/assets/nginx-server.conf +59 -0
- package/lib/assets/nginx.conf +85 -0
- package/lib/assets/nginx.yaml +13 -0
- package/lib/assets/node.sh +25 -0
- package/lib/assets/node.yaml +8 -0
- package/lib/assets/npmrc +1 -0
- package/lib/assets/package.json +7 -0
- package/lib/assets/packages.yaml +5 -0
- package/lib/assets/start.sh +21 -0
- package/lib/aws.js +98 -0
- package/lib/aws.js.map +1 -0
- package/lib/certificates.js +64 -0
- package/lib/certificates.js.map +1 -0
- package/lib/command-handlers.js +774 -0
- package/lib/command-handlers.js.map +1 -0
- package/lib/commands.js +145 -0
- package/lib/commands.js.map +1 -0
- package/lib/download.js +27 -0
- package/lib/download.js.map +1 -0
- package/lib/eb-config.js +269 -0
- package/lib/eb-config.js.map +1 -0
- package/lib/env-ready.js +121 -0
- package/lib/env-ready.js.map +1 -0
- package/lib/env-settings.js +22 -0
- package/lib/env-settings.js.map +1 -0
- package/lib/index.js +111 -0
- package/lib/index.js.map +1 -0
- package/lib/policies.js +144 -0
- package/lib/policies.js.map +1 -0
- package/lib/prepare-bundle.js +245 -0
- package/lib/prepare-bundle.js.map +1 -0
- package/lib/recheck.js +27 -0
- package/lib/recheck.js.map +1 -0
- package/lib/upload.js +75 -0
- package/lib/upload.js.map +1 -0
- package/lib/utils.js +678 -0
- package/lib/utils.js.map +1 -0
- package/lib/validate.js +67 -0
- package/lib/validate.js.map +1 -0
- package/lib/versions.js +116 -0
- package/lib/versions.js.map +1 -0
- package/package.json +65 -0
- package/readme.md +18 -0
package/.babelrc
ADDED
package/.eslintignore
ADDED
package/.eslintrc.yml
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# These are supported funding model platforms
|
|
2
|
+
|
|
3
|
+
github: [zodern] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
|
4
|
+
patreon: # Replace with a single Patreon username
|
|
5
|
+
open_collective: # Replace with a single Open Collective username
|
|
6
|
+
ko_fi: # Replace with a single Ko-fi username
|
|
7
|
+
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
|
8
|
+
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
|
9
|
+
liberapay: # Replace with a single Liberapay username
|
|
10
|
+
issuehunt: # Replace with a single IssueHunt username
|
|
11
|
+
otechie: # Replace with a single Otechie username
|
|
12
|
+
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
|
package/changelog.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
## 0.8.0 - July 18, 2022
|
|
2
|
+
|
|
3
|
+
- Support `.platform` files (@s7dhansh)
|
|
4
|
+
- If you manually configure the ssl certificate instead of configuring it in the mup config, mup-aws-beanstalk will no longer remove your changes (@filipenovola)
|
|
5
|
+
- `mup beanstalk shell` and `mup beanstalk debug` will temporarily add a rule to the security group to allow ssh access from your ip address
|
|
6
|
+
- Fix configuring nginx when using Amazon Linux 2
|
|
7
|
+
- Fix health checks when using Amazon Linux 2
|
|
8
|
+
- Improve documentation (@filipenevola)
|
|
9
|
+
- Increase s3 upload timeout (@ramijarrar)
|
|
10
|
+
- Improve error when sshKey is not configured
|
|
11
|
+
- When requesting logs, wait for env to be ready
|
|
12
|
+
|
|
13
|
+
## 0.7.0 - October 19, 2021
|
|
14
|
+
|
|
15
|
+
New features:
|
|
16
|
+
|
|
17
|
+
- Add support for custom .ebextensions folder (@s7dhansh)
|
|
18
|
+
- New environments use platforms based on Amazon Linux 2. The docs have instructions for migrating existing environments to the new platforms
|
|
19
|
+
- During deploys, the environment will only be updated a single time. This makes deploys much faster when updating env vars or the settings.json during a deploy, or when longEnvVars is enabled.
|
|
20
|
+
- Add `mup beanstalk shell` to get a production Meteor shell. Look in the docs for how to enable
|
|
21
|
+
- Add `mup beanstalk debug` to allow connecting your local Node debugging tools to the app. Look in the docs for how to enable.
|
|
22
|
+
- Logs if the deploy fails. It also sets the exit code to an error code
|
|
23
|
+
- The environment name can be changed
|
|
24
|
+
|
|
25
|
+
Bug fixes:
|
|
26
|
+
|
|
27
|
+
- Fix node version used when rebuilding native npm dependencies
|
|
28
|
+
- Fix unnecessarily updating environment during deploys when longEnvVars is enabled (@alexkyen)
|
|
29
|
+
- Fix few cases where it did not wait until the environment was ready before updating it
|
|
30
|
+
- Fix `mup status` when the environment does not exist
|
|
31
|
+
- Reduce timeout of automation document used for graceful shutdown
|
|
32
|
+
|
|
33
|
+
## 0.6.4 - June 14, 2020
|
|
34
|
+
|
|
35
|
+
- Fix compatibility with Meteor Up 1.5
|
|
36
|
+
|
|
37
|
+
## 0.6.3 - April 18, 2020
|
|
38
|
+
|
|
39
|
+
- Fix memory leak in health-check.js (@jimrandomh)
|
|
40
|
+
- Fix nginx config for fonts in packages (@cunneen)
|
|
41
|
+
|
|
42
|
+
## 0.6.2 - November 15, 2018
|
|
43
|
+
|
|
44
|
+
- Fix `Throttling: Rate exceeded` errors
|
|
45
|
+
|
|
46
|
+
## 0.6.1 - September 17, 2018
|
|
47
|
+
|
|
48
|
+
- Fix using longEnvVars in regions other than us-east-1 (@gerwinbrunner and @cunneen)
|
|
49
|
+
|
|
50
|
+
## 0.6.0 - June 19, 2018
|
|
51
|
+
|
|
52
|
+
- Add graceful shutdown (sponsored by [Hive](https://hive.com/))
|
|
53
|
+
- Add support for large settings.json files and long environment variables
|
|
54
|
+
- Set `Strict-Transport-Security` when `app.forceSSL` is enabled (@fschaeffler)
|
|
55
|
+
- Use the last git's commit message for the version description
|
|
56
|
+
- Add option to configure number of old application versions to keep
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Getting Started with mup-aws-beanstalk
|
|
2
|
+
|
|
3
|
+
## Install
|
|
4
|
+
|
|
5
|
+
You can install `mup` and `mup-aws-beanstalk` by running
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i -g mup mup-aws-beanstalk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The AWS Beanstalk plugin requires Node 4 or newer and Meteor Up 1.3.5 or newer.
|
|
12
|
+
|
|
13
|
+
## Step 1: Initialize your project
|
|
14
|
+
|
|
15
|
+
In the terminal, run
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd path/to/app
|
|
19
|
+
mup init
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`mup init` will create a `.deploy` folder and put a Meteor settings file and mup config in it.
|
|
23
|
+
|
|
24
|
+
## Step 2: Customize your Mup Config
|
|
25
|
+
|
|
26
|
+
You can replace the mup config in `.deploy/mup.js` with this:
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
module.exports = {
|
|
30
|
+
app: {
|
|
31
|
+
// Tells mup that the AWS Beanstalk plugin will manage the app
|
|
32
|
+
type: 'aws-beanstalk',
|
|
33
|
+
name: 'myApp',
|
|
34
|
+
path: '../',
|
|
35
|
+
env: {
|
|
36
|
+
ROOT_URL: 'http://app.com',
|
|
37
|
+
MONGO_URL: 'mongodb://user:pass@domain.com'
|
|
38
|
+
},
|
|
39
|
+
auth: {
|
|
40
|
+
id: '12345',
|
|
41
|
+
secret: '6789'
|
|
42
|
+
},
|
|
43
|
+
minInstances: 1
|
|
44
|
+
},
|
|
45
|
+
plugins: ['mup-aws-beanstalk']
|
|
46
|
+
};
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
You will want to modify:
|
|
50
|
+
|
|
51
|
+
1) The app name. It must be at least 4 characters
|
|
52
|
+
2) `app.env.ROOT_URL`
|
|
53
|
+
3) `app.env.MONGO_URL` You will need to get a database from MongoDB Atlas, ScaleGrid, or another DBaaS provider
|
|
54
|
+
|
|
55
|
+
The next step will provide the values for the `app.auth` object.
|
|
56
|
+
|
|
57
|
+
## Step 3: Create AWS user
|
|
58
|
+
|
|
59
|
+
You will need to [create an Amazon account](https://portal.aws.amazon.com/billing/signup#/start) if you do not have one.
|
|
60
|
+
|
|
61
|
+
Next, create an IAM user at [https://console.aws.amazon.com/iam/home#/users](https://console.aws.amazon.com/iam/home#/users)
|
|
62
|
+
|
|
63
|
+
The access type should be `Programmatic access`.
|
|
64
|
+
You can select `Add user to group` and create a new group. The group should have the following permissions:
|
|
65
|
+
|
|
66
|
+
- `AdministratorAccess-AWSElasticBeanstalk`
|
|
67
|
+
- `IAMFullAccess` This is used to create the roles and Instance Profiles needed by Elastic Beanstalk. After the first deploy, you can replace it with `IAMReadOnlyAccess`
|
|
68
|
+
- `AWSCertificateManagerFullAccess` Used to create and manage SSL certificates for the app
|
|
69
|
+
- `EC2InstanceConnect` is optional. Used when accessing a production Meteor shell or to connect your node developer tools to the app running in Elastic Beanstalk
|
|
70
|
+
- `AmazonEC2FullAccess`
|
|
71
|
+
- `AmazonS3FullAccess`
|
|
72
|
+
|
|
73
|
+
In your mup config, set `app.auth.id` to the Access Key ID, and `app.auth.secret` to the Secret access key AWS gives you after creating the user.
|
|
74
|
+
|
|
75
|
+
## Step 4: Deploy
|
|
76
|
+
|
|
77
|
+
Simply run:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
mup deploy
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
It will setup and deploy your app.
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
## Getting Started
|
|
2
|
+
|
|
3
|
+
Read the [Getting Started tutorial](./getting-started.md).
|
|
4
|
+
|
|
5
|
+
## Config
|
|
6
|
+
|
|
7
|
+
- This plugin is configured with the `app` object in your config.
|
|
8
|
+
- `app.type` should be set to `aws-beanstalk` so Meteor Up knows this plugin will deploy and manage the app.
|
|
9
|
+
- You will need to add `mup-aws-beanstalk` to the `plugins` array in your config
|
|
10
|
+
- The `servers` object is not needed
|
|
11
|
+
|
|
12
|
+
Example config:
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
module.exports = {
|
|
16
|
+
app: {
|
|
17
|
+
type: 'aws-beanstalk',
|
|
18
|
+
// Must be at least 4 characters
|
|
19
|
+
name: 'app-name',
|
|
20
|
+
path: '../',
|
|
21
|
+
auth: {
|
|
22
|
+
// IAM user's Access key ID
|
|
23
|
+
id: '12345',
|
|
24
|
+
// IAM user's Secret access key
|
|
25
|
+
secret: '6789'
|
|
26
|
+
},
|
|
27
|
+
env: {
|
|
28
|
+
ROOT_URL: 'http://website.com',
|
|
29
|
+
MONGO_URL: 'mongodb://user:pass@domain.com'
|
|
30
|
+
},
|
|
31
|
+
// (required) Minimum number of servers running your app
|
|
32
|
+
minInstances: 2,
|
|
33
|
+
// (optional, default is minInstances) Maximum number of servers
|
|
34
|
+
// for autoscale to scale up to
|
|
35
|
+
maxInstances: 5
|
|
36
|
+
},
|
|
37
|
+
plugins: ['mup-aws-beanstalk']
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Complete example:
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
module.exports = {
|
|
45
|
+
app: {
|
|
46
|
+
type: 'aws-beanstalk',
|
|
47
|
+
// Must be at least 4 characters
|
|
48
|
+
name: 'app-name',
|
|
49
|
+
path: '../',
|
|
50
|
+
auth: {
|
|
51
|
+
// IAM user's Access key ID
|
|
52
|
+
id: '12345',
|
|
53
|
+
// IAM user's Secret access key
|
|
54
|
+
secret: '6789'
|
|
55
|
+
},
|
|
56
|
+
env: {
|
|
57
|
+
ROOT_URL: 'http://website.com',
|
|
58
|
+
MONGO_URL: 'mongodb://user:pass@domain.com'
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// (required) Minimum number of servers running your app
|
|
62
|
+
minInstances: 2,
|
|
63
|
+
// (optional, default is inInstances) Maximum number of servers
|
|
64
|
+
// for autoscale to scale up to
|
|
65
|
+
maxInstances: 5,
|
|
66
|
+
|
|
67
|
+
// (optional, default is t2.micro) Type of instance to use
|
|
68
|
+
instanceType: 't2.small',
|
|
69
|
+
|
|
70
|
+
// (optional) Array of domains to request an ssl certificate for
|
|
71
|
+
sslDomains: ['app.com', 'www.app.com'],
|
|
72
|
+
|
|
73
|
+
// (optional) Redirect http to https
|
|
74
|
+
forceSSL: true,
|
|
75
|
+
|
|
76
|
+
// (optional, default is us-east-1) AWS region to deploy to
|
|
77
|
+
region: 'us-west-1',
|
|
78
|
+
|
|
79
|
+
// (optional, default is "mup-env-<app name>")
|
|
80
|
+
// Name of AWS Elastic Beanstalk environment
|
|
81
|
+
envName: 'production',
|
|
82
|
+
|
|
83
|
+
// (optional) Packages to install with the yum package manager
|
|
84
|
+
yumPackages: {
|
|
85
|
+
// Property is the version. Leave as an empty string to install the latest version.
|
|
86
|
+
'cairo': '',
|
|
87
|
+
'cairo-devel': '',
|
|
88
|
+
'libjpeg-turbo-devel': '',
|
|
89
|
+
'pango': '',
|
|
90
|
+
'pango-devel': '',
|
|
91
|
+
'giflib-devel': ''
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
// (optional) Send a SIGTERM signal to the app instances 30 seconds before they will be shut down.
|
|
95
|
+
gracefulShutdown: true,
|
|
96
|
+
|
|
97
|
+
// (optional) Supports large environment variables and settings.json by storing them in s3.
|
|
98
|
+
longEnvVars: true,
|
|
99
|
+
|
|
100
|
+
// (optional, default is 3) Number of old application versions to keep
|
|
101
|
+
oldVersions: 3,
|
|
102
|
+
|
|
103
|
+
// (optional) Same options as when deploying with mup.
|
|
104
|
+
// The one difference is serverOnly now defaults to true
|
|
105
|
+
buildOptions: {
|
|
106
|
+
// Default is true
|
|
107
|
+
serverOnly: true,
|
|
108
|
+
debug: false,
|
|
109
|
+
buildLocation: '../../build',
|
|
110
|
+
mobileSettings: {},
|
|
111
|
+
server: 'http://app.com',
|
|
112
|
+
allowIncompatibleUpdates: true,
|
|
113
|
+
executable: 'meteor'
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
// (optional) Override or add options in the beanstalk config
|
|
117
|
+
// this plugin creates.You can customize any option on:
|
|
118
|
+
// https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options-general.html
|
|
119
|
+
customBeanstalkConfig: [
|
|
120
|
+
{
|
|
121
|
+
namespace: 'aws:autoscaling:asg',
|
|
122
|
+
option: 'Cooldown',
|
|
123
|
+
value: '300'
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
|
|
127
|
+
// (optional) Used by "shell" and "debug" commands
|
|
128
|
+
// Public key is temporarily added to the server when needed using
|
|
129
|
+
// EC2 Instance Connect
|
|
130
|
+
sshKey: {
|
|
131
|
+
privateKey: '~/.ssh/beanstalk',
|
|
132
|
+
publicKey: '~/.ssh/beanstalk.pub'
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
plugins: ['mup-aws-beanstalk']
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Changes to `yumPackages`, `forceSSL`, `buildOptions`, and `longEnvVars` requires deploying a new version to take affect.
|
|
140
|
+
|
|
141
|
+
## Commands
|
|
142
|
+
|
|
143
|
+
- `mup deploy` Sets up and deploys your app to AWS Beanstalk
|
|
144
|
+
- `mup setup` Sets up AWS Beanstalk in preperation to deploy. Automatically run by `mup deploy`
|
|
145
|
+
- `mup reconfig` Update Meteor settings and the Beanstalk config. Automatically run by `mup deploy`
|
|
146
|
+
- `mup logs` View last 100 lines of the app's logs
|
|
147
|
+
- `mup logs-nginx` View nginx logs
|
|
148
|
+
- `mup beanstalk logs-eb` View last 100 lines of the logs from Beanstalk setting up the server and the app
|
|
149
|
+
- `mup stop` Scales the app to 0 instances
|
|
150
|
+
- `mup start` Scales the app back up after being stopped
|
|
151
|
+
- `mup restart` Restarts the app
|
|
152
|
+
- `mup beanstalk events` View events from the app's Beanstalk enviroment. Useful when troubleshooting problems.
|
|
153
|
+
- `mup beanstalk clean` Removes old application versions from s3 and Beanstalk. Is automatically run by `mup deploy`
|
|
154
|
+
- `mup beanstalk ssl` Sets up SSL and shows you it's current status. Automatically run by `mup reconfig` and `mup deploy`
|
|
155
|
+
- `mup beanstalk status` View the app's and server's health and http request stats
|
|
156
|
+
|
|
157
|
+
## Cost
|
|
158
|
+
|
|
159
|
+
AWS Elastic Beanstalk is free, but you do pay for the services it uses, including:
|
|
160
|
+
|
|
161
|
+
- EC2 Instances. By default, it uses `t2.micro`, which costs $8.50/month($0.012 / hour). While the Beanstalk environment is updating, or a new version is being deployed, 25% additional servers will be used.
|
|
162
|
+
- Application Load Balancer. Pricing details are at https://aws.amazon.com/elasticloadbalancing/pricing/
|
|
163
|
+
- S3. 3 - 4 app bundles are stored on s3. Each deploy will make 2 list requests and upload 1 file. Beanstalk might store additional files on s3.
|
|
164
|
+
|
|
165
|
+
Graceful Shutdown uses the following services:
|
|
166
|
+
|
|
167
|
+
- Cloud Trail. The trail is stored in s3 and, according to their docs, usually costs less than $3 / month.
|
|
168
|
+
|
|
169
|
+
## Rolling Deploys
|
|
170
|
+
|
|
171
|
+
When deploying a new version, there is no downtime, and the number of servers handling requests is not reduced.
|
|
172
|
+
|
|
173
|
+
Beanstalk is configured to use Rolling updates with additional batch with a batch size of 25%. This means that Beanstalk first creates an additional 25% instances and deploys the new version of the app to them. After the app has started, it will update the remaining servers in batches of 25%, except for the last 25%, which it terminates.
|
|
174
|
+
|
|
175
|
+
This does not apply when changing the instance type. Instead, Beanstalk terminates the instances and replaces them in batches of 1/3 (rounded to the nearest integer). If you only have one server, there will be downtime until the app is running on the new server. Before changing `instanceType`, increase `minInstances` to at least 2 and run `mup reconfig` to avoid downtime.
|
|
176
|
+
|
|
177
|
+
## Load balancing
|
|
178
|
+
|
|
179
|
+
Load balancing is automatically configured and supports web sockets and sticky sessions.
|
|
180
|
+
|
|
181
|
+
## Scale
|
|
182
|
+
|
|
183
|
+
To scale your app, modify `app.minInstances` in your mup config to how many servers you want your app deployed to. Then run `mup reconfig`.
|
|
184
|
+
|
|
185
|
+
You cannot scale to 0 servers. Instead, use `mup stop`.
|
|
186
|
+
|
|
187
|
+
AWS limits how many instances your account can have. To increase the limit, you will need to contact their customer support. Learn more [here](https://aws.amazon.com/premiumsupport/knowledge-center/manage-service-limits/).
|
|
188
|
+
|
|
189
|
+
## Autoscaling
|
|
190
|
+
|
|
191
|
+
To enable autoscaling, make sure that `app.maxInstances` in your mup config is greater than `app.minInstances`.
|
|
192
|
+
|
|
193
|
+
After modifying `app.maxInstances` or `app.minInstances`, run `mup reconfig`.
|
|
194
|
+
|
|
195
|
+
The average cpu for the previous 5 minutes is used to trigger autoscaling. When the average is above 75%, it will be scaled up, and an average below 35% scales down.
|
|
196
|
+
|
|
197
|
+
## Enhanced Health
|
|
198
|
+
|
|
199
|
+
Enhanced health is enabled for your app. No metrics are configured to be stored in CloudWatch.
|
|
200
|
+
|
|
201
|
+
You can view the health by running `mup beanstalk status` or on the [AWS Console](https://console.aws.amazon.com/elasticbeanstalk/home).
|
|
202
|
+
|
|
203
|
+
## Logs
|
|
204
|
+
|
|
205
|
+
The log commands shows the last 100 lines. You can download a zip file with all of the logs from the [aws console](https://console.aws.amazon.com/elasticbeanstalk/home).
|
|
206
|
+
|
|
207
|
+
## Meteor and Node versions
|
|
208
|
+
|
|
209
|
+
This plugin supports meteor 1.2 or newer. It will automatically use the correct Node and npm version.
|
|
210
|
+
|
|
211
|
+
## SSL
|
|
212
|
+
|
|
213
|
+
This plugin can request a certificate for you using the [Amazon Certificate Manager (ACM)](https://aws.amazon.com/certificate-manager/).
|
|
214
|
+
|
|
215
|
+
In your config, add:
|
|
216
|
+
|
|
217
|
+
```js
|
|
218
|
+
module.exports = {
|
|
219
|
+
app: {
|
|
220
|
+
// ... rest of config
|
|
221
|
+
|
|
222
|
+
// Enables SSL. Array of domain names to create the certificate for.
|
|
223
|
+
sslDomains: [
|
|
224
|
+
'website.com',
|
|
225
|
+
'www.website.com',
|
|
226
|
+
'website.net'
|
|
227
|
+
],
|
|
228
|
+
|
|
229
|
+
// (optional) Redirect http to https
|
|
230
|
+
forceSSL: true
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Then run `mup deploy` or `mup beanstalk ssl`.
|
|
236
|
+
|
|
237
|
+
The command will show a list of email addresses that ACM sent an email to with instructions on verifying the domain name. The list includes your domain's registrant, and administrative and technical contact, as well as a few common addresses.
|
|
238
|
+
|
|
239
|
+
After you have followed the instructions in the email, run `mup beanstalk ssl` to configure Beanstalk to use the certificate.
|
|
240
|
+
|
|
241
|
+
You can also run `mup beanstalk ssl` to view the certificate's status or to resend the confirmation email.
|
|
242
|
+
|
|
243
|
+
ACM automatically renews the certificates.
|
|
244
|
+
|
|
245
|
+
## Graceful Shutdown
|
|
246
|
+
|
|
247
|
+
This plugin can setup CloudWatch Events to send a `SIGTERM` signal to your app on instances that are being drained by the load balancer. Your app can listen for this signal and gradually disconnect users or do other work needed before shutting down. The signal is sent at least 30 seconds before before the load balancer finishes draining it.
|
|
248
|
+
|
|
249
|
+
Before enabling this feature, make sure the IAM user has these policies:
|
|
250
|
+
|
|
251
|
+
- `IAMFullAccess`
|
|
252
|
+
- `AWSCloudTrailFullAccess`
|
|
253
|
+
- `CloudWatchEventsFullAccess`
|
|
254
|
+
- `AmazonSSMFullAccess`
|
|
255
|
+
|
|
256
|
+
Next, install the [@meteorjs/ddp-graceful-shutdown](https://github.com/meteor/ddp-graceful-shutdown) npm package and add this code to your app's server:
|
|
257
|
+
|
|
258
|
+
```ts
|
|
259
|
+
import { DDPGracefulShutdown } from '@meteorjs/ddp-graceful-shutdown';
|
|
260
|
+
import { Meteor } from 'meteor/meteor';
|
|
261
|
+
|
|
262
|
+
new DDPGracefulShutdown({
|
|
263
|
+
gracePeriodMillis: 1000 * process.env.METEOR_SIGTERM_GRACE_PERIOD_SECONDS,
|
|
264
|
+
server: Meteor.server,
|
|
265
|
+
}).installSIGTERMHandler();
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
`METEOR_SIGTERM_GRACE_PERIOD_SECONDS` is set to 30 seconds.
|
|
269
|
+
|
|
270
|
+
In your config, set `app.gracefulShutdown` to `true`:
|
|
271
|
+
|
|
272
|
+
```js
|
|
273
|
+
module.exports = {
|
|
274
|
+
app: {
|
|
275
|
+
// ... rest of config
|
|
276
|
+
|
|
277
|
+
gracefulShutdown: true
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Then run `mup deploy`.
|
|
283
|
+
|
|
284
|
+
You can now replace the policies you added with their read only equivilents: `AWSCloudTrailReadOnlyAccess`, `CloudWatchEventsReadOnlyAccess`, `IAMReadOnlyAccess`, and `AmazonSSMReadOnlyAccess`.
|
|
285
|
+
|
|
286
|
+
## Meteor Shell and Debug
|
|
287
|
+
|
|
288
|
+
To help with debugging issues that happen in production mup-aws-beanstalk provides two commands:
|
|
289
|
+
|
|
290
|
+
1) `mup beanstalk shell` to open a production Meteor shell. This is the same shell you get with `meteor shell`, but connected to your app running in Elastic Beanstalk. Your app must use the [`qualia:prod-shell`](https://github.com/qualialabs/prod-shell) or equivalent package
|
|
291
|
+
2) `mup beanstalk debug` to allow connecting your local Node developer tools to the app running in production
|
|
292
|
+
|
|
293
|
+
Requirements:
|
|
294
|
+
|
|
295
|
+
1) The IAM user to have the `EC2InstanceConnect` policy.
|
|
296
|
+
2) The beanstalk environment should use a platform based on Amazon Linux 2. If mup-aws-beanstalk times out while trying to connect, the platform might be based on an older version of Amazon Linux.
|
|
297
|
+
3) The `app.sshKey` option should be configured in your mup config:
|
|
298
|
+
|
|
299
|
+
```js
|
|
300
|
+
module.exports = {
|
|
301
|
+
app: {
|
|
302
|
+
sshKey: {
|
|
303
|
+
privateKey: '~/.ssh/beanstalk',
|
|
304
|
+
publicKey: '~/.ssh/beanstalk.pub'
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ... rest of app config
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
The public key is temporarily added to the instance when needed using EC2 Instance Connect. Also, a rule will be added to the instance's security group to allow ssh access from your IP address. The rule is removed when mup exits.
|
|
313
|
+
|
|
314
|
+
## Upgrading to Amazon Linux 2
|
|
315
|
+
|
|
316
|
+
AWS Elastic Beanstalk requires doing a [blue/green deployment] to update to Amazon Linux 2. This involves:
|
|
317
|
+
|
|
318
|
+
1) Creating a new environment for the AWS Beanstalk app. An easy way to do this is set `app.envName` in your mup config to a different name, and then run `mup deploy`. It will create a new environment with the new name you set.
|
|
319
|
+
2) After the new environment is ready, make sure the app is working correctly
|
|
320
|
+
3) [Swap the CNAME between the old and new environment](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.CNAMESwap.html). This will move traffic to the new environment
|
|
321
|
+
4) Once the old environment is no longer being used, you can terminate it
|
|
322
|
+
|
|
323
|
+
## Custom `.ebextensions`
|
|
324
|
+
|
|
325
|
+
You can create a `.ebextensions` folder to further customize the Elastic Beanstalk environment. More details are in [Elastic Beanstalk's docs](https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/ebextensions.html).
|
|
326
|
+
|
|
327
|
+
mup-aws-beanstalk copies your app's `.ebextensions` folder into the app bundle when deploying your app.
|
|
328
|
+
|
|
329
|
+
## Troubleshooting
|
|
330
|
+
|
|
331
|
+
- View the logs with `mup logs` or from the AWS Console
|
|
332
|
+
- View the environment events with `mup beanstalk events`
|
|
333
|
+
- Check the app and instance's health with `mup beanstalk health`
|
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./lib');
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
bucket="<%= bucketName %>"
|
|
3
|
+
VERSION="2018-03-28"
|
|
4
|
+
env_version=`sudo /opt/elasticbeanstalk/bin/get-config environment --key MUP_ENV_FILE_VERSION`
|
|
5
|
+
|
|
6
|
+
echo "env_version=$env_version"
|
|
7
|
+
|
|
8
|
+
[[ -z "$env_version" ]] && { echo "Long Env is not enabled."; exit 0; }
|
|
9
|
+
|
|
10
|
+
export NVM_DIR="/.nvm"
|
|
11
|
+
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
|
12
|
+
|
|
13
|
+
instance_profile=`curl http://169.254.169.254/$VERSION/meta-data/iam/security-credentials/`
|
|
14
|
+
json=`curl http://169.254.169.254/$VERSION/meta-data/iam/security-credentials/${instance_profile}`
|
|
15
|
+
instance_region=`curl http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/.$//'`
|
|
16
|
+
|
|
17
|
+
function getInstanceProfileProperty () {
|
|
18
|
+
result=`node -e "console.log(JSON.parse(process.argv.slice(2).join(''))[process.argv[1]])" $1 $json`
|
|
19
|
+
echo "$result"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
aws_access_key_id=`getInstanceProfileProperty "AccessKeyId"`
|
|
23
|
+
aws_secret_access_key=`getInstanceProfileProperty "SecretAccessKey"`
|
|
24
|
+
token=`getInstanceProfileProperty "Token"`
|
|
25
|
+
|
|
26
|
+
file="env/$env_version.txt"
|
|
27
|
+
resource="${bucket}/${file}"
|
|
28
|
+
|
|
29
|
+
mkdir -p /etc/app || true
|
|
30
|
+
sudo aws s3 cp s3://${resource} /etc/app/env.txt
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Resources:
|
|
2
|
+
AWSEBAutoScalingGroup:
|
|
3
|
+
Metadata:
|
|
4
|
+
AWS::CloudFormation::Authentication:
|
|
5
|
+
S3Auth:
|
|
6
|
+
type: "s3"
|
|
7
|
+
buckets: ["<%= bucketName %>"]
|
|
8
|
+
roleName:
|
|
9
|
+
"Fn::GetOptionSetting":
|
|
10
|
+
Namespace: "aws:autoscaling:launchconfiguration"
|
|
11
|
+
OptionName: "IamInstanceProfile"
|
|
12
|
+
DefaultValue: "aws-elasticbeanstalk-ec2-role"
|
|
13
|
+
files:
|
|
14
|
+
"/opt/elasticbeanstalk/hooks/appdeploy/pre/48env.sh":
|
|
15
|
+
mode: "000775"
|
|
16
|
+
owner: root
|
|
17
|
+
group: users
|
|
18
|
+
content: |
|
|
19
|
+
<%- padScript(include('./env.sh'), 6) %>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
echo "Setting up"
|
|
4
|
+
mkdir /mup_graceful_shutdown || true
|
|
5
|
+
ID=$(curl http://169.254.169.254/latest/meta-data/instance-id)
|
|
6
|
+
FILE=/mup_graceful_shutdown/$ID
|
|
7
|
+
echo "File $FILE"
|
|
8
|
+
test -e $FILE && exit
|
|
9
|
+
echo "File does not exist"
|
|
10
|
+
echo 'PATH="/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/.local/bin:/home/ec2-user/bin"' >> $FILE
|
|
11
|
+
|
|
12
|
+
# Platforms based on Amazon Linux 2 use a different user name
|
|
13
|
+
echo 'sudo pkill -SIGTERM -u nodejs -n node || sudo pkill -SIGTERM -u webapp -n node' >> $FILE
|
|
14
|
+
chmod +x $FILE
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/* eslint-disable no-var, prefer-template, func-names, prefer-arrow-callback */
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* The health check expects the response's status code to be 200
|
|
5
|
+
* Some apps set their status code to something else, which would
|
|
6
|
+
* cause the health check to always fail.
|
|
7
|
+
*
|
|
8
|
+
* The health check gets sent to this server, which checks if
|
|
9
|
+
* the app is responding to requests, and then sets the correct
|
|
10
|
+
* status code for the health check.
|
|
11
|
+
*
|
|
12
|
+
* This uses the same version of node that the app is using,
|
|
13
|
+
* so it needs to support Node 0.10.
|
|
14
|
+
*/
|
|
15
|
+
var http = require('http');
|
|
16
|
+
|
|
17
|
+
var debugEnabled = process.env.HEALTH_CHECK_VERBOSE === 'true';
|
|
18
|
+
|
|
19
|
+
var log = function log(message, debug) {
|
|
20
|
+
if (!debug || debugEnabled) {
|
|
21
|
+
console.log('[HealthCheck] ' + new Date() + ': ' + message);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
var server = http.createServer(function (request, response) {
|
|
26
|
+
var timeout;
|
|
27
|
+
var appRequest;
|
|
28
|
+
log('Received health check request', true);
|
|
29
|
+
appRequest = http.get('http://127.0.0.1:8081', function (res) {
|
|
30
|
+
log('Health check succeeded', true);
|
|
31
|
+
response.statusCode = 200;
|
|
32
|
+
response.end('Success');
|
|
33
|
+
clearTimeout(timeout);
|
|
34
|
+
res.resume();
|
|
35
|
+
}).on('error', function (e) {
|
|
36
|
+
log('Request to app failed ' + e);
|
|
37
|
+
response.statusCode = 500;
|
|
38
|
+
response.end('Failed');
|
|
39
|
+
clearTimeout(timeout);
|
|
40
|
+
});
|
|
41
|
+
timeout = setTimeout(function () {
|
|
42
|
+
log('Request to app timed out after 3 seconds');
|
|
43
|
+
appRequest.abort();
|
|
44
|
+
}, 3000);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
server.listen(8039);
|
|
49
|
+
log('Started health check server', true);
|
|
50
|
+
} catch (e) {
|
|
51
|
+
// Port is being used, likely from another health-check server running
|
|
52
|
+
log('Port being used');
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=health-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/assets/health-check.js"],"names":["http","require","debugEnabled","process","env","HEALTH_CHECK_VERBOSE","log","message","debug","console","Date","server","createServer","request","response","timeout","appRequest","get","res","statusCode","end","clearTimeout","resume","on","e","setTimeout","abort","listen"],"mappings":"AAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA,IAAIA,IAAI,GAAGC,OAAO,CAAC,MAAD,CAAlB;;AAEA,IAAIC,YAAY,GAAGC,OAAO,CAACC,GAAR,CAAYC,oBAAZ,KAAqC,MAAxD;;AAEA,IAAIC,GAAG,GAAG,SAASA,GAAT,CAAaC,OAAb,EAAsBC,KAAtB,EAA6B;AACrC,MAAI,CAACA,KAAD,IAAUN,YAAd,EAA4B;AAC1BO,IAAAA,OAAO,CAACH,GAAR,CAAY,mBAAmB,IAAII,IAAJ,EAAnB,GAAgC,IAAhC,GAAuCH,OAAnD;AACD;AACF,CAJD;;AAOA,IAAII,MAAM,GAAGX,IAAI,CAACY,YAAL,CAAkB,UAAUC,OAAV,EAAmBC,QAAnB,EAA6B;AAC1D,MAAIC,OAAJ;AACA,MAAIC,UAAJ;AAEAV,EAAAA,GAAG,CAAC,+BAAD,EAAkC,IAAlC,CAAH;AAEAU,EAAAA,UAAU,GAAGhB,IAAI,CAACiB,GAAL,CAAS,uBAAT,EAAkC,UAAUC,GAAV,EAAe;AAC5DZ,IAAAA,GAAG,CAAC,wBAAD,EAA2B,IAA3B,CAAH;AACAQ,IAAAA,QAAQ,CAACK,UAAT,GAAsB,GAAtB;AACAL,IAAAA,QAAQ,CAACM,GAAT,CAAa,SAAb;AACAC,IAAAA,YAAY,CAACN,OAAD,CAAZ;AACAG,IAAAA,GAAG,CAACI,MAAJ;AACD,GANY,EAMVC,EANU,CAMP,OANO,EAME,UAAUC,CAAV,EAAa;AAC1BlB,IAAAA,GAAG,CAAC,2BAA2BkB,CAA5B,CAAH;AACAV,IAAAA,QAAQ,CAACK,UAAT,GAAsB,GAAtB;AACAL,IAAAA,QAAQ,CAACM,GAAT,CAAa,QAAb;AACAC,IAAAA,YAAY,CAACN,OAAD,CAAZ;AACD,GAXY,CAAb;AAaAA,EAAAA,OAAO,GAAGU,UAAU,CAAC,YAAY;AAC/BnB,IAAAA,GAAG,CAAC,0CAAD,CAAH;AACAU,IAAAA,UAAU,CAACU,KAAX;AACD,GAHmB,EAGjB,IAHiB,CAApB;AAID,CAvBY,CAAb;;AA0BA,IAAI;AACFf,EAAAA,MAAM,CAACgB,MAAP,CAAc,IAAd;AACArB,EAAAA,GAAG,CAAC,6BAAD,EAAgC,IAAhC,CAAH;AACD,CAHD,CAGE,OAAOkB,CAAP,EAAU;AACV;AACAlB,EAAAA,GAAG,CAAC,iBAAD,CAAH;AACD","sourcesContent":["/* eslint-disable no-var, prefer-template, func-names, prefer-arrow-callback */\n\n/*\n * The health check expects the response's status code to be 200\n * Some apps set their status code to something else, which would\n * cause the health check to always fail.\n *\n * The health check gets sent to this server, which checks if\n * the app is responding to requests, and then sets the correct\n * status code for the health check.\n *\n * This uses the same version of node that the app is using,\n * so it needs to support Node 0.10.\n */\n\nvar http = require('http');\n\nvar debugEnabled = process.env.HEALTH_CHECK_VERBOSE === 'true';\n\nvar log = function log(message, debug) {\n if (!debug || debugEnabled) {\n console.log('[HealthCheck] ' + new Date() + ': ' + message);\n }\n};\n\n\nvar server = http.createServer(function (request, response) {\n var timeout;\n var appRequest;\n\n log('Received health check request', true);\n\n appRequest = http.get('http://127.0.0.1:8081', function (res) {\n log('Health check succeeded', true);\n response.statusCode = 200;\n response.end('Success');\n clearTimeout(timeout);\n res.resume();\n }).on('error', function (e) {\n log('Request to app failed ' + e);\n response.statusCode = 500;\n response.end('Failed');\n clearTimeout(timeout);\n });\n\n timeout = setTimeout(function () {\n log('Request to app timed out after 3 seconds');\n appRequest.abort();\n }, 3000);\n});\n\n\ntry {\n server.listen(8039);\n log('Started health check server', true);\n} catch (e) {\n // Port is being used, likely from another health-check server running\n log('Port being used');\n}\n"],"file":"health-check.js"}
|