Jenkins文件中的“sh”命令是否启动新会话或新shell?

epggiuax  于 2023-02-03  发布在  Jenkins
关注(0)|答案(1)|浏览(181)

我观察到一个场景,当我写Jenkinsfile时,首先在AWS上验证一个会话,然后将一个dockerfile推送到指定的ECR。下面的代码块工作正常,并将图像推送到ECR:

stage('build and push images') {
            steps {
                sh """
                sh assume_role.sh
                source /tmp/${assume_role_session_name}
                aws ecr get-login --region ${aws_region} --registry-ids ${ROLEARN} --no-include-email
                docker build -t my-docker-image .  
                docker tag my-docker-image:latest ${ROLEARN}.dkr.ecr.${aws_region}.amazonaws.com/${ECR_name}:${ECS_TAG_VERSION}
                docker push ${ROLEARN}.dkr.ecr.${aws_region}.amazonaws.com/${ECR_name}:${ECS_TAG_VERSION}
                docker rmi -f my-docker-image:latest
                """
            }
        }

但是,当我用单独的sh命令划分每个步骤时(如下所示),docker push失败了,因为Jenkins代理还没有经过身份验证,这意味着身份验证令牌没有传递到docker push命令行。

stage('build and push images') {
            steps {
                sh "assume_role.sh"
                sh "source /tmp/${assume_role_session_name}"
                sh "aws ecr get-login --region ${aws_region} --registry-ids ${ROLEARN} --no-include-email"
                sh "docker build -t my-docker-image . "
                sh "docker tag my-docker-image:latest ${ROLEARN}.dkr.ecr.${aws_region}.amazonaws.com/${ECR_name}:${ECS_TAG_VERSION}"
                sh "docker push ${ROLEARN}.dkr.ecr.${aws_region}.amazonaws.com/${ECR_name}:${ECS_TAG_VERSION}"
                sh "docker rmi -f my-docker-image:latest"
            }
        }

因此,我怀疑每个sh都在Jenkins步骤中启动一个新会话,在这两个步骤之间,认证令牌无法通过,我不知道我的猜测是否正确,以及如何找到证据来支持我的猜测。

a1o7rhls

a1o7rhls1#

我想我应该分享一下我的解决方案,告诉大家我是如何克服在每个sh块中重复承担角色这一恼人的需求的,将提取的凭据(当然是动态的)作为环境变量传递给我解决了这个问题,并且不需要在不同的脚本中再次重新进行身份验证。
将凭据添加到环境变量会强制每个脚本使用它们。

environment {
    ACCESS = sh(
        returnStdout: true, 
        script: ''' 

            echo "$(aws \
                sts assume-role \
                --role-arn="arn:aws:iam::\${AWS_ACCOUNT_DEV}:role/\${ASSUME_ROLE}" \
                --role-session-name="jenkins" \
                --output json
            )" 

            '''
        ).trim()

}

stages{
    stage('Create env variables') {
        steps {
            script { 
                env.AWS_ACCESS_KEY_ID  = sh(
                    returnStdout: true, 
                    script: '''

                        echo "${ACCESS}" | jq -re '.Credentials.AccessKeyId' 

                    '''
                ).trim()

                env.AWS_SECRET_ACCESS_KEY  = sh(
                    returnStdout: true, 
                    script: '''

                        echo "${ACCESS}" | jq -re '.Credentials.SecretAccessKey'
                        
                    '''
                ).trim()

                env.AWS_SESSION_TOKEN  = sh(
                    returnStdout: true, 
                    script: '''

                        echo "${ACCESS}" | jq -re '.Credentials.SessionToken'
                        
                    '''
                ).trim()
            }
        }
    }
}

对于您的问题,this StackOverflow answer描述了sh执行中设置的环境变量会发生什么。
希望这有帮助;)

相关问题