Skip to content

CloudBees' Blog - Continuous Integration in the Cloud
Syndicate content
CloudBees provides an enterprise Continuous Delivery Platform that accelerates the software development, integration and deployment processes. Building on the power of Jenkins CI, CloudBees enables you to adopt continuous delivery incrementally or organization-wide, supporting on-premise, cloud and hybrid environments.
Updated: 5 hours 28 min ago

Announcing the New CloudBees Partner Program

Tue, 07/21/2015 - 16:56
As adoption of Jenkins continues to grow, our ecosystem of resellers, services partners, training partners and technology partners plays a critical role delivering the enterprise-scale Jenkins solutions and complimentary tools our joint customers are seeking. Which is why we are pleased to announce today that we are deepening our commitment to our partner ecosystem through our newly redesigned partner program.
Our redesigned partner program offers greater value to our partner community, ensures that customers seeking enterprise Jenkins solutions have expanded choice from trusted partners and addresses the specific needs of our services partners, resellers and training partners.
As the Enterprise Jenkins company, CloudBees is committed to helping our partners become more successful. Through the delivery of key sales and technical tools, resources, training and content, we will ensure that our partners are positioned to effectively deliver the CloudBees Enterprise Jenkins solutions that enable customers to respond rapidly to the software delivery needs of the business.
The new program expands its scope to include new tracks for reseller and training partners. In addition, for reseller and services partners, there are two participation tiers, Platinum and Gold.
  • Platinum: for partners ready to increase their commitment to delivering Jenkins solutions at enterprise-scale.
  • Gold: for partners looking to ramp up their Jenkins practices. 
All partners will receive enhanced benefits and access to additional resources from CloudBees to drive growth and profitability, uncover new business opportunities and capitalize on growth of Jenkins adoption. Benefits include:
  • Dedicated Partner Managers
  • Software for demo use
  • Partner onboarding and enablement
  • Discounts on classroom training
  • Joint marketing activities
  • Opportunity registration and lead distribution
  • Access to sales and technical assets and tools via a new partner portal (Coming Q3)
We invite you to join our community of partners and take advantage of the opportunities Jenkins presents for you and your customers. Contact the CloudBees partner team to discuss the participation type and tier that best meets your organization's needs. Your partner manager will then provide an agreement and will help get you started with key partner communications and training.

Durga Sammeta, Sr. Director, Global Alliance and Channels, dsammeta@cloudbees.comMichael Anderson, Sr. Partner Manager, manderson@cloudbees.com

Learn more: Visit www.cloudbees.com/partner/joinView the presentation from our July 16 Partner Update
With our partners, we can deliver even greater value to customers. 
Categories: Companies

Template Hierarchies and Using Aux Models to Simplify Template Construction

Fri, 07/17/2015 - 12:37


The blog post will demonstrate how you can simplify your Jenkins Job Templates through creating re-usable models using Auxiliary Templates.

Concepts and DefinitionsBefore we dive into the detail, we will recap on some of the concepts of Templates. The Templates plugin, available with the CloudBees Jenkins Platform, captures the sameness of configuration in multiple places. Administrators define templates of jobs/build steps/publishers and replicate them while creating new jobs. Changes are made in one central location and are reflected in all dependent configurations. The Templates Plugin lets you define four types of template:
  • Job 
  • Folder 
  • Builder 
  • Auxiliary
This post focuses on Auxiliary and Job templates.

Templates are conceptually broken down into a few pieces:ModelA model defines a set of attributes that constitutes a template. Roughly speaking, you can think of this as a class of an object-oriented programming language. For example, if you are creating a template for your organization’s standard process of running a code coverage, you might create a model that has attributes like “packages to obtain coverage”, “tests to run.”AttributeAn attribute defines a variable, what kind of data it represents, and how it gets presented to the users. This is somewhat akin to a field definition in a class definition.
InstanceAn instance is a use of a model. It supplies concrete values to the attributes defined in the template. Roughly speaking, the model-to-instance relationship in the template plugin is like the class-to-object relationship in a programming language. You can create a lot of instances from a single template.
TransformerA transformer is a process of taking an instance and mapping it into the “standard” Jenkins configuration, so that the rest of Jenkins understands this and can execute it. This can be logically thought of as a function.


