This Jenkins declarative pipeline invokes AWS Lambda for staging and production based on a runtime parameter and optional cron trigger. It assumes an IAM role, executes Lambda invocations with AWS CLI, and sends an email summary when triggered by timer.
Pipeline Behavior
- Manual or scheduled run with
Environmentselector - Separate staging and production stages
- Role assumption via STS before invoking Lambda
- Timer-trigger email summary in
postsection
Jenkins Pipeline (Groovy)
import com.amazonaws.regions.Regions;
import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClient;
import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
import com.amazonaws.services.securitytoken.model.Credentials;
pipeline {
agent {
label 'master'
}
triggers {
cron('0 10 1-7 * 0') // First Sunday of the Month
}
parameters {
choice(name: 'Environment', choices: ['Both', 'Staging', 'Production'], description: 'Pick environment')
}
stages {
stage('Invoke Lambda for Staging') {
when {
expression { params.Environment == 'Both' || params.Environment == 'Staging' }
}
steps {
script {
try {
def functionName = ""
def currentAWSRegion = Regions.getCurrentRegion()?.toString() ?: ''
def roleArn = 'arn:aws:iam:::role/'
def payload = '{"bucket_name":"","extra_args":"--regions "}'
def stagingUrl = ""
AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest()
.withRoleArn(roleArn)
.withRoleSessionName('')
Credentials credentials = new AWSSecurityTokenServiceClient()
.assumeRole(assumeRoleRequest).getCredentials()
sh (script: """set +x
export AWS_ACCESS_KEY_ID=\${credentials.getAccessKeyId()}
export AWS_SECRET_ACCESS_KEY=\${credentials.getSecretAccessKey()}
export AWS_SESSION_TOKEN=\${credentials.getSessionToken()}
aws lambda invoke --function-name \${functionName} --payload '\${payload}' --region \${currentAWSRegion} --cli-read-timeout 300 response_staging.json""", returnStdout: true).trim()
println("Staging REPORT: \${stagingUrl}")
} catch(Exception e) {
println("Exception: \${e}")
echo "Failed"
throw e
}
}
}
}
stage('Invoke Lambda for Production') {
when {
expression { params.Environment == 'Both' || params.Environment == 'Production' }
}
steps {
script {
try {
def functionName = ""
def currentAWSRegion = Regions.getCurrentRegion()?.toString() ?: ''
def roleArn = 'arn:aws:iam:::role/'
def payload = '{"bucket_name":"","extra_args":"--regions "}'
def productionUrl = ""
AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest()
.withRoleArn(roleArn)
.withRoleSessionName('')
Credentials credentials = new AWSSecurityTokenServiceClient()
.assumeRole(assumeRoleRequest).getCredentials()
sh (script: """set +x
export AWS_ACCESS_KEY_ID=\${credentials.getAccessKeyId()}
export AWS_SECRET_ACCESS_KEY=\${credentials.getSecretAccessKey()}
export AWS_SESSION_TOKEN=\${credentials.getSessionToken()}
aws lambda invoke --function-name \${functionName} --payload '\${payload}' --region \${currentAWSRegion} --cli-read-timeout 300 response_production.json""", returnStdout: true).trim()
println("Production REPORT: \${productionUrl}")
} catch(Exception e) {
println("Exception: \${e}")
echo "Failed"
throw e
}
}
}
}
}
post {
always {
script {
def triggeredByTimer = isTriggeredByTimer()
if (triggeredByTimer) {
def subject = "\${currentBuild.currentResult}: Scout Suite Monthly Scan Report"
def body = "
The monthly Scout Suite scan has completed with status: \${currentBuild.currentResult}.
"
body += "
Reports:
"
if (params.Environment == 'Staging' || params.Environment == 'Both') {
body += '
Staging: Staging Report
'
}
if (params.Environment == 'Production' || params.Environment == 'Both') {
body += '
Production: Production Report
'
}
body += '
'
emailext(
to: ''
subject: subject,
body: body,
mimeType: 'text/html'
)
}
}
}
}
}
@NonCPS
def isTriggeredByTimer() {
def buildCauses = currentBuild.rawBuild.getCauses()
return buildCauses.any { cause ->
cause instanceof hudson.triggers.TimerTrigger.TimerTriggerCause
}
}
Operational Recommendations
- Move hardcoded values (role ARN, function names, payload fields) to Jenkins credentials and parameters.
- Add explicit timeout and retry wrappers around AWS CLI calls.
- Store Lambda responses as build artifacts for auditability.
Official Documentation
- Jenkins Pipeline Syntax: https://www.jenkins.io/doc/book/pipeline/syntax/
- AWS CLI Lambda Invoke: https://docs.aws.amazon.com/cli/latest/reference/lambda/invoke.html
