We moved. Actually, we bought a house. We weren’t planning on it. We weren’t saving for it. It was basically handed to us on a silver platter. Back in April or May we were discussing our current living arrangements. We were in an amazing apartment with no upstairs neighbors. The upstairs neighbors had moved out in April. They were quite noisy with an even noisier large dog that was afraid of being alone…

Since we’ve rented for quite a long time, that was our first idea. Let’s move out of the apartment and find a rental house to move into. We were getting frustrated with high rental prices, and the thought popped into my head one Saturday morning to see if there were any zero down financing options. Purchasing can be so much cheaper month to month, so we decided to step out in faith, ask the Lord to shut it down if it wasn’t what we were supposed to do, apply for a loan, and just wait to see what would happen. Lo and behold we were pre-approved! Let’s start shopping!

We got plugged in with a realtor that was mediocre. We weren’t crazy about him. The morning after we met him we went out on our own and checked out a place in Aubrey that was for sale by a company called Open Door. They have a pretty slick mobile app that can take your location and give you a door code for a private tour of nearby homes. OpenDoor purchases the homes so they are vacant when you tour. No working around homeowner schedules or dashing around trying to coordinate with a realtor. You can bring a realtor if you like, but it’s not necessary. Perfect.

We walked in and loved every bit of the layout, price, and location. OpenDoor called us later that day to discuss the process. It took maybe ten minutes. We made an offer the next day. It was accepted the day after. Talk about quick! Our house had been on the market for just over a month and we were the first and only offer which is just crazy in the DFW market. We went through inspection, contract, foundation inspection, etc. and at closing we were actually walking away with money. 😲

We paid our earnest money, inspection, and other fees, but we still came out with no money down and zero paid at closing because OpenDoor basically covered all of it. Unheard of.

So we moved. We moved out of our apartment into a home in Aubrey. It has all of the space that we need. It has all of the things that we wanted. It was such a gift from The Lord. It couldn’t have worked out better.

Dynamics & Inherited Interfaces

A coworker and I made an interesting discovery today. I was getting a SQL error back indicating that a method–one that was clearly available to my object–wasn’t being found. We’d run into this issue before and found a work around, but it wasn’t until today that we dug in figured out why it was happening.

We’re using Dapper as our ORM. We use these statements all the time.

_db.Execute(“SELECT TOP 1 FROM dbo.MyTable”);
_db.Query("UPDATE dbo.MyTable SET MyField = 'new value'");

Many times we pass in data as such:

_db.Execute(“SELECT TOP 1 FROM dbo.MyTable WHERE Id = @id”, new {id = 5});

In this case, 5 would be some strongly typed object or variable. Dapper does great with these. We created a wrapper for Dapper that gives us some extra functionality:

public interface ICoolDb : IDapperDatabase
void WithTransaction(Action action);

The above is just an example of something you could do for wrapping up a bunch of SQL statements in a transaction. No biggie, right? This is also where the issue lies. I only have one method available here. If I try to pass in a dynamic object to Execute or Query, the compiler doesn’t evaluate the available methods until runtime. When it does evaluate, it doesn’t pick up the inherited interface methods of Execute or Query from IDapperDatabase, so it throws an error. For some reason, the compiler doesn’t know to work up the inheritance tree to find those methods. #fail

_db.Execute(“SELECT TOP 1 FROM dbo.MyTable WHERE Id = @id”, new {id = 5});

This works because id is strongly typed as int. The fix that we came up with awhile back was this:

_coolDb.Execute(sql, account as object);

This casts our dynamic account object as object which makes everyone happy. I’m not sure if this same quirk applies to later versions of .NET, but we’re running 4.5 and it’s there. It’s annoying to add that as object bit in there each time I’m passing a dynamic, but I guess it’s the best we can do.

Scale Or Optimize

As documented earlier this week, I migrated my whole online ecosystem to AWS over the weekend. It was a fun project. I shared this with a co-worker at lunch today which naturally launched into a conversation about our own environment in the healthcare industry. Because of HIPPA compliance and such, it’s probably not a worthwhile endeavor (for now at least). Our conversation led to scale in general. Does every app really need to scale to the level that AWS allows? Probably not. We own our servers, and, as far as I know, we have maybe three boxes…not even enough to fill a rack. Maybe there’s more, but we support tons of stuff on those three boxes. AWS is way overkill for my measly WordPress site, but it was fun to build and get some experience in nonetheless.

