4
votes

I have a shell script of about 200 lines. I want to use it to bootstrap an ec2 instance. Is there any tool available for converting shell script into userdata?

2
Is there a reason why you wouldn't just copy the script file to file and execute with cloud formation?Edwin
I'm a newbie to cloudformation. If you're talking about "wget" a shell script from s3 bucket and executing it after changing the permissions, Is that a feasible option?OpsEco
I was answering your question, but then I realized that there might be some confusion between userdata and CloudFormation. They are independent concepts. You can certainly do a wget and execute with just userdata. Are there other reasons you are using cloud formation?Edwin
Please mark the question as "Resolved" if it is the case.Benoît Sauvère

2 Answers

3
votes

You can do it with perl (extract from one of my Bash script) :

SOURCE_FILE=$1
perl -p -e 's/\"/\\"/g;' "${SOURCE_FILE}"            |  # Escape of "
perl -p -e 's/^(.*)$/"\1\\n",/g;'                    ;  # Add a " at the beginning of each lines + Add a " at the end of each lines \n",
echo '""'
# Add "" as the last line of the file (to match the , from the previous line)
0
votes

You need to account for special characters, like ', *, \, etc. This works for me, but I'm not sure it is complete to cover every case.

echo -n '"' ; sed ':again; N; $!b again; s/\\/\\\\/g; s/"/\\"/g; s/\n/\\n/g; s/$/\\n/;' $1 | tr -d '\n' ; echo '"'

This will produce one, long string that can be placed into the "UserData": { "Fn::Base64": field. Here's an example shell script:

#!/bin/bash

echo $(date "+%F %R:%S") ":: get metadata"
MD=/etc/profile.d/metadata.sh
echo "# AWS metadata" >  $MD
metadata=$(curl -sf http://169.254.169.254/latest/dynamic/instance-identity/document)
echo declare -x metadata=\'$metadata\' >> $MD

echo $(date "+%F %R:%S") ":: yum update"
yum -y update

echo $(date "+%F %R:%S") ":: awscli update"
yum -y install python-pip
rm -rf /tmp/pip-build-root/ ; pip install awscli --upgrade

echo $(date "+%F %R:%S") ":: set a cronjob"
echo '*/15 * * * *    ~/bin/cronjob.sh' > /var/spool/cron/root

echo $(date "+%F %R:%S") ":: userdata complete"

Converted to CloudFormation:

"#!/bin/bash\n\necho $(date \"+%F %R:%S\") \":: get metadata\"\nMD=/etc/profile.d/metadata.sh\necho \"# AWS metadata\" >  $MD\nmetadata=$(curl -sf http://169.254.169.254/latest/dynamic/instance-identity/document)\necho declare -x metadata=\\'$metadata\\' >> $MD\n\necho $(date \"+%F %R:%S\") \":: yum update\"\nyum -y update\n\necho $(date \"+%F %R:%S\") \":: awscli update\"\nyum -y install python-pip\nrm -rf /tmp/pip-build-root/ ; pip install awscli --upgrade\n\necho $(date \"+%F %R:%S\") \":: set a cronjob\"\necho '*/15 * * * *    ~/bin/cronjob.sh' > /var/spool/cron/root\n\necho $(date \"+%F %R:%S\") \":: userdata complete\"\n"