aws Archives - Stackify Thu, 16 May 2024 11:45:19 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.4 https://stackify.com/wp-content/uploads/2023/02/favicon.png aws Archives - Stackify 32 32 AWS Fargate Monitoring https://stackify.com/aws-fargate-monitoring/ Fri, 05 Nov 2021 18:05:00 +0000 https://stackify.com/?p=27118 How do you perform AWS Fargate monitoring? Today, we’ll discuss the background of AWS Fargate and using Retrace to monitor your code.

As companies evolve from a monolithic architecture to microservice architectures, some common challenges often surface that companies must address during the journey.

In this post, we’ll discuss one of these challenges: observability and how to do it in AWS Fargate.

A Little History Before Talking AWS Fargate Monitoring

Twenty plus years ago, applications were different from what they are today. They were fragile, slow and lacked automation. Developers would package software manually. With the aid of file transfer programs, application code landed on servers. Each of these servers had a name and tags. Then, when a server went down, everybody scrambled to resolve the problem and bring business back online. New releases took days to roll out, and businesses could afford minutes or even an hour of downtime.

As the demands for faster, highly available applications increased, things changed. Businesses had one choice: more rapid innovation with frequent software releases.

Today, businesses serve a growing mix of on-premises and remote employees across multiple geographical areas, not to mention customer-facing applications with global availability. A minute of downtime could mean losing millions of dollars.

Container technologies like Docker, which enable you to package your app once and run it everywhere, have become commonplace. Modern applications with microservice architectures. help you to create hundreds of services in one entire system. While modern applications have taken a better turn, they are not without challenges.

The Challenges of Modern Applications

From development to production, modern applications come with challenges, including server provisioning, scaling, observability, security and maintenance. For small businesses, finding the right talent to meet and hopefully exceed these challenges can be daunting.

In a world that’s changing fast and with technology disruption happening in every sector, a leading business today may be overtaken tomorrow. To be successful, businesses must leverage technologies that deliver real business value while optimizing costs.

One such technology is AWS Fargate. In 2017, AWS introduced Fargate as a new way of running containers in the cloud to further abstract complexities.

AWS Fargate allows you to deploy container workloads without thinking about EC2 server instances or container orchestration. The grunt work of managing EC2 instances or scaling is taken care of by AWS.

With Fargate, your only focus is building your Docker images and defining some basic requirements for your application. Do that, and you can go to bed with no worries.

As exciting as AWS Fargate sounds, having 360-degree visibility into your apps could still be a problem without the right monitoring tools. For the rest of this post, we’ll look at AWS Fargate monitoring using Retrace.

What Is Retrace?

Retrace is a SaaS APM that gives you granular visibility into your applications. Just as its name indicates, it allows you to monitor and troubleshoot applications faster. Let’s look at how Retrace can help you gain deep visibility into an AWS Fargate application.

First things first. To use Retrace, you need an activation key. The Retrace container agent uses this key to authenticate to the Retrace server. You can get an activation key by signing up for a free Retrace trial account, if you don’t already use the solution. After registration, you’ll receive your activation key by email. Please note that you’ll need the key later on, so don’t lose it.

For the demo app, we’ll create a simple Docker container from a Node.js app, deploy to Fargate, and monitor the app using Retrace.

Creating the Demo App

Now, let’s proceed to create a simple Node.js container application for this demo.

First, install express-generator by executing this:

$ npm install -g express-generator

Next, generate the application boilerplate with this:

$ express fargate-app

If you ran the command above, then your directory structure should look like this:

Now, execute the command below to install the app dependencies:

$ npm install

For error logging in the application, we need to install a Retrace APM package. You can install it with this command:

$ npm install stackify-node-apm

After installation, it’s important to copy node_modules/stackify-node-apm/stackify.js to the root folder of the application. This is where you define your application environment and Retrace’s activation key.

So, execute the command below to copy:

$ cp node_modules/stackify-node-apm/stackify.js ./

And when you’ve done that, update the content of the file to this:

//stackify.js
exports.config = {
/**
* Your application name.
*/
application_name: process.env.APPLICATION_NAME,
/**
* Your environment name.
*/
environment_name: process.env.STACKIFY_ENV
}

Finally, open app.js and add this line at the top in order to initialize the Retrace profiler:

//app.js
require('stackify-node-apm')

Okay, onto the next step. We’ll now build a Docker container image that AWS Fargate can run.

Creating a Docker Container Image

In order to build the Docker image for the app, we need to create a Dockerfile. A Dockerfile is a text file that contains instructions on how to assemble a Docker image. Ideally, you should have Docker installed for this step.

To keep things simple, we won’t go into details how the Docker build works. You can learn more about it here.

At the root directory of the app, create a Dockerfile with this content:

# filename : Dockerfile
FROM node:12.2.0-alpine
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
COPY . . 
CMD [ "npm", "start" ]

Then build a Docker image by running this:

$ docker build .

Usually, the command above will take a couple of minutes to complete the building process.

On successful completion, run the command below to see the Docker image you just built:

$ docker image ls

The output will be similar to the image below. Note the IMAGE ID.

At this point, the image still resides in your local environment. You’ll need to push it to a Docker registry.

A Docker registry is a repository where you can store one or more versions of your Docker image. For this demo, we’ll use DockerHub as our Docker registry.

Before you can push a Docker image to DockerHub, you need to tag it.

You can do so with this command:

$ docker tag <image-id> <docker-registry-username/image-tag>

Ensure you replace the image-id with your Docker IMAGE ID mentioned previously. You’ll also want to replace the docker-registry-username with your registry username and the image-tag with the tag.

$ docker tag 0b2b699a0c8e abiodunjames/stackify-node

Now, we’ll push the image to DockerHub with this command:

docker push abiodunjames/stackify-node

With the Docker image in a Docker registry, the next step is creating a task definition on AWS ECS.

Creating a Task Definition

A task definition is the first step to running a container workload with AWS Fargate and is somewhat like a design plan for an application. It’s where we define the images to use, the number of containers for the task, the memory allocation, etc.

But Retrace will not automatically monitor your app. Monitoring AWS Fargate with Retrace requires you to define the Retrace container agent in the same task definition as your application.

A task definition for our demo app and Retrace container agent would look like this:

{
    "containerDefinitions": [
      {
        "cpu": 1,
        "environment": [
          {
            "name": "STACKIFY_DEVICE_ALIAS",
            "value": "Aws Fargate"
          },
          {
            "name": "STACKIFY_ENV",
            "value": "Production"
          },
          {
            "name": "STACKIFY_KEY",
            "value": "YOU-STACKIFY-KET"
          }
        ],
        "mountPoints": [
          {
            "containerPath": "/var/stackify",
            "sourceVolume": "stackify"
          }
        ],
        "image": "stackify/retrace:latest",
        "readonlyRootFilesystem": false,
        "name": "stackify-retrace"
      },
      {
        "portMappings": [
          {
            "hostPort": 80,
            "protocol": "tcp",
            "containerPort": 80
          }
        ],
        "environment": [
          {
            "name": "PORT",
            "value": "80"
          },
          {
            "name": "APPLICATION_NAME",
            "value": "fargate-app"
          },
          {
            "name": "STACKIFY_KEY",
            "value": "YOUR-STACKIFY-KEY"
          }
        ],
        "mountPoints": [
          {
            "containerPath": "/usr/local/stackify",
            "sourceVolume": "stackify"
          }
        ],
        "memory": 128,
        "image": "abiodunjames/stackify-node:latest",
        "name": "fargate-app"
      }
    ],
    "memory": "512",
    "family": "my-fargate-app",
    "requiresCompatibilities": [
      "FARGATE"
    ],
    "networkMode": "awsvpc",
    "cpu": "256",
    "volumes": [
      {
        "name": "stackify"
      }
    ]
  }

Let’s put the code snippet above in a file and name it task-definition.json. Make sure to replace the placeholder YOUR-STACKIFY-KEY with your activation key.

In the task definition, we defined two container images: stackify/retrace and abiodunjames/stackify-node (the Docker image we built). We also defined some environment variables like APPLICATION_NAME, STACKIFY_ENV and STACKIFY_KEY. These variables are passed into the containers.

To create this task on AWS, you’ll have to execute the following command using AWS CLI:

$ aws ecs register-task-definition --cli-input-json file://path/to/task-definition.json

If successful, the description of the task definition will be output in your console. If you list your task definition using the command

$ aws ecs list-task-definitions

… then you should get an output similar to this:

{    
"taskDefinitionArns": [
        "arn:aws:ecs:eu-west-1:xxxxxxx:task-definition/my-fargate-app:1"
    ]
}

Creating a Service

Before we create the service, let’s create a cluster to run the service in. You can see a cluster as a logical group of resources (tasks and services).

To create a cluster, run this command:

$ aws ecs create-cluster --cluster-name my-fargate-cluster

Now, let’s run the task with this command:

$ aws ecs create-service --cluster my-fargate-cluster --service-name my-service --task-definition my-fargate-app --desired-count 1 --launch-type "FARGATE" --network-configuration "awsvpcConfiguration={subnets=[your-subnet-id],securityGroups=your-security-group-id,assignPublicIp=ENABLED}"

The command above uses a few arguments. Let’s take a moment to look at them.

  • cluster: the cluster to create the service in.
  • service-name: the name to give to the service. For this example, we named it my-service.
  • task-definition: the task definition to use and we used the task definition we created earlier.
  • desired-count: the number of replicas of our service.
  • launch-type: the launch type.
  • network-configuration: where we defined the subnet to create the service in and the security group to use. It accepts subnet-id and the desired security group-id.

Also, we enabled automatic public IP assigning.

If you log in to the AWS console, you should see the service you just created running in the cluster, as shown in this image:

And if you log in to your Retrace dashboard, you should see metrics from your application in real time. Retrace provides a rich dashboard where you can access your application logs.

You can drill down to see details of each log.

In addition to application logs, Retrace also monitors your system health, availability and resource utilization like CPU, memory and network usage. You can see the information in your Retrace dashboard.

AWS Fargate Monitoring Summary and More Resources

To summarize, we’ve learned all about AWS Fargate monitoring: how you can use the Retrace container agent to monitor your Node.js application running in AWS Fargate in real time.

Retrace also supports other programming languages, like .NET, Java, PHP, Ruby, Python, and EC2 launch types. To build on this knowledge, we recommend you head on to Retrace official documentation.

]]>
AWS Elastic Beanstalk .NET Core Getting Started https://stackify.com/aws-elastic-beanstalk-tutorial/ Fri, 17 Jan 2020 14:10:00 +0000 https://stackify.com/?p=20090 AWS offers a variety of services to solve specific needs. There are some core services, like EC2 and VPC, that let you create an infrastructure for your applications that scales easily. But if you’re new to AWS and also new to infrastructure, you might need to invest some time reading before you deploy your application to AWS.

I remember my first time using AWS; the sysadmin explained to me what systems we were using in AWS to run the company’s main application. To be honest, I didn’t understand how all the services were interacting and what role each component played in the architecture of the application.

When I found out about AWS Elastic Beanstalk (EB), many things started to make sense to me because I could see how the app I was creating in EB connected all the resources for several other services, such as EC2, under the hood. EB made a potentially confusing task easy—I just followed the wizard. After a while, I had my first application running in AWS.

That’s what we’re going to do today. Keep reading to learn how to deploy a .NET application to AWS using AWS Elastic Beanstalk.

What Is AWS Elastic Beanstalk?

AWS offers over many services, which can be pretty overwhelming for someone who’s just starting out or hasn’t been paying attention to what’s new. Every year, AWS launches new services, as well as new features for existing services.

AWS Elastic Beanstalk (EB) makes using AWS services simple. It’s just a matter of configuring the application and the environment. AWS does all the heavy lifting and also provides you with a set of useful metrics to monitor the health of the application.

EB supports platforms for Go, Java, .NET, Node.js, PHP, Python, Ruby, and Docker. And if that’s not enough, you can make EB even more versatile by adding customization scripts in the application package you upload to the service. You can also create templates after customizing the EC2 instance with the packages or software you want the environment to have pre-installed.