So, should we plan for scaling? Or should we optimize our existing code base to be as performant as possible while minimizing our additional overhead in load-balancers and other such fun magic? We chose to simplify. Less code to maintain means we get to do more fun projects in the future because we have far less cognitive load in keeping up an increasingly complex code base that has more room for bugs. Fewer lines and less complicated architecture keeps smells from creeping in because there’s no place for it to hide.

Migrating to AWS

I spent some time over the course of this past week migrating my entire online ecosystem to AWS. There was talk at work about using the AWS SQS for some pushes that we have for various objects to various back-end service providers. I already have a CDN at AWS, so I took the opportunity to migrate a piece at a time.

I started by moving DNS to Route53. I created a new CloudFront for my static site and requested some new certificates using ACM. Once I got certs applied to the new CloudFront instance, I moved my static site (this one) to S3. I shuffled the DNS around to point to the right place. I’d spent some time awhile back with GitLab’s pipelines to automatically deploy this Jekyll site. Now I’ve got a dilemma: at this point because I couldn’t automatically deploy to S3 from GitLab. I could; I just wasn’t sure how. More on this later.

The other project I took on was getting familiar with RDS and EC2. I started by pointing the existing site (not on AWS) to the RDS instance. I got that working, then recreated my WordPress install on EC2. I got that working, but certs were broken… 😕 The whole reason I switched to ACM was to keep from having to upload new certs through the AWS CLI each time I needed to renew. After some quick research, I discovered that ACM can manage certs automatically but only for Elastic Beanstalk and load balanced instances. Oi! I guess I’m going to get real comfortable with AWS!

I did some reading on ELB and got everything sorted out there for a WordPress install. After some trial and error, I finally got it working on Saturday morning. This was the trickiest part, not due to anything AWS related, but in how I wanted my SSL to work. I don’t want anything non-SSL on any site. After some finagling of the WordPress database, and a lot of tinkering with the ELB environment and load balancer, I’ve got it working exactly how I want it.

Now, back to CI for my static site. Naturally I started with the code repository. I moved the repo to CodeCommit, created a CodeBuild project, then automated all of it with CodePipeline. This was the easiest part of the whole process, and it put a big smile on my face. Even this post has been automatically deployed using all of the magic above. Git push, and we’re on our way.

To summarize:

  • Moved DNS to Route53
  • Moved SSL certs to ACM
  • Moved static professional site to S3
  • Moved WordPress family site to ELB with load balancer (like we’ll ever need it 😉 )
  • Moved repos for both sites to CodeCommit
  • Automated deployment for each site to ELB and S3 with CodeBuild and CodePipeline respectively
  • All of the above include establishing IAM roles and policies to ensure appropriate access for every service involved in the processes

After some lengthy evenings (in the midst of trying to buy a house!), I was done…at least for now. It was frustrating at times because I was in some very new and foreign territory to me. Thanks to lots of tutorials, I was successful.

I was very pleased with the entire experience, though. Amazon has made it incredibly easy to onboard into their ecosystem…almost too easy. It was an extremely fun project. Their documentation is stellar. The community around it is also very active and seems to provide lots of helpful tips. I’m not on a paid support plan, so it took a little bit of digging to find the answers I needed, but I can’t see myself moving from AWS for quite awhile.

Why I Deleted My LinkedIn Account

I pulled the trigger on deleting my LinkedIn account just last week. Some people might think this is crazy in time when social networking is pretty much a given in the world. I don’t use Facebook for much of anything these days. I might use it for authentication to a site or service if I’m feeling lazy. Twitter gets the same treatment. I have a very slim online profile for privacy concerns above all else, but secondarily, I just don’t want the cognitive load. I like to own my information, own my writing, own my eyeballs…

Let me preface this next paragraph. Recruiters are great, and I’m thankful that I have my current job through one.

That said, with the number of recruiter calls that I got last year and even continuing on into this year despite my being very happy with my job and not actively searching, I started to wonder why they might think I’m interested in a new job. Like most of you, I routinely brush up my resume on LinkedIn to keep it current and document various projects I work on. I wonder if LinkedIn has some sort of mechanism that puts that info into recruiter’s hands even though I chose the “don’t publicize this update option”. As I said, recruiters are awesome. I’m just not in a season that I want to entertain anything but once in a lifetime opportunities.

If you’re looking for me out on the internet, this is my home. I can’t share much of what I do as it’s HIPPA protected, but I’ll try to share some snippets and thoughts from time to time here.