Bash 作为用户数据文件传递给 AWS EC2 实例的脚本无法在初始启动时加载

Bash script passed to AWS EC2 Instance as User Data file fails to load on initial boot

我有一个简单的 bash 脚本,我正尝试使用 AWS 库通过 Powershell 脚本传递给 AWS EC2 ubuntu 实例。

#!/bin/bash

apt-get update
apt-get upgrade

这是对文件内容进行 base64 编码并调用启动 EC2 实例的 cmdlet 的 powershell 脚本:

$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

这是来自云初始化日志的片段:

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

这是在 /var/lib/cloud/instance/scripts/part-001 的 ubuntu 实例上加载的用户数据脚本的片段:

#!/bin/bash  apt-get update apt-get upgrade

我尝试使用 010 Editor 和 Cygwin 将 windows 文件转换为 linux。我试过用 LF 字节替换 CRLF 字节。结果是一样的:整个 bash 脚本被压缩为 1 行,所有换行符都被删除,用户数据脚本在初始启动时加载失败。

更新:我已经包含了我用来进行换行符转换的两个代码片段。两者都经过同行来源 (SO) 的审查。出于某种原因,脚本仍然显示在 linux 实例中,没有换行符。

片段 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)

片段 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
}

我无法回答您的 Powershell 代码需要是什么样子,但如果有帮助,我可以告诉您 Powershell 脚本的输出需要是什么样子,所以您需要确认这是您在模板中进入 UserData 时最终得到的结果:

"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
            "#!/bin/bash\n\n",
            "apt-get update\n",
            "apt-get upgrade\n"
        ]]}}