EB theory is really simple; it all starts with the application. An application is a logical collection of resources where you can have different environments and versions of the application. An environment is a set of AWS resources that allow you to promote different application versions to a certain environment. Environments are really helpful when you want to roll back to a working version—you just select a working version and wait for AWS to finish the update.

So you create applications to isolate related resources and then use environments to test changes in a similar infrastructure to the one that’s live. All this so you can be sure you won’t break something important.

And that’s a basic intro for EB. If you want to know more about it, I suggest you take a look at the official docs. So let’s get our hands dirty and create our first application in EB.

Creating a Simple .NET Application

Log in to your AWS account and go to the EB home page—you’ll see the screen below. Click on the blue “Get started” button:

Creating a .NET Application in AWS Beanstalk - Screenshot

A new screen will appear. This is where you’ll start configuring the application. For the name of the application (noted in the callout as “1” in the image below), I typed “dotnetapp,” but you can choose a more meaningful name. Choose the “.NET (Windows/IIS)” option for the platform (callout 2 below). Unfortunately, AWS doesn’t currently offer a preconfigured platform for Linux. Since we don’t have an application yet, select the “Sample application” option (callout 3). This will allow you to see the “Hello World” application in EB. Click on the blue “Create application” button (callout 4):

Creating a .NET Application in AWS Beanstalk - Screenshot of basic information you need

Let’s wait a few minutes for the environment to be ready. In the meantime, you can take a look at the logs to see what’s happening:

After five minutes or so have passed, you’ll see that the environment is healthy. In the following screen, you can get the URL for the environment. If you decide to use a custom subdomain, the subdomain should then point to this URL.

Click on the URL indicated by the arrow above and you’ll see the following congratulations page for the sample application:

Creating a .NET Application in AWS Beanstalk - Screenshot of finished step

And that’s it! You’ve created a simple .NET application. That was easy, right? Then let’s make things more interesting and replace the sample app with one that we’ll create.

Create and upload a custom application

Let’s use Visual Studio’s .NET Core templates and create a Razor application using the default template. But first, let’s create a folder for the application and go to that folder. To do so, run the following commands in the terminal:

$ mkdir dotnetapp
$ cd dotnetapp

Create the application using the Razor template by running the following command:

$ dotnet new razor

We need to tell AWS to replace the existing content with the content we’re uploading to the EB platform. Let’s create a file called “aws-windows-deployment-manifest.json” with the following content:

{
    "manifestVersion": 1,
    "deployments": {
        "aspNetCoreWeb": [
            {
                "name": "dotnetapp",
                "parameters": {
                    "appBundle": ".",
                    "iisPath": "/",
                    "iisWebSite": "Default Web Site"
                }
            }
        ]
    }
}

This file is saying that the compiled code that you’re uploading needs to replace the existing content in the default website of the server.

Now let’s compile the application locally with the following command:

$ dotnet publish -c Release -o site

We need to zip the contents of the folder. How you’ll do this will depend on the OS you’re using. But if you’re using a Mac, you can go ahead and use this command:

$ zip -r -X site.zip site/

Go back to the AWS Elastic Beanstalk console and upload the zip file you just created by clicking on the “Upload and Deploy” button:

Creating a .NET Application in AWS Beanstalk - Screenshot of ready to upload and deploy

Locate the zip file to upload and click on the blue “Deploy” button:

Creating a .NET Application in AWS Beanstalk - Screenshot of ready to upload and deploy

You’ll see that AWS starts to upload the zip file and update the servers.

Creating a .NET Application in AWS Beanstalk - Screenshot of a healthy environment

When the console shows that the environment is healthy (above) and that it’s using the version you just uploaded, click on the URL again to see the new app live:

Creating a .NET Application in AWS Beanstalk - Completed

Congrats! You’ve just deployed a custom .NET Core application to AWS Elastic Beanstalk.

NOTE: If for some reason the update doesn’t work, try to zip the files manually instead of using a command. I’ve struggled with this a few times because it seems that the zip file was uploaded incompletely so the application didn’t get updated. My slow internet connection at the time could have contributed to the issue as well.

Exploring the application and its environment

At the beginning of this post, I talked about applications and environments. Now I’d like to show you how these look in the AWS console.

In the above screen, you can see that the only application is the “dotnetapp” I just created. Below that app, there’s a list of environments for the application. In this case, the default one is for development. Note that you can have more than one to safely promote artifacts to production. You just need to upload the application once and then redeploy it in the other environments.

Now let’s take a look at some other options that will be useful, especially if you’re new to AWS and/or infrastructure. Go back to the environment of the application by clicking on the name of the environment.

Configuration

In the left panel, there’s a menu for a link to different things you can change in the environment. Let’s start with the “Configuration” section.

In here, you can change the runtime, enable log streaming, add/change environment variables, change the instance type, make the application private, and configure high-availability, among other things.

Logs

You can also take a look at some logs from here. You don’t lose remote access to the infrastructure, but you have the ability to inspect logs without needing more privileged permissions.

You’ll get logs in batches of 100 lines; you can download the generated logs and analyze them offline.

Monitoring

I like the monitoring section the most because even though there aren’t too many metrics, it gives you a quick overview of what’s happening in your application and how it’s being used. You can then go and take a look at the AWS resources that EB created.

Alarms

It’s also possible to configure alarms when something bad happens, like if CPU consumption goes up or networking traffic increases. This behavior might just mean that you’re receiving more genuine traffic and you simply need to set things up to grow/shrink on demand after an alarm has been triggered.

Alarms and Notifications in AWS Beanstalk

Events

Lastly, you have events. These are different than logs because the information recorded here is about the things that happen to the environment. For example, if a new version is deployed or something happened with the infrastructure and it needed to be recreated, you’ll see a log entry here.

Modify the instance type

By default, AWS set the instance type as “t1.micro,” but that’s a legacy version and there’s a cheaper instance type called “t2.micro” with the latest virtualization technology. This isn’t actually a big deal if you’re just practicing setting up your first environment. But I want to change it so that you can see how easy it is to alter these types of configurations in EB.

Go back to the “Configuration” section we just reviewed in the previous section and click on “Modify” in the “Capacity” box.

Scroll down a little bit, in the instance type drop-down menu, choose a different instance type—I chose “t3.micro” (see the callout labeled “1” below) because it’s cheaper. 

Scroll down a little bit and click on the blue “Apply” button. Click the blue “Confirm” button on the following screen and then wait for a bit. This process will take several minutes even though the console says it’s healthy. AWS recreates the environment by terminating the current instance and then creating the new instance with the same code you uploaded before. You’ll see the changes applied, like on the following screenshot:

Preparing for high availability

When you explore the EC2 service, you’ll see that there’s only one instance. Again, this is because we created our first application and environment using the default options. But you can change this configuration as well and make the application elastic by changing just a few things.

Go back to the “Configuration” section we reviewed before and click on “Modify” in the “Capacity” box.

You can change the configuration of how many instances you need for the application to run smoothly. By default, it’s configured to run with one instance, with an elastic IP address assigned. Let’s change the environment type to “Load balanced.” You’ll see that a number of options will be enabled that will allow you to scale out/in when needed.

When you modify the capacity, you’re not just preparing to have a resilient application; you’re also giving AWS a chance to do deployments without downtime. Every time AWS needs to deploy a new change, it will either take a server out of the rotation, or it will create a new server and include it in the load balancer when it’s ready.

What are the next steps?

You could use Visual Studio to deploy new code into EB…but please don’t. Instead, use the CLI so that you can automate deployments in Jenkins or even VSTS. We did everything manually in this guide, with the intention of showing you how everything is connected. That way when you’re automating deployments, you’ll understand what the EB CLI is doing.

If there’s something special you need to have in the servers, you can extend this configuration with the .ebextensions. The .ebextensions functionality is really powerful because you no longer have to make changes manually. Next time the environment needs to be rebuilt because something happened in AWS, you don’t have to worry about setting things up again.

When you use AWS Elastic Beanstalk, you leave all the heavy lifting to AWS.

]]>
AWS Batch: A Detailed Guide to Kicking Off Your First Job https://stackify.com/aws-batch-guide/ Thu, 26 Dec 2019 14:19:00 +0000 https://stackify.com/?p=16560 There are always the kind of tasks that need to run periodically, either to analyze and process information (like fraud detection), or to simply do things like send email reports. But for that, we need to have a tool to schedule computer resources and, of course, the script.

But what if we only need to worry about coding the script?

Introducing AWS Batch. It’s a free service that takes care of batch jobs you might need to run periodically or on-demand. And you only pay for the resources you use.

In this tutorial, you’ll learn how to kick off your first AWS Batch job by using a Docker container.

What Is AWS Batch? A Quick Overview

Before we dive in, let’s do a quick overview of the subject at hand. AWS Batch is a service that lets you run batch jobs in AWS. You don’t have to worry about installing a tool to manage your jobs. AWS Batch will do that for you.

There are a lot of features you might not need when you’re first starting out, but let’s explore a few of them anyway:

  • Instances will run only for the time that’s needed, taking advantage of the per-second billing. You can also lower your costs by using spot instances.
  • It’s possible to configure how many retries you’d like for any job.
  • It offers queues where you send the jobs. Each queue could be configured with a certain priority so you can configure which jobs will run first. You can also have queues that use better resources to speed up the process.
  • It supports Docker containers so that you can focus only on your code.
  • And more

So, enough theory. Let’s get our hands dirty.

dirty hands covered in paint

Kick Off Your First Job

Before we start, there are some prerequisites that will make this tutorial easy to follow, and it will include some good practices in regards to security. If you think you need more details, you can check the setup page in AWS’s official docs.

Prerequisites

  1. Have an AWS account.
  2. Create an IAM user with administrator permissions. To do this, you can just follow this tutorial. I recommend you give granular permissions to the user that will do the provisioning.
  3. Install and configure AWS CLI.

If something from the above doesn’t work, it might be because a permission is missing, or the CLI is not configured properly. I’ll let you know exactly what’s needed in the following steps.

Go to AWS Batch

Log in to your AWS account and look for AWS Batch in the initial screen, or you can go directly by using this link.

You’ll see a screen like the following:

AWS Batch guide

Click the “Get started” button. Then, this next screen will appear:

AWS Batch guide

Click the “Skip wizard” button. We’re not going to follow this wizard because I want to explain each step to you. Also, after this, you’ll probably use AWS CloudFormation or something else to provision, not the wizard.

Create a Compute Environment

The jobs will run on a compute environment. Here, you’ll configure the instance type, family, and some other things that we’ll see in a bit.

It’s important that you know we’re not going to create any instances now. AWS Batch will create one when it’s needed. You can also configure things to create instances right away, speeding up job scheduling, but we won’t tackle that in this post.

Click the “Compute environments” link that appears in the left menu. You’ll see the following screen:

AWS Batch guide instances

Instance Type and Permissions

Now click the “Create environment” blue button so you can start defining the compute environment. You’ll start configuring the environment in the following screen:

AWS Batch guide create environment

For simplicity, we’re going to choose all default values. You just need to name the environment. I called it “first-compute-environment.”

You don’t have to worry about creating a service or instance role right now. Just choose the option “Create new role” for both, and AWS will create them for you with the proper permissions. It will help you see which permissions are needed and adjust them if you want to.

Leave the EC2 key pair blank because we don’t need to access the servers for now.

Compute Resources

Scroll down a little bit, and let’s talk about the compute resources section. You’ll see the following screen:

AWS Batch guide compute resources

This is where you get to choose if you want to use on-demand or spot instances. For simplicity, let’s choose “On-demand.”

The “Allowed instance types” field is where you define which family type you’d like these environments to create. This is where things get fun because you can create compute environments that are CPU-intensive and choose between C family instance types. Or if there are jobs that are memory intensive, you can choose M family instance types. You’re limiting which instance types can be created. I chose “optimal,” so AWS decides for me which instance is better based on the configuration of job queues.

Now, vCPUs are one of the most important things here in order for your first job to run.

