<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Boring Geek</title>
    <link>http://www.boringgeek.com</link>
    <description>Who says geeks are boring?</description>
    <pubDate>Thu, 12 Nov 2015 21:20:00 +0000</pubDate>
    <item>
      <title>The Departure from Ghost to Jekyll</title>
      <link>http://www.boringgeek.com/the-departure-from-ghost-to-jekyll</link>
      <description><![CDATA[On a recent vacation to Yellowstone, I realized I would probably be without internet for a couple weeks… and like any tech addict, I scrambled to figure out how I was going to survive. I had already planned on fishing, reading and generally enjoying nature, but I needed something to do after everyone else was long passed out and snoring. It seemed like a tossup between sleeping or writing and since I’m terrible at sleeping, I went for writing. To be more specific, I decided to spend the time working on blogging again.

]]></description>
      <pubDate>Thu, 12 Nov 2015 21:20:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/the-departure-from-ghost-to-jekyll</guid>
      <content:encoded><![CDATA[On a recent vacation to Yellowstone, I realized I would probably be without internet for a couple weeks... and like any tech addict, I scrambled to figure out how I was going to survive. I had already planned on fishing, reading and generally enjoying nature, but I needed something to do after everyone else was long passed out and snoring. It seemed like a tossup between sleeping or writing and since I'm terrible at sleeping, I went for writing. To be more specific, I decided to spend the time working on blogging again.

I've been meaning to play around with [Jekyll](http://jekyllrb.com/) for some time, but until now, I never really had a good enough reason.  It seemed fun and capable, but so was my existing blog powered by [Ghost](http:www.ghost.org).  So, what changed?  It's quite simple - lack of internet.  Like other blogging platforms, Ghost lacks off-line support. So, if I was going to make use of the time and actually write, I wanted something that would be there for me, when the internet was not.  Jekyll seemed to fit this bill perfectly.  

While at the airport, I quickly installed a copy on my laptop and scraped a copy of the help docs.  It took about twenty to thirty minutes to wrap my head around the process, but within the hour I was already a post deep and starting to tweak the theme a bit.  I remember looking over at my wife and mouthing 'this is great', to which she gave me her typical "yeah thats nice, you're such a nerd smile".  It truly was great.

Pretty much every night after everyone else had gone to bed, I had a good hour or two to myself to just write about anything I wanted.  It was quite freeing and Jekyll seemed to work like a charm.  I really enjoy markdown and the simplicity it offers for writing well structured content.  I also love the fact that my posts sit in a directory of tangibility (as tangible as digital good can get).  I can peruse them in [Atom](http://atom.io), I can pull them up on my local machine and preview them in the browser.  I have complete control over everything and tweaks are simple and don't require NPM and a litany of dependencies. To be honest, it feels more like making a static website, than working with a publishing platform.  And I think thats why I like it so much.

It follows a paradigm that is very comfortable to me and almost feels like second nature.  Everything down to the editor I'm using to write the posts follows the same workflow as any of the web applications I work on every day: write code, save, add, commit and push. In fact, its even the same mix of Atom, terminal, git and Github.  It just feels so natural and fluid.

This familiarity also carries over to hosting, which is another area where the processes starts to differ greatly from hosting a Ghost blog.  Instead of needing a Node.js environment, regular backups, version updates and security patches, Jekyll simply needs static hosting... in the truest form.  I'm talking no frills, super simple hosting.  The kind you find using an [S3 bucket](http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html) or [Surge.sh](http://surge.sh). You can even host it on Github.com with its [GitHub Pages](https://help.github.com/articles/using-jekyll-with-pages/) functionality (which also happens to support Jekyll).

The real wow factor is the shear simplicity of it.  I don't have to worry about managing an application environment.  It can't get hacked and I can host it completely free and place it behind the free tier of [CloudFlare](https://www.cloudflare.com/), caching the heck out of it.  For me, this is filled with win.

That doesn't mean it comes without its own trade-offs, though. This transition means that I have to manage a few more moving parts - that other bloggers don't typically have to focus on - such Git repos, command line tools and some basic ruby gems and node packages.  Additionally, I have to setup **_everything_** and am limited to what functionality can be achieved Jekyll plugins and the capabilities of the Liquid templating language. Thats not to say this is by any stretch difficult work, or even a ton of work, but its certainly _different_ work than many bloggers are probably used to and/or familiar with. So it's definitely something that needs to be considered when deciding to make this move.  Certainly know what you're getting yourself into and what you are giving up along the way.  

For me, the extra effort to get everything setup is pretty straight forward and analogous to the amount of effort needed to setup any blog initially. Additionally, once you've got it setup the way you want, you don't really need to touch those components and can focus on writing posts. So, this effort was perfectly acceptable to me and, so far, I'm thrilled with the results.

In a follow up post, I provide some step-by-step instructions on how to make the transition yourself and include the considerations for hosting, caching and even automating deployment on commit. Until then, hit me up in the comments if you have any questions.  
]]></content:encoded>
      <dc:date>2015-11-12T21:20:00+00:00</dc:date>
    </item>
    <item>
      <title>Make Your .Ebextensions PowerShell scripts "Self Destruct"</title>
      <link>http://www.boringgeek.com/make-your-ebextensions-scripts-self-destruct</link>
      <description><![CDATA[If you’re using Amazon’s PaaS offering, Elastic Beanstalk, you’re more than likely using .EBExtensions to control the configuration or other aspects of your applications.  And I’m sure, As any responsible devloper/admin would, you’re cleaning up after yourself as well… right?

]]></description>
      <pubDate>Thu, 03 Sep 2015 18:48:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/make-your-ebextensions-scripts-self-destruct</guid>
      <content:encoded><![CDATA[If you're using Amazon's PaaS offering, [Elastic Beanstalk](https://aws.amazon.com/elasticbeanstalk/), you're more than likely using .EBExtensions to control the configuration or other aspects of your applications.  And I'm sure, As any responsible devloper/admin would, you're cleaning up after yourself as well... right?

In the event that you aren't, its not tough to start.  In fact, here is the PowerShell code you need to have your scripts remove themselves after they've completed their duties.

```PowerShell
Remove-Item -LiteralPath $MyInvocation.MyCommand.Path -Force
```

Just throw that in as the last line of your PowerShell script and they'll run through their task and then - *\*poof\** - no more script!

This is particularly useful for things that are only needed on initial deployments, or only need to be run once.  I personally use it to setup scheduled tasks on the initial deployment.
]]></content:encoded>
      <dc:date>2015-09-03T18:48:00+00:00</dc:date>
    </item>
    <item>
      <title>Remove Already Tracked Items from Git</title>
      <link>http://www.boringgeek.com/remove-already-tracked-items-from-git</link>
      <description><![CDATA[After wrestling with a .NET app that wasn’t excluding the “packages” directory from the repo, I realized I had missed a crucial and obvious step… I forgot to commit the change to finalize the removal.  Talk about one of those “you forgot a comma” moments…

]]></description>
      <pubDate>Thu, 20 Aug 2015 17:25:27 +0000</pubDate>
      <guid>http://www.boringgeek.com/remove-already-tracked-items-from-git</guid>
      <content:encoded><![CDATA[After wrestling with a .NET app that wasn't excluding the "packages" directory from the repo, I realized I had missed a crucial and obvious step... **I forgot to commit the change to finalize the removal**.  Talk about one of those "you forgot a comma" moments...

If you find yourself in the same boat - here is how you do it.

To remove the directory:

```sh
git rm -cache -r directory/path/
```

This will recurse through the directory and pull all of its contents out of the history.

To finalize this, ensure that the directory is listed in your `.gitignore` file and commit the change:

```sh
git commit -m "Removed directory from tracking and added to .gitignore"
```

And that's it!

`</brainfart>`
]]></content:encoded>
      <dc:date>2015-08-20T17:25:27+00:00</dc:date>
    </item>
    <item>
      <title>Thoughts on Migrating to a Microservices Architecture</title>
      <link>http://www.boringgeek.com/thoughts-on-migrating-to-a-microservices-architecture</link>
      <description><![CDATA[I was recently asked when it made sense to choose to architect an application based on micro-services vs the more common approach of using a more centralized core framework or codebase.  Answering this over Twitter is simply impossible as the answer isn’t simple. In fact, there’s a lot that needs to be considered as the decision extends well beyond just the code.

]]></description>
      <pubDate>Fri, 22 May 2015 16:25:32 +0000</pubDate>
      <guid>http://www.boringgeek.com/thoughts-on-migrating-to-a-microservices-architecture</guid>
      <content:encoded><![CDATA[I was recently asked when it made sense to choose to architect an application based on micro-services vs the more common approach of using a more centralized core framework or codebase.  Answering this over Twitter is simply impossible as the answer isn't simple. In fact, there's a lot that needs to be considered as the decision extends well beyond just the code.  

>*Disclaimer: The following is by no way meant to be definitive. It's just meant to highlight some things you should consider*

##### So What are Microservices?
The idea is pretty simple: instead of building your application as one massive monolithic code-base, you break its core functions up into separate, smaller applications that operate as independent services. These services tend to perform a single specific function or purpose.  From there your app is a service itself that consumes the others.  There are a lot of good reasons for doing this, as I'm sure you can imagine.

Some highlights include:

* It allows for clear ownership of each service. This can help reduce issues when working with multiple development teams, as well as when the teams or ownership of a service changes. There is also less to ramp up on than a monolithic app.
* Speeds up development and release. As the services are independent, they can be developed in a loosely coupled manner and built, tested and deployed on their own schedules.
* Improves the ability scale efficiently; if one or two services are the ones getting heavy load, you can scale them independently instead of having to scale the entirety of a monolithic app.
* Allows you to use the right tool-set for the task. As they are independent, they can be built using a language, framework or set of utilities that best fulfills the required need.

With such fantastic benefits, it honestly sounds like the ideal way to build an application. Why would we every choose to build a monolithic app over this?

##### Considerations
As with any project we tackle in Applications Architecture - and even Solutions Architecture - there are a lot of things that need to be considered beyond just the code.  You have to consider development, infrastructure, operations, release management, security and networking among others. You have to look at it from a sunrise to sunset perspective. A microservices architecture is far more complex than a monolithic app and can be impacted by or have an impact on these teams and their abilities to support and manage the overall components.

The reasons for this are that when moving from one monolithic app to multiple smaller apps your're increasing the overall complexity of your environment. Think of it this way, while you may be separating concerns from a code and functionality perspective, you are creating a potentially large web of dependencies that now need to be accounted for at all layers of the "application".

To help frame this better, lets break it up into some logical groupings...

###### Infrastructure and Operations
At the foundation layer of the microservices stack is your I/O team. Honestly, this is the team that is probably hit the hardest by moving to a microservices architecture. The degree of complexity requires them to rely heavily on automation tools and the shift in architecture means they will need to manage the environments in ways they may not be used to. It may be a loaded term, but this is where the "DevOps" ideal starts to come in. In order to stand a chance of staying ahead of all this, your opts team will need to be tightly coupled with the dev teams building the applications. If anything, just to stand as a voice of sanity and reason.

**Load Balancing and Scaling.**  Depending on your Ops staff, this is a HUGE shift in mentalities.  Yes, you can strap a load balancer(s) in front of these services and scale horizontally (x-scale), but following a true microservices model may require your Ops team to explore both y and z-scaling.  The change is scaling and load balancing will most likely require using service discovery and load balancing tools like Zookeeper, Curator and Eureka.  Chances are, this is a whole new pattern for your Ops team (and Dev team). More on this later...

**Monitoring.**  Like the scaling challenge, configuring and maintaining monitoring for x<sup>n</sup> services adds to operational burden and additional load to your monitoring solution. This will also require a degree of scripting and automation to ensure that as services are scaled up and down, your monitoring solutions are updated to reflect the change.

**Operational Support.** As you can already tell... this is WAY more complex than a monolithic app to support, build, deploy, troubleshoot and maintain. Now... factor in that there is a chance that these services may be built using different languages, frameworks and services and you really need to take time to consider whether Ops staff can manage it all. Another reason why its good to join your Ops and Dev teams at the hip. That way, when one of the developers decides they want to built the next service in Go lang, they have to make eye contact with the Ops guy who is contemplating where they can hide their body.

###### Networking and Security
The next groups in the stack is your network and security teams.  While they don't have it as bad as I/O, they certainly do have their work cut out for them.

**Bandwidth.** Networking requirements also need to be considered as what was previous 1 request within a monolithic app now can spider into x<sup>n</sup> requests between the various services. Ensuring this happens with as little latency as possible is important, but we'll get into that a bit more later...

**Firewall.** As you're going from one application to many services, you have to consider which services get exposed externally and which are kept internal. These decisions require the firewall rules and security groups to become more complex than with a single application, which segues nicely into...

**Application Security.** As you now have multiple services with varying degrees of external exposure, you now have a much larger target for potential attackers.  The fact that these services could potentially span multiple languages, frameworks and OSes increases the complexity for your security team to successfully perform security audits and penetration tests against the services.

**Threat Management**  As there is now a lot more communication happening between all of these potential services, there is a lot more for your security team to need to monitor and be aware of.  This makes discerning between expected traffic and rouge requests more complex and where dependency mapping tools like Neebula (Service Watch) can really help.

###### Development
At the top of the stack you have the development teams. While they certainly get some wins when moving to this architecture, there are still a number of things they now need to consider that may not have been an issue with a monolithic architecture.

**Caching.** As there is now more chatter between services developers have to find ways to limit the number of requests that they need to may.  One obvious way to account for this is with caching of requests. The ideal would be to cache wherever possible and try and refresh data across as many services as possible in one request. While this is something any developer worth his salt should be doing regardless of app architecture, caching requests across multiple services that you may or may not manage can become complex and require coordination across services and the teams building them...

**Use of request headers.**  In addition to caching, developers have to address how they handle sending data (such as authentication details) between services that need it to reduce the number of requests. One way of doing this is through the use of request headers.  Imagine needing to call 5 services that all require authentication. Each of those services will need to call the authentication service to validate you are authenticated. Or, a better way would be to include your auth details in the header of each request so that the services can check for it and only call the authentication service when its not there. Again, like caching, doing this across multiple services that you may or may not manage may require coordination with other teams.

**Latency.** With increase in the number of requests, developers need to account for the time it takes for these requests to be processed; serialization and deserialization of requests to x<sup>n</sup> services can add up. We'll discuss why this can be bad next...

**Resilience and Fault Tolerance** As this architecture is one based on a web of interdependence, developers must go above and beyond to build the services to be fault tolerant and resilient to failures, timeouts and etc. This is an order of magnitude more challenging than with a monolithic app. If requests to one service start to back up, this could easily cause others to back up which could lead to a domino effect of failures cascading across your services or even triggering of unnecessary scaling of the services.

##### That's great. Answer the question already!
So when should you choose to build a solution based on microservices instead of a monolithic app?? The answer is simple - *it depends!*

Yeah, you should have seen that coming a mile away.  The answer, as should be clear from all this lead up, is that it depends on a number of things:

* The purpose of the application and its intended use and audience
* The makeup of the team that is going to be developing it
* The capabilities of the infrastructure, operations, networking and security teams
 that will need to scale, support, monitor, maintain and secure it

The reality, if its not painfully obvious, is that building an app using a microservices architecture can be a lot of work and requires doing things in different ways. I'm not saying "Don't do it! It's Hard!", I'm saying ensure that the benefits outweigh the costs and that you're doing it for the right reasons; because the application needs it, it will help you ship faster, ensure stability and/or create a stable platform for your customers to build off of.

###### Additional Resources
Thinking about taking the plunge? Like DevOps, Microservices are all the rage right now and there are TONS of resources to help you along the way.  Good luck.

* [Microservices at Netflix - Lessons for Team and Process Design](http://nginx.com/blog/adopting-microservices-at-netflix-lessons-for-team-and-process-design/)
* [Microservices at Netflix - Architectural Best Practices](http://nginx.com/blog/microservices-at-netflix-architectural-best-practices/)
* [Microservices at Netflix - Best Practices and Tools of the Trade (Video)](https://www.youtube.com/watch?v=LEcdWVfbHvc)
* [Microservice Patterns](http://microservices.io/patterns/index.html)
* [Using Containers to Build a Microservices Architecture](https://medium.com/aws-activate-startup-blog/using-containers-to-build-a-microservices-architecture-6e1b8bacb7d1)
* [Microservices - Not a Free Lunch](http://highscalability.com/blog/2014/4/8/microservices-not-a-free-lunch.html)
* [Microservices - The Good, The Bad and What You Could Be Doing Better](http://nordicapis.com/microservices-architecture-the-good-the-bad-and-what-you-could-be-doing-better/)
* [Building Microservices at Karma](https://blog.yourkarma.com/building-microservices-at-karma)
]]></content:encoded>
      <dc:date>2015-05-22T16:25:32+00:00</dc:date>
    </item>
    <item>
      <title>Create an ".EBextensions" Folder on Windows</title>
      <link>http://www.boringgeek.com/create-an-ebextensions-folder-on-windows</link>
      <description><![CDATA[I have a number of Linux-based applications that have been using the .ebextensions functionality of Elastic Beanstalk for quite some time. Its a great way of managing the configuration of your environments and running tasks both pre and post-deploy. However, one of my current projects is a C# .NET app and it took me a while to remember how to create a folder in Windows with a leading (.) period.  It seems so trivial, but, honestly, I can’t recall the last time I’ve had to do it - chances are many of you can’t either.

]]></description>
      <pubDate>Mon, 11 May 2015 19:29:03 +0000</pubDate>
      <guid>http://www.boringgeek.com/create-an-ebextensions-folder-on-windows</guid>
      <content:encoded><![CDATA[I have a number of Linux-based applications that have been using the .ebextensions functionality of Elastic Beanstalk for quite some time. Its a great way of managing the configuration of your environments and running tasks both pre and post-deploy. However, one of my current projects is a C# .NET app and it took me a while to remember how to create a folder in Windows with a leading (.) period.  It seems so trivial, but, honestly, I can't recall the last time I've had to do it - chances are many of you can't either.

So here it is in all of its strange simplicity:

<code>.ebextensions.</code>

Yes, you're seeing that correctly - simply add a trailing (.) period and Windows will create the folder and remove the trailing period.

Enjoy!
]]></content:encoded>
      <dc:date>2015-05-11T19:29:03+00:00</dc:date>
    </item>
    <item>
      <title>Tips for working with Node.js on Ubuntu</title>
      <link>http://www.boringgeek.com/installing-nodejs-on-ubuntu</link>
      <description><![CDATA[####Installing Nodejs from the standard Ubuntu repos.####
While this won’t get you bleeding edge 0.12.x, it will it will get you a relatively recent and stable version of 0.10.x.  This probably isn’t a bad thing as 0.12.x is pretty new and not everything supports it - yet.

]]></description>
      <pubDate>Tue, 21 Apr 2015 04:57:04 +0000</pubDate>
      <guid>http://www.boringgeek.com/installing-nodejs-on-ubuntu</guid>
      <content:encoded><![CDATA[####Installing Nodejs from the standard Ubuntu repos.####
While this won't get you bleeding edge 0.12.x, it will it will get you a relatively recent and stable version of 0.10.x.  This probably isn't a bad thing as 0.12.x is pretty new and not everything supports it - yet.  

```
$ sudo apt-get update && sudo apt-get upgrade
$ sudo apt-get install nodejs
```

Important to note is that Ubuntu isn't going to call the binary "node".  Instead, its going to call it "nodejs".  Regardless of the logic behind this decision, its an easy fix by creating a simple symlink:

```
$ sudo ln -s "$(which nodejs)" /usr/bin/node
```

From there, most people are going to want to work with Node's package manager, NPM, so install this as well:

```
$ sudo apt-get install npm
```

At this point, you should be ready to rock with Node and NPM.  To validate your setup, feel free to check your versions.

```
$ node -v
v0.10.25
$ npm -v
1.4.21
```

In the event that you want to try a newer version of Node, I would recommend using the stellar PPA's provided by [Nodesource](http://nodesource.com).  Full instructions for 0.12 and even Io.js can be found here: [Node.js v0.12, io.js, and the NodeSource Linux Repositories](https://nodesource.com/blog/nodejs-v012-iojs-and-the-nodesource-linux-repositories)

If you're just getting started with Node, then I would recommend taking a look at the following resources to get you off to a good start:

* [Nodeschool.io](http://nodeschool.io/) - might take a few minutes to figure out the Workshops, but not a bad training method.  Gets you right into the code.
* [CodeSchool](https://www.codeschool.com/courses/real-time-web-with-node-js) - I'm a huge Pluralsight fan, so [CodeSchool](http://codeschool.com) always gets a bump from me.
* [Human Javascript](http://read.humanjavascript.com/) - While not a tutorial specifically on Node, it is a fantastic tutorial on building real apps with node and [Ampersand.js](http://ampersandjs.com/) and worth your time. The author ([@HenrikJoreteg](http://twitter.com/henrikjoreteg)) is an old acquaintance of mine and kind of a big deal in the JavaScript world. His [video tutorials](http://learn.humanjavascript.com) are awesome as well!

Good luck and happy coding!
]]></content:encoded>
      <dc:date>2015-04-21T04:57:04+00:00</dc:date>
    </item>
    <item>
      <title>2015 Goals and Roadmap</title>
      <link>http://www.boringgeek.com/2015-goals-and-roadmap</link>
      <description><![CDATA[This year I plan on changing up the process just a little bit.  While I still want to have a few goals that are for the year as a whole, I also want to come up with one super simple and achievable items for each month. The reason for this is that, upon reviewing last year, it became clear that there wasn’t a whole lot to keep things happening.  So, this year I want to ensure that there are activities with enough frequency to keep the engagement and excitement - while still being realistic.

]]></description>
      <pubDate>Mon, 05 Jan 2015 17:05:49 +0000</pubDate>
      <guid>http://www.boringgeek.com/2015-goals-and-roadmap</guid>
      <content:encoded><![CDATA[This year I plan on changing up the process just a little bit.  While I still want to have a few goals that are for the year as a whole, I also want to come up with one **super simple and achievable** items for each month. The reason for this is that, upon reviewing last year, it became clear that there wasn't a whole lot to keep things happening.  So, this year I want to ensure that there are activities with enough frequency to keep the engagement and excitement - while still being realistic.

This years list...

* **Get my Certified ScrumMaster Certificate from the Agile Alliance**
I have taken ScrumMaster training twice now, but the first time (two years ago) I didn't take the certification test.  This time I want to have that certificate.  If anything just to give me that feeling of accomplishment and add to my LinkedIn profile. This was a December goal, but the holidays caused a delay; should be done in the next week.

* **Get my AWS Certified Solution Architect - Associate Certification**
This is my January goal and it shouldn't be too hard; I've been studying for it for months.  My goal is to take the test in the middle of January and with luck on my side, I  can add it to my email signature.

* **Complete the Chef course from Linux Academy** This one is for February. While I've used Chef in AWS for simple, trivial things, I want to go through a more formal training process and learn how to use it to the full extent.  I feel that this is a must have for growing my role as a Solutions Architect.

* **Attend at least one startup, entrepreneurial or dev meetup event each month**. This one shouldn't be that hard as there is a litany of these events in Southern California. Hearing and seeing other peoples excitement helps get me excited as well.

* **Visit three startups or tech companies and get a tour** This one is for fun.  Last year I had a complete blast visiting a friend at GitHub and this year I want to continue that.  I work in an "enterprise" setting, so its fun and refreshing to see how smaller, more agile shops do things.

* **Produce one product of my own**
Yup... this old gem. Its actually not that far off in reality.  I have a working initial version, but I need to add the accounting bits and improve the error handling.  With focus and some luck, this one will stick.  Fortunately, I've chosen to build it on the wonderful Laravel framework, which has functionality to make a lot of this simple. It even includes [Laravel Cashier](http://laravel.com/docs/4.2/billing) which is an interface to [Stripe](http://stripe.com). Like my friend [Josh Northcott](https://twitter.com/jnorthcott) always says - its "Awesome Sauce."

* **Listen to or read at least one entrepreneurial book every other month** I did this with both [The 4-Hour Workweek](http://www.amazon.com/dp/0307465357/ref=cm_sw_r_tw_dp_DoKQub0R6NQ2T) and [Rework](ttp://www.amazon.com/dp/0307463745/ref=cm_sw_r_tw_dp_dqKQub0P7WP5E), so this is a no-brainer.  My daily commute to and from work is about 45 minutes of prime listening time.  Its tough being employed full time, a father of two young children and a supportive husband - and be able to sit down for hours to read.  However, theres plenty of time between things to listen to books and gain knowledge!

* **Set Reminders and pick real dates** In order to help ensure these get done, I plan on setting up regular reminders to review progress and ensure each months activities are planned and have been done.  If one was missed, it should be made up for in some fashion. Some of these I plan on inviting others to participate in. This should not only help ensure they happen, but also help make them fun.


As usual, I will continue to finesse these throughout the year and am open to suggestions.  I wish you all luck with your goals.  2015 is going to be a truly great year. I hope you do everything you can to make it YOUR year.
]]></content:encoded>
      <dc:date>2015-01-05T17:05:49+00:00</dc:date>
    </item>
    <item>
      <title>2014 Year in Review</title>
      <link>http://www.boringgeek.com/2014-a-year-in-review</link>
      <description><![CDATA[For the past few years I’ve made a list of the things I would like to accomplish in the new year. For the most part, these items are more than resolutions; they’re meant as a plan of attack for personal growth and development.  Each item is something personal to me, is meant to be actionable and something I honestly hope to accomplish.  Of course, a year is quite a bit of time, so anything can happen.  Lets see how I did…

]]></description>
      <pubDate>Sun, 04 Jan 2015 23:32:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/2014-a-year-in-review</guid>
      <content:encoded><![CDATA[For the past few years I've made a list of the things I would like to accomplish in the new year. For the most part, these items are more than resolutions; they're meant as a plan of attack for personal growth and development.  Each item is something personal to me, is meant to be actionable and something I honestly hope to accomplish.  Of course, a year is quite a bit of time, so anything can happen.  Lets see how I did...

###Last Year's Goals In Review

Last years goals - [Another Year of Opportunity](/another-year-of-opportunity/) - were pretty simple as I strive pretty hard to follow my own advice (found at the beginning of the post) and keep them actionable.

Primary goals were as follows...

* **Introduce two simple SaaS applications - Vertict: Fail.** The idea was to build these on an existing platform that handles things such as billing and distribution, such as [Shopify](http://www.shopify.com) and [Envato](http://www.envato.com). While I was able to begin work on ideas, I was, ultimately, unable to make progress toward delivery.

* **Complete one 30x500 style project - Verdict: Fail** Unfortunately, the solution I decided to build was centered around cloud cost modeling across cloud providers.  During the conceptual phase I was concerned that my role in my day job presented a conflict of interest. After waiting a few weeks for a decision, it was determined that there was, and I was asked to remove myself from any involvement. This had a pretty deep impact on me that affected me for months.

Secondary goals were as follows...

* **Give back to at least one OSS project - Verdict: Partial Success** I love Ghost and spent some time trying to find ways to make hosting it a bit easier and wrote a, now outdated, post on hosting it in [AWS Elastic Beanstalk](/how-to-setup-ghost-on-elastic-beanstalk/) to help others. I was also able to make monetary contributions to a number of OSS projects including Wikipedia and Ubuntu. Unfortunately, I did not show Laravel some much deserved love...

* **Attend Google I/O as a developer - Verdict: Partial Success** Google changed the registration process this year to a lottery system.  Unfortunately, I was not a winner and was unable to attend.  That being said, I *did* get to attend another developer conference - [AWS re:Invent](https://reinvent.awsevents.com/). This was an absolutely amazing and eye opening event. I came back feeling alive and invigorated. It was one of the best experiences I had all year.

* **Teach my son to swim - Verdict: Success** My wife and I got him into a great class where he was the ONLY student and he picked it up like it was nothing! Now he's fearless in the water!

While two of the major goals were "fails", overall, I don't see the year as a bust.  There were many other successes not listed as goals.

* I was honored to be the best man for my closest friend Rob
* I was able to expand my social network and made connections to many of the people and companies I respect the most in tech. Some of them are CEO's.
* Was a featured testimonial on [Linux Academy's](http://LinuxAcademy.com) website.  While it may seem like a simple thing, seeing it always makes me grin, so it counts.
* I was able to continue to build practical skills in AWS and solutions architecture.
* Realized that I have a passion for empowering teams with toolsets including continuous integration and deployments.  Something I hope to grow exponentially in 2015.

So, all in all, not a bad year. With the things I've learned and the drive and determination its provided me, I know 2015 is going to be even better. I hope yours is as well!
]]></content:encoded>
      <dc:date>2015-01-04T23:32:00+00:00</dc:date>
    </item>
    <item>
      <title>What is DevOps</title>
      <link>http://www.boringgeek.com/what-is-devops</link>
      <description><![CDATA[A topic that has come up in many discussions for me recently is DevOps. Its an important thing to understand, but I’m finding a lot of people have some serious misconceptions about what it is and actually means. This is surprising due to how common a practice it has become.  For instance, AWS re:Invent had an entire track dedicated to DevOps.  Regardless, its interesting to hear peoples thoughts on the subject.

]]></description>
      <pubDate>Sun, 04 Jan 2015 18:55:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/what-is-devops</guid>
      <content:encoded><![CDATA[A topic that has come up in many discussions for me recently is DevOps. Its an important thing to understand, but I'm finding a lot of people have some serious misconceptions about what it is and actually means. This is surprising due to how common a practice it has become.  For instance, AWS re:Invent had an entire track dedicated to DevOps.  Regardless, its interesting to hear peoples thoughts on the subject.  

Here are some of the things I've heard over the last 2-3 weeks:
1. It's simply a way of streamlining and automating the deployment process.  
2. It's defining standard processes that sys admins follow.
3. It's a way to empower developers to do deploys on their own.
4. It's a way to get rid of needing system admins - entirely. This person was serious too...

While I can certainly see where some of these ideas are spawned from, I don't think any of them really touch on the heart of what DevOps is. So what is it?

###What is DevOps

According to a fantastic training video on [Chef](https://www.chef.io/) from [Linux Academy](http://linuxacademy), they summarize DevOps as the following:

1.  DevOps is about "How well people work together and how streamlined our Operations really are" - Adam Jacob.
2. An ideal where applications and the infrastructure that they run on are not treated as separate entities to each other - and neither are the teams that manage them.
3. DevOps is part of continuous delivery where all aspects of the deployment process are automated.
4. DevOps is infrastructure as code.

This is pretty susinct to me, but I think there is still more too it. This is why I really like the "[What is DevOps](http://theagileadmin.com/what-is-devops/)" post made on [The Agile Admin](http://theagileadmin.com/) site.

The Agile Admin post, is great because it makes a coralary to agile development, in which they feel DevOps is built on top of a set of core values, principles, methods, practices and tools. And, much like agile methodology, if you lack one or more of these components, you're really keeping your team from reaching its full potential.

Thats where I think you'll find the real definition. At its core, DevOps its about harmony and efficiency.  In that, its the realization that your product team needs to be comprised of people across multiple disciplines - which includes operations. This is necessary to allow your teams to achieve faster, more frequent and more stable releases.  Its expanding the agile approach beyond the just the Dev team and, more arguably, realizing that "Dev team" has a much broader definition and makeup than we used to think it did.

What are your thoughts? As always, feel free to comment below.
]]></content:encoded>
      <dc:date>2015-01-04T18:55:00+00:00</dc:date>
    </item>
    <item>
      <title>How to Setup Ghost on Elastic Beanstalk</title>
      <link>http://www.boringgeek.com/how-to-setup-ghost-on-elastic-beanstalk</link>
      <description><![CDATA[Over the past six months, the Ghost blogging platform has made some huge waves in the blogging world. It has a responsive, streamlined interface that gets out of the way and enables authors to blog quickly and efficiently. At a time when WordPress is growing more and more complex, this is a breath of fresh air. And, even in its pre-1.0 release status, the platform is undoubtedly stable and usable.

]]></description>
      <pubDate>Tue, 22 Jul 2014 07:00:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/how-to-setup-ghost-on-elastic-beanstalk</guid>
      <content:encoded><![CDATA[Over the past six months, the [Ghost blogging platform](http://ghost.org) has made some huge waves in the blogging world. It has a responsive, streamlined interface that gets out of the way and enables authors to blog quickly and efficiently. At a time when [WordPress](http://wordpress.org) is growing more and more complex, this is a breath of fresh air. And, even in its pre-1.0 release status, the platform is undoubtedly stable and usable.

For those of you who want to run it in a production level environment, this post will walk you through the process of getting it up and running on Amazon Web Services; providing speed, stability, monitoring and security.

To get started, you will need access and familiarity with the following AWS tools and services:

1. AWS Console
2. Elastic Beanstalk - for hosting and monitoring the blog
3. RDS - for the MySQL database
4. SES - for sending email (optional if you have your own SMTP service)
5. EBS - for ephemeral storage
6. IAM - to allow access to mount EBS volumes

### Setup Simple Email Service
The first step in this process is to get yourself setup with SES. This will be your blogs email mechanism and will allow you to track things like bounces, complaints and successes all from with the AWS console. Now, to be honest, you could just use your GMail account or any other SMTP server you access to.  However, if you're planning on making your blog a success - getting the stats on bounces and complaints is worth setting up SES.

#### Setup
1. Created a Verified Email
 1. Log into the AWS console and select the SES service from the menu
 2. Under the "Verified Senders" heading on the left navigation, click "Email Addresses"
 3. If you don't have a verified email address listed, click the "Verify a New Email Address" button and enter your email address.
 4. Click the "Verify This Email Address" button and Amazon will send an email to the address you entered.
 5. Open your email an click the verification link.
2. Create your SMTP Credentials
 1. From the SES Console in AWS, click the "SMTP Setting" link in the left nav.
 2. Click the "Create My SMTP Credentials" button. This will take you over to the IAM Console and show a wizard for creating a user for SMTP
 3. Give the IAM User a name. I put "SES-SMTP-USER" and deleted the date stamp.
 4. Click the "Create" button.
 5. This will create the user and ask you to download their credentials. **It is important that you put this somewhere safe**; you will only get to do this once. If you lose these credentials, you'll need to delete the user and create a new one.
3. Request Production Access.
 1. If you don't already have production access to send email via SES, you'll need to request it.  From the SES Dashboard, click the "Request Production Access" button at the top of the screen.
 2. This will take you to a support screen to request a "Service Limit Increase".  Fill out the form with accurate information and submit it.  They will review your request and either approve it or contact you with any questions.

### Setup Persistent Storage
By default, Ghost stores images and other data within the `content` directory.  However, since we're using Elastic Beanstalk, if your instance becomes unhealthy, AWS will kill it - and take that `content` directory with it.  To get around this, we're going to use a combination of EBS and ebextension configs to mount persistent storage and symlink those directories over to it. To get started we'll need to create an EBS volume.

#### Create an EBS Volume
1. From the EC2 console, click the `volumes` link on the left navigation.
2. Click the `Create Volume` button.
3. Follow the wizard to create a volume
	- **Take note of the availability zone you select**, you will need this later when setting up your elastic beanstalk environments
    - Size the volume using your best judgment, for my purposes 5GB was adequate. Changing this later is possible, but its not as simple as increasing the size.
4. When the volume has been created, **take note of the `Volume ID` as you will need this later on in the process**.

Now you have a volume, however, this is basically the equivalent of adding a drive to your own computer; without formatting that drive, nothing can use it.  In order to format the drive, you will need to [attach it to an EC2 Instance running Linux](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-attaching-volume.html), [SSH in to that instance](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AccessingInstancesLinux.html) and [format it](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-using-volumes.html) by doing the following:

1. From the command prompt, use `lsblk` to list the drives attached to the instance
2. Find the device name for the drive you need to format
3. Run `sudo mkfs -t ext4 device_name` swapping out `device_name` for that of your particular device.
4. Logout of the shell and unmount the volume from that instance. If you created that instance for this step, now is a good time to terminate the instance as well.

#### Create an IAM User
In order to allow our scripts to mount the EBS volume, we will need to create an IAM user and grant it the specific permissions needed to accomplish this.

1. From the IAM Console, click the `Users` link on the left navigation
2. Click the `Create New Users` button
3. Provide a username for the user. I used `ghost-ebs-user`
4. If its not checked, check the "Generate an access key for each User" checkbox.  We will use these access keys in our scripts to mount the drive.
5. Click the `create` button.
6. Click the `Download Credentials` button to download a CSV of the users credentials.  This will be the only time you can do this; forgetting them, will require you to generate new ones. **Keep these handy as you will need these for a later step**
7. Click `Close Window`.
8. Select the checkbox next to the newly created user
9. In the user properties window on the bottom half of the screen, click the `Properties` tab.
10. Click the `Attach User Policy` button
11. Select the `Policy Generator` option and click the `Select` button
12. Under the `AWS Service` dropdown select `Amazon EC2`
13. Under `Actions` select the following options

    	AttachVolume
        DescribeVolumeAttribute
        DescribeVolumeStatus
        DescribeVolumes
        DetachVolume
14. For the `Amazon Resource Name` enter `*`
15. Click the `Add Statement`


### Prepare Ghost for Installation
Based on our configuration within AWS, we need to make some minor tweaks to our Ghost codebase before we can begin the installation.

#### Download Ghost
1. Down load a copy of Ghost from the [Ghost download page](https://ghost.org/download/)
2. Unzip it somewhere convenient for you to access it

#### Modify the Default Node.js HTTP Port
In order to get node working in Beanstalk, you will need to ensure it using the correct port: `8081`. This is the port used by Elastic Beanstalks HTTP nGinx web server.

1. From within the Ghost directory, create a copy of `config.example.js` and name it `config.js`.
2. Edit the `server` section of the file and change the port reference from `2368` to `8081` in both the "Development" and "Production" sections of the file.

##### Modify the Default URL
In order to actually use this as a production instance, you will need to update the `config.js` file to reflect your desired url for your blog.

1. Edit `config.js` and update the `url` value in both the `development` and `production` sections of the file to reflect the correct url
2. Save the file.

#### Ensure the Proper Node.js Version
Ghost is built to run on Node.js version `0.10.*`, but Beanstalk will default to `0.8.*`.  To ensure that your Beanstalk Environment provisions with the proper version, we will need to instruct it to via EB's "[ebextensions](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers.html)" functionality.

1. In the root of your ghost directory (the one with "content" and "core"), create a new folder called `.ebextensions`.
2. In the `.ebextensions` direction create a config file called `00_ghost.config` and put the following in it:

        option_settings:
  		- namespace: aws:elasticbeanstalk:container:nodejs
    		option_name: NodeVersion
    		value: 0.10.21

This config will get executed during the provisioning of your environment and ensure that your Node.js server starts up with the correct version that Ghost needs.

#### Configure the EBS Mount
As we have the EBS volume and user permissions created, we need to setup another extensions config script that will attach the volume at boot. To do this, we will use an undocumented post-deploy hook that will run the script after the application has been deployed.  This is essential as this depends on symbolic links that point `/var/app/current/content/data` and `/var/app/current/content/images` to `/var/app/data/` where we will mount our ebs volume.

1. Create another file in your `.ebextensions` folder called `01_mount_volumes.config` and put the following into it:

		files:
  		/opt/elasticbeanstalk/hooks/appdeploy/post/99_ephemeral_storage.sh:
    		mode: "000755"
    		owner: root
    		group: root
    		content: |
      		#!/usr/bin/env bash
      		export JAVA_HOME=/usr/lib/jvm/jre && \
      		export EC2_HOME=/opt/aws/apitools/ec2 && \
      		export DATA_DIR=/var/app/data && \
      		export IN_USE=$(/opt/aws/bin/ec2-describe-volumes --region us-west-2 --hide-tags \
      		--aws-access-key [[YOUR-AWS-ACCESS-KEY]] \
      		--aws-secret-key [[YOUR-AWS-SECRET-KEY]] \
      		[[YOUR-EBS-VOLUME-ID]] | grep "in-use") && \
      		if [ -z "${IN_USE}" ]; then
      		/opt/aws/bin/ec2-attach-volume --region us-west-2 [[YOUR-EBS-VOLUME-ID]] \
        	-i $(/opt/aws/bin/ec2-metadata --instance-id | cut -c14-) \
        	-d /dev/sdh \
        	--aws-access-key [[YOUR-AWS-ACCESS-KEY]] \
        	--aws-secret-key [[YOUR-AWS-SECRET-KEY]] &&
        	sleep 30 && \
        	if [ ! -d "${DATA_DIR}" ]; then
                mkdir -p ${DATA_DIR}
        	fi
        	mount /dev/xvdh ${DATA_DIR} && \
        	sleep 30 && \
        	if [ ! -d "${DATA_DIR}/content" ]; then
                mkdir -p ${DATA_DIR}/content
        	fi
        	echo "Creating persistent Ghost data directory" && \
        	if [ ! -d "${DATA_DIR}/content/data" ]; then
                mv /var/app/current/content/data ${DATA_DIR}/content/.
        	else
                rm -R /var/app/current/content/data
        	fi
        	echo "Creating persistent Ghost images directory"
        	if [ ! -d "${DATA_DIR}/content/images" ]; then
                mv /var/app/current/content/images ${DATA_DIR}/content/.
        	else
                rm -R /var/app/current/content/images
        	fi
        	chown -R nodejs.nodejs ${DATA_DIR} && \
        	echo "Symlinking data directory" && \
        	ln -sf ${DATA_DIR}/content/data /var/app/current/content/. && \
        	echo "Symlinking images directory" && \
        	ln -sf ${DATA_DIR}/content/images /var/app/current/content/.
      	fi

Be sure to update it with the following information:
1. Replace `[[YOUR-EBS-VOLUME-ID]]` with the volume ID of the EBS instance you are using.
2. Replace `[[YOUR-AWS-ACCESS-KEY]]` and `[[YOUR-AWS-SECRET-KEY]]` with the ones from the `ghost-ebs-user` you created earlier.

Also, if you copy and pasted the script from above, it may be a good idea to paste it into a [YAML validator](http://yamllint.com/) to ensure the format is good; things like an extra `tab` will cause all kinds of headaches.

#### MySQL RDS Configuration
1. Edit the `config.js` file
2. Under both the `development` and `production` sections of the config:
3. Delete the "sqlite3" connection string:
      database: {
          	client: 'sqlite3',
          	connection: {
              	filename: path.join(__dirname, '/content/data/ghost-dev.db')
          	},
          	debug: false
      },
4. Replace it with the RDS connection strings:
  ```
    database: {
    	client: 'mysql',
    	connection: {
    			host: process.env.RDS_HOSTNAME,
    			user: process.env.RDS_USERNAME,
    			password: process.env.RDS_PASSWORD,
    			database: 'ebdb',
    			charset: 'utf8'
    	},
    		debug: true
    },
  ```
5. Save the File
3. Edit `package.json` to remove the Sqlite requirements.
 1. Under the `dependencies` section delete the line for Sqlite.
 2. Save and close the file.


#### Configure the SMTP Settings for SES
1. Edit `config.js`
2. Delete the commented mail section under Development and Production.  Replace it with the following:

		```
    mail: {
    		transport: 'SMTP',
    		host: 'YOUR-SES-SERVER-NAME',
        	options: {
            	port: 465,
            	service: 'SES',
            	auth: {
                	user: 'YOUR-SES-ACCESS-KEY-ID',
                	pass: 'YOUR-SES-SECRET-ACCESS-KEY'
            	}
        	}
        }
      ```
3. Be sure to replace the following sections with your SES information
	1. Host - replace this with the "Server Name" listed on the SES Consoles "SMTP Settings" page.  Mine was `email-smtp.us-west-2.amazonaws.com`, but yours will vary based on the region you configured SES in.
    2. user and pass - these will be found in the `credentials.csv` that you downloaded during the SES setup above.
4. Save the file and close it.

#### Package it all up
Now that the necessary config has been done, we need to zip up the directory and get it;ready for uploading to Elastic Beanstalk.

To do this:

1. Create a zip of your ghost installation. You will want the configuration files and the ghost `core` and `content` folders to be at the root level of the zip.

### Setup and Deploy to Elastic Beanstalk
Now that you have all the preliminary work done, we can go ahead and start setting up our hosting.  

1. From the Elastic Beanstalk Console, click the `Create a New Application` button
2. Name the application accordingly. I used `Ghost Blog`.
3. Click `next`
4. From the `Environment tier` dropdown, select `Web Server`
5. From the `Predefined configuration` dropdown, select `Node.js`
6. From `Environment type` choose `Load Balancing, autoscaling`
	- This is important.  While we will only have a single instance, the load balancer and autoscaling group will help ensure that if anything happens to the health of that instance, it will be terminated and replaced.
7. Select `Upload your own` and choose your previously created zip file of the Ghost install
8. Click `Next`
9. Name your environment as you choose and click `Next`
10. Select the option to `Create an RDS DB Instance`
11. Select the option to `Create this environment inside a VPC`
12. Click `Next`
13. Select your instance size. You can change this later. I started with a `t1.micro`
14. Select your EC2 key pair.
	- if you don't have one created, open a new tab and create one from the `Key Pairs` link on the left navigation of the EC2 Console. Come back to this tab and then click the refresh link and it should show up.
15. Fill out the remaining fields as desired and click `Next`
16. Tag your environment as you see fit and click `Next`
17. Select the instance class for your RDS instance.  For my example I chose `db.t1.micro`.
18. Allocate at least 5GB of storage
19. Enter a username
20. Enter a password
21. As the goal is to make this redundant
	- Choose `Create Snapshot` from the `Retention setting` dropdown
    - Choose `Multiple Availability Zones` from the `Availability` dropdown
22. Click `Next`
23. Choose your VPC. I left mine as default
24. For your ELB, EC2 and RDS, you need to select the same availability zone as the one you used for your EBS Volume.  For your RDS, you will also need to select an additional AZ as it requires two.
25. Click `Next`
26. Review your settings and click `Launch`.

Now sit back and wait. It will take about 20 minutes for your RDS instance to come up.  When it does, you should see a green health status for your Beanstalk environment and clicking its URL should show you the default Ghost blog homepage.

You will note that the URL does not match the one you put in your `config.js` though. Instead, the url will resemble something along the lines of `my-app-env.elasticbeanstalk.com`. This is expected. To use your own domain name, you will need to create a DNS CNAME the points your domain to the Elastic Beanstalk URL. Instructions on this will vary based how you manage your DNS Service. I recommend using CloudFlare, detailed below.

### Next Steps
So now that you have your blog up and running, you could just stop there.  However, if you really plan on **blogging**, you should consider doing some additional steps to protect your blog from hackers, make it go faster and let it scale - for when it become really popluar.

#### CloudFlare
For those of you who aren't familiar with [Cloudflare](http://www.cloudflare.com), its a great - *free* -  service to add on top of any site that helps speed it up, keep it safe and reduce load.

	Note: CloudFlare replaces your current DNS service, so you'll need access to your domain registrar to update your name servers.

Here is a high-level overview of some of its benefits:

1. **Speed**.  It acts as a content delivery network for your site and keeps cached copies of it on its servers around the globe.  Your visitors will get the copy that closest to them ensuring the fastest pageloads possible.
2. **Overhead**.  If the bulk of your content is static, then the majority of your traffic will be served by the caches. This means your server will only see cache refreshes or dynamic content requests and you can size your instances smaller than if they had to server it all. And we all know smaller instances cost less!
2. **Security**. As all traffic routes through them, they scan it for known threats and block them before they reach your servers.  This is a huge deal as protecting your site from being hacked will help ensure a happy blogging experience for both you and your readers.

#### Centralized Storage
One of the downsides to Elastic Beanstalk is that the storage is not persistent and its not shared.  We solved this for a single instance environment using our second EBS volume for our content directory. However, if you scale your site up beyond a single instance, this won't work. As this affects one of our goals of scaling with demand, this is definitely no bueno. But have no fear, using [S3FS](https://code.google.com/p/s3fs/wiki/FuseOverAmazon), you can mount an S3 bucket as your content directory.  This works *pretty well* - so long as you don't use AWS's US-EAST-1 region - and will allow your site to scale to multiple instances without issue. If the load of your site demands, I would highly reccomend doing this.

#### Monitoring and Logging
As with any production-level environment, its always a good practice to setup proper monitoring, alerts and logging.  Elastic Beanstalk make this quite straight-forward as you get basic infrastructure monitoring out of the box.  I would recommend taking some time to setup the basic thresholds and alerts to notify you of any issues that may arise.  You can also enable CloudWatch Logging through an ebextensions config that will send all your system logs to CloudWatch where you can create custom alerts based on events within your logs. [Here is a good walkthrough of the process](http://aws.amazon.com/blogs/aws/cloudwatch-log-service/).

Couple these with Google Analytics within your theme or through CloudFlare and you'll have everything you need to monitor traffic and performance for your blog.

### Conclusion
If everything went correctly, you should now have a stable, durable blogging environment that you can grow with your demand. I hope you found this walkthrough useful.  If anything, its a great way to exercise your knowledge of the AWS stack and its many useful services.

If you have any questions or suggestions, feel free to use the comments below or hit me up via [Twitter](http://twitter.com/boringgeek).

#### Sources:

- [Six Steps to Deploy Ghost to AWS Elastic Beanstalk](http://blogs.aws.amazon.com/application-management/post/Tx37ALIK2KLNIVC/Six-Steps-to-Deploy-Ghost-to-AWS-Elastic-Beanstalk)
- [Installing Ghost & Getting Started](http://docs.ghost.org/installation/deploy/)
- [Using Amazon RDS with Node.js](http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_nodejs.rds.html)
- [Mount EBS Volume to Amazon Elastic Beanstalk Environment](http://www.jcabi.com/jcabi-beanstalk-maven-plugin/example-ebs-volume.html)
- [OpenShift Ghost Quickstart](https://github.com/openshift-quickstart/openshift-ghost-quickstart/blob/master/.openshift/action_hooks/deploy)
- [Undocumented post-deploy hooks](https://forums.aws.amazon.com/thread.jspa?messageID=493887)
]]></content:encoded>
      <dc:date>2014-07-22T07:00:00+00:00</dc:date>
    </item>
    <item>
      <title>Add or Update Tags on Existing Elastic Beanstalk Environments</title>
      <link>http://www.boringgeek.com/add-or-update-tags-on-existing-elastic-beanstalk-environments</link>
      <description><![CDATA[Back in May, Amazon introduced the ability to tag your Beanstalk environments. This is great for anyone that properly uses tags to monitor, track and account for the resources they are using.  One challenge that I’ve run into recently, though, is that this is only during the creation of an environment; AWS currently doesnt offer the ability to add, remove or update tags to existing environments.

]]></description>
      <pubDate>Sat, 12 Jul 2014 21:33:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/add-or-update-tags-on-existing-elastic-beanstalk-environments</guid>
      <content:encoded><![CDATA[Back in May, Amazon introduced the ability to tag your Beanstalk environments. This is great for anyone that properly uses tags to monitor, track and account for the resources they are using.  One challenge that I've run into recently, though, is that this is only during the creation of an environment; AWS currently doesnt offer the ability to add, remove or update tags to existing environments.

For those of you that want to make that happen, here are some simple, albeit long, instructions on how to rotate environments out with new, properly tagged ones.

1. From the AWS Console, select Elastic Beanstalk from the Services Menu.
2. Click the name of the application you wish to tag. This will take you to the “Environments” view for this particular app.
3. From the “Actions” menu at the top right of the console, choose “Launch New Environment”.
4. Follow the wizard to spin up a new “B” environment for the specific environment you wish to update.
	- For example, if this were for a "NODE-APP-PRD" environment, create an environment titled “NODE-APP-PRD-B”.
	- Ensure the configurations matche that of the desired environment. (One thing you could do is save a configuration of the base environment.)
	- Ensure that the correct version of the code is deployed to this environment.
	- For this environment, do not worry about putting any tags in; this is simply a temporary space and you will terminate it once you're done.
5. Have the development team for the App test the environment and confirm functionality.
6. If everything is working as expected, click on the title of the new “B” environment to view that specific environment.
7. From the “Actions” menu on the top right, select “Save Configuration” to save a copy of the configuration. Name the configuration after the environment it is for.
8. From the “Environments” view for the application, click the “Swap URLs” button from the top right.
9. Select the correct two environments that you would like to swap and click the “Swap” button.
10. Once the URL swap is complete, have the development team test the app again and confirm functionality.
11. From the “Environments” view for the application, click the title of the original environment.
12. From the “Actions” menu on the top right and select “Terminate the original environment.
	- This will warn that the URL “NODE-APP-PRD-B.elasticbeanstalk.com” will be deleted.  This is ok; it's a temp URL anyway.  The real URL is currently assigned to the “B” environment.
13. Once the environment has been terminated, return to the “Environments” view for the application and click “Launch New environment” from the actions menu.
14. Follow the wizard to recreate the original environment.
	* Be sure to select the configuration you just saved.
	* Enter in the correct tags following the format that works for your organization.
15. Launch the new environment.
16. Once the environment is launched, confirm the configuration settings are correct and that the tags are showing up properly.
17. Have the development team confirm that the new environment is functioning properly.
18. From the “Environments” view for this application, select “Swap URLs” from the top right and swap the A and B URLS. This will point the original URL to the new, properly tagged environment.
19. Have the development team confirm that the environment is functioning properly
20. Terminate the “B” environment.

Thats pretty much it.  While there are a lot of steps, its pretty straight forward for an interim option while we wait for updated AWS functionality.  Another benefit of following this process is that it allows you to make the swap without any downtime for your end users.

If you have any suggestions or thougths on this, let me know in the comments!
]]></content:encoded>
      <dc:date>2014-07-12T21:33:00+00:00</dc:date>
    </item>
    <item>
      <title>New Years Resolutions: SaaS Mastery</title>
      <link>http://www.boringgeek.com/another-year-of-opportunity</link>
      <description><![CDATA[Every year, a large chunk of the people who set resolutions are destined for failure. Complete and utter failure. While we can all speculate the reasons, more often than not, it comes down to a combination of procrastination, unactionable goals and lack of a clear game plan.  Seriously.

]]></description>
      <pubDate>Wed, 08 Jan 2014 05:12:27 +0000</pubDate>
      <guid>http://www.boringgeek.com/another-year-of-opportunity</guid>
      <content:encoded><![CDATA[Every year, a large chunk of the people who set resolutions are destined for failure. Complete and utter failure. While we can all speculate the reasons, more often than not, it comes down to a combination of procrastination, unactionable goals and lack of a clear game plan.  Seriously.

If you plan on making goals this year, sit down for a moment and consider doing the following:  

* Write down each goal.
* For each goal write:
	* Why you feel it should be a goal.
    * What you hope to accomplish by achieving that goal.
    * How you plan to achieve the goal.
* Review each goal to see how achievable or actionable the goal is.  
For example, "Lose weight" is a decent goal, but "Lose 25lbs by March 1st" is far better.  It sets a _**specific**_ goal and a _**timeframe**_ for reaching it.

Some things to consider:  

* Don't be scared to put lofty goals.  Just try not to make them the majority.
* They don't all have to be serious. Just try to ensure they are deeply personal to you. Otherwise you are less likely to achieve them.  
	* For example, a good friend of mine put "Drive a Tesla" for one of his.  Sounds pretty mundane, but as a lover of all things tech, it will bring him a great deal of joy and happiness. Not to mention it will probably lead to a future goal of "Own a Tesla by 201X".

The whole idea of the exercise is to do more than state your goals, but instead create a clear list of achieveable goals with an real action plan to achieve them.

Another fun activity is to put these in a place where your friends can see them and then hold you accountable for them.  

Or better yet, you can hold yourself accountable...

###Last Year's Goals In Review

[Last year was my first year of really setting any formal goals](/the-year-of-the-hustle/).  I was a bit agressive, but as the post describes, I felt it was deeply necessary. Below is the list of goals with my review of how successful I was. Enjoy.

* Restore the web assets I lost to a hacker.
	* **Success.** Not only have all the sites been restored, but I have also decided to shutter my consulting company, Epoxy Labs, Inc., and replace it with a new company focused on deliverying SaaS solutions [Alchemy Codeworks](http://www.alchemycodeworks.com).
* Restore my portfolio.
	* **Sort-of Successful.** Available free time was a challenge, so nothing has been shipped yet. However, I remain optimistic that this will be resolved towards the end of this month.  I'd rather be a month late, than not at all.
* Introduce two simple SaaS applications.
	* **Unsuccessful.** As much as i wish I could report otherwise, I was unable to acheive this goal. Progress is being made, just at a much slower pace than expected. Still focused on delivering these through platforms such as [Shopify](http://shopify.com) and [Envato](http://envato.com).
* Complete one 30x500 style project.
	* **Unsuccessful.** I knew this was lofty to begin with, but is still a good goal and will carry forward to 2014.
* Get my name back out into the wild.
	* **Unsuccessful.** This is still a goal and will carry forward to 2014.

When I wrote these goals, it was already clear that I had deviated away from what I truly enjoyed doing. So even though I wasn't able to make as much progress as I had hoped, the little I did make had a profound impact on my mood and general well-being. Also, due to a serious health concern, I also changed my role at my day job.  My current position as a Solutions Architect, not only lets me do what I truly love, but honestly sets my mind free and brings me tremendous amounts of joy. It shouldn't surprise you to know how much mood plays a role in your success towards anything.

###This Years Goals

* Carry overs from last year:
	* **Introduce two simple SaaS applications.**
    These should be simple and be build on an existing platform that handles things such as billing and dsitribution.  Two platforms from last year still stand out to me: [Shopify](http://www.shopify.com) and [Envato](http://www.envato.com).  
    * **Complete one 30x500 style project.**  
    This one is the big one. The goal is to make my own product that I own and run.  I've already defined it and am taking steps to build it. The goal is to reach minimum viable product by the end of January, but due to circumstances, this could slip to March.  Any later than that and you can all throw a slushy at me.  
&nbsp;

* New goals for this year:
	* **Give back to at least one OSS project**  
    I've been benefitting from OSS for years and it's honestly time to give back.  I will select from one of the following projects:
    	* Laravel PHP Framework
        * Ghost Blogging Platform
        * Ubuntu Linux
    * **Attend Google I/O as a developer**  
    I've been trying to go to I/O for years. I am a Google fan-boy before Apple and feel like attending this event will bring me a great deal of happiness, but also help inspire some of my other goals.
    * **Teach my son to swim.**  
	Last summer I didn't take the opportunity and deeply regret it.  He is definitely ready, so this spring/summer this is happening.

As usual, I will continue to finese these throughout the year and am open to suggestions.  I wish you all luck with your goals.  2014 is going to be a truly great year. Make it YOUR year.
]]></content:encoded>
      <dc:date>2014-01-08T05:12:27+00:00</dc:date>
    </item>
    <item>
      <title>Instructions: Build Mcrypt for OSX Mavericks</title>
      <link>http://www.boringgeek.com/instructions-build-mcrypt-for-osx-mavericks</link>
      <description><![CDATA[Yes, another post on Mcrypt, but this time for OSX Mavericks.  I cannot stress how frustrated I was when upgrading to Mountain Lion hosed my web development environment, let alone when it did it again upgrading to Mavericks.  Here is a great post on compiling PHP 5.4.17 with Mcrypt on OSX 10.9.
]]></description>
      <pubDate>Sun, 01 Dec 2013 20:00:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/instructions-build-mcrypt-for-osx-mavericks</guid>
      <content:encoded><![CDATA[Yes, another post on Mcrypt, but this time for OSX Mavericks.  I cannot stress how frustrated I was when upgrading to Mountain Lion hosed my web development environment, let alone when it did it again upgrading to Mavericks.  Here is a great post on [compiling PHP 5.4.17 with Mcrypt on OSX 10.9](http://www.coolestguidesontheplanet.com/install-mcrypt-php-mac-osx-10-9-mavericks-development-server/).
]]></content:encoded>
      <dc:date>2013-12-01T20:00:00+00:00</dc:date>
    </item>
    <item>
      <title>Workaround: MCrypt bug in Ubuntu 13.10</title>
      <link>http://www.boringgeek.com/workaround-mcrypt-bug-in-ubuntu-13-10</link>
      <description><![CDATA[Having problems installing PHP5-MCrypt on Ubuntu 13.10?  You’re not alone.  Apparently this is a bug with the latest version of Ubuntu, where they changed the default location for php modules, but mcrypt was apparently left behind. For full details and a workaround, feel free to visit this Ubuntu Stack Exchange thread.
]]></description>
      <pubDate>Mon, 25 Nov 2013 20:00:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/workaround-mcrypt-bug-in-ubuntu-13-10</guid>
      <content:encoded><![CDATA[Having problems installing PHP5-MCrypt on Ubuntu 13.10?  You're not alone.  Apparently this is a bug with the latest version of Ubuntu, where they changed the default location for php modules, but mcrypt was apparently left behind. For full details and a workaround, feel free to visit this [Ubuntu Stack Exchange thread](http://askubuntu.com/questions/360646/cant-use-php-extension-mcrypt-in-ubuntu-13-10-nginx-php-fpm).
]]></content:encoded>
      <dc:date>2013-11-25T20:00:00+00:00</dc:date>
    </item>
    <item>
      <title>Enter: Alchemy Codeworks</title>
      <link>http://www.boringgeek.com/enter-alchemy-codeworks</link>
      <description><![CDATA[Starting from scratch, with severely limited free time, has been a challenge - to say the least. However, it has afforded me a few luxuries; most notable is that I can truly start fresh. Because of this, I have taken quite a bit of time to step back and evaluate new directions. My current company, Epoxy Labs, has served me well for many years. However, much of the work I have produced under that entity is either locked away behind NDA’s or no longer online. This was by design; it was meant to provide income and experience, not an elaborate, hyped portfolio. It also worked out well because my work spoke for itself and word of mouth recommendations replaced any need for ever advertising my services. However, times are changing - as is the model for the web. Custom, contract-driven, one-off solutions are no longer the value proposition that I want to target. Instead, I feel that its time to move on to something new. My goal now is to create a fresh company with a focus on delivering simple, intuitive and elegant SaaS solutions; read: products. These need to be so compelling that the ROI is instantly understandable and the barrier to purchase must be incredibly low. They need to be worth their weight in gold, but cost the same as tin.

]]></description>
      <pubDate>Mon, 25 Mar 2013 19:00:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/enter-alchemy-codeworks</guid>
      <content:encoded><![CDATA[Starting from scratch, with severely limited free time, has been a challenge - to say the least. However, it has afforded me a few luxuries; most notable is that I can truly start fresh. Because of this, I have taken quite a bit of time to step back and evaluate new directions. My current company, Epoxy Labs, has served me well for many years. However, much of the work I have produced under that entity is either locked away behind NDA's or no longer online. This was by design; it was meant to provide income and experience, not an elaborate, hyped portfolio. It also worked out well because my work spoke for itself and word of mouth recommendations replaced any need for ever advertising my services. However, times are changing - as is the model for the web. Custom, contract-driven, one-off solutions are no longer the value proposition that I want to target. Instead, I feel that its time to move on to something new. My goal now is to create a fresh company with a focus on delivering simple, intuitive and elegant SaaS solutions; read: products. These need to be so compelling that the ROI is instantly understandable and the barrier to purchase must be incredibly low. They need to be worth their weight in gold, but cost the same as tin.

With that in mind, I will be setting up and transitioning to a new entity: [Alchemy Codeworks](http://www.alchemycodeworks.com/). Epoxy Labs will not be restored and the remaining components will be shut down. It's going to take a few weeks to get everything finalized and setup, but expect something awesome.

If you're thinking of taking a similar step towards your own work, I highly recommend reading the following books:

* [The Age of the Platform: How Amazon, Apple, Facebook, and Google Have Redefined Business](http://www.amazon.com/Age-Platform-Facebook-Redefined-Business/dp/0982930259)
* [Rework](http://www.amazon.com/Rework-Jason-Fried/dp/0307463745/ref=sr_1_1?s=books&ie=UTF8&qid=1364260343&sr=1-1&keywords=rework)
* [The 4-Hour Workweek](http://www.amazon.com/4-Hour-Workweek-Anywhere-Expanded-Updated/dp/0307465357/ref=sr_1_1?s=books&ie=UTF8&qid=1364260384&sr=1-1&keywords=4+hour+work+week)
]]></content:encoded>
      <dc:date>2013-03-25T19:00:00+00:00</dc:date>
    </item>
    <item>
      <title>The Tomboy and The Geek is Back Online!</title>
      <link>http://www.boringgeek.com/the-tomboy-and-the-geek-is-back-online</link>
      <description><![CDATA[I have finally gotten The Tomboy and the Geek back online! This is third site I needed to restore and is right in-line with my Year of the Hustle post. This particular site is meant to help keep our friends and family in the loop with what we’ve been up to. The site previously housed years worth of pictures and content, so it will take a while to get the old content (as much as we still have) republished and available.

]]></description>
      <pubDate>Tue, 12 Feb 2013 20:00:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/the-tomboy-and-the-geek-is-back-online</guid>
      <content:encoded><![CDATA[I have finally gotten [The Tomboy and the Geek](http://www.thetomboyandthegeek.com) back online! This is third site I needed to restore and is right in-line with my [Year of the Hustle post](/the-year-of-the-hustle/). This particular site is meant to help keep our friends and family in the loop with what we've been up to. The site previously housed years worth of pictures and content, so it will take a while to get the old content (as much as we still have) republished and available.

As for the nerdy details - the site is powered by [Wordpress](http://www.wordpress.org) (naturally), is hosted on [Pagoda Box](http://www.pagodabox.com) and behind a [Cloudflare CDN] (http://cloudflare.com). In addition to that, the site is running a Redis cache that is storing both the session states and the content. I'm making nightly backups of the site which are emailed offsite and then stored in secure cloud solution. The content is also being abstracted to other providers (Vimeo, YouTube, Picasa Web Albums, etc) and simply being referenced. In this regard, if there ever is another incident, recovering should be as simple as a Git push and a DB restore. Lets hope I never have to test that.
]]></content:encoded>
      <dc:date>2013-02-12T20:00:00+00:00</dc:date>
    </item>
    <item>
      <title>CurtisRissi.com Is Back Online!</title>
      <link>http://www.boringgeek.com/curtisrissi-com-is-back-online</link>
      <description><![CDATA[I am happy to report that CurtisRissi.com up and online! Its not much, but its at least a start and will continue to increase in functionality over time.  As mentioned in my post, “The Year of the Hustle”, this is simply one item of step one, but is, by far, my most critical site and seeing tangible progress is invigorating.  The site is my first real attempt at implementing a Twitter Bootstrap theme and was a great learning experience.  If anyone reading this has suggestions, please list them in the comments; I’d love to hear them.
]]></description>
      <pubDate>Thu, 24 Jan 2013 20:00:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/curtisrissi-com-is-back-online</guid>
      <content:encoded><![CDATA[I am happy to report that [CurtisRissi.com](http://www.curtisrissi.com) up and online! Its not much, but its at least a start and will continue to increase in functionality over time.  As mentioned in my post, "The Year of the Hustle", this is simply one item of step one, but is, by far, my most critical site and seeing tangible progress is invigorating.  The site is my first real attempt at implementing a Twitter Bootstrap theme and was a great learning experience.  If anyone reading this has suggestions, please list them in the comments; I'd love to hear them.
]]></content:encoded>
      <dc:date>2013-01-24T20:00:00+00:00</dc:date>
    </item>
    <item>
      <title>Pagoda Box</title>
      <link>http://www.boringgeek.com/pagoda-box</link>
      <description><![CDATA[For the past few months I have been experimenting with the various Platform as a Service (PaaS) providers for PHP and the winner so far is hands down - Pagoda Box.  This amazing tool is still under active development, but is insanely cheap and offers some amazing functionality that its competitors don’t.  Probably most compelling feature is its support for persistent files storage with - wait for it - SSH access. That’s correct - not everything has to be stored in Git. If you haven’t decided on a PHP PaaS solution, or even if you already have, I recommend checking them out.
]]></description>
      <pubDate>Mon, 21 Jan 2013 20:00:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/pagoda-box</guid>
      <content:encoded><![CDATA[For the past few months I have been experimenting with the various Platform as a Service (PaaS) providers for PHP and the winner so far is hands down - [Pagoda Box](http://www.Pagodabox.com).  This amazing tool is still under active development, but is insanely cheap and offers some amazing functionality that its competitors don't.  Probably most compelling feature is its support for persistent files storage with - wait for it - SSH access. That's correct - not everything has to be stored in Git. If you haven't decided on a PHP PaaS solution, or even if you already have, I recommend checking them out.
]]></content:encoded>
      <dc:date>2013-01-21T20:00:00+00:00</dc:date>
    </item>
    <item>
      <title>The Year of the Hustle</title>
      <link>http://www.boringgeek.com/the-year-of-the-hustle</link>
      <description><![CDATA[2013 has begun and so far its off to a great start; the holidays were fantastic, the kids are happy and Nancy and I have a renewed focus on making ourselves independent. In a nutshell, this year is going to be the year of the hustle. To help kick it off with a bang, my focus is going to be on new sites and projects built with modern tools and cloud-based infrastructure.  Yup, if it all works out, 2013 is going to be one wild ride.

]]></description>
      <pubDate>Sun, 06 Jan 2013 20:00:00 +0000</pubDate>
      <guid>http://www.boringgeek.com/the-year-of-the-hustle</guid>
      <content:encoded><![CDATA[2013 has begun and so far its off to a great start; the holidays were fantastic, the kids are happy and Nancy and I have a renewed focus on making ourselves independent. In a nutshell, this year is going to be the year of the hustle. To help kick it off with a bang, my focus is going to be on new sites and projects built with modern tools and cloud-based infrastructure.  Yup, if it all works out, 2013 is going to be one wild ride.

Rough plan of attack:

* Restore lost web assets. This includes [CurtisRissi.com](http://www.curtisrissi.com), [BoringGeek.com](http://www.boringgeek.com), [The Tomboy and The Geek](http://www.thetomboyandthegeek.com) and [Epoxy Labs](http://www.epoxylabs.com). Some of you may know that I lost my sites due to my EC2 instance getting hacked by a botnet - and laziness with regard to my own backups. This time around the sites are going to be hosted on an online PaaS - [Pagoda Box](http://www.pagodabox.com) with Cloudflare acting both as a CDN and a threat management solution.
* Restore my portfolio.  I've been pretty much out of development for almost two years now as I've been working as a PM and Manager during the day. I'm realizing this isn't my desired career path and that my portfolio has pretty much evaporated in front of my eyes. To help, I'm getting up to speed with some cool projects such as Twitter Bootstrap and Laravel.
* Introduce two simple SaaS applications.  I'm going to target online services that have their own app stores, such as Shopify and Big Commerce among others. This is an effort to bring in some extra income to help reduce debt so that I can focus on item number 4.
* Complete one 30x500 style project.  For those not familiar with 30x500, you can learn all about it here: Amy Hoy's 30x500.  In a nutshell the concept is producing one useful product or service that you can sell to 500 people for $30 a month.  That equates to roughly $180K a year in income.  The idea isn't to get rich, but instead to make a living on your own.
* Get my name back out into the wild.  To do this, I plan on speaking, at minimum, at one conference and contributing to at least two open source projects. We'll see how this goes.

If you have any additional ideas or suggestions, I'd love to hear them.  I'll update this list as new goals materialize.
]]></content:encoded>
      <dc:date>2013-01-06T20:00:00+00:00</dc:date>
    </item>
    <dc:date>2015-11-12T21:20:00+00:00</dc:date>
  </channel>
</rss>