Search code examples
shelljenkinsgroovyjenkins-pipelinejenkins-groovy

A variable iterated from an array in Jenkins Groovy script is not showing its value inside a shell command


Inside my Groovy scripted Jenkins pipeline I have the following function:

def getEarliestLaunchTime(asg_name, aws_region) {
    def asg_instance_ids = sh (
    script: "aws --region $aws_region autoscaling describe-auto-scaling-instances --query 'AutoScalingInstances[?AutoScalingGroupName==`$asg_name`]' | jq -r '.[].InstanceId'",
    returnStdout: true
    ).trim().split('\n')
    print "ASG Instance IDs: $asg_instance_ids"

    for (instance_id in asg_instance_ids) {
        print "instance_id: ${instance_id}"

        def instance_launch_time = sh(script: '''
            launch_time=$(aws --region "${aws_region}" ec2 describe-instances --instance-ids "${instance_id}" --query 'Reservations[].Instances[].LaunchTime' --output text)
            launch_time_sec=$(date -d "$launch_time" +%s)
            echo "$launch_time,$launch_time_sec"
        ''', returnStdout: true).trim().split(',')

        // other commands
    }
    // other commands
}

Here are the console logs from this function:

23:38:36  [Pipeline] sh
23:38:37  + aws --region us-east-1 autoscaling describe-auto-scaling-instances --query AutoScalingInstances[?AutoScalingGroupName==`dev-fo-energy-bkr-blue-asg`]
23:38:37  + jq -r .[].InstanceId
23:38:38  [Pipeline] echo
23:38:38  ASG Instance IDs: [i-03fb5a1504a7ffb91, i-042f40358287d1745]
23:38:38  [Pipeline] echo
23:38:38  instance_id: i-03fb5a1504a7ffb91
23:38:38  [Pipeline] sh
23:38:38  + aws --region us-east-1 ec2 describe-instances --instance-ids  --query Reservations[].Instances[].LaunchTime --output text
23:38:39  
23:38:39  An error occurred (MissingParameter) when calling the DescribeInstances operation: The request must contain the parameter InstanceId
23:38:39  + launch_time=

From the logs, I can see that the istance_id is getting a value from the array instance_ids, but it is showing empty, inside the shell script command def instance_launch_time = sh(script: '''... ...'''). This shell script is using the other variable aws_region passed in to the function with no issue though.

What is wrong here and how can I make this working?


Solution

  • The syntax ''' denotes a multi-line literal string. You need a multi-line interpolated string which is indicated by the """ syntax, and to escape shell variables' $ syntax characters to avoid interpretation by Groovy:

    def instance_launch_time = sh(script: """
      launch_time=\$(aws --region "${aws_region}" ec2 describe-instances --instance-ids "${instance_id}" --query 'Reservations[].Instances[].LaunchTime' --output text)
      launch_time_sec=\$(date -d "\$launch_time" +%s)
      echo "\$launch_time,\$launch_time_sec"
    """, returnStdout: true).trim().split(',')