Search code examples
groovyaws-cli

Groovy Script Returns empty list for AWS ec2 describe-instances


I am trying to fetch the ec2 instance id along with instance name(from ec2 tag 'Name' which mentioned the app name) and trying to return this combination separated with '_'. I am able to get this details quite fine from the AWS CLI on shell but when using the same aws cli command in Groovy Script, I am getting empty list

Groovy Script

import java.util.logging.LogManager
import java.util.logging.Level
import jenkins.model.Jenkins

def env = System.getenv()
logger.log(Level.INFO,"AWS Account is: "+aws_account)
logger.log(Level.INFO,"Region is: "+regions)
def output = []

try {
logger.log(Level.INFO,"Region is: "+"${regions}")
def command = "/usr/local/bin/aws ec2 describe-instances --profile ${aws_account} --region ${regions} --query [Reservations[*].Instances[*].{InstanceId:InstanceId,Tags:Tags[?Key == `Name`] | [0].Value}] --output text | tr '\t' '_'"


println("Command is: "+command)
def proc = command.execute()
proc.waitFor()
output = proc.in.text.tokenize()

}
catch(Exception e) {
  logger.log(Level.SEVERE, e.getMessage(), e)
}
if(output.size() == 0)
  throw new Exception("No instances found")

return output

Output received from AWS CLI Command directly from shell

i-0XXXXXXXXXXXXXXX1_app-11
i-0XXXXXXXXXXXXXXX2_app-21
i-0XXXXXXXXXXXXXXX3_app-prd-11
i-0XXXXXXXXXXXXXXX4_app-poc-11

Solution

  • You are not catching stderr. There could be an error message.

    Use this approach:

    Curl request from command line and via Groovy script

    And to use pipe you should run shell/bash

    The code for bash:

    def command = "...some shell command..."
    def output = ['bash', command ].execute().with{
        def stdout = new StringWriter()
        def stderr = new StringWriter()
        //wait for process end and catch stderr and stdout 
        it.waitForProcessOutput(stdout, stderr)
        //check there is no error
        assert stderr.toString().size()==0: stderr
        //assert it.exitValue()==0 //or we can do check by error code
        //return stdout from closure 
        return stdout.toString()
    }