If you’re familiar with running workloads using ECS, you might get confused here. You might configure so many vCPUs that AWS won’t be able to create the environment. And even if there are a few instances running, jobs won’t run until the environment is ready. So keep in mind that vCPUs are virtual CPUs, not CPU units that you configure in a container when running in ECS.

I configured a maximum of four vCPUs. It means that if at some point the cluster has four vCPUs among all instances, it won’t create more. Jobs will run slowly, but your costs will remain controlled. I also put one vCPU as desired, just so it starts creating an instance right now. AWS will adjust this later if needed, and you can change it when submitting a job if you’re in a hurry.

Networking

Scroll down a little bit, and you’ll now configure the networking section and tags. You’ll see a screen like this:

AWS Batch guide networking

Leave the VPC and subnets as default for now. Click the “Create” blue button and wait a bit while the environment is created.

AWS Batch guide compute environments

Create a Job Queue

Now you need a queue where you’ll send the jobs to get executed. This queue will be attached to a compute environment so the AWS Batch service will create the resources needed based on the load of the queue. It will use the min, max, and desired vCPUs configuration to know how many instances to create.

Click the “Job queues” link in the left menu and you’ll see the following screen:

AWS Batch guide jon queues

Then, you can click the “Create queue” blue button. You’ll see this:

Let’s put a name to the queue so it’s easy to identify. I called it “first-job-queue.”

In the priority, make sure you type a value that lets you play with lower priority queues later. I put “100” in case I need to create a lower priority queue later—say, for example, one with 50.

Enable the job queue. By default, this checkbox will be checked. You should leave it that way.

You now need to connect this queue to one or more compute environments. I chose the one I just created, the “first-compute-environment” one. If there were any other environment, this is where you’d choose it.

Why would I like to have more than one compute environment? Well, it’s useful if you want to speed up a job’s processing time by creating more instances using the spot market. You can have an on-demand compute environment where you always have resources available. And if the load increases, you can create spot instances if there are any available, based on the bid you configured.

Click the “Create queue” blue button.

http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-2.24.36-PM.png

Create a Job Using Docker

We’re going to use a “hello world” job that AWS evangelists have used for demo purposes. I couldn’t find a repository with all the files they’ve used, so I created one with all the files we’re going to need. You can find it on GitHub here.

Let’s explore what’s in there, as well as why and how to use those files to create our first job in AWS Batch.

 Docker Image

We’re going to create a simple job that will pull a Bash script from S3 and execute it. The Dockerfile and the script that does what I just described is located in the “job” folder of the repository.

AWS Batch guide create job

I won’t explain either the script or the Dockerfile just yet—we’ll just use it. So let’s build the Docker image and push it to the Docker hub. You need to have Docker installed on your machine, a Docker hub account, and a login for your computer.

Let’s build the Docker image. You can skip this step and use my image located here, or you can run the following command and tag the image using your username instead of mine:

docker build -t christianhxc/aws-batch-101:latest .

Now, let’s push the image. You need to be logged in with your user ID. And make sure you push the image that has your username in the tag. Run the following command:

docker push christianhxc/aws-batch-101:latest

That’s it! You now have the Docker image that will download a Bash script from S3 and run it.

A Bash Script

Let’s create the Bash script. You can use the one I have in the repo. That script simply puts a Fibonacci sequence in a DynamoDB table. It uses an environment variable called FOO to create the series of numbers, and it uses an argument just to print it in the console.

This script is in the root of the GitHub repository I linked before, and it’s called mapjob.sh

AWS Batch guide bash script

Now, because this is outside the scope of AWS Batch, I’m just going to list the actions you’ll need for this guide to work. We’ll need to do the following:

  1. Create a DynamoDB table in the Virginia region with primary key of “jobID”. Mine is called “fetch_and_run.” If you decide to enter a different name, make sure you change it at the end in the mapjob.sh script.
  2. Create an S3 bucket in the Virginia region. Mine is called “cm-aws-batch-101.” Don’t make it public.
  3. Upload the mapjob.sh script in the bucket you just created.
  4. Create an IAM role for an ECS service task with permissions to the S3 bucket and the DynamoDB table. If you don’t know how to do that, follow these instructions. I called my IAM role “aws-batch-101.” We’ll use this one next.

You’re almost ready to kick off your first job. You already have a script and a Docker image to use.

Let’s create the job definition in AWS and then submit a job.

Create a Job Definition

At this point, you’ve defined the environment where your jobs will run and the queue, which means AWS takes care of creating resources only when they’re needed. Now you need to run the job definition. And this is where things get more interesting.

Click the “Job definitions” link in the left menu and you’ll see the following screen:

AWS Batch guide job definitions

Click the “Create” blue button and let’s start defining the job.

Enter any name you’d like. I put “first-job.” We set job attempts to 1.   Job attempts is the maximum number of times to retry your job if it fails. And Execution timeout, is the maximum number of seconds your job attempts would run. For this example, we set it to 60 seconds.

Scroll down a bit and let me explain what’s there:

Job role provides a drop down menu where you select the job role. choose the IAM role you created previously; mine is “aws-batch-101.”

Note that:  Only roles with Amazon Elastic Container Service Task Role  trust relationship will be shown. You can learn more about creating roles with AWS ECS trust relationship here.

Now pick a name for the container image. Like I said before, for simplicity, you can use mine. I called it “christianhxc/aws-batch-101:latest.” These values can’t be changed when submitting a job, but the ones we’re about to explore can be changed.

The command field describes the command passed to the container. It maps to the COMMAND parameter to docker run. Here, we’ll type the name of the script that will run the container and its parameters. Because we can override this value, we’ll leave it as it is right now.

Now, here’s another trick to be able to run a job. Unfortunately, you can’t configure CPU units to a container, only vCPUs. It means that, at minimum, the container will have 1024 CPU units because that’s the equivalent to one vCPU. You can configure the CPU, then, in blocks of 1024. This is important because I entered 256, thinking that this was CPU units, and the job never started. It sticks in the RUNNABLE state if there’s nowhere to run it.

Configure how much memory this container will need. I put 256. Leave the rest as it is.

Submit a Job

You’re now, finally, able to submit a job.

Click the “Jobs” link in the left menu, and you’ll see the following screen:

AWS Batch guide jobs

Click the “Submit job” blue button. Let’s submit one!

Next, name your job submission. I called it “my-first-job.” Choose the job definition and the queue we just created, and choose “Single” as a job type.

Scroll down a little and let’s override some values here:

In here, you’ll need to put the name of the script in the S3 bucket and the Fibonacci number as parameter. But these are only for reference. I used “mapjob.sh 60.” Type in “1” for vCPU and “256” for memory.

Scroll down some because our scripts need environment variables in order to work. Let’s add the corresponding values:

http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-3.46.47-PM.png

Let’s add the environment variables. For FOO, enter the Fibonacci number. I used 60. For BATCH_FILE_TYPE, put “script”, and for BATCH_FILE_S3_URL, put the S3 URL of the script that will fetch and run.

Click the “Submit job” blue button and wait a while. You can go to the computer environment and changed the desired vCPUs to 1 to speed up the process.

http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-3.52.53-PM.png

It will start creating one instance. When the instance is ready to process a job, the job will transition from RUNNABLE to SUCCEEDED.

http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-3.54.01-PM.png

And you’ll see a new entry in the DynamoDB table.

http://www.hitsubscribe.com/wp-content/uploads/2018/03/Screen-Shot-2018-03-13-at-3.55.38-PM.png

You can keep submitting jobs and change the FOO var to generate a different sequence of numbers. When you don’t submit any other job, AWS Batch will terminate the instance it created.

It’s Your Turn Now

You now have the basics to kick off a job in AWS Batch. Once you’ve finished this guide, it’s up to you which scripts or code you’ll put in a container. AWS Batch will manage all the infrastructure, scheduling, and retries for you.

Now the challenge is in how to code your application so that you can submit several instances of a job. AWS Batch will run them as you submit them and will scale out/in when it’s needed, saving you some money. You can start by migrating any existing cronjob, but don’t stop there. Many things could go wrong with your job execution.

The container may be buggy. Performance may be slow. Sometimes, you may need to provision more memory for the job.

To investigate and debug issues like these, you need monitoring tools.

This post was written by Christian Meléndez. Christian is a technologist that started as a software developer and has more recently become a cloud architect focused on implementing continuous delivery pipelines with applications in several flavors, including .NET, Node.js, and Java, often using Docker containers.

]]>
Sending CloudWatch Custom Metrics From Lambda With Code Examples https://stackify.com/custom-metrics-aws-lambda/ Thu, 14 Nov 2019 14:44:28 +0000 https://stackify.com/?p=19906 Today’s post is a detailed guide on how to send custom metrics to AWS CloudWatch monitoring using AWS Lambda. Starting from scratch, we’re going to finish up this post by leaving a serverless project running on Amazon Web Services (AWS). And do you want to hear the best part? Getting started will cost you less than you might spend on a cheeseburger.

I’ve used AWS Lambda to send custom metrics to CloudWatch to collect data on business metrics like purchases made in the application. At one company where I used to work, there were times where users were starting to experience problems, and system metrics like CPU or memory were in the normal trend. By sending those metrics to AWS CloudWatch, I was able to act proactively with the infrastructure, either by restarting the app or by scaling out the infrastructure.

Keep in mind that, in order to follow the tutorial, you’re going to need to be logged to your Amazon AWS account.

Let’s get started!

Create an IAM Policy

The first thing we need to do is to create an IAM policy in AWS Identity & Access Management with the fewest privileges.

Go to the IAM Policies page and click on the blue “Create policy” button:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-policy.jpg

The user we’re going to create will only need to have permissions to put metric data into CloudWatch. Copy the following JSON definition for the policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "cloudwatch:PutMetricData"
            ],
            "Resource": "*"
        }
    ]
}

Click on the “JSON” tab and paste the policy you just copied:
https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-put-iam-policy.jpg

Click on the blue “Review policy” button. Name the policy (I typed “put-custom-metric”) and then click on the blue “Create policy” button:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-review-policy.jpg

Great! The policy has been created. Now we’re going to create a user that we’ll attach this policy to.

Create an IAM User for Local Testing

Go to the IAM Users page and click on the blue “Add user” button:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-user.jpg

Create a username (I typed “custom-metrics”) and make sure you select the “Programmatic access” checkbox. Click on the blue “Next: Permissions” button:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-user-details-1.jpg

Now it’s time to attach the IAM policy we created earlier to this user.

Start typing the name of the policy and it will appear in the list below. I only had to type “put-” before my “put-custom-metric” policy appeared. Check the policy, scroll down a little bit, and click on the blue “Next: Review” button:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-user-policy.jpg

Click on the blue “Create user” button to finish creating the user. Remember, we set this up so the user only has permissions to send custom metrics data to CloudWatch. You should now be able to retrieve an access key ID and a secret access key (credentials) that you can use on your local computer to interact with AWS.

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-user-review2.jpg

Copy or download the credentials. If you just want to copy the values, you’ll need to click on the “Show” link (see above).

Install the AWS SDK for Python

We’ll create the Lambda function using Python 2.7, so let’s start by installing the Bot Builder SDK for .NET to test locally before going to AWS. If you don’t have Python installed, you can install it here. You also need to have PIP installed on your local machine. It doesn’t matter which OS you use; we’ll create a simple app using the AWS SDK.

The AWS SDK for Python is called Boto 3. You can install it simply by running this command on the terminal:

pip install boto3

Configure the AWS Credentials

In order to avoid having to put the AWS credentials in the code and risk them persisting in version control, we need to configure the AWS credentials in the local files that the AWS SDK will use to interact with the AWS API.

Go to the ~/.aws/credentials file (if it doesn’t exist, create it) and replace the content there with the following:

[default]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY

YOUR_ACCESS_KEY_ID is the access key from the user you just created, and YOUR_SECRET_ACCESS_KEY is the secret access key from that user. So replace those fields with your own access keys values.

Next, configure the AWS region where you want to store the custom metrics. Go to the ~/.aws/config file (if it doesn’t exist, create it) and replace the content there with the following:

[default]
region=us-east-1

The value you put in this file is the AWS region code. The value I used in this example will persist metrics in North Virginia. You can get the full list of codes from the official docs.

