Como usar o Input Transformer para o alvo de regras do CloudWatch SSM Run Command - AWS-RunShellScript

1

Estou tentando executar um script em uma de nossas instâncias sempre que o estado de um contêiner é alterado. Estou criando um destino SSM Run Command com o documento sendo AWS-RunShellScript (Linux)

Eu teria pensado que poderia passar dados do evento para o script, mas não consigo encontrar uma maneira de fazer isso. A maneira que eu pensei que poderia ser feito estava usando um Input Transformer

Caminho de entrada: {"lastStatus":"$.detail.lastStatus"}

Modelo: { "commands":["/path/to/script <lastStatus>"] }

mas recebo o seguinte erro

InputTemplate for target [id] contains placeholder within quotes

Eu estava tentando não adicionar um componente adicional a isso com o Lambda.

    
por Tyler Clendenin 28.03.2018 / 15:14

2 respostas

1

O valor InputTemplate precisa ser uma string JSON válida. Portanto, seu modelo de entrada precisa ter JSON com escape.

Aqui está um exemplo de uma string JSON com escape como um valor JSON (obtido de um evento de alteração de estado de lote aws):

"InputPathsMap": {
    "job_number" : "$.detail.container.environment.JOB_NUMBER",
    "status" : "$.detail.status"
},
"InputTemplate": "\"{ \\"job\\": \\"StatusChangeJob\\", \\"payload\\": { \\"job_number\\": \\"<job_number>\\", \\"status\\": \\"<status>\\" } }\""
    
por 01.04.2018 / 22:28
0

Eu não sei se você acabou descobrindo isso, mas vou postar minha solução para qualquer outra pessoa que se depara com essa pergunta enquanto pesquisa no Google.

Acabei criando um documento de comando personalizado com um parâmetro extra especificamente para o valor em que eu estava interessado. Dessa forma, não precisei citar o espaço reservado ao especificá-lo no modelo, apenas passá-lo diretamente. Exemplo, baseado no documento de comando RunShellScript existente:

{
    "schemaVersion": "2.2",
    "description": "Pass previous status to local script.",
    "parameters": {
        "scriptPath": {
            "type": "String",
            "descripton": "(Required) The absolute path to the local script.",
            "maxChars": 4096
        },
        "lastStatus": {
            "type": "String",
            "description": "The previous status of the container.",
            "maxChars": 100
        }
        "workingDirectory": {
            "type": "String",
            "default": "",
            "description": "(Optional) The path to the working directory on your instance.",
            "maxChars": 4096
        },
        "executionTimeout": {
            "type": "String",
            "default": "3600",
            "description": "(Optional) The time in seconds for a command to complete before it is considered to have failed. Default is 3600 (1 hour). Maximum is 172800 (48 hours).",
            "allowedPattern": "([1-9][0-9]{0,4})|(1[0-6][0-9]{4})|(17[0-1][0-9]{3})|(172[0-7][0-9]{2})|(172800)"
        }
    },
    "mainSteps": [{
        "action": "aws:runShellScript",
        "name": "runShellScript",
        "inputs": {
            "runCommand": [
                "{{ scriptPath }} '{{ lastStatus }}'"
            ],
            "workingDirectory": "{{ workingDirectory }}",
            "executionTimeout": "{{ executionTimeout }}"
        }
    }]
}

Em seguida, você pode definir apenas "lastStatus": "$.detail.lastStatus" no caminho de entrada e {scriptPath: "/path/to/script", "lastStatus": <lastStatus>} (observe a ausência de aspas) no modelo, e você deve estar pronto.

Eu não testei esse arranjo exatamente, mas eu testei um similar (o que eu queria extrair era a hora do evento), e isso funcionou perfeitamente.

    
por 19.05.2018 / 21:51