How can I run
npm update -g npm
It turns out this one is tricky, took a bit of digging and experimentation.
First, a quick bit about Elastic Beanstalk's lifecycle. There are several steps taken by AWS scripts running on each instance on deploy. For a Node.JS server, there are two of interest:
Installing Node.JS is where we can step in and do some magic. Most errors prompting the desire to do magic, or other things, to a beanstalk instance come from the
npm install step.
Getting back on topic, the script AWS used to install node on beanstalk instances is
/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 node versions to
/opt/elasticbeanstalk/node-install, including the one selected in the beanstalk configuration. Wouldn't it be nice to run
npm update -g npm with one of the node versions sitting in that folder?
It turns out beanstalk supplies a mechanism to swap out files on each instance during deploy. Basically you configure YAML files in a
.ebextensions folder in your app. There are two ways to reference the file contents, in line, or in an s3 bucket. I use the s3 bucket approach, giving a
node.config YAML looking 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
S3Access property. We keep the bucket private, granting access to the
aws-elasticbeanstalk-ec2-role using IAM.
Now all we need is a version of
40install_node.sh running 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 install in this file as well. Just remember to keep an eye on the path to node, it will change as node versions go up in the beanstalk configuration.