Now that we have everything we need to test locally, let’s start coding.

Create a new Python file (.py extension) and start by adding the Boto 3 import:

import boto3

We need to create a CloudWatch client to send metric data using the Boto 3 SDK. It’s as simple as creating a Boto 3 client and typing the name of the service we’d like it to interact with:

cloudwatch = boto3.client('cloudwatch')

What I like about creating a client in Boto 3 as opposed to other approaches is that it’s a 1:1 relation with the AWS CLI. In this case, we’ll send metric data to CloudWatch.

How do you do that? Well, according to the official docs, there’s a command called “put-metric-data”. There’s also a function called “put_metric_data” in the Boto 3 official docs. The only difference is that in Python you use an underscore (_) instead of a hyphen (-).

Now that we’ve set up all the dependencies we’ll need, it’s time to add the code to send custom metrics.

Try Stackify’s free code profiler, Prefix, to write better code on your workstation. Prefix works with .NET, Java, PHP, Node.js, Ruby, and Python.

Let’s Add the Magic

Add the following line below the “cloudwatch” client you just created. This line will send a custom metric for the number of purchases that have been made in the application:

response = cloudwatch.put_metric_data(
    MetricData = [
        {
            'MetricName': 'KPIs',
            'Dimensions': [
                {
                    'Name': 'PURCHASES_SERVICE',
                    'Value': 'CoolService'
                },
                {
                    'Name': 'APP_VERSION',
                    'Value': '1.0'
                },
            ],
            'Unit': 'None',
            'Value': random.randint(1, 500)
        },
    ],
    Namespace='CoolApp'
)

You can find a good explanation for each of those parameters in the Boto 3 official docs, but the name makes most of their functions pretty clear. Or you can always read the AWS official docs to get an even better understanding.

What’s interesting about the above code is that I put two dimensions (copied below) for the metric:

'Dimensions': [
    {
        'Name': 'PURCHASES_SERVICE',
        'Value': 'CoolService'
    },
    {
        'Name': 'APP_VERSION',
        'Value': '1.0'
    },
],

According to the AWS docs, a dimension is “a name/value pair that uniquely identifies a metric.” So first, we’re identifying the metric data by saying that the value is for the “CoolService” purchase app, then we’re specifying that it’s for version 1.0 of the app. Later, when we check that data is in AWS, you’ll get a better idea of how helpful this will be.

I’m also including a random number generator so that we can get different data when the lambda runs.

'Value': random.randint(1, 500)

For this to work, you need to include the random import line at the beginning of the script:

import random

In a real-world application, you would replace that random number with a number that you got, for example, after querying the database.

Lastly, add a print instruction to make sure that the metric data was persisted successfully. It will also be useful when there are errors because you’ll be able to see what’s happening. When this code is deployed into AWS Lambda, the message we just printed will go to the CloudWatch logs.

All the Code Combined

So, putting everything together, the code should look like this:

import boto3
import random
cloudwatch = boto3.client('cloudwatch')
response = cloudwatch.put_metric_data(
MetricData = [
    {
        'MetricName': 'KPIs',
        'Dimensions': [
            {
                'Name': 'PURCHASES_SERVICE',
                'Value': 'CoolService'
            },
            {
                'Name': 'APP_VERSION',
                'Value': '1.0'
            },
        ],
        'Unit': 'None',
        'Value': random.randint(1, 500)
    },
],
Namespace = 'CoolApp'
)
print response

Run the script. If everything went well, you should see something like this printed in the terminal:

$ python kpis.py
$ {'ResponseMetadata': {'RetryAttempts': 0, 'HTTPStatusCode': 200, 'RequestId': 'f3332a04-62d6-11e8-be03-81a0e74b2ca8', 'HTTPHeaders': {'x-amzn-requestid': 'f3332a04-62d6-11e8-be03-81a0e74b2ca8', 'date': 'Tue, 29 May 2018 00:26:36 GMT', 'content-length': '212', 'content-type': 'text/xml'}}}

Great! This code is almost ready to be deployed to AWS Lambda.

Wrap the Code into a Handler

When you deploy code to AWS Lambda, one of the prerequisites is that you need to indicate what the code’s handler is. All that means is that Lambda needs the code’s starting point. For Python scripts, AWS Lambda needs the name of the file and the name of the function where the code workflow starts.

So let’s wrap the current code into a handler (or def in Python terms). Add this line right after the imports section:

def lambda_handler(event, context):

Tab the code below so that it becomes part of the function.

Now the code should look like this:

import boto3
import random
def lambda_handler(event, context):
    cloudwatch = boto3.client('cloudwatch')
    response = cloudwatch.put_metric_data(
        MetricData = [
            {
                'MetricName': 'KPIs',
                'Dimensions': [
                    {
                        'Name': 'PURCHASES_SERVICE',
                        'Value': 'CoolService'
                    },
                    {
                        'Name': 'APP_VERSION',
                        'Value': '1.0'
                    },
                ],
                'Unit': 'None',
                'Value': random.randint(1, 500)
            },
        ],
        Namespace = 'CoolApp'
    )
print response

This is the code that we’ll deploy to AWS Lambda.

Create an IAM Role for the AWS Lambda Function

Go back to the AWS Console to create an IAM role. The AWS Lambda function will use this to send metrics data to CloudWatch. To test our code locally, we created an IAM user and then configured our machine to use the credentials of the user. But that’s not a good security practice, which is why we need an IAM role.

When you work with roles, the credentials expire automatically after a short period of time. The SDK will make sure to request new credentials when it’s needed. That way you don’t need to worry about generating new credentials all the time.

We’ll use the same IAM policy that we assigned the user we created to test locally. But we also need to create a new IAM policy so that our AWS Lambda function can put logs into CloudWatch logs.

How to Create the IAM Role Using the Console

Let’s create a new policy the same way we just did before. Go to the policies page and click on the blue “Create policy” button. Click on the “JSON” tab and paste the following JSON definition:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

Click on the blue “Review policy” button. Name this policy (I typed “cloudwatchlogs-write”) and then click on the blue “Create policy” button.

______________________________________________________________________________________________________________________________

NOTE: If you decide to interact with a private resource in AWS by using the VPC, you need to add the following permissions to the above policy (or create a new one) so that the AWS Lambda function can connect to the internal resources.

"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface"

______________________________________________________________________________________________________________________________

Go to the IAM role page and click on the blue “Create role” button:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-new-role.jpg

Make sure the “AWS Service” is selected and click on the “Lambda” link:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-iam-role.jpg

Click on the blue “Next: Permissions” button to attach the policies we just created. Type the names of the policies and then select the ones called “cloudwatchlogs-write” and “put-custom-metric”… If you chose different names, type those names here and select the policies.

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-iam-role2.jpg

Click on the blue “Next: Review” button. Now name the role (I typed “put-custom-metric”) and at the bottom, you’ll see the policies that we just selected. Click on the blue “Create role” button.

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-iam-role3.jpg

Create the AWS Lambda Function

Now it’s time to create the AWS Lambda function. Go to the Lambda page and click on the orange “Create function” button:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-lambda2.jpg

If you don’t have any function there, go to the Lambda home page and click on the orange “Create a function” button. You’ll see the following screen:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-lambda1.jpg

Select the “Author from scratch” option—we’ll upload the code we just created.

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-lambda-scratch.jpg

Scroll down a little bit and fill in the details for the function. Name the function (I typed “cool-kpis”) and choose “Python 2.7” for the runtime. Then select the “Choose an existing role” option for the role. You’ll now be able to choose the IAM role we created earlier. Select it.

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-lambda-3.jpg

Click on the orange “Create function” button to finish. In the next screen, you’ll be able to see which permissions the lambda function has. In this case, it has permissions to CloudWatch and CloudWatch logs.

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-lambda-4.jpg

Deploy the AWS Lambda Function Code

We’re going to deploy the code manually now, which I’ll admit is a bit archaic. But before I automate things, I like to do things manually so I have a chance to understand what I’m doing when automating. So let’s keep it simple and copy the code from the Wrap the code into a handler section that we created earlier in this guide.

Scroll down a little bit and replace the code that’s there with the new one:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-lambda-code2.jpg

Click on the orange “Save” button in the upper-righthand corner.

Great! The lambda function is already created and it has the code we just tested locally. So how can we make sure that the function is working? Let’s configure a test event.

Configure a Test Event

Scroll up a little bit and click on the “Test” button:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-test.jpg

This time we’re not configuring a trigger for our lambda function, so it really doesn’t matter what the test event has. So leave everything as default, type a name for the event, scroll down a little bit, and click on the orange “Create” button.

Click on the “Test” button again to test the lambda function:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-lambda-test.jpg

Now we wait—it will take some time to see the metrics in AWS.

You can go to CloudWatch Metrics page to check if the metrics are visible. (If this is your first time doing this, it could take 5–20 minutes.) You should see the “CoolApp” namespace:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-metrics.jpg

You can also go to the CloudWatch logs for the .lambda function to see the results:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-logs.jpg

This is where you’ll go to debug when metrics are not being sent to CloudWatch.

Configure the Function to Run on a Schedule

Now let’s have some fun and do something more interesting with this project.

What if you could make the .lambda function run every five minutes to get new metric values every time? You would be able to create dashboards to see how the metrics have changed over time. In our case, it will generate random numbers, but in a real-world situation, having a schedule for the .lambda to run will be valuable because you’ll see more data in CloudWatch.

Go back to the AWS Lambda page and click on the “CloudWatch Events” trigger in the left panel. A new box will appear with the “CloudWatch Events” name.

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-lambda-trigger.jpg

Let’s configure the schedule. Scroll down a little bit and you’ll see the event form. Choose the “Create a new rule” option for the Rule field. Type a descriptive name for the event, something like “every-five-minutes”, and a detailed description. Then select the “Schedule expression” option and type the expression in cron format. So if you want it to be every five minutes, type “cron(0 0/5 * * * *)”. It should look like this:

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-create-event2.jpg

Scroll down a little bit and click on the “Add” button. Then click on the orange “Save” button in the upper-righthand corner for the lambda function.

https://www.hitsubscribe.com/wp-content/uploads/2018/05/aws-cloudwatch-metrics.jpg

And that’s it! You just created an AWS Lambda using Python. Even though our example isn’t that complex, you had the chance to connect and interact with several AWS services.

Beware that you can’t delete metrics—you just have to wait for them to expire as the FAQ page indicates in the questions: Q: What is the retention period of all metrics? and Q: Can I delete any metrics?

What’s Next?

Well, the code is generating random data, but now you have a placeholder to add more complex things like querying a database or making a request to another service. In the end, AWS is just a hosting service, so more complex tasks shouldn’t be a problem since you’re still working with Python code.

You may also need to send the metrics somewhere other than CloudWatch. If a library to do more complex things is not natively supported in AWS Lambda, you can pack the libraries with the code and upload it to AWS.

Everything we did here was manual, so you might need to automate at least deployments by using the AWS CLI, Serverless Framework, SAML, or similar services.

AWS Lambda is just a way to expose and host your code; it shouldn’t restrict you from doing interesting things.

]]>
AWS Lambda with Python: A Complete Getting Started Guide https://stackify.com/aws-lambda-with-python-a-complete-getting-started-guide/ Sat, 22 Jun 2019 14:15:39 +0000 https://stackify.com/?p=25386 In this post, we’ll learn what Amazon Web Services (AWS) Lambda is, and why it might be a good idea to use for your next project. For a more in-depth introduction to serverless and Lambda, read AWS Lambda: Your Quick Start Guide to Going Serverless.

In order to show how useful Lambda can be, we’ll walk through creating a simple Lambda function using the Python programming language. We’ll test it out, as well as take a look at what Lambda provides for metrics and logging.

By the end of this tutorial, you’ll be ready to start integrating other AWS serverless frameworks using Python Lambda functions as the glue to bind them all together. Note that the usage of the term Lambda here is not related to anonymous functions in Python, which are also known as lambda functions.

Serverless, or Why you don’t need a server!

In a traditional cloud usage model, you provision servers, deploy code to the server, and manage resource usage and scaling, along with other traditional server activities.

