2

I am using Jenkins Declarative Pipeline for a serverless application. Trying to abstract logic by creating functions. But I am stuck at referencing the function variable 'stackname' when execute the command 'sam deploy --template-file packaged.yaml --stack-name stackname'.

A TLDR version of my code is below:

    stages {
        stage('Deploy') {
            steps {
                echo '[STAGE] Deploying...'
                //switch to each lambda sub-folder as working directory
                dir ("${env.WORKSPACE}") {
                    deployAllProject("my-test-stack")
                }
            }
        }
    }

/*
 * Deploy lambda functions
*/
void deployAllProject(stackname){
    sh 'sam package  --output-template-file packaged.yaml --s3-bucket my-lambda-midway'
    sh 'sam deploy --template-file packaged.yaml --stack-name stackname'
}

I have tried to different variable syntax eg. $stackname, ${stackname}, also tried to enclosed inside a Script block. Here is a more complete version of the code:

def LAMBDA_BUILD_LIST = "dailybackup-ebs-volumes,dailybackup-ebs-volumes-test"
def CLOUDFORMATION_STACK = "DEVOPS-serverless-apps"
def LAMBDAS

pipeline {

    agent {
        node {
            label 'docker'
        }
    }

    stages {
        //checkout scm in defined through Jenkins console

        stage('Init'){
            steps {
                echo "[STAGE] Init..."

                script {

                    // init variables
                    LAMBDAS = splitStringWithComma(LAMBDA_BUILD_LIST)

                    // check lambda sub-folders exist
                    for(String lambda: LAMBDAS) {
                        def var_lambda_dir = "${env.WORKSPACE}/${lambda}"
                        if (!fileExists(var_lambda_dir)) {
                            println("[WARNING]"+ var_lambda_dir +" does not exist.")
                        }
                    }
                }
            }
        }
        stage('Build') {
            steps {
                echo '[STAGE] Building...'

                script {
                    for(String lambda: LAMBDAS) {
                        println("lambda is:"+lambda)
                        def var_lambda_dir = "${env.WORKSPACE}/${lambda}"

                        //switch to each lambda sub-folder as working directory 
                        dir (var_lambda_dir) {
                            buildNodejsProject()
                        }
                    }
                }
            }
        }
        stage('Deploy') {
            steps {
                echo '[STAGE] Deploying...'
                //switch to each lambda sub-folder as working directory
                dir ("${env.WORKSPACE}") {
                    //TODO change hardcoded to variable 'CLOUDFORMATION_STACK'
                    deployAllProject("my-test-stack")
                }
            }
        }
    }
}

/*
 * Transform a comma delimited String into a String list/array
*/
def splitStringWithComma(projects){
    println ("splitStringWithComma() - result: "+projects.split(","))

    return projects.split(",")
}

/*
 * Build lambda functions
*/
void buildNodejsProject(){
    sh 'npm prune'
    sh 'npm install'
}

/*
 * Deploy lambda functions
*/
void deployAllProject(stackname){
    sh 'sam package  --output-template-file packaged.yaml --s3-bucket my-lambda-midway'
    sh 'sam deploy --template-file packaged.yaml --stack-name stackname'
}

I think I must have overlooked some fundamental syntax, but just couldn't figure out the correct keyword for that. Please recommend me a good way to handle the variable, and point me the official doc section I should be looking at. Thanks in advance for the help !!

GreenLake4964
  • 744
  • 9
  • 20

1 Answers1

0

I found a post that help me to resolved the issue. How to pass variables from Jenkinsfile to shell command

But I still don't know what are the core differences between the one I wrote earlier and the workable solution that I use as below.

Thanks for ppl reading this post. If you have better workarounds or can point me to the doc that I should read, I will up vote !! TA

/*
 * Deploy lambda functions
*/
void deployAllProject(stackname){
    sh 'sam package  --output-template-file packaged.yaml --s3-bucket bc-lambda-midway'
    sh """
        sam deploy --template-file packaged.yaml --stack-name ${stackname}
    """
}
GreenLake4964
  • 744
  • 9
  • 20
  • 3
    It might be the wrapping of the command with a single quote vs. double quotes that allow resolution of variables wrapped with `${var}`. – Eldad Assis Jan 16 '19 at 07:11
  • **INSANELY**, the single quote versus double quote was the solution. When I switched the `sh(returnStdout: true, script: '...')` to `sh(returnStdout: true, script: "...")` it WORKED! This is counterintuitive because in shell the _literal_ substitution shows up literally and in Jenkins it shows up as _empty_. – ingyhere Oct 28 '20 at 05:48