如何在AWS CLI上使用AWS-RunRemoteScript?

时间:2019-06-17 17:20:12

标签: json amazon-web-services powershell aws-cli

我要做什么

我正在尝试在Windows上使用AWS CLI将PowerShell脚本从GitHub存储库中提取到AWS EC2实例上,然后在该实例上运行该脚本。

我尝试过的事情

我知道转义的双引号(\“)是有效的,因为我尝试了将双引号(\”)无效。我还尝试将--parameters之后的JSON部分放在单独的文件中,然后将该文件加载到命令,但是在这种情况下它抱怨格式化。

我已经在PowerShell和Windows CMD中尝试了该命令(两者的语法不同,即使用双引号)。我在下面列出了这两种版本。

使用AWS EC2控制台,我可以使用图形界面来完成所有这些工作。现在的关键是使它也可以使用命令行工作。

以下是PowerShell的命令:

aws ssm send-command --document-name "AWS-RunRemoteScript" --document-version "1" --targets "Key=instanceids,Values=<INSTANCE-ID>" --parameters '{\"sourceType\":[\"GitHub\"],\"sourceInfo\":{\"owner\":\"<USERNAME>\",\"repository\":\"Projects\",\"path\":\"test_script.ps1\"},\"commandLine\":[\".\\test_script.ps1\"],\"workingDirectory\":[""],\"executionTimeout\":[\"3600\"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region us-east-2

问题似乎来自--parameters参数及其后的JSON。

以下是Git Bash的命令(实际上有效):

aws ssm send-command --document-name "AWS-RunRemoteScript" --document-version "1" --targets "Key=instanceids,Values=<INSTANCE-ID>" --parameters '{"sourceType":["GitHub"],"sourceInfo":["{\"owner\": \"<USERNAME>\", \"repository\": \"Projects\", \"path\": \"test_script.ps1\"}"],"commandLine":[".\\test_script.ps1"],"workingDirectory":[""],"executionTimeout":["3600"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region us-east-2

这是导致的错误:

  

Parameter validation failed: Invalid type for parameter Parameters.sourceInfo, value: OrderedDict([('owner', '<USERNAME>'), ('repository', 'Projects'), ('path', 'test_script.ps1')]), type: <class 'collections.OrderedDict'>, valid types: <class 'list'>, <class 'tuple'>


如何以适当的格式指定这些参数?

3 个答案:

答案 0 :(得分:0)

PowerShell或CMD.exe存在一些JSON解析问题,同一命令在Linux Shell中也可以正常工作:

aws ssm send-command --document-name "AWS-RunRemoteScript" --document-version "1" --targets "Key=instanceids,Values=mi-012dcb3ecea45b678" --parameters '{"sourceType":["GitHub"],"sourceInfo":[" {\n \"owner\":\"<user>\",\n \"repository\":\"<my-repo>\",\n \"path\":\"get-param.ps1\",\n \"getOptions\":\"branch:master\",\n \"tokenInfo\":\"{{ssm-secure:<my-token>}}\"\n }"],"commandLine":["get-param.ps1"],"workingDirectory":[""],"executionTimeout":["3600"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region eu-west-1

我实际上已经与awscli团队打开了这个问题,他们确认了Windows的这种解析限制,请检查:https://github.com/aws/aws-cli/issues/4212#issuecomment-507378423

因此,如果您使用相同的方法来使用json文件中的参数,则可以按照以下步骤进行操作:

使用以下内容创建param.json文件:

{
    "sourceType": [
        "GitHub"
    ],
    "sourceInfo": [
        " {\n \"owner\":\"<user>\",\n \"repository\":\"<repo>\",\n \"path\":\"get-param.ps1\",\n \"getOptions\":\"branch:master\",\n \"tokenInfo\":\"{{ssm-secure:<token>}}\"\n }"
    ],
    "commandLine": [
        "get-param.ps1"
    ],
    "workingDirectory": [
        ""
    ],
    "executionTimeout": [
        "3600"
    ]
}

这时您应该能够运行以下命令:

aws ssm send-command --document-name "AWS-RunRemoteScript" --document-version "1" --targets "Key=instanceids,Values=mi-012dcb3ecea45b678" --parameters file://param.json --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region eu-west-1

这将从cmd.exe和PowerShell中运行

答案 1 :(得分:0)

您总是可以发疯(就像我一样),然后对内容进行两次转义。 参数的值应该是代表json的字符串,该字符串包含一个属性,该属性是代表json的字符串的集合。

我是认真的。

aws ssm send-command --document-name "AWS-RunRemoteScript" --document-version "1" --targets "Key=instanceids,Values=<INSTANCE-ID>" --parameters '{\"sourceType\":[\"GitHub\"],\"sourceInfo\":[\"{\\\"owner\\\":\\\"<USERNAME>\\\",\\\"repository\\\":\\\"Projects\\\"}\"],\"commandLine\":[\".\\test_script.ps1\"],\"workingDirectory\":[""],\"executionTimeout\":[\"3600\"]}' --timeout-seconds 600 --max-concurrency "50" --max-errors "0" --region us-east-2

因此,这里的整个技巧是通过在正确的位置将已转义的反斜杠\\放在已转义的引号\"之前来创建转义的反斜杠。

答案 2 :(得分:0)

使用PowerShell Send-SSMCommand cmdlet,我发现最简单的方法是splatting命令,而不用担心封装和转义(尽可能多)

$mySSMCommand = @{
  ProfileName = 'default'
  DocumentName = 'DocumentName'
  Target = @{Key='InstanceIds'
  Values=@('i-ABCDEFG')}
  Parameter = @{
    sourceType='S3'
    sourceInfo='{"path": "https://bucketbucketbucket.s3-us-west-2.amazonaws.com/somescript.ps1"}'
    commandLine='somescript.ps1 -MyParam "value"'
  }
}

Send-SSMCommand @mySSMCommand