While this is still the right way to handle a lot of scenarios, sometimes you just need to run a bit of code to handle some kind of event. For example, let’s say you have an application that allows users to upload a photo for a profile image. The application stores these images in Amazon S3. Now, say you want to resize the image to a max resolution. You could most definitely handle this task using the traditional model, but since this code runs based on an event (the file upload), Amazon S3 can fire an event and trigger the execution of code to handle the image resize.

Where does this piece of code live, if we aren’t deploying a server? Well, that’s where AWS Lambda comes into play.

AWS Lambda is the glue that binds many AWS services together, including S3, API Gateway, and DynamoDB. Alexa Skill Kits and Alexa Home also have events that can trigger Lambda functions!

Using a serverless architecture also handles the case where you might have resources that are underutilized, since with Lambda, you only pay for the related execution costs. In many cases, this approach can be cheaper than provisioning and running code in the traditional cloud model. Amazon also handles all the resource scaling and load balancing!

At this point, I’m sure you’re ready start writing your first Lambda function. So let’s get to it.

Start by creating your first Python Lambda function

Create the Lambda function on the AWS Lambda homepage by clicking the Create a Function button.

AWS Lambda Create Function

This brings us to the function creation screen where we have a few items to configure, before our function is created:

  • Author from scratch
  • Function name
  • Runtime

For Permissions, Lambda will automatically create a basic execution role so the Lambda function can access CloudWatch for logs. We’ll just leave it at that for now.

Go ahead and name the function something glorious, and then we’ll be all set to create our function.

No, wait! What? Node.js? This is a Python tutorial! No Node allowed.

Set this drop-down to the correct value of Python 3.7. Now go ahead and click the Create function button, which will bring you to the function configuration screen. This can be a bit overwhelming at first, but we’ll briefly cover a few of the essentials here.

Also Read-https://stackify.com/aws-lambda-with-node-js-a-complete-getting-started-guide/

Understanding the Lambda function configuration screen

This view shows two tabs: Configuration and Monitoring. We’ll get into the monitoring section later in this article, when we learn about viewing activity and CloudWatch logs. For now, we’ll focus on the first portion of the configuration screen.

The first area that you’ll see is the Designer view. This view is a handy visual representation of which triggers are utilizing this function, as well as the resources that the function has access to. By default, Lambda adds a resource for Amazon CloudWatch for function logging.

We aren’t using any triggers for this simple function, but triggers can be added by clicking on the trigger in the left column. The designer view will update to show the trigger.

As an example, in the following screenshot, I’ve added triggers for the API Gateway and Alexa Skills Kit.

myFirstLambdaFunction

If you’re curious about what a layer is, here’s what you need to know: a layer essentially allows you to add additional dependencies or frameworks for your function to use. We won’t be using any layers, but for more information, refer to the AWS Lambda Layers documentation.

The next portion of the configuration screen is where the real action here is, and that’s the Function code section. One of the beautiful things about Lambda is the ability to write our function without needing to install anything locally. We can do it all in the browser. Later in this article, you’ll learn how to test the function as well.

lambda function code

If writing the function in the browser isn’t your cup of tea, you can change the Code entry type drop-down and upload a zip file containing the code or give it a URL to the file on Amazon S3. For our purposes, we can stick with the inline code editor.

The code that Lambda generates for us is its version of the venerable Hello, World! program.

import json

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

This code imports the JSON Python package and defines a function named lambda_handler. This is important, as when an event trigger occurs, Lambda needs to know what to execute.

This function entry point is defined in the Handler field. The format is filename.handler_name. In our example, the filename our code resides in is lambda_function.py. The function name within this file is lambda_handler.

You can name these whatever you want, but the value in the Handler field needs to be updated to match; otherwise, Lambda has no idea how to execute our function.

As an example, if our function is called handler and it’s in the file named main.py, the Handler value needs to be set to main.handler. The below screenshot shows how this ties together:

lambda code entry type

While you can run this example now as is, there’s one more change to make, for illustration purposes. Add a print statement to the code as in this example:

import json

def lambda_handler(event, context):
    print("Hello from Lambda!")
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

Okay. Now we’re ready to run our function.

Next, take the Python Lambda function for a spin

I lied. There’s one last thing we need to do before running, and that’s to save the function. At the top of the screen, click the orange Save button.

Once saved, the function will have a green check next to it in the Designer window:

lambda function designer

Since our function doesn’t take any input, running it is straightforward using the built-in test functionality. Click the Test button to the left of the Save button and Lambda will execute the function.

After the function completes, the screen will update to show the result of the execution, along with additional information such as the execution duration, maximum memory used, and the billing duration.

log output

At the bottom of the window, it also shows the log output from this execution. Let’s introduce an error in our code to see what this screen looks like when things don’t go so well.

Update the print statement in the code so it’s no longer correct by leaving off the closing parenthesis:

import json

def lambda_handler(event, context):
    print("Hello from Lambda!"
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

Save the function and click the test button again.

This time, when the function executes, it fails. You’ll once again see information about the execution—and this time, you’ll see the error message and stack trace as well.

lambda execution failed

Next, let’s take a look at the Monitoring section mentioned earlier in this post.

View your function logs using CloudWatch

Let’s free up a bit of screen real estate by removing the error message from the previous run. You’ll do that by clicking the X in the upper right part of the window.

Click on the Monitoring tab, next to the Configuration tab, to view this function’s CloudWatch metrics:

lambda CloudWatch

On this screen, we can see a lot of information, such as the function invocation count, error count, and success rate.

We don’t currently have a lot of data to look at here, so let’s take a look at the CloudWatch logs. Click the View logs in CloudWatch button above the charts to see the log streams for this function. Click on the first log stream in the table to see the log from our recent failure test case.

CloudWatch Logs

Each time our function runs, it creates a new log stream. This makes it easy to analyze what went wrong in a particular failure scenario. The most recent log stream shows the log output that the error message uses.

CloudWatch Log Groups

To see more information for each log event, click the arrow in the left to expand the message:

CloudWatch Log Groups

There’s a lot of other great information that CloudWatch tracks for us that we can’t cover here, but I suggest perusing the Getting Started With Amazon CloudWatch user guide. Now that we have a test function written and working, let’s add the ability to access environment variables so we can connect to a database.

Configure and access environment variables

If you recall from earlier in the article, Lambda allows us to set environment variables when configuring the function. In this section, we’ll set up an environment variable to indicate what release environment our function is executing in, for example, DEVSTAGE, or PROD. We’ll then look at how to encrypt sensitive information in environment variables, which AWS makes very easy with the Key Management Service (KMS).

First, scroll down to the Environment variables section on the function configuration screen. Environment variables are sets of key-value pairs, and we’ll use the ENV key to hold the release environment information.

Your environment variables should look like the following:

KMS environment variables

Now that the environment variables are set, let’s update our function to access the value of ENV.

You access environment variables in Lambda functions the same way as you would anywhere else. In Python, this is through the os.environ module.

Scroll back up and update the Python function to retrieve the values we set, and log the DB_HOST and DB_USER to CloudWatch:

import os

def lambda_handler(event, context):
    DB_HOST = os.environ["DB_HOST"]
    DB_USER = os.environ["DB_USER"]
    DB_PASS = os.environ["DB_PASS"]
    print("Connected to %s as %s" % (DB_HOST, DB_USER))
    return None

The above code first imports the os module. Then, in the lambda_handler function (our main entry point), it uses the os.environ function to access the environment variables, and it stores them in local variables.

Go ahead and save the function. Now, test it out, as we did earlier, by clicking the Test button. After it runs, expand the Execution result section, and you’ll see the log message containing the environment variables DB_HOST and DB_USER:

Lambda execution

If you’re as security conscious as I am, there’s something about this example that doesn’t sit right with you: the setting for the DB_PASS value. It’s in plaintext!

Let’s add a bit of security here and encrypt the environment variable.

Encrypt environment variables? Yes, please!

AWS makes it very easy to encrypt the environment variables using KMS. In order to save time, the example below uses a pre-existing key with the name myLambdaFunctionKey. If you don’t have a key yet, refer to AWS’s Creating Keys guide to create one before moving on.

Now that you have a key, return to the Environment variables configuration screen and expand the Encryption configuration section:

Check the Enable helpers for encryption in transit box, which displays a search box beneath it to select the key to use. Once done, you’ll have something similar to the following:

encryption in transit

Now there’s just one last thing to do, and that’s to actually encrypt the environment variable.

After selecting the key, you’ll notice that a couple of new buttons appear where you define the environment variables:

environment variables

Clicking the Encrypt button for any of these will encrypt the values and mask it from view on the screen. Note that you need to remove the value first and add it back in before the Encrypt button will perform the encryption.

Since this password wasn’t encrypted, we can consider it to be exposed. So let’s change it and then encrypt the new one:

Now our database password is safe and secure. But how do we use it in our function?

AWS provides a KMS client as part of the AWS software development kit. Let’s use that to handle our decryption.

Decrypt environment variables with the AWS SDK

Since the DB_PASS value is encrypted, we need to decrypt it before we use it.

Once again, AWS comes to our aid with the Boto 3 library. Boto is the Python version of the AWS software development kit (SDK). AWS also provides us with an example snippet, which can be seen by clicking the Code button. This will display example code showing how to decrypt the environment variable using the Boto library.

Secrets Snippet

Let’s work the above example in our function and clean it up a bit:

import os
import boto3
from base64 import b64decode

DB_HOST = os.environ["DB_HOST"] 
DB_USER = os.environ["DB_USER"]
 
DB_PASS_ENCRYPTED = os.environ["DB_PASS"]
cipherTextBlob = b64decode(DB_PASS_ENCRYPTED)
DB_PASS_DECRYPTED = boto3.client('kms').decrypt(CiphertextBlob=cipherTextBlob)['Plaintext']

def lambda_handler(event, context): 
    print("Connected to %s as %s" % (DB_HOST, DB_USER)) 
    return None

First, we import the b64decode function from the Python base64 library. We move the retrieval of the environment variables outside of the lambda_handler function since we don’t want the decryption routines running every time the handler is called. Putting the other environment variables outside of the function isn’t necessary, but it just keeps things tidy to have it all in one place.

The meat of this example is lines 11 and 12. The encrypted environment variable is stored in base64, so this is decoded and stored as binary in the cipherTextBlob variable. A KMS client is instantiated through the boto3.client interface, and the decrypt function is called on the cipherTextBlob. The decrypted environment variable is stored in the DB_PASS_DECRYPTED variable just like before.

Finally, we just print the host and user again. Save and run this, and then you can bask in the warm green light of knowing that you’ve made your function much more secure!

Troubleshooting

When initially setting this example up, I ran into a few configuration issues that I had to resolve. Those issues went places there’s just not room for in this article.

If you run into problems, here are some things to do and to know:

  • Check to make sure the function role has VPC access. The execution role set in the function configuration needs to have Amazon Virtual Private Cloud (VPC) access, or the function will time out. Check the role in the AWS Identify Access and Management (IAM) console to add the correct policies.
  • Check to ensure that the correct VPC is selected. The function needs to be in the right network, so double check that the correct VPC (and security group) is selected under the Network section of the function configuration screen.
  • It’s never the codeWell, sometimes it is. When adjusting the code for the last section, I left out the import statement for the b64decode function. I was also looking at the wrong error messages in CloudWatch and wasted a bit of time hunting down the issue. Such is life. Sometimes (most of the time?) it’s the simple things that get overlooked.

At this point, you’re probably wondering where to go next. Or maybe you already have a lot of great ideas. So let’s discuss next steps.

Where to go next?

Now that you’re here, you’ve successfully written your first Lambda Python function and can understand what happens when the function works according to your expectations—and also what happens when it fails. Like most things, however, this barely scratches the surface of the power of Lambda. So what now?

For starters, here are just a few ideas:

Once your applications get more complex, you’ll need additional tooling to help understand performance bottlenecks, as well as to troubleshoot harder-to-identify issues. Stackify created Retrace to address these exact scenarios. Retrace is an application performance monitoring tool that allows you to monitor, profile, and troubleshoot your code.

Also, try Stackify’s free code profiler, Prefix, to write better code on your workstation. Prefix works with .NET, Java, PHP, Node.js, Ruby, and Python.

Since Lambda ties so many different pieces of the AWS ecosphere together, there is no limit with what you can do. So go create something awesome, and welcome to the world of serverless computing!

Start Free Trial
]]>
AWS Lambda With Ruby: A Complete Getting Started Guide https://stackify.com/aws-lambda-with-ruby-a-complete-getting-started-guide/ Fri, 14 Jun 2019 14:19:30 +0000 https://stackify.com/?p=25324 It’s five o’clock on a Friday afternoon. There are no new bug reports and everything is looking smooth. Your plan of a relaxing weekend is in sight when you get a call—the website you look after isn’t responding. 

