Search code examples
amazon-ec2ec2-userdata

EC2 User Data Script Not Executing NodeJs File On Launch or Reboot


I'm trying to build a user data file to be included on each and every AWS EC2 instance I launch.

The data should be executed on initial launch, as well as on every reboot/restart.

It is supposed to create/overwrite a .env file using params passed in the data itself, and then run a nodejs app that comes as part of the custom system image.

This is what I have so far

Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0

--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
cloud_final_modules:
- [scripts-user, always]

--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"

#!/bin/bash

# Create .env file -- This works
cat << EOF > /home/ec2-user/.env
UN=XXX
PW=XXX
CID=XXX
KEY=XXX
EOF

# Start the Node.js app --Nothing happens here
screen -d -m node index.js

--//--

With a bit of additional logging, I have managed to get the machine to output the following: Node.js is not installed.

However, I don't believe this is correct, because when I SSH into the machine directly and run node --version it spits back v20.14.0.

Could this be a timing issue? Should I be calling another shell script included in the machine image directly instead to execute the file?

I have also tried to remove screen and just run node index.js directly, which no success.

Any help would be greatly appreciated!


Solution

  • The issue was that, by default, user data scripts execute on the machine as root user. So when I would ssh in as the default ec2-user and look for any sign the script executed, it wouldn't be there (root made it, not ec2).

    To get around this, I just modified the user data script to execute relevant commands as ec2-user rather than root.

    sudo -u ec2-user -i <<'EOF'
    commandhere
    EOF
    

    Handled it.