【问题标题】:How to use AWS-RunRemoteScript on AWS CLI?如何在 AWS CLI 上使用 AWS-RunRemoteScript?
【发布时间】:2020-05-09 13:13:23
【问题描述】:

我要做什么

我正在尝试使用 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'>


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

【问题讨论】:

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


    【解决方案1】:

    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

    【讨论】:

      【解决方案2】:

      您总是可以发疯(就像我一样)并双重转义内容。 参数的值应该是一个表示 json 的字符串,该字符串包含一个属性,该属性是表示 json 的字符串集合。

      我是认真的。

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

      所以这里的全部技巧是通过将转义的反斜杠 \\ 放在已经转义的引号 \" 之前的正确位置来创建转义的反斜杠。

      【讨论】:

        【解决方案3】:

        使用 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
        

        【讨论】:

          猜你喜欢
          • 2018-09-22
          • 1970-01-01
          • 2019-10-30
          • 2016-03-25
          • 2023-03-13
          • 2016-11-18
          • 1970-01-01
          • 2018-12-21
          • 2020-09-07
          相关资源
          最近更新 更多