Serverless web app using AWS Lambda

One of the most interesting trends I’ve come across recently is Serverless compute. That is, running your custom code in the cloud without the need to provision or maintain a server to run it on.

To lean more about this I decided to build a webapp using AWS Lambda. I wanted a bit more than the typical “Hello World”, something I could show doing useful work rather than just returning a hard coded string. But I also didn’t want to spend time developing an app when this is not really about that.

So I settled on building a Subnet Calculator (something close to my heart working for an ISP). It’s super-simple, but useful enough that I’m going leave it up (unless the AWS bill gets too much!).

The basic design is:

  • A single page HTML and Javascript app as the front end, hosted on AWS S3,
  • This makes calls to the AWS API Gateway,
  • Which invokes the AWS Lambda function. [IMAGE]

Step One: The Lambda Function

Setting up the actual Lambda function was actually the easiest part of this whole exercise: In the AWS console go to Lambda in the Compute section, click the Create function button. Give the function a name and chose which runtime to use. Lambda supports a few languages, I used Python 3.6 for this project. Finally either create a new IAM role or select an existing role with permissions to execute Lambda functions.

Now you write the code you want to execute when the function is triggered. If you need to use third party libraries or other dependencies, you can package these all up together as a zip file and upload it (there are good instructions for this here). Or you can just write directly into the online code editor (which is actually pretty good).

Over-engineering a simple blog with Jenkins

Like many IT professionals exploring new technology, I am trying it out on a personal project before using it in production. I have heard about the CI/CD tools like Jenkins, Travis, Bamboo, but never had the chance to use them.

So I decided to start a blog about my DevOps journey, beginning with building a Jenkins server and using it build my code then deploy it to AWS as the web host.

Jenkins is the focus of this post, so I will not dwell on the other coponents of this deployment, but in short they are:

  • CentOS 7.4
  • Jekyll 3.7 (and associated Ruby dependencies)
  • Amazon Web Services (Route 53 and S3)

Step 1: Installing Jenkins

Starting will a minimal install of CentOS, first install Java and wget

sudo yum install java-1.8.0 wget

Add the Jenkins repo and import the keyfile

sudo wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
sudo rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key

Install, enable and start Jenkins

sudo yum install -y jenkins
sudo systemctl enable jenkins
sudo systemctl start jenkins

Open the port Jenkins uses on the firewall

sudo firewall-cmd --zone=public --add-port=8080/tcp
sudo firewall-cmd --reload

Step 2: Configuring Jenkins

Login to the Jenkins interface running on the server just installed using port 8080

http://<your-ip-address>:8080

The initial admin password is set automatically during installation and can be found in the Jenkins user home directory

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

Follow the first use wizard, installing the suggested plugins and creating an admin user when prompted You can now login to Jenkins to really get started!

First we need to install a plugin so Jenkins can upload the site to AWS S3.

  1. In the Jenkins menu choose Manage Jenkins and then select Manage Plugins.
  2. Click on the Available tab then search for “S3”.
  3. Select the S3 publisher plugin then click the Download now and install after restart button.
  4. It will now start installing, Check the box labelled Restart Jenkins when installation is complete and no jobs are running.
  5. Jenkins will restart and the plugin can now be used.

Next configure Jenkins to use an AWS account with access to the S3 bucket.

  1. In the Jenkins menu choose Manage Jenkins and then select Configure System.
  2. Scroll down to the section Amazon S3 profiles.
  3. Add a profile, specifing the Access key and Secret key for the AWS account with access to the S3 bucket.

Step 3: Create the Jenkins pipeline

  1. Click New Item enter a name for the project, select Freestyle project and click the OK button
  2. Scroll down to Build, click the Add build step button and choose Execute shell
  3. In the Command box, enter the build script to run:
    ~/.rvm/gems/ruby-2.4.1/wrappers/jekyll build --source ~/pixyll/
  4. Scroll down to Post-build Actions, click the _Add post-build action button and choose Publish artifacts to S3 Bucket.
  5. Enter the Source for the files to upload
    _site/**/*
  6. Enter the Destination bucket
    pmcwhite.co.uk
  7. Select the correct AWS region for the S3 bucket and check the No upload on build failure option.
  8. Click the Save button.

Step 4: Run the Build

Click on the Build now icon and the build will run. It will compiles the Jekyll code, then uploads the resulting website to AWS, which you are viewing now :)

From the Jenkins project page, you can chose a build from the Build History and then click on Console Output to see the results of the run. This is especially useful if the build failed. Jenkins Console Output In this example the build failed due to an error with the build script (Due to the way RVM works you need to specify the whole path the script, but for reasons that escape me, “bin” on the real path needs to be replaced with “wrapper”.)