Structuring TemplatesTypical implementations will consist of multiple templates. Templates can be created for each new requirement, but oftentimes, there is a degree of similarity between the required templates. As with all good system implementations, a little advance planning and ongoing refactoring will pay dividends in the long run.

The Templates plugin provides two mechanisms to reuse previously designed models:
  • Auxiliary Templates
  • Template Inheritance
Template InheritanceTypically you may create a template that performs a typical activity - in this example we assume that the job will need to access a web server running on standard ports. The Model will include the hostname of the server.

We configure the Job Template with the required parameter:




The full config.xml for the job is shown below:

<job-template plugin="cloudbees-template@4.17">
<actions/>
<description>template-web-host</description>
<displayName>template-web-host</displayName>
<attributes>
<template-attribute>
<name>name</name>
<displayName>Name</displayName>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
<template-attribute>
<name>hostname</name>
<displayName>hostname</displayName>
<helpHtml>hostname</helpHtml>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
</attributes>
<properties/>
<instantiable>true</instantiable>
<help>template-web-host</help>
<transformer class="com.cloudbees.workflow.template.WorkflowTransformer" plugin="cloudbees-workflow-template@1.3">
<template><flow-definition/></template>
<sandbox>false</sandbox>
<script>echo "The value of hostname is $hostname"</script>
<scriptSandbox>false</scriptSandbox>
</transformer>
</job-template>

So let’s assume that having done this, we now identify the need for a new Job Template that will access a Web Server on a non-standard port. We could make changes to the original template to add complexity and make it universal, but, we don’t want to do that and risk impacting the existing job instances. We could also just create a brand new Job Template and ignore that the two are related. Duplicating the model definition may not seem a big deal when there is only one attribute, but what if there were many? A better approach is to create a new job that inherits from the previous one - this allows the existing model to be re-used and extended.

We will create a new Job Template. This time, we ensure that the `Super Type` is specified as the previously created Job Template:




We then add our additional attribute:




We now have a full job configuration of:

<job-template plugin="cloudbees-template@4.17">
<actions/>
<description>template-web-host-non-standard-port</description>
<displayName>template-web-host-non-standard-port</displayName>
<attributes>
<template-attribute>
<name>name</name>
<displayName>Name</displayName>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
<template-attribute>
<name>port</name>
<displayName>port</displayName>
<helpHtml>port</helpHtml>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
</attributes>
<properties/>
<superType>
Template examples/Template-Hierarchies/template-web-host
</superType>
<instantiable>true</instantiable>
<help>template-web-host-non-standard-port</help>
<transformer class="com.cloudbees.workflow.template.WorkflowTransformer" plugin="cloudbees-workflow-template@1.3">
<template><flow-definition/></template>
<sandbox>false</sandbox>
<script>
echo "The value of hostname is $hostname" echo "The value of port is $port"
</script>
<scriptSandbox>false</scriptSandbox>
</transformer>
</job-template>

Next we go ahead and create a Job Instance from this new template:


We now have both the original and the new attributes available.

Using the inheritance approach saves the need to duplicate common Model definitions in each Job Template Variant.


Auxiliary ModelsAn alternative to inheriting templates to add further details is to use nested Auxiliary Models.
A nested auxiliary model allows a Model to compose other Models. See the section called “Auxiliary Template”

In this example, we want to model different server types used in a deployment workflow. Both the MySQL and Apache servers extend a base server. This is represented as:



The servers are defined as Auxiliary Templates. We create them using New Item->Auxiliary Template.

Create the Auxiliary TemplatesWe create a new Auxiliary Template called aux-server-base. We add three attributes - hostname, userid and password.

The full config.xml for aux-server-base is:

<com.cloudbees.hudson.plugins.modeling.impl.auxiliary.AuxModel plugin="cloudbees-template@4.17">
<actions/>
<description>aux-server-base</description>
<displayName>aux-server-base</displayName>
<attributes>
<template-attribute>
<name>hostname</name>
<displayName>hostname</displayName>
<helpHtml>hostname</helpHtml>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
<template-attribute>
<name>userid</name>
<displayName>userid</displayName>
<helpHtml>userid</helpHtml>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
<template-attribute>
<name>password</name>
<displayName>password</displayName>
<helpHtml>password</helpHtml>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
</attributes>
<properties/>
<instantiable>true</instantiable>
</com.cloudbees.hudson.plugins.modeling.impl.auxiliary.AuxModel>

We will repeat for aux-apache-server. Ensure that the Super type is set to the base server aux template.




We then add the required extra attribute. The resultant config.xml looks like:

<com.cloudbees.hudson.plugins.modeling.impl.auxiliary.AuxModel plugin="cloudbees-template@4.17">
<actions/>
<description>aux-apache-server</description>
<displayName>aux-apache-server</displayName>
<attributes>
<template-attribute>
<name>httpPort</name>
<displayName>httpPort</displayName>
<helpHtml>httpPort</helpHtml>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
</attributes>
<properties/>
<superType>
Template examples/Template-Hierarchies/aux-server-base
</superType>
<instantiable>true</instantiable>
<help>aux-apache-server</help>
</com.cloudbees.hudson.plugins.modeling.impl.auxiliary.AuxModel>


Repeat for the MySQL-Server. The resultant config.xml looks like:

<com.cloudbees.hudson.plugins.modeling.impl.auxiliary.AuxModel plugin="cloudbees-template@4.17">
<actions/>
<description>aux-mysql-server</description>
<displayName>aux-mysql-server</displayName>
<attributes>
<template-attribute>
<name>mysqlPassword</name>
<displayName>mysqlPassword</displayName>
<helpHtml>mysqlPassword</helpHtml>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
<template-attribute>
<name>mysqlUserid</name>
<displayName>mysqlUserid</displayName>
<helpHtml>mysqlUserID</helpHtml>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
<template-attribute>
<name>mysqlPort</name>
<displayName>mysqlPort</displayName>
<helpHtml>mysqlPort</helpHtml>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
</attributes>
<properties/>
<superType>
Template examples/Template-Hierarchies/aux-server-base
</superType>
<instantiable>true</instantiable>
<help>aux-mysql-server</help>
</com.cloudbees.hudson.plugins.modeling.impl.auxiliary.AuxModel>

Create Job TemplatesTo use the previously created Models in a Job Template, it is necessary to add an Attribute with the type “Nested auxiliary models”. Note the chosen value for Attribute ID will be used to reference the Model in the transformer.


The nested model then needs to be selected from the drop down list. In this instance we will select ‘aux-apache-server’. For now we will select the UI Mode of “Single Value”. I will cover the different modes later in the post.

Transformers access these values as an instance (or as a java.util.List of instances) of auxiliary models. The instance is accessed using the ID allocated to the Nested Auxillary Model in the template definition. In our example this would be apacheHost, so the attributes are accessed as apacheHost.httpPort etc.

Our full config.xml for the Job Template is:
<job-template plugin="cloudbees-template@4.17">
<actions/>
<description>template-deploy-single-apache</description>
<displayName>template-deploy-single-apache</displayName>
<attributes>
<template-attribute>
<name>name</name>
<displayName>Name</displayName>
<control class="com.cloudbees.hudson.plugins.modeling.controls.TextFieldControl"/>
</template-attribute>
<template-attribute>
<name>apacheHost</name>
<displayName>apacheHost</displayName>
<helpHtml>apacheHost</helpHtml>
<control class="com.cloudbees.hudson.plugins.modeling.controls.NestedAuxModelControl">
<itemType>
Template examples/Template-Hierarchies/aux-apache-server
</itemType>
<mode>SINGLE</mode>
</control>
</template-attribute>
</attributes>
<properties/>
<instantiable>true</instantiable>
<transformer class="com.cloudbees.workflow.template.WorkflowTransformer" plugin="cloudbees-workflow-template@1.3">
<template><flow-definition/></template>
<sandbox>false</sandbox>
<script>
echo "apacheHost.hostname : $apacheHost.hostname" echo "apacheHost.userid : $apacheHost.userid" echo "apacheHost.httpPort : $apacheHost.httpPort"
</script>
<scriptSandbox>false</scriptSandbox>
</transformer>
</job-template>


