Heptio Quick Start for Kubernetes using the AWS IOT Button

I’ve been doing a lot of personal learning around the Kubernetes project in the past year and one tool that’s been front and center when it comes to hacking around with almost any new Kubernetes based project is the Heptio Quickstart. Sure, there are full-fledged hosted services and tools like kops, but in the event that I need to get a cluster up quickly, the quick start has been my easy to work with go-to tool…

An easy button you say? OK!

Exactly. So, how do we make the process of deploying the quickstart that much easier? Ideally, instead of logging into the AWS console every time and filling out a form to deploy the template, I’d rather just hit a button and have it happen… With the help of the help of the AWS IOT button, some lambda built out of crappy python code, I’ve been able to hack together just that.

Architecture – How it all ties together:

  • The AWS IOT Service recognizes the difference between a single click and a double click of the IOT button (A single click deploys the CloudFormation stack. A double click destroys the CloudFormation Stack). IOT Passes the “CLICKTYPE” along with a bit of information about the device that was clicked over to AWS lambda.
  • AWS Lambda houses a bit of bad python code that was hacked together by yours truly. This code along with some environmental variables uses boto3 to tell CloudFormation to deploy the Heptio Quick Start using a new VPC from the publicly available Heptio S3 bucket.
  • CloudFormation creates or deletes the Heptio CloudFormation nested stack based on how the button was pushed and the environmental variables passed to the lambda function

Let’s get building!

Really there are two parts to the project the IOT part and the lambda part. For me, clearly hacking together the Lambda part was the most difficult part of the journey, but also the most rewarding. Feel free to use my work to get your stack up and running fast! The IOT stuff can seem complex but if you approach it from the AWS lambda side, there’s a form to help you get up and running lickety-split! Let’s dive into the Lambda part first and end at adding the IOT button in the end.

IAM for the lambda function

In order to deploy CloudFormation templates with AWS Lambda, an IAM role needs to be defined with the appropriate permissions to create and delete the stacks on your behalf. We’ll need to jump over “Identity and Access Management” in the console to do this work:

From the IAM page in the AWS console:

  • Click Roles in the left-hand navigation bar
  • Select the “Create role” blue button.
  • Select AWS service as the trusted entity and “Lambda” as the service that will use the role.
  • Select the AdministratorAccess and click next. (Still working on a better policy document)
  • Add something under “Role Name” – k8s-control
  • Add a description if you would like
  • Click “Create role” in the lower right-hand corner

Building the Lambda function:

Now that the IAM role is ready, we can worry about getting the Lambda function in place to execute the CloudFormation stack build. Jump over to AWS Lambda in the AWS Services console to create the Lambda Function:

  • Click Create Function
  • Select Author from Scratch
  • Add a name – heptio-qs-iot-button
  • Select Python 2.7 for the Runtime
  • Select Choose an existing role for the Role
  • From the “Existing Role” select the role that you just configured in the IAM console.
  • Click “Create function”

In the AWS Lambda function console, we’ll be working in the “Function code” area.

  • Under Code entry type – select “Edit code inline”
  • Under Runtime – select “Python 2.7”
  • Under Handler – lambda_function.lambda_handler


Copy the launch-cfn.py code from my GitHub repo and paste it into the integrated Cloud9 editor. Review the code to make sure that I’m not doing anything that you don’t agree with in your environment. You’ll see that we’re picking up the Heptio Quick Start CloudFormation template and then passing it the parameters that it needs to build the stack (more on that in a second).

In the left-hand corner of the editor click file – Save

Environmental Variables:

If you have a look at my python code you’ll notice in a few places I’ve included a way to access environmental variables by using – os.environ[‘variable’]. Keep this in mind as this provides a way to pass data from the AWS console Environment Variable input points. Perhaps there are other bits of this Lambda Function that you’d like to customize with Environment Variables – feel free! For our work, we’ll need to at least define two – keyPair which will map to your the value of the name of your EC2 instance key name in the region that you’re deploying your stack and also stackName which will simply provide the name for the CloudFormation stack.

Add the keyPair and stackName keys and their Values to the Environment variables section.

At this point click the Save button in the upper right-hand corner of the AWS Lambda console.

Testing the Lambda function:

When configured as a lambda trigger and clicked, the IOT button coupled with the AWS IOT service provide an output that looks something like this:

{
“serialNumber”: “DEVICE SERIAL NUMBER”,

“batteryVoltage”: “1466mV”,

“clickType”: “SINGLE”
}

We’ll use this to provide a way in AWS Lambda to test our code prior configuring. Let’s setup a test to launch the stack and a test to destroy the stack. In the upper right-hand corner of the AWS Lambda console click the Configure test events button to the left of the Test and Save button:

  • Select the “Create new test” event radio button
  • Name it “Single Button Push”
  • Copy the following text into the form:

{

“serialNumber”: “DEVICE SERIAL NUMBER”,

“batteryVoltage”: “1466mV”,

“clickType”: “SINGLE”

}

  • Click “Save”

We’ll now do the same for the Double-click option

 Select the “Create new test” event radio button

  • Name it “Double Button Push”
  • Copy the following text into the form:

{

“serialNumber”: “DEVICE SERIAL NUMBER”,

“batteryVoltage”: “1466mV”,

“clickType”: “DOUBLE”

}

  • Click “Save”

Okay, we now have two different test event triggers configured to pass into the Lambda function that mimic the output of an IOT event. Let’s test. From the dropdown select “Single Button Push” and click test. Jump over to the CloudFormation service console and you should see a CloudFormation stack being deployed. If your stack isn’t showing up check to make sure that you’ve created appropriate keys in the us-west-2 region (assuming that you’ve not modified the launch-cfn.py to provision to a seperate region). Jump back to your newly created Lambda function and test the “Double Button Push” option. Again, jumping back to the CloudFormation console you should see the same stack now being Deleted.

Now that we’ve tested that our Lambda function is working as expected, let’s go ahead and configure the IOT button to be our trigger.

Adding an IOT trigger:

Honestly, this part is cake compared to the rest. There are several quick start guides available for the IOT button, but honestly just adding the IOT button as a trigger for the Lambda function is by far the easiest. In the Lambda function console jump back to our lambda function and click IOT as a trigger from the left-hand column. This will bring up a configure triggers panel below.

  • Under the IOT type select the “IOT” radio button
  • Add your device serial number from the back of your IOT button
  • Click generate certificate and keys
  • Download the certificate and private key file and copy the “endpoint subdomain” to your clipboard.

With all of this info, you’re ready to configure your button.

  • Press and hold your IOT button until the light starts flashing.
  • Connect to the wireless network called Button ConfigureMe – XXX The password the first time that you connect to the network is the last eight characters of the Device’s serial number
  • Navigate to http://192.168.0.1
  • Enter in your wireless network SSID and password
  • Select the certificate that you downloaded
  • Select the private key file that you downloaded
  • Paste in the Endpoint Subdomain that you copied
  • Select the appropriate endpoint location. I used us-west-2.
  • Make sure the enable trigger box is selected
  • Click Add.

Publish the completed function

Now that this is all done, publish a v1 version of the function.

  • At the top click “Actions” and publish a new version
  • Enter a Version Description – v1
  • Click Publish

Deploy

At this point, you should now be able to click your IOT button and the Heptio Quick Start CloudFormation template starts to deploy. Click your IOT button twice and the stack deletes.

What’s next?

All of the code for this project is up on my GitHub. I’m not a great programmer so please, if there are ways that I can improve what I’ve done, feel free to comment or submit a PR. I’m happy to work with the community to make this simple little hack a bit more streamlined. Hopefully, when you need a quick cluster for testing Kubernetes or some new Kubernetes project in AWS this can speed that process up for you! Cheers to the Heptio team for making it so accessible to the community.

Leave a Reply

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