Yikes.

AWS Lambda minimizes the chance of this truly terrifying event from happening by taking care of server maintenance while you focus on coding robust applications.

AWS Lambda is a function-as-a-service platform that stores and executes your code when triggered by an Amazon Web Service (AWS) event. These events range from making an API call, to saving a file, to updating a database. You only pay for the execution of the function. There’s no other associated running costs or server maintenance, and you don’t need to worry about server load, because AWS will handle scaling. That gives you a consistent experience, no matter how much your function is used.

This post introduces AWS Lambda, discusses when you should and shouldn’t use it, and takes an in-depth look at how to create your first Ruby function using the AWS console.

The origins of AWS Lambda

At the 2014 AWS re:Invent conference, Amazon introduced Lambda to the world. Dr. Tim Wagner, general manager of AWS Lambda at the time, explained the benefits of using Lambda over EC2, the popular compute engine. Renting virtual machines in the form of EC2 instances from AWS brings flexibility and choice, but the tradeoff is that there’s an unnecessary cost when idle. Plus, there’s the additional complexity maintaining the infrastructure even when it’s not in use.

The benefits of Lambda

The benefits of AWS Lambda, as explained by Tim Wagner at re:Invent 2014, are

  • Reduced complexity. There’s a fixed operating system, fixed software language, and a fixed version.
  • No infrastructure to manage. AWS owns and manages the infrastructure. You only pay for the time your code runs.
  • Implicit scaling. AWS will handle scaling, no matter how much you use your functions.

An explanation of AWS events

An AWS event is a JSON message containing the origin and associated event information, depending on the service. For example, if you add a file to the Amazon Simple Storage Service (S3), this will create an event containing the origin as the Simple Storage Service, the location of the file, and information that an item was added.

The services that can raise events that can trigger a function are

Events trigger a Lambda function execution

Events trigger a Lambda function to execute. It’s executed either directly or is added to a queue to be executed in the future. If you’d like the full list of how services create events, you can check out the AWS documentation. In short, a Lambda function subscribes to the notification-specific event from a specific source and will ignore all other events from any other source.

Programming language support

AWS Lambda currently supports RubyJava, Go, PowerShell, Node.js, C#, Ruby and Python. AWS also periodically introduces support for new programming languages

Use cases where Lambda excels

Lambda excels when the task has one or more of the following characteristics:

  • It’s isolated. Tasks that perform only one function—for example, updating a database or storing a file—are great.
  • It’s asynchronous. We’re talking about low priority tasks that don’t expect an immediate response. This could be sending an email or SMS.
  • It broadcasts. That means it’s updating lots of different systems from one action, like creating a repository on GitHub.
  • There are big peaks in demand. Lambda works well when, during different times of the year or day, the demand is different. This could occur during peak holiday season.
  • There’s low throughput. This occurs when a task happens rarely, such as a sensor that only reports on change (like a door).
  • It’s a prototype or mock. Lambda shines when you’re working with a proof of concept before committing more time to a project.
  • It’s stateless. Nothing needs to be stored in memory.

Use cases where Lambda is not so useful

Lambda doesn’t excel where the task has the following characteristics:

  • It’s long-running. Functions are limited to 15 minutes, so any tasks that exceed that will fail.
  • It has a consistent load. It may be cheaper to use a dedicated instance if the load is predictable.
  • It’s intensive. Functions can only allocate 3GB of memory, so any intensive tasks will fail.
  • It requires a specific operating system or language. If tasks are tied to a specific operating system and have limited language support, Lambda might not help.
  • It has a stateful system. Here, we’re talking about tasks that rely on a state to be stored between functions—for example, storing and retrieving files locally on the server.

A use case for writing a Lambda function

Imagine you’re building a solution for users to store files. You choose AWS S3 as the location of your files because it’s easy to manage and scale. The users can name the images anything they want, but you want to shorten the names to fit with the user interface design of a new app.

Renaming files is an ideal task for a Lambda function because it’s a small isolated function, and it doesn’t have to be run immediately. Plus, it’s stateless.

The starting point for your Ruby Lambda function

The starting point for creating this function is a Lambda concept known as a handler. A handler is a method written in a Ruby file. In Ruby, file names are normally all lower case and separated by an underscore. For this example, we’ll use the default file name when creating a new Lambda, lambda_function.rb.

The lambda_function.rb file contains a method, and its default name is lambda_handler. This method contains the logic, and it will be run on an event trigger.

The first named argument for the lambda_handler method is the event. The JSON AWS event converts into a Ruby object and is assigned to this argument.

The second method argument is the context. The context is assigned to a hash, which contains methods that provide information about the function, such as the name and any limits. A full list of all the information context holds can be found in the AWS docs.

This code shows my lambda_function.rb file and the method, lambda_handler.

#lambda_function.rb
def lambda_handler(event:, context:)
end

This the base of a Lambda function and the minimum required for the Lambda to execute.

Reading information from an event

The main method that handles the processing of our event, named lambda_handler above, accepts event as an argument. This parameter is a Ruby hash converted from a JSON string containing the origin of the event and any contextual information. For our example, this will contain the name of the bucket and key of the file stored in S3.

The bucket name and key in S3 uniquely reference the image we’re storing. To retrieve these values from the event hash, update the lambda_handler method to reference the bucket name and key values from the event. See the code below for how this looks in the lambda_handler function:

def lambda_handler(event:, context:)
    first_record = event["Records"].first
    bucket_name = first_record["s3"]["bucket"]["name"]
    file_name= first_record["s3"]["object"]["key"] 
end

The above code shows retrieving the first record of the event. There will only be one record in total when adding a file to an S3 bucket. The bucket_name and file_name are then extracted from the record.

Shorten the name of the file

To shorten the name of the file, we’ll use standard Ruby libraries to extract the first 21 characters of the original file name.

One of the great aspects of using Ruby for writing Lambda functions is the simplicity of string manipulation. The below code will assign the first 21 characters of the variable file_name to the variable short_name:

short_name = file_name[0..20]

This code uses the fact that a string can be accessed the same way as arrays and selects the range from zero to 20.

Using the AWS SDK

Lambda functions are already configured to use the AWS SDK for Ruby, so no gems need to be installed before we can use the library. To reference the SDK, add a require statement to the top of your lambda_function.rb file. The below code shows the require statement at the top of the lambda_function.rb file:

require "aws-sdk-s3"

The code above loads the gem containing helper functions to communicate with the S3 service.

Moving your file from one bucket to another

To move your files from one bucket to another, reference the original image and call the move_to function on that object. The code below shows how to use the built-in SDK functions to move the file:

# Get reference to the file in S3
client = Aws::S3::Client.new(region: 'eu-west-1')
s3 = Aws::S3::Resource.new(client: client)
object = s3.bucket(bucket_name).object(file_name)

# Move the file to a new bucket
object.move_to(bucket: 'upload-image-short-name', key: short_name)

This code will create a new client in the eu-west-1 region, create a new s3 resource, and use the resource to reference a specific object: in this case, a file. The next action is to move the object to a new location. The move_to method calls the S3 service to copy the original file to the new location. Then, it deletes the original.

Putting the code together

When put together, the above code will achieve our goal of moving a file from one bucket to another, shortening the name to 21 characters.

require "aws-sdk-s3"

def lambda_handler(event:, context:)
    # Get the record
    first_record = event["Records"].first
    bucket_name = first_record["s3"]["bucket"]["name"]
    file_name = first_record["s3"]["object"]["key"]

    # shorten the name
    short_name = file_name[0..20]

    # Get reference to the file in S3
    client = Aws::S3::Client.new(region: 'eu-west-1')
    s3 = Aws::S3::Resource.new(client: client)
    object = s3.bucket(bucket_name).object(file_name)

    # Move the file to a new bucket
    object.move_to(bucket: 'upload-image-short-name', key: short_name)
end

This a working Lambda function containing the code from the previous sections of this post.

Now that we have our function, we can configure AWS to run it in a Lambda when we upload a file. To achieve this we need

  • An AWS account.
  • Two buckets—one for the initial upload and the other for storing the files once the name is changed.
  • A Lambda function triggered by upload of a file.

Setting up an AWS account

If you don’t already have an AWS account, you’ll need to set one up with Amazon. They have a generous free tier, which will cover creating this function and testing it. Amazon has a great guide on how to create and activate an AWS account, so follow this guide if you don’t already have one.

Create two S3 buckets

Create two buckets: one that will allow initial upload of the files and another to store the files once they have been renamed. Amazon has a great guide on how to create a bucket, if you wind up needing help.

Creating your Lambda function using the AWS console

You can create a function by writing the code directly into the AWS console or by writing the code on your computer and then uploading to AWS. The rest of this post covers creating your function via the AWS console.

It’s important to note that functions are located in a specific region. A region relates to a specific datacenter owned and ran by AWS. Services can’t communicate between regions easily, so make sure the Lambda is in the same region as the S3 buckets.

If you’re choosing a region for the first time, choose the region closest to you. You should also consider that some regions don’t have all the features that others do. Concurrency Labs has a great blog post called “Save yourself a lot of pain (and money) by choosing your AWS Region wisely,” and it’ll help you choose.

Create your function using the console

To create a Lambda function through the AWS console, navigate to https://console.aws.amazon.com/lambda in your browser. By default, this will open the console in your default region. My default region is eu-west-2, located in the nearest location to me, London.

Select Create function to create a new Ruby function in the eu-west-2 region.

AWS Lambda Ruby Function

The above image shows the values you should select to create a new Ruby function successfully. Once you have selected these values, click Create function. This will display the designer view shown below:

Designer View

This is a visual representation of your Lambda workflow. On the left is the trigger and on the right is the flow from the trigger to the output of the function.

Trigger your Lambda function from an event

To set up a trigger for your Lambda function, select S3 from the designer view. This will open the configuration menu for the S3 trigger, as shown below:

AWS S3 Trigger

The above trigger view shows the configuration options for S3. Select the bucket that contains the uploaded images in the Bucketdropdown and press AddYour Lambda function will now run whenever an image is uploaded to that bucket.

Configure your Lambda function

Select the Lambda function box from the designer view. This will open the Function code view, shown below the designer, already populated with an example function. Copy the code we created earlier in this blog post into the lambda_handler method in the lambda_function.rb file:

Lambda Function Ruby

Give Lambda permissions to write to S3

To allow your function to copy the file from one bucket to another the function requires some extra privileges. Select the Lambda function and scroll down to the configuration section shown below:

Lambda Execution Role

The above image shows the Lambda configuration section, focused on Execution role. Click the link named View the RenameFile-role-<unique value>. The link will redirect you to the AWS IAM service. Click Attach policy.

AWS IAM Attach Policy

The above shows the attach policy view of the IAM service.

Now, search for s3. This will show all the policies relevant to S3. Select AmazonS3FullAccess and press the Attach policy button. You should now see an extra box on the designer view, and Lambda will now have access to all buckets in S3.

AWS S3 Buckets

Test your function

Upload a file with a name longer than 21 characters to your image bucket. The file will shortly be deleted and transferred to the small names bucket and be 21 characters long. And there you go—test passed!

Writing Lambda functions in Ruby

Ruby is a great language, and I’m really happy AWS is now supporting Ruby functions in Lambda. Once you’re comfortable with the basics and want more advanced functions, Serverless Framework is a great next step. Serverless Framework allows you to package up gems to use in your function outside of those provided by Lambda. It also helps with versioning and organizing your code, along with storing the configuration for your functions.

Another tool that could speed up your development is Ruby on Jets, an easy-to-use Rails-like framework to create API endpoints and recurring jobs. These tools provide an abstraction on top of Lambda, and the generated functions can always be verified via the AWS console.

CloudWatch is the default monitoring tool created by AWS to keep track of errors in your Lambda functions. It’s a good tool, but it’s very labor intensive because looking through the CloudWatch logs is a manual process. Using a tool like Retrace could help monitor how and when each of your functions are being executed and track any errors together with context in a convenient dashboard.

Lambda is not the solution to every problem, and overuse might lead to unnecessary complexity. Take each use case one at a time and decide if Lambda is the correct solution for you.

]]>
What is Cloud Monitoring? How to Make Sure Cloud Services are Working Properly https://stackify.com/cloud-monitoring/ Sat, 23 Sep 2017 15:25:15 +0000 https://stackify.com/?p=13564 Cloud monitoring is the process of evaluating, monitoring, and managing cloud-based services, applications, and infrastructure. Companies utilize various application monitoring tools to monitor cloud-based applications. Here’s a look at how it works and best practices for success.

Types of Cloud Services to Monitor

There are multiple types of cloud services to monitor. Cloud monitoring is not just about monitoring servers hosted on AWS or Azure. For enterprises, they also put a lot of importance into monitoring cloud-based services that they consume. Including things like Office 365 and others.

  • SaaS – Services like Office 365, Salesforce and others
  • PaaS – Developer friendly services like SQL databases, caching, storage and more
  • IaaS – Servers hosted by cloud providers like Azure, AWS, Digital Ocean, and others
  • FaaS – New serverless applications like AWS Lambda and Azure Functions
  • Application Hosting – Services like Azure App Services, Heroku, etc

Many of these can be monitored usually traditional application performance monitoring tools. However, cloud monitoring has some unique requirements over basic server monitoring tools. There are also companies like Exoprise who focus on monitoring Office 365, Salesforce and other services.

How It Works

The term cloud refers to a set of web-hosted applications that store and allow access to data over the Internet instead of on a computer’s hard drive.

  • For consumers, simply using the internet to view web pages, access email accounts on services such as Gmail, and store files in Dropbox are examples of cloud computing for consumers.
  • Businesses use it in many of the same ways. They also may use Software as a Service (SaaS) options to subscribe to business applications or rent server space to host proprietary applications to provide services to consumers.

Cloud monitoring works through a set of tools that supervise the servers, resources, and applications running the applications. These tools generally come from two sources:

  1. In-house tools from the cloud provider — This is a simple option because the tools are part of the service. There is no installation, and integration is seamless.
  2. Tools from independent SaaS provider — Although the SaaS provider may be different from the cloud service provider, that doesn’t mean the two services don’t work seamlessly. These providers also have expertise in managing performance and costs.

Cloud monitoring tools look for problems that can prevent or restrict businesses from delivering service to their customers. Generally, these tools offer data on performance, security, and customer behavior:

  • Cybersecurity is a necessary part of keeping networks safe from cyber attacks. IT teams can use it to detect breaches and vulnerabilities early and secure the network before the damage gets out of hand.
  • By testing at regular intervals, organizations can detect errors quickly and rectify them in order to mitigate any damage to performance and functionality, which improves the customer experience and, as a result, can boost sales and enhance customer retention.
  • Speed — like functionality and user experience — is a primary driver of customer satisfaction. Speed metrics can be monitored and generate data that helps organizations optimize websites and applications.

If an organization monitors early and often, they can use the data to troubleshoot problems and implement repairs in a timely — if not instantaneous — manner.

Benefits of Cloud Monitoring

The top benefits of leveraging cloud monitoring tools include:

  • They already have infrastructure and configurations in place. Installation is quick and easy.
  • Dedicated tools are maintained by the host. That includes hardware.
  • These solutions are built for organizations of various sizes. So if cloud activity increases, the right monitoring tool can scale seamlessly.
  • Subscription-based solutions can keep costs low. They do not require startup or infrastructure expenditures, and maintenance costs are spread among multiple users.
  • Because the resources are not part of the organization’s servers and workstations, they don’t suffer interruptions when local problems disrupt the organization.
  • Many tools can be used on multiple types of devices — desktop computers, tablets, and phones. This allows organizations to monitor apps and services from any location with Internet access.

[adinserter block=”33″]

Best Practices

Organizations need to make cloud monitoring a priority and plan for it. The plan should include questions that need to be answered and goals of implementation, such as:

  • Identify metrics and events – What activity needs to be monitored? Not everything that can be measured needs to be reported. Monitor the metrics that matter to the bottom line.
  • Use one platform to report all the data – Organizations may have their own infrastructures in addition to cloud services to monitor. They need solutions that can report data from different sources on a single platform, which allows for calculating uniform metrics and results in a comprehensive view of performance.
  • Monitor cloud service use and fees – The ability to scale is a feature is a key feature of cloud services, but increased use can trigger increased costs. Robust monitoring solutions should track how much organization activity is on the cloud and how much it costs.
  • Monitor user experience – Organizations need to know what users experience when using their cloud-based applications. Monitor metrics such as response times and frequency of use to get the complete picture of performance.
  • Trigger rules with data – If activity exceeds or falls below defined thresholds, the right solution should be able to add or subtract servers to maintain efficiency and performance.
  • Separate and centralize data – Organizations should store monitoring data separately from their apps and services, and it should be centralized for easy access for key stakeholders.
  • Try failure – Test your tools to see what happens when there is an outage or data breach and evaluate the alert system when certain thresholds are met.

Additional Resources and Tutorials

For more information and tips for implementation, visit the following resources:

Monitoring is a must for any organization leveraging the cloud, both for security and performance, but choosing the right application performance monitoring (APM) solution can be challenging. Check out this post to learn about the common mistakes IT management teams make when evaluating and implementing APM solutions. Got noisy neighbors impacting your performance? Read our article for tips on monitoring your noisy cloud neighbors and web apps with Stackify’s Retrace for APM.

]]>
What is the Future of Multi-Cloud Computing? https://stackify.com/future-multi-cloud-computing/ Fri, 25 Aug 2017 15:17:49 +0000 https://stackify.com/?p=13527 Like so many other IT solutions, cloud computing services have long been promoted from a standpoint of administrative efficiency. As the rationale goes, if you get your cloud services from a single provider, you’ll enjoy the reduced hassle of consolidating third party business relationships, receive IT services at bargain prices, and have an easier time coordinating those services.

It’s true that using fewer service providers can offer some nice perks, but cloud computing is moving in the opposite direction at many companies. Instead of reaping the benefits of placing cloud services under one umbrella, businesses are mining the advantages of the antithetical approach: receiving cloud services from multiple providers ― a discipline known as “multi-cloud computing.”

According to a mid-2016 report from Business Cloud News (BCN), “57% of organizations have no multi-cloud strategy at all, whereas 35% do not have a private cloud strategy, and 28% lack one for [a] public cloud.” According to IT commentators ranging from Google to Forbes, these three groups have one thing in common: All of them will increasingly adopt multi-cloud strategies as the technology improves and proliferates.

The Sun Behind the Clouds

Multi-cloud computing brings the need to maintain multiple cloud provider relationships instead of maintaining just one. In the aftermath of the Great Recession, when company decision makers are still accustomed to viewing every kind of business functionality through the lens of cost cutting, it begs the question: What do companies get in return for taking extra time to oversee those relationships?

The answer is simultaneously vague and clear: It depends on the needs of the company in question. However, the characteristics of some companies set them up to benefit from multi-cloud computing more than other companies.

Company Size

For example, company size can be a big determinant of multi-cloud benefits. According to a 2017 report from Network World, “It’s inevitable big companies with many divisions and their own agendas and vendor alliances will end up with multiple clouds … Settling on a single cloud model would create compromises for such [companies] that would ultimately dilute [the cloud’s] benefits and the business use case.”

Cloud Performance

Another value proposition of multi-clouding involves the performance of cloud resources. From the same Network World report: “Organizations tend to prefer a multi-cloud strategy to get out of the ‘keeping all your eggs in one basket’ problem that can leave them vulnerable to a variety of issues, such as cloud data center outages, bandwidth problems, and vendor lock-in.”

Data Compliance

Concern over data compliance also leads to using multiple clouds. This alleviates the worry about the level of data exposure in places where cloud services are largely ungoverned. Companies that do this can store offsite backup data close to home, while opportunistically receiving other cloud services from providers in other locations.

Hybridization: A Sensible Approach

For comparison’s sake, cloud computing is commonly discussed using two basic cloud models: public clouds, which are outsourced; and private clouds, which are deployed and maintained in-house. But there’s another popular cloud model ― the hybrid cloud ― that has taken on new meaning in the age of multi-clouding.

Forward-looking companies utilize this model of hybridization when it comes to efficient, yet security-focused storage and network processes. While public or third-party clouds offer a wealth of resources when it comes to data storage, they’re still vulnerable to hacks, data breaches, or other security failures. For organizations that need a heightened level of security, hybrid models of private servers plus outsourced public solutions provide the best of both worlds: convenience and peace of mind.

Data Migration

Hybrid clouds are precisely what they sound like: a hybridization of public clouds and private ones. Hybrid clouds are often used for efficiency’s sake. Cloud functions that apply to the user’s core business practices may be kept in-house, while functions that are tertiary to core practices ― and should ideally be handled by an expert third party ― are outsourced.

This situation also provides a highly flexible way for companies to fully outsource multi-clouding. Instead of implementing a public multi-cloud in one fell swoop and incurring a steep learning curve for using the new system(s), companies can migrate services from private clouds to public servers one by one, in a manner less jarring to cloud-based processes.

Proprietary Data

Another advantage of gradually migrating from private to public clouds is that companies have more time to evaluate service providers. The providers store a company’s business data ― albeit, in encrypted form ― on their servers. Considering that proprietary data is the most valuable asset most companies possess, the more time they have to vet offsite data storage providers, the better.

This brings us to a question many companies face when they evaluate the benefits of multi-cloud computing: What if company policy prevents third party service providers from storing proprietary information in a public cloud?

You could develop an initiative to change company policy, but it would be timelier ― and probably involve a lot fewer clashes of opinion ― to simply keep using a hybrid model, in a reduced capacity. Simply save the cloud for apps that involve sensitive data you can’t share. This doesn’t reduce the effectiveness of a multi-cloud setup but rather plays into its general philosophy: Use the best cloud for a particular, cloud-supported IT function.

Cloud Computing Tomorrow

Due to these concerns and others, multi-cloud computing is poised to morph from a pervasive trend into a longstanding practice in numerous industries that have business-critical cloud computing needs. But the growth of using multiple clouds doesn’t necessarily mean the number of the clouds in multi-cloud setups will increase.

Rather, the goal will be to use as many clouds as necessary to address the drawbacks of using one cloud from a single provider ― even if that provider is a company providing its own cloud on a private model. Moving from cloud to cloud to perform tasks can be complicated, especially right out of the gate. But cloud service providers are working to make toggling between clouds increasingly efficient. The more efficient it becomes, the more multi-cloud computing will thrive.

Also check out: 8 Cloud Computing Advantages for Developers

]]>
6 Reasons Cloud Monitoring Is Different Than Server Monitoring https://stackify.com/cloud-monitoring-vs-server-monitoring/ Thu, 25 May 2017 14:30:27 +0000 https://stackify.com/?p=11442 Traditional IT monitoring has revolved around monitoring the infrastructures and servers. As you move to the cloud, it is possible that you don’t have either of those things. You could deploy your app via a service like Azure App Services and rely on Azure’s hosted Redis and SQL offerings. You could literally have access to zero servers.

In the cloud, it is even more important to monitor your actual applications and not just your servers. Application performance management solutions become even more important. Your cloud provider is responsible for monitoring the infrastructure and keeping your servers online. You still need to monitor the performance of your actual applications.

Cloud Application Monitoring vs Server Monitoring

1. Monitoring Platform-as-a-Service (PaaS) Style App Hosting

One of the big advantages of cloud computing is the ability to deploy your applications, and the server aspects of it are completely managed. As a developer, I love only having to worry about my application.

Application deployment options like Heroku, Azure App Services, Google Cloud Engine and others potentially create some monitoring challenges. You may not have full access to the underlying servers and typical monitoring solution will not work. Some of these also provide deployment slots which are also unique from a monitoring perspective.

At Stackify we use Azure App Services. Using them as an example, we do not have access to the server themselves. We can use the Azure KUDU console to access a pseudo file system, Event Viewer, IIS Logs, running processes, and other information. We also can’t access Windows Performance Counters. To monitor our instances we use a special WebJob as a monitoring agent instead of installing on directly on the server. Cloud application monitoring is really critical in these scenarios.

2. Auto Scaling in the Cloud

One of the big advantages of cloud hosting is the auto-scaling capabilities. Many companies have peak times of day or week for their applications. Outside of those peak times, they should scale their applications down to save on server expenses.

Cloud monitoring solutions have to support the autoscaling of the applications. The number of the instances of the applications could constantly be changing, and each one still needs to be monitored. The cloud monitoring tool must easily install as servers are created and handle scaling down.

3. Server Monitoring is Not Cloud Monitoring

Traditional server monitoring has revolved around if a server was up or down and what the CPU and memory usage is. Once you move to the cloud, these are details you don’t have to worry as much about or may not even have access to. You can setup auto-scaling or use a serverless architecture and it just works. Monitoring cloud applications is a little different!

Application performance monitoring is still very important. You still need to know which requests in your application are used the most and which are the slowest. APM solutions, like Retrace, can help provide cloud performance monitoring. You also need to monitor application metrics via Windows Performance Counters, JMX MBeans, or other common metrics.

More: Application Monitoring Best Practices for Developers with Retrace APM

4. Function-as-a-Service (Faas) or Serverless Architectures

Developers are starting to take advantage of new serverless architectures. Services like AWS Lambda and Azure Functions make it easy for developers to deploy applications as individual pieces of business logic. The cloud providers can then process requests for those functions at nearly infinitely scale. They have completely abstracted away from the concept of servers.

Monitoring serverless architectures is a whole new paradigm. Cloud monitoring solutions are going to have to play catch-up when it comes to monitoring these new types of applications. The cloud providers are also going to have to build new capabilities to make the monitoring possible.

5. Monitoring Cloud Application Dependencies

Cloud providers provide a wide array of specialized databases, queuing, storage, and other services. Some examples from Azure are Cosmos DB, Service Bus, Table Storage, and others. For AWS it would be services like Redshift, DyanamoDB, SQS, and others. Traditional monitoring solutions were not designed to monitor the special services. You will need to monitor these via the cloud provider or via specialized cloud monitoring solutions.

Cloud performance monitoring dependency map
Application Dependency Mapping

More: Application Dependency Mapping & Performance

6. No Infrastructure to Monitor

In the cloud, you don’t have to worry about monitoring traditional IT infrastructure. There are no switches, firewalls, hypervisors, SANs, or similar devices to monitor. The cloud providers are responsible for all of this under the covers. It has all been abstracted away from us, which is a beautiful thing. I just want to setup 100 servers, and I need 10 terabytes of SSD storage. I don’t care how it works!

Summary

If you have taken your app and moved it to some virtual machines in the cloud, you can probably keep monitoring your servers and applications the same way you have been. However, if you are “all in” and taking full advantages of all the Platform-as-a-Service features, you will likely need to re-think how you monitor your applications. Moving to the cloud creates new opportunities and challenges. Cloud performance monitoring is perhaps both!

]]>
Azure vs. AWS Cloud Service Comparison: Which One is Better? https://stackify.com/azure-vs-aws-comparison/ Tue, 11 Apr 2017 13:00:45 +0000 https://stackify.com/?p=10405 We’ve used Azure for nearly five years at Stackify; in fact, we built Retrace with Azure in mind. But is Azure the right cloud for you? The battle between Azure and AWS is heated, so we decided to see how they measure up in this head-to-head comparison. (Get a side-by-side, feature-by-feature comparison chart including Google Compute.)

Customers love Amazon Web Services (AWS).  There is no doubt about that.  The segment earned a profit of more than $3 billion on revenues of more than $12 billion for the full year of 2016.  That’s an increase from only a little less than $8 billion in revenues the year before.

That gives AWS a run rate of $14 billion, which is similar to the run rate posted by Microsoft for its commercial cloud services.  While it does not mean that Microsoft’s Azure is on equal footing as AWS as far as customers go, it does show us that Azure is a worthy contender for the cloud service provider of choice.  This perception is boosted by Azure’s offerings, which can easily match those of AWS.

If anything, Amazon has the starting lead as it has been in the cloud computing services space for more than ten years.  Azure has only been a market player starting 2010.  That is not to say that AWS is better by default because Microsoft is a known powerhouse and it has the resources to create an outstanding product or service if it decides to.  And by all indications, Azure is one of those products that the software giant is relying on for its revenues.  So how does Azure compare with AWS?

The Essentials

Amazon’s AWS has a range of offerings that fall under IaaS, and each of these is categorized into four classes:

  • content delivery and storage,
  • compute,
  • networking, and
  • database.

No matter which IaaS offering you get, you will be using Amazon’s identity and security services such as AWS CloudHSM’s key storage service and Amazon’s own Active Directory.  Not only that, but AWS offerings also have a range of management tools that users can use, including AWS Config, AWS Cloudtrail, and Cloudwatch.

Azure, on the other hand, also has four classes of offerings:

  • Data management and databases,
  • compute,
  • networking, and
  • performance.

Security and management tools include Active Directory Federation Services, Azure Active Directory, Multi-Factor Auth, among others, as well as a range of integrations for Azure monitoring and performance tweaks.

Developer Love: Deploying Apps & PaaS

One of the biggest advantages of cloud computing is the simplicity of deploying an application. As a developer, I want to deploy my app to multiple servers without having to deal with the actual servers. Being able to take advantage of PaaS features like SQL databases, caching, queueing, NoSQL and other technologies are also a big deal. Developers can use services like Redis & Elasticsearch without having to figure out how to install and manage them. Check out our post on top Azure PaaS services developers love and why.

Azure has multiple app deployment options for developers. Including App Services, Cloud Services, Service Fabric, Container Service, Functions, Batch, WebJobs and more. No matter what type of application you are developing, Microsoft has great tools in place to help deploy and scale it.

AWS offers similar solutions with Container Service, Elastic Beanstalk, Lambda, and Batch. AWS does not have as many options or features on the app hosting side. Microsoft has flexed their knowledge of developer tools to have a little bit of an advantage for hosting cloud apps.

Containers seem to be the preferred mechanism to deploy apps in the future, especially for open source applications. Look for more and more advancements in hosting containerized apps in the cloud.

Hybrid Cloud & Legacy Apps

One of the hindrances of companies that are planning to migrate to cloud computing is their use of legacy apps.  Not all companies would have the resources to create new apps for the cloud environment or even start everything up.  For those that need to rely on legacy apps, a hybrid cloud that would combine the cloud environment with their data centers would be a lot of help.

Hybrid clouds are also one of the most popular choices for some companies that do not want to make a full conversion to the cloud and would want to keep some of their data and systems in-house.

Hybrid clouds are easier with Azure, partly because Microsoft has foreseen the need for hybrid clouds early on.  Azure offers substantial support for hybrid clouds, where you can use your onsite servers to run your applications on the Azure Stack.  You can even set your compute resources to tap cloud-based resources when necessary. This makes moving to the cloud seamless.  Aside from that, several Azure offerings help you maintain and manage hybrid clouds such as Azure Stack, Hybrid SQL Server, and Azure StorSimple. Microsoft’s long history of working on enterprise IT gives them an upper hand when it comes to the hybrid cloud.

While Amazon realizes that it needs to strengthen its offerings to support hybrid clouds, it is still catching up, with more investments earmarked for hybrid clouds, according to Brian Olsavsky, Amazon’s chief financial officer. Still, the retail giant currently has a handful of solutions that is geared for companies who wants hybrid cloud deployments such as Storage Gateway, Direct Connect, and DynamoDB Local.

Azure vs AWS for Microsoft Shops

Microsoft has long been synonymous with larger enterprise customers. Microsoft Azure makes it easy for those currently using Windows Server, SQL Server, Exchange, and other Microsoft technologies to move to the cloud.

For .NET developers, publishing your application to Azure is amazingly simple. Publishing an app to Azure App Services or Cloud Services takes away all of the headaches of deploying apps and managing servers.

For Microsoft shops, Azure will hold a strong edge. Although, AWS supports Windows, SQL Server and other technologies that .NET developers are used. Amazon AWS has a great SDK for .NET. AWS might be more compelling for .NET developers if there is a particular AWS feature that is needed, that does not have an Azure equivalent.

Learn more about how Stackify uses Azure: Azure lets Stackify easily empower fellow developers

Azure vs AWS for Open Source Developers

Amazon might have started off as merely an online seller, but Microsoft has consistently had its eye on business customers focusing on Windows and similar platforms.  Azure continues this rapport with enterprise users by making sure that integration with Visual Studio is smooth, as well as the integration with Active Directory.  You can even use your current Active Directory account to sign on the Azure platform and Office 365.

However, Amazon shines when it comes to open source developers.  Microsoft has historically been very closed to open source applications, and it turned a lot of companies off.  AWS, on the other hand, welcomed Linux users and offered several integrations for open source apps.

In recent times, Microsoft has openly embraced open source technologies. Microsoft recently opens sourced the .NET Framework and the new .NET Core runs on Windows, MacOS, and Linux. SQL Server now runs on Linux. Microsoft also claims that about 1/3 of Azure Virtual Machines are running Linux and some of the infrastructure that drives Azure even uses Linux.

Government Cloud

When you think of the cloud, you probably think of startups and big tech companies. IT leaders working in the government are also working on moving their apps to the cloud. Government websites and other cloud deployments need to adhere to certain regulations, which is why putting government assets on public clouds raises warning flags as far as compliance is concerned.

The good news is that both Azure and AWS have a special section for government users.  These government clients make use of this isolated area so that their workloads do not share the computing, networking and other resources with ordinary business users.  Azure and AWS promise compliance with various regulations, such as the HIPAA, DISA, FIPS, among many others.

MORE: Azure Government Cloud & AWS Government Cloud

License, Fees and License Mobility

AWS has always made it a point to give customers headache-free licensing.  It is all a matter of paying for the licenses that you use no matter what AWS is offering you avail of.  But if you have Microsoft licenses that you’ve already paid for, you might be eligible for license mobility.  This means that you do not have pay double for using the same Microsoft server applications you’re currently using.

Azure also has the same license and mobility standards.

Do not assume, however, that all your Microsoft licenses are eligible.  For instance, Windows Server is not a part of the list of available applications, but Exchange Server, SQL Server, Skype, System Center Server and Project Server are.

Estimated costs for the use of either AWS or Azure might be a little difficult to come up with, but both services currently offer cost calculators that users can use to get an idea of how much they can expect to spend on each platform.

Features

On a per feature basis, you will find that most of all features offered on Azure have a corresponding or similar feature on AWS.  And while it will be quite difficult to come up with an exhaustive features list, you might find it interesting that some Azure services have no AWS equivalent. These include the Azure Visual Studio Online, Azure Site Recovery, Azure Event Hubs, and Azure Scheduler.  However, it seems that AWS is trying to close the gap.  For instance, AWS now offers AWS Lambda on preview to counter Azure’s Logic Apps.

In the end, choosing between Azure and AWS would depend on what you need and what they offer.   Which one is better? There is simply no blanket and definitive answer to that question.  Both AWS and Azure have free offerings and trials, so give each one a test run to help you get a feel of what to pick!

Cloud Services Comparisons

The battle between Microsoft Azure and Amazon Web Services has been heated for months, and experts everywhere are placing bets on who’s going to win the race. For more insights on the ongoing battle between these two leading cloud vendors, check out the following resources:

]]>