Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Migrating from Amazon Linux to Amazon Linux 2 with Elastic Beanstalk and Node.js

This file is a log of everything I've encountered when trying to migrate a Node.js, Elastic Beanstalk application from the Amazon Linux platform to the Amazon Liunx 2 platform. Here's why you should migrate:

  1. LTS support up to 2023 source
  2. The Amazon Linux AMI's end-of-life is December, 2020 source
  3. Amazon Linux 2 has some big package upgrades (GCC, Glibc, etc.)
  4. Elastic Beanstalk also has some upgrades on top of Amazon Linux 2 (e.g. faster deploys)

Challenges

Disabling NPM install

Previously you were able to use a .ebextensions file and override /opt/elasticbeanstalk/hooks/appdeploy/pre/50npm.sh and /opt/elasticbeanstalk/hooks/configdeploy/pre/50npm.sh. The new EB version doesn't have this and runs its commands internally.

I found that Elastic Beanstalk will not run npm if it cannot find your package.json file and skip those commands. To avoid making modifications to the code base, we temporarily move it during the build phase of Elastic Beanstalk. To do so, we utilized .platform/hooks.

./platform/hooks/prebuild/00_disable_npm.sh

#!/bin/bash
mv package.json package.json.tmp
mv package-lock.json package-lock.json.tmp

./platform/hooks/predeploy/00_enable_npm.sh

#!/bin/bash
mv package.json.tmp package.json
mv package-lock.json.tmp package-lock.json

These two files must have executable permissions, remember to run chmod +x on them!

nginx config

The default nginx config is a bit limiting and you'd probably want to extend it in some way. The old way of using an .ebextensions file gets blown away by Elastic Beanstalk on deploy so you'll now want to create a .platform/nginx/conf.d/proxy.conf file instead, a method that Elastic Beanstalk recognizes.

Here's an example we utilize to increase the upload size and timeout limits.

client_max_body_size 32M;
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
send_timeout 120s;

Logs

Logging is now done with syslog and writes to /var/log/web.stdout.log and /var/log/web.stderr.log. If you want to mimick the previous version of /var/log/nodejs/nodejs.log, you'll need to edit Elastic Beanstalk's default rsyslog config /opt/elasticbeanstalk/config/private/rsyslog.conf. We are using an .ebextension to override it.

files:
  "/opt/elasticbeanstalk/config/private/rsyslog.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      # This rsyslog file redirects Elastic Beanstalk platform logs.
      # Logs are initially sent to syslog, but we also want to divide
      # stdout and stderr into separate log files.

      template(name="SimpleFormat" type="string" string="%msg%\n")
      $EscapeControlCharactersOnReceive off

      if $programname  == 'web' then {
        *.=warning;*.=err;*.=crit;*.=alert;*.=emerg; /var/log/web.stderr.log; SimpleFormat
        *.=info;*.=notice /var/log/web.stdout.log; SimpleFormat
      }

npm start

You no longer are able to specify a start command. Instead, they implemented Heroku's version of Procfile. Make sure you have a web: npm start proc.

Additionally, if you use the same code base for different environments, you'll need to use an environment variable and have your own bash script choose what to run.

#!/bin/bash
#!/bin/bash

if [ "$INTERSELLER_ENV" = "" ]
then
  echo -e "INTERSELLER_ENV not set\n"
else
  npm run $INTERSELLER_ENV
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.