Explanation of the UI ModesNested auxiliary models can have one of 4 different UI modes:

  • Single Value
  • Single Value (choice of all the subtypes of the specified model)
  • List of values
  • List of values, including all subtypes

Single valueThe attribute will hold one and only one value of the specified aux model. The UI will show the configuration of the aux model inline, and the user will not really see that it is a part of another model. This is useful for splitting a common fragment into a separate model and reusing it.

The input will look as follows:


The model attributes are accessed using this style:
apacheHost.hostname

For example, in workflow this looks like:

echo "apacheHost.hostname : $apacheHost.hostname"
echo "apacheHost.userid : $apacheHost.userid"
echo "apacheHost.httpPort : $apacheHost.httpPort"

Single value (choice of all the subtypes of the specified model)The attribute will hold one and only one value, but the type can be any of the instantiable concrete subtypes of the specified aux model (including itself, unless it's abstract.) The user will see a radio button to select one of the possible types.

The input will look as follows:


The model attributes are accessed using this style: host.hostname

It is also possible to determine the Type of the model using attributeid.model.id

Below is a workflow example:

echo "host.hostname : $host.hostname"
echo "host.userid : $host.userid"
if (host.model.id.contains("aux-apache-server")) {
    echo "Type: $host.model.id"
    echo "host.httpPort : $host.httpPort"
}

List of valuesThe attribute will hold arbitrary number of the specific aux model. Example of this is the JDK/Ant/Maven configuration in Jenkins system config page. Users will use add/remove buttons to modify the list.

The input will look as follows:


The model attributes are accessed by iterating through the array. Below is a workflow example:

apacheHosts.each {
    userid=it.userid
    host=it.hostname
    echo "Host: $host, Userid = $userid"
}

List of values, including all subtypesSomewhat like "list of values" above, but you'll specify the base model type (typically abstract one) in the nested model field above, and Jenkins will allow users to instantiate arbitrary concrete subtypes. The UI will show an add button with a drop-down menu, with which users will select the specific subtype to instantiate. An example of this is the tool installer configuration to JDK/Ant/Maven.

The input will look as follows:



The model attributes are accessed by iterating through the array. Below is a workflow example:
hosts.each {
    userid=it.userid
    host=it.hostname
    echo "Host: $host, Userid = $userid"
}

ConclusionThe CloudBees Jenkins Platform provides a rich templating capability that allows job complexity to be abstracted away from users, only exposing the relevant fields that they are required to enter.

The ability to extract out a hierarchy of common Models enables the template developer to re-use the definitions efficiently across many individual Job Templates and enforces standardised naming and usage patterns.

ReferencesTemplate plugin user manual
Categories: Companies

Jenkins Workflow - Creating a Class to Wrap Access to a Secured HTTP Endpoint

Tue, 07/14/2015 - 14:40
This blog post will demonstrate how to access an external system using HTTP with form-based security. This will show how you can use the following features:
  • Jenkins Workflow plugin
  • Groovy built-in libraries such as HttpClient
  • Git-based Workflow Global Library repository
Getting StartedRequirements
  1. JDK 1.7+
  2. Jenkins 1.609+
  3. An external system secured with form-based authentication - e.g., a Jenkins server with security enabled and anonymous access rescinded
Installation
  1. Download and install JDK 1.7 or higher
  2. Download and install Jenkins
  3. Start Jenkins
Setup Jenkins
  • Update plugins - Make sure you have the latest Workflow plugins by going to Manage Jenkins –> Manage Plugins -> Updates and selecting any Workflow-related updates. Restart Jenkins after the updates are complete. As of this writing the latest version is 1.8.
  • Global libraries repo - Jenkins exposes a Git repository for hosting global libraries meant to be reused across multiple CD pipelines managed on the Master. We will setup this repository so you can build on it to create your own custom libraries. If this is a fresh Jenkins install and you haven’t setup this Git repository, follow these instructions to setup.


Important - Before proceeding to the next steps, make sure your Jenkins instance is running

See Workflow Global Library for details on how to set up the shared library - note that if security is enabled, the ssh format works best.If using ssh ensure that your public key has been configured in Jenkins. To initialise the git repository:

git clone ssh://<USER>@<JENKINS_HOST>:<SSH_PORT>/workflowLibs.git
Where
  • USER is a user a valid user that can authenticate
  • JENKINS_HOST is the DNS name of the Jenkins server you will be running the workflow on. If running on the CloudBees Jenkins platform, this is the relevant client master not the Jenkins Operations Center node.
  • SSH_PORT is the ssh port defined in Jenkins configuration:

Screen Shot 2015-07-09 at 09.15.36.png

Note the repository is initially empty.
To set things up after cloning, start with:
git checkout -b master

Now you may add and commit files normally. For your first push to Jenkins you will need to set up a tracking branch:

git push --set-upstream origin master

Thereafter it should suffice to run:

git push

Creating a Shared Class to Access JenkinsCreate a class in the workflow library:

cd workflowLibs
mkdir -p src/net/harniman/workflow/jenkins
curl -O \
https://gist.githubusercontent.com/harniman/36a004ddd5e1c0635edd/raw/3997ddab0ab571c902068afad60cbc56eeda07cb/Server.groovy
git add *
git commit
git push
This will make the following class

net.harniman.workflow.jenkins.Server
available for use by workflow scripts using this syntax:

def jenkins=new net.harniman.workflow.jenkins.Server(<parameters>)
and methods accessed using:

jenkins.logon()
jenkins.getURL(<supplied url>)
Note:
  • Classes follow the usual Groovy package naming formats and thus need to be in the appropriate directory structure
  • It is unnecessary to go out of process to access this Jenkins instance - it can be accessed from Groovy via the Jenkins model, however, this is to show how a client for form-based access could be built
  • The below script is built to access Jenkins as an example for demonstration

This is the actual contents of Server.groovy:

package net.harniman.workflow.jenkins


import org.apache.commons.httpclient.Header
import org.apache.commons.httpclient.HostConfiguration
import org.apache.commons.httpclient.HttpClient
import org.apache.commons.httpclient.NameValuePair
import org.apache.commons.httpclient.methods.GetMethod
import org.apache.commons.httpclient.methods.PostMethod
import org.apache.commons.httpclient.cookie.CookiePolicy
import org.apache.commons.httpclient.params.HttpClientParams


class Server {
String user
String password
String host
Integer port
String proto
HttpClient client = new HttpClient()

Server(String user, String password, String host, Integer port, String proto) {
this.user = user
this.password=password
this.host=host
this.port=port
this.proto=proto
client.getHostConfiguration().setHost(host, port, proto);
client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
}
HttpClient getHttpClient() {
return client
}
Integer logon() {
String logonInitiationURL = proto + "://" + host + ":" + port + "/login?from=%2F"
String logonSubmitURL = proto + "://" + host + ":" + port + "/j_acegi_security_check"


// We need to make a call first to set up the session
// HttpClient will automatically handle cookies based on the
// CookiePolicy set above
GetMethod get = new GetMethod(logonInitiationURL)
client.executeMethod(get);
get.releaseConnection()
PostMethod authpost = new PostMethod(logonSubmitURL)


def json='{"j_username": "'+user+'", "j_password": "'+password+'", "remember_me": false, "from": "/"}'


def param1=new NameValuePair("j_username", user)
def param2=new NameValuePair("j_password", password)
def param3=new NameValuePair("from", "/")
def param4=new NameValuePair("json", json)
def param5=new NameValuePair("Submit", "log in")


authpost.addParameters(param1)
authpost.addParameters(param2)
authpost.addParameters(param3)
authpost.addParameters(param4)
authpost.addParameters(param5)


client.executeMethod(authpost)

// We need to follow the redirect to understand whether authentication
// was successful
// 200 = Success
// 401 = Credentials failure

Header header = authpost.getResponseHeader("location");
def response
if (header != null) {
String newuri = header.getValue();
if ((newuri == null) || (newuri.equals(""))) {
newuri = "/";
}
GetMethod redirect = new GetMethod(newuri);
client.executeMethod(redirect);
response=redirect.getStatusCode()
redirect.releaseConnection()
}
authpost.releaseConnection()
return response
}


String getURL(String URL) {
GetMethod get = new GetMethod(URL)
client.executeMethod(get)
def body = get.getResponseBodyAsString()
get.releaseConnection()
return body
}

}
Creating the workflowCreate a new workflow job with the Workflow Definition as follows:

stage "Initialise"
def jenkins = new net.harniman.workflow.jenkins.Server("annie.admin","password", "jenkins.beedemo.local", 80, "http" )


def response


stage "Logon"
response = jenkins.logon()
echo "Response = $response"


stage "Query"
response = jenkins.getURL("http://jenkins.beedemo.local/roles/whoAmI")
echo "Response = $response"


Ensure you substitute in real values for:
  • <USERID>
  • <PASSWORD>
  • <HOST>
  • <PORT>
  • <JENKINS_HOST>
You can substitute in the required URL for the query - for instance, it could be <jobname>/config.xml to retrieve a job’s config. Run the Job Time to check that it all works, so go ahead and trigger the build. When you run the job you should see each stage being processed, the stage name output in the logs and shown in the list of running steps. If you have CloudBees Enterprise workflow extensions then you will also have a Stage View output like below: Screen Shot 2015-07-09 at 15.59.01.png

If it works successfully you should see the raw body of the response printed in the console log.
A successful authentication results in
Response = 200
being printed in the console log. Anything else indicates a failure with the Logon step. Conclusion The Workflow Global Library provides the ability to share common libraries (Groovy scripts) across many workflow jobs to help keep workflows DRY.

In this instance, we have also shown how the built-in Groovy libraries can be used to simplify making calls to external systems. These could be configuration databases, ticketing platforms or custom deployment tools. The underlying Groovy libraries can be leveraged to implement complex capabilities such as handling authentication, following redirects, etc. The advantage of using groovy rather than using command line tools from say an `sh` step, is that you have the option perform the logic outside of a `node` block. When executing inside a `node` block, an executor is allocated/consumed, whereas code outside the node block runs as a flyweight task and does not consume an executor. References HttpClient Examples
Jenkins Workflow - Getting Started by Udaypal Aarkoti
Categories: Companies

Continuous Delivery with CloudBees Jenkins Platform and AWS Lambda

Mon, 07/06/2015 - 11:52
Last month, CloudBees announced its CloudBees Jenkins Platform now runs on AWS. The extension is a new level of integration that enables customers to easily install the CloudBees Jenkins Platform and run it on Amazon Web Services’ EC2 cloud service.

Building off this initial integration, CloudBees and AWS are actively working to rollout additional integration points - the latest of which being the integration with AWS Lambda. This blog will present how to implement a continuous delivery pipeline with Jenkins and AWS Lambda service.

AWS LambdaAWS Lambda is a new service (Nov 2014) proposed by AWS to help implement event driven architectures on the cloud such as:
  • Transforming data as it reaches the cloud,
  • Perform notification, audit and analysis,
  • Start workflows.
AWS Lambda function can be written in javascript/Node.js and Java languages.

The new style of programming introduced by AWS Lambda requires new best practices to build, test and deploy these services.

Let's implement a continuous delivery pipeline for AWS Lambda using CloudBees Jenkins Platform and the CloudBees AWS CLI Plugin for Jenkins.

We will use the CreateThumbnail sample described in AWS Lambda Walkthrough 2: Handling Amazon S3 Events Using the AWS CLI (Node.js). The source code is available at https://github.com/CloudBees-community/aws-lambda-create-thumbnail.

AWS Lambda function CreateThumbail.js
Jenkins project to build, test and deploy an AWS Lambda functionCloudBees Jenkins Platform
Jenkins ProjectCreate a Freestyle project named "aws-lambda-create-thumbnail".


Source code configurationIn the "Source Code Management" section, select "Git" enter the repository URL "https://github.com/CloudBees-community/aws-lambda-create-thumbnail.git"

Git configuration








AWS CLI ConfigurationIn the "Build Environment" section, tick the "Setup AWS CLI".
Define the desired set of credentials and AWS region.

AWS CLI configuration in Jenkins




If the desired credentials are not yet created, click on the "Add" button of the field "API credentials".
In the "Add Credentials" screen, select the kind "Amazon Web Services Basic Credentials", enter the Access Key ID and the Secret Access Key and then click on "Add".
Please note that you can also access the advanced configuration to define a human readable ID for the created Jenkins credentials and help readability when using Jenkins workflow.

Add AWS credentials








Build steps and AWS CLIFor this Node.js function demo, we will use a build automation based on simple shell scripts rather than on a specific build framework.

In the Build section, click on "Add build step" and select "Execute shell".

The aws-lambda-create-thumbnail project contains a "build" script to package the Node.js function. Invoke this build script in the command.
# BUILD
./build

Once the AWS Lambda function is packaged, we upload it to AWS Lambda invoking the AWS CLI command "aws lambda update-function-code":
# UPLOAD AMAZON LAMBDA FUNCTION TO AWS
aws lambda update-function-code \
--region us-east-1 \
--function-name CreateThumbnail \
--zip-file file://./target/CreateThumbnail.zip

It is time now to test the deployed function using the AWS CLI "aws lambda invoke":
# TEST AMAZON LAMBDA FUNCTION ON AWS
aws lambda invoke \
--invocation-type Event \
--function-name CreateThumbnail \
--payload file://./src/test/input.json \
target/test-outputfile.json

Build shell steps and AWS CLI invocations










Creating an AWS Lambda functionIt is time to create the AWS Lambda function if it doesn't already exists.
AWS Lambda FunctionIn AWS Management Console, create an AWS Lambda function named "CreateThumbnail":
New AWS Lambda function








Lambda function code with Node.jsSelect the Runtime type Node.js, you can keep the Code entry type and Code template to their default values Edit code inline and Hello World.
Define the handler to CreateThumbnail.handler as defined in CreateThumbnail.js.
Select the Role IAMLambdaExecute as defined in AWS Lambda Walkthroughs (Node.js) » ... » Step 2.2: Create an IAM Role (execution role) (Amazon S3 Events).
AWS Lambda function code












AWS Lambda Function creationWe can now create the function clicking on Create Lambda function:
Create Lambda function




The AWS Management Console renders a dashboard of the function with valuable graphs and logs:
AWS Management Console dashboard for AWS Lambda functions












ConclusionIn this blog we have shown you how easy it is to create a continuous delivery pipeline to continuously build, test and deploy an AWS Lambda service with CloudBees Jenkins Platform and the CloudBees AWS CLI Plugin.

The CloudBees AWS CLI plugin is intended to be the Swiss Army knife to automate from a Jenkins job any action on an AWS infrastructure such as:
  • Copy generated artifacts to Amazon S3
  • Deploy a new version of an AWS Elastic Beanstalk application
  • Restore a snapshot of an Amazon RDS database before a test
  • Create an ephemeral environment (EC2, RDS ...) to run an integrated test

Resources
Categories: Companies