Question:
I’m following these instructions to bootstrap a Windows ec2 instance with a powershell script (call it “bootstrap.ps1”). However, it looks as if the script has never run when I log into the machine for the first time. I check C:\Program Files\Amazon\Ec2ConfigService\Logs\Ec2ConfigLog, and I see this:
1 2 3 4 |
2014-03-11 00:08:02: Ec2HandleUserData: Start running user scripts 2014-03-11 00:08:02: Ec2HandleUserData: Could not find 2014-03-11 00:08:02: Ec2HandleUserData: Could not find |
This is what my script looks like:
1 2 3 4 |
(multiple lines of powershell script here) |
I’m base64-encoding the script in Python and sending it through boto:
1 2 3 4 5 6 7 |
import base64 # (create connection to aws region in boto called 'conn') conn = ... # run the instance and provide base64-encoded bootstrap powershell script in user_data with open("bootstrap.ps1", "r") as fd: conn.run_instances(..., user_data=base64.encodestring(fd.read())) |
I’ve made sure that:
- The script I’m sending (“bootstrap.ps1”) is using \r\n as line endings
- The script available at
http://169.254.169.254/latest/user-data
base64-decoded is the same as the raw “bootstrap.ps1” I’ve written (verified by downloading it, then running throughbase64.decodestring
in Python) - There are no characters before or after
<powershell>
and</powershell>
in “boostrap.ps1”, respectively.
Clearly, I’m including <powershell>
and </powershell>
in user_data. These are encoded base-64, yet somehow they’re not being found by ec2config? Can anyone see what I’m doing wrong here?
Answer:
The problem lies in the encoding of user_data
, which is already performed by boto
. According to the boto documentation, user_data
should be “[t]he Base64-encoded MIME user data to be made available to the instance(s) in this reservation,” which I find to be very misleading, since the encoding need not and should not be done in the call to run_instances
. The following Python works for me now:
1 2 3 4 5 6 7 |
# create connection... conn = ... # run instance with open("bootstrap.ps1", "r") as fd: # don't encode user_data conn.run_instances(..., user_data=fd.read()) |