问题
I have a simple bash script I'm trying to pass to an AWS EC2 ubuntu instance via a Powershell script using the AWS Library.
#!/bin/bash
apt-get update
apt-get upgrade
Heres the powershell script that encodes the file contents in base64 and calls the cmdlet that starts the EC2 instance:
$fileContent = Get-Content $UserDataTarget
$fileContentBytes = [System.Text.Encoding]::UTF8.GetBytes($fileContent)
$fileContentEncoded = [System.Convert]::ToBase64String($fileContentBytes)
$MasterInstance = New-EC2Instance -ImageId ami-4c7a3924 -MinCount 1 -MaxCount 1 -KeyName AWSKey -SecurityGroups $SecurityGroup -InstanceType "t1.micro" -UserData $fileContentEncoded
This is a snippet from the cloud init log:
Cloud-init v. 0.7.5 running 'modules:final' at Fri, 02 Oct 2015 21:05:24 +0000. Up 33.88 seconds.
/bin/bash: apt-get update apt-get upgrade: No such file or directory
2015-10-02 21:05:24,294 - util.py[WARNING]: Failed running /var/lib/cloud/instance/scripts/part-001 [127]
2015-10-02 21:05:24,298 - cc_scripts_user.py[WARNING]: Failed to run module scripts-user (scripts in /var/lib/cloud/instance/scripts)
2015-10-02 21:05:24,298 - util.py[WARNING]: Running scripts-user (<module 'cloudinit.config.cc_scripts_user' from '/usr/lib/python2.7/dist-packages/cloudinit/config/cc_scripts_user.pyc'>) failed
Here's a snippet of the loaded user data script on the ubuntu instance at /var/lib/cloud/instance/scripts/part-001:
#!/bin/bash apt-get update apt-get upgrade
I have tried converting the windows file to linux using 010 Editor and Cygwin. I've tried replacing the CRLF bytes with LF bytes. The result is the same: the entire bash script is condensed to 1 line, all line breaks are removed, and user data script fails to load on initial boot.
UPDATE: I've included both code snippets I've used to do the line break conversion. Both were vetted from peer sources (SO). For some reason, the script still shows up in the linux instance without the line break characters.
Snippet 1
function ConvertTo-LinuxLineEndings($path) {
$oldBytes = [io.file]::ReadAllBytes($path)
if (!$oldBytes.Length) {
return;
}
[byte[]]$newBytes = @()
[byte[]]::Resize([ref]$newBytes, $oldBytes.Length)
$newLength = 0
for ($i = 0; $i -lt $oldBytes.Length - 1; $i++) {
if (($oldBytes[$i] -eq [byte][char]"`r") -and ($oldBytes[$i + 1] -eq [byte][char]"`n")) {
continue;
}
$newBytes[$newLength++] = $oldBytes[$i]
}
$newBytes[$newLength++] = $oldBytes[$oldBytes.Length - 1]
[byte[]]::Resize([ref]$newBytes, $newLength)
[io.file]::WriteAllBytes($path, $newBytes)
}
ConvertTo-LinuxLineEndings($UserDataTarget)
Snippet 2
try{
# get the contents and replace line breaks by U+000A
$contents = [IO.File]::ReadAllText($UserDataSource) -replace "`r`n", "`n"
# create UTF-8 encoding without signature
$utf8 = New-Object System.Text.UTF8Encoding $false
# write the text back
[IO.File]::WriteAllText($UserDataTarget, $contents, $utf8)
}
catch [Exception]
{
echo $_.Exception|format-list -force
}
回答1:
I can't give you an answer on what your Powershell code needs to look like, but in case it helps I can tell you what the output from your Powershell script needs to look like, so you need to confirm that this is what you're ending up with in the UserData when it goes in the template:
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash\n\n",
"apt-get update\n",
"apt-get upgrade\n"
]]}}
来源:https://stackoverflow.com/questions/32916167/bash-script-passed-to-aws-ec2-instance-as-user-data-file-fails-to-load-on-initia