Jenkins pipeline for running AWS Lambda manually and with trigger

devops-cicd

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 Environment selector
  • Separate staging and production stages
  • Role assumption via STS before invoking Lambda
  • Timer-trigger email summary in post section

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

Leave a Reply

Your email address will not be published. Required fields are marked *

โ˜• Support us ยท ๐Ÿ’ณ Monobank