ssm automation document input in AWS-RunShellScript not substituting variable

Viewed 1016

I am trying to run a command in bash where part of the command is substituted from a variable that I created in a previous step, however the string substitution is not working. I have tried many variations of this with single, double quotes, etc but cant not get it to work.

mainSteps:
  - name: getIps
    action: 'aws:invokeLambdaFunction'
    timeoutSeconds: 1200
    maxAttempts: 1
    onFailure: Abort
    inputs:
      FunctionName: Automation-GetIPs
      Payload: '{"asg": "Staging_web_ASG"}'
    outputs:
      - Name: asg_ips
        Selector: $.Payload.IPs
        Type: StringList
  - name: updatelsync
    action: 'aws:runCommand'
    timeoutSeconds: 1200
    inputs:
      DocumentName: AWS-RunShellScript
      InstanceIds:
        - '{{ InstanceID }}'
      Parameters:
        commands:
          - 'echo {{getIps.asg_ips}} > /root/asg_ips.test'

In the above code. I set asg_ips in step1 who's OutputPayload is as follows :

{"Payload":{"IPs": ["172.xx.x.xxx", "172.xx.x.xxx"]},"StatusCode":200}

but for input in the 2nd step, it shows as follows...

{"commands":["echo {{getIps.asg_ips}} > /root/asg_ips.test"]}

I need to get it to show something like this...

{"commands":["echo ["172.xx.x.xxx", "172.xx.x.xxx"] > /root/asg_ips.test"]}
1 Answers

Based on the comments.

The issue was caused by incorrect use of outputs in aws:invokeLambdaFunction SSM action. Specifically, the lambda action does not have outputs attribute as shown in the linked documentation:

name: invokeMyLambdaFunction
action: aws:invokeLambdaFunction
maxAttempts: 3
timeoutSeconds: 120
onFailure: Abort
inputs:
  FunctionName: MyLambdaFunction

In contrast, as a side note, outputs attribute is valid in aws:executeAwsApi.

Therefore, the solution is to directly refer to the Payload returned by the lambda action:

mainSteps:
  - name: getIps
    action: 'aws:invokeLambdaFunction'
    timeoutSeconds: 1200
    maxAttempts: 1
    onFailure: Abort
    inputs:
      FunctionName: Automation-GetIPs
      Payload: '{"asg": "Staging_web_ASG"}'
  - name: updatelsync
    action: 'aws:runCommand'
    timeoutSeconds: 1200
    inputs:
      DocumentName: AWS-RunShellScript
      InstanceIds:
        - '{{ InstanceID }}'
      Parameters:
        commands:
          - 'echo {{getIps.Payload}} > /root/asg_ips.test'

The side effect is that now asg_ips.test needs to be post-processed to get the IP ranges values.

Related