November 15, 2017
Cloud

Building Furnace: Part III

Image
Brautigam Gergely
Cloud Engineer

Here is the 3rd part of our blogpost series about building Furnace. In the first part we talked about the AWS services used in the brief, the second part was about AWS Go SDK and we began dissecting the intricacies of Furnace. This episode is discussing the experimental plugin system of Furnace.

Image

Here is the 3rd part of our blogpost series about building Furnace. In the first part we talked about the AWS services used in the brief, the second part was about AWS Go SDK and we began dissecting the intricacies of Furnace. This episode is discussing the experimental plugin system of Furnace.

Go Experimental Plugins

Since Go 1.8 was released, an exciting and new feature was introduced called a Plug-in system. This system works with dynamic libraries built with a special switch to go build. These libraries, .so or .dylib (later), are loaded and once that succeeds, specific functions can be called from them (symbol resolution). We will see how this works. For package information, visit the plugin packages Go doc page here.

Furnace Plugins

So, what does Furnace use plugins for? Furnace utilizes plugins to execute arbitrary code in, currently, four given locations/events. These are: pre_create; post_create; pre_delete; post_delete. These events are called- as their name suggests- before and after the creation and deletion of the CloudFormation stack. It allows the user to execute some code without having to rebuild the whole project. It does this by defining a single entry point for the custom code called RunPlugin. Any number of functions can be implemented, but the plugin MUST provide this single, exported function. Otherwise, it will fail and ignore that plugin.

Using Plugins

It’s super easy to implement and use these plugins. I’m not going to go into details of how to load them because that is done by Furnace; I will be focusing instead on how to write and use them.
To use a plugin, create a go file called: 0001_mailer.go. The 0001 before it will define WHEN it’s executed. Having multiple plugins is completely okay. Execution of order however, depends on the names of the files. Now, in the 0001_mailer.post_create, we would see something like this:

package main
 

  1. import "log"
  2. 
     
  3. // RunPlugin runs the plugin.
  4. func RunPlugin() {
  5.     log.Println("My Awesome Pre Create Plugin.")
  6. }


The next step is to build this file to be a plugin library. Please note: Right now, this only works on Linux! To build this file run the following:

go build -buildmode=plugin -o 0001_mailer.pre_create 0001_mailer.go

The important part here is the extension of the file specified with -o. It’s important because that’s how Furnace identifies what plugins it has to run. Finally, copy this file to ~/.config/go-furnace/plugins and you are all set to go. 
 

Slack Notification Plugin

To demonstrate how plugin can be used, if you need some kind of notification once a Stack is completed. For example: you might want to send a message to a Slack room. To do this, your plugin would look something like this:

package main
 

  1. import (
  2.     "fmt"
  3.     "os"
  4. 
     
  5.     "github.com/nlopes/slack"
  6. )
  7. 
     
  8. func RunPlugin() {
  9.     stackname := os.Getenv("FURNACE_STACKNAME")
  10.     api := slack.New("YOUR_TOKEN_HERE")
  11.     params := slack.PostMessageParameters{}
  12.     channelID, timestamp, err := api.PostMessage("#general", fmt.Sprintf("Stack with name '%s' is Done.", stackname), params)
  13.     if err != nil {
  14.         fmt.Printf("%s\n", err)
  15.         return
  16.     }
  17.     fmt.Printf("Message successfully sent to channel %s at %s", channelID, timestamp)
  18. }


Currently, Furnace has no ability to share information of the stack with an outside plugin. Thus ‘Done’ could be anything from Rollback to Failed to CreateComplete.
 

Closing Words
 

That’s it for plugins. Thanks a lot for reading! Gergely.
 

Related posts

Image
Image
October 13, 2017
Cloud

This is the first part of a IV part series which discusses the process of building a mid-sized project in Go with AWS, including unit testing and an experimental plugin feature. In this one we will discuss the AWS services used in the brief and will contain a basic description.13

Image
Image
November 3, 2017
Cloud

We have recently started a blogpost series about building a mid-sized project in Go with AWS, with unit testing and experimental plugin feature. In this section we will discuss AWS Go SDK. We will also begin to dissect the intricacies of Furnace.

Image
Image
December 28, 2017
Cloud

This is the 4th, final part our blogpost series about building Furnace. In this part we'll discuss Unit Testing Furnace and how to work some magic with AWS and Go.