How to run npm update -g npm` on Elastic Beanstalk?
How can I get npm update -g npm
my Elastic Beanstalk instances running when they are spinning? It is easy enough to run the update command manually on each instance, but this will not work through the scaling event, as more instances are added automatically.
How can I get the latest NPM on Elastic Beanstalk instances running through the autoscale event?
source to share
It turns out that it is difficult, I dug a little and experimented.
First, a quick bit about the elastic bob life cycle. There are several steps that AWS scripts execute on each instance during deployment. There are two questions for the Node.JS server:
- Install Node.JS
- Execute
npm install
Installing Node.JS is where we can step in and do the magic. Most of the errors that make a beanstalk instance want to do magic or other things start with a step npm install
.
Returning to the theme, script AWS, used to set the node to duplicate beanstalk, /opt/elasticbeanstalk/hooks/appdeploy/pre/40install_node.sh
. It usually looks like this:
#!/bin/bash
set -xe
/opt/elasticbeanstalk/containerfiles/ebnode.py --action node-install
This script installs a bunch of different versions of node on /opt/elasticbeanstalk/node-install
, including the one selected in the beanstalk config. Wouldn't it be nice to run npm update -g npm
with one of the node versions sitting in that folder?
It turns out that beanstalk provides a mechanism for sharing files on each instance during deployment. Basically you are setting up the YAML files in a folder .ebextensions
in your application. There are two ways to refer to the contents of a file, in a string or in a s3 bucket. I am using the s3 bucket approach, creating node.config
YAML that looks like this:
files:
"/opt/elasticbeanstalk/hooks/appdeploy/pre/40install_node.sh" :
mode: "000775"
owner: root
group: users
source: https://s3.amazonaws.com/bucketname/40install_node.sh
authentication: S3Access
Resources:
AWSEBAutoScalingGroup:
Metadata:
AWS::CloudFormation::Authentication:
S3Access:
type: S3
roleName: aws-elasticbeanstalk-ec2-role
buckets: bucketname
Pay attention to the property S3Access
. We keep the bucket private by sharing it aws-elasticbeanstalk-ec2-role
with IAM.
Now we need a version 40install_node.sh
that triggers the npm update:
#!/bin/bash
set -xe
/opt/elasticbeanstalk/containerfiles/ebnode.py --action node-install
# Update npm
cd /opt/elasticbeanstalk/node-install/node-v0.12.2-linux-x64/bin/ && /opt/elasticbeanstalk/node-install/node-v0.12.2-linux-x64/bin/npm update npm -g
You can put any customization of your node installation in this file. Just remember to keep track of the path to the node, it will change as the node versions will show up in the beanstalk config.
source to share
If you don't want to add the script on S3, you can just put the following in .ebextensions
, if you are using node v12, the path node-v0.12.6-linux-x64
will be different for other versions .
commands:
01-updatenpmv3:
command: PATH=$PATH:/opt/elasticbeanstalk/node-install/node-v0.12.6-linux-x64/bin/ && npm update -g npm
cwd: /opt/elasticbeanstalk/node-install/node-v0.12.6-linux-x64/bin/
source to share
It's not obligatory. You can specify in your config which version of Nodejs you want to run, and thus it will be paired with the corresponding npm version. If you want to have an older version of nodejs with a newer version of npm then this exercise is worth it.
In this case, I'll probably go to the npm install script in the file dropped in the .ebextensions folder (for example 00_default.config):
files:
"/opt/elasticbeanstalk/hooks/appdeploy/pre/50npm.sh":
mode: "000755"
owner: root
group: users
content: |
#!/bin/bash
#==============================================================================
# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Amazon Software License (the "License"). You may not use
# this file except in compliance with the License. A copy of the License is
# located at
#
# http://aws.amazon.com/asl/
#
# or in the "license" file accompanying this file. This file is distributed on
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or
# implied. See the License for the specific language governing permissions
# and limitations under the License.
#==============================================================================
set -xe
/opt/elasticbeanstalk/containerfiles/ebnode.py --action npm-install
# Update npm
cd /opt/elasticbeanstalk/node-install/CURRENTNODEVERSIONHERE/bin/ && /opt/elasticbeanstalk/node-install/CURRENTNODEVERSIONHERE/bin/npm update npm -g
Replace CURRENTNODEVERSIONHERE with the correct path / version for your installation.
These are the available versions that I see in my copies. You will want to check your own resources to see what you are working with.
Location: / opt / elasticbeanstalk / node-install
- node -v0.10.46-linux-x64
- node -v0.12.15-Linux-x64
- node -v0.8.28-linux-x64
- node-v4.4.6-Linux-x64
- node-v5.12.0-Linux-x64
- node-v6.2.2-Linux